aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-12-09 22:50:49 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2009-12-09 22:50:49 -0500
commit3e7468313758913c5e4d372f35b271b96bad1298 (patch)
treeeb612d252a9e2349a1173451cd779beebd18a33e
parent6825fbc4cb219f2c98bb7d157915d797cf5cb823 (diff)
parente97f4677961f68e29bd906022ebf60a6df7f530a (diff)
Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6
* 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6: (345 commits) V4L/DVB (13542): ir-keytable: Allow dynamic table change V4L/DVB (13541): atbm8830: replace 64-bit division and floating point usage V4L/DVB (13540): ir-common: Cleanup get key evdev code V4L/DVB (13539): ir-common: add __func__ for debug messages V4L/DVB (13538): ir-common: Use a dynamic keycode table V4L/DVB (13537): ir: Prepare the code for dynamic keycode table allocation V4L/DVB (13536): em28xx: Use the full RC5 code on HVR-950 Remote Controller V4L/DVB (13535): ir-common: Add a hauppauge new table with the complete RC5 code V4L/DVB (13534): ir-common: Remove some unused fields/structs V4L/DVB (13533): ir: use dynamic tables, instead of static ones V4L/DVB (13532): ir-common: Add infrastructure to use a dynamic keycode table V4L/DVB (13531): ir-common: rename the debug routine to allow exporting it V4L/DVB (13458): go7007: subdev conversion V4L/DVB (13457): s2250: subdev conversion V4L/DVB (13456): s2250: Change module structure V4L/DVB (13528): em28xx: add support for em2800 VC211A card em28xx: don't reduce scale to half size for em2800 em28xx: don't load audio modules when AC97 is mis-detected em28xx: em2800 chips support max width of 640 V4L/DVB (13523): dvb-bt8xx: fix compile warning ... Fix up trivial conflicts due to spelling fixes from the trivial tree in Documentation/video4linux/gspca.txt drivers/media/video/cx18/cx18-mailbox.h
-rw-r--r--Documentation/DocBook/dvb/dvbapi.xml13
-rw-r--r--Documentation/DocBook/dvb/dvbproperty.xml (renamed from Documentation/DocBook/dvb/isdbt.xml)4
-rw-r--r--Documentation/DocBook/dvb/frontend.h.xml415
-rw-r--r--Documentation/DocBook/dvb/frontend.xml185
-rw-r--r--Documentation/DocBook/media-entities.tmpl3
-rw-r--r--Documentation/DocBook/v4l/controls.xml20
-rw-r--r--Documentation/DocBook/v4l/pixfmt.xml5
-rw-r--r--Documentation/DocBook/v4l/videodev2.h.xml7
-rw-r--r--Documentation/DocBook/v4l/vidioc-g-fbuf.xml17
-rw-r--r--Documentation/video4linux/CARDLIST.cx238852
-rw-r--r--Documentation/video4linux/CARDLIST.cx881
-rw-r--r--Documentation/video4linux/CARDLIST.em28xx3
-rw-r--r--Documentation/video4linux/CARDLIST.saa71342
-rw-r--r--Documentation/video4linux/gspca.txt19
-rw-r--r--Documentation/video4linux/si4713.txt2
-rw-r--r--Documentation/video4linux/zr364xx.txt1
-rw-r--r--drivers/media/common/Makefile2
-rw-r--r--drivers/media/common/ir-functions.c71
-rw-r--r--drivers/media/common/ir-keymaps.c167
-rw-r--r--drivers/media/common/ir-keytable.c429
-rw-r--r--drivers/media/common/saa7146_video.c16
-rw-r--r--drivers/media/common/tuners/Kconfig7
-rw-r--r--drivers/media/common/tuners/Makefile1
-rw-r--r--drivers/media/common/tuners/max2165.c442
-rw-r--r--drivers/media/common/tuners/max2165.h48
-rw-r--r--drivers/media/common/tuners/max2165_priv.h60
-rw-r--r--drivers/media/common/tuners/mxl5005s.c5
-rw-r--r--drivers/media/common/tuners/mxl5005s.h4
-rw-r--r--drivers/media/common/tuners/mxl5007t.c2
-rw-r--r--drivers/media/common/tuners/tda18271-common.c16
-rw-r--r--drivers/media/common/tuners/tda18271-fe.c114
-rw-r--r--drivers/media/common/tuners/tda18271-maps.c1
-rw-r--r--drivers/media/common/tuners/tda18271-priv.h47
-rw-r--r--drivers/media/common/tuners/tda18271.h12
-rw-r--r--drivers/media/common/tuners/tda8290.c1
-rw-r--r--drivers/media/common/tuners/tda9887.c2
-rw-r--r--drivers/media/common/tuners/xc5000.c97
-rw-r--r--drivers/media/common/tuners/xc5000.h6
-rw-r--r--drivers/media/dvb/bt8xx/dvb-bt8xx.c2
-rw-r--r--drivers/media/dvb/dm1105/dm1105.c12
-rw-r--r--drivers/media/dvb/dvb-core/dvb_demux.c39
-rw-r--r--drivers/media/dvb/dvb-core/dvb_demux.h5
-rw-r--r--drivers/media/dvb/dvb-core/dvb_frontend.c179
-rw-r--r--drivers/media/dvb/dvb-core/dvbdev.h28
-rw-r--r--drivers/media/dvb/dvb-usb/Kconfig8
-rw-r--r--drivers/media/dvb/dvb-usb/Makefile3
-rw-r--r--drivers/media/dvb/dvb-usb/af9015.c33
-rw-r--r--drivers/media/dvb/dvb-usb/af9015.h215
-rw-r--r--drivers/media/dvb/dvb-usb/cxusb.c117
-rw-r--r--drivers/media/dvb/dvb-usb/dib0700_devices.c182
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-dvb.c1
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-ids.h11
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb.h3
-rw-r--r--drivers/media/dvb/dvb-usb/ec168.c440
-rw-r--r--drivers/media/dvb/dvb-usb/ec168.h73
-rw-r--r--drivers/media/dvb/dvb-usb/friio-fe.c59
-rw-r--r--drivers/media/dvb/firewire/Kconfig7
-rw-r--r--drivers/media/dvb/firewire/Makefile1
-rw-r--r--drivers/media/dvb/firewire/firedtv-1394.c41
-rw-r--r--drivers/media/dvb/firewire/firedtv-avc.c54
-rw-r--r--drivers/media/dvb/firewire/firedtv-dvb.c15
-rw-r--r--drivers/media/dvb/firewire/firedtv-fw.c376
-rw-r--r--drivers/media/dvb/firewire/firedtv-rc.c2
-rw-r--r--drivers/media/dvb/firewire/firedtv.h19
-rw-r--r--drivers/media/dvb/frontends/Kconfig21
-rw-r--r--drivers/media/dvb/frontends/Makefile3
-rw-r--r--drivers/media/dvb/frontends/atbm8830.c495
-rw-r--r--drivers/media/dvb/frontends/atbm8830.h76
-rw-r--r--drivers/media/dvb/frontends/atbm8830_priv.h75
-rw-r--r--drivers/media/dvb/frontends/au8522_decoder.c22
-rw-r--r--drivers/media/dvb/frontends/au8522_priv.h2
-rw-r--r--drivers/media/dvb/frontends/dib7000p.c33
-rw-r--r--drivers/media/dvb/frontends/dib7000p.h13
-rw-r--r--drivers/media/dvb/frontends/dib8000.c23
-rw-r--r--drivers/media/dvb/frontends/dib8000.h14
-rw-r--r--drivers/media/dvb/frontends/ds3000.c1367
-rw-r--r--drivers/media/dvb/frontends/ds3000.h45
-rw-r--r--drivers/media/dvb/frontends/ec100.c335
-rw-r--r--drivers/media/dvb/frontends/ec100.h46
-rw-r--r--drivers/media/dvb/frontends/ec100_priv.h39
-rw-r--r--drivers/media/dvb/frontends/s5h1409.c149
-rw-r--r--drivers/media/dvb/frontends/s5h1409.h7
-rw-r--r--drivers/media/dvb/frontends/stb6100_proc.h138
-rw-r--r--drivers/media/dvb/frontends/stv0900.h3
-rw-r--r--drivers/media/dvb/frontends/stv0900_core.c1560
-rw-r--r--drivers/media/dvb/frontends/stv0900_init.h257
-rw-r--r--drivers/media/dvb/frontends/stv0900_priv.h81
-rw-r--r--drivers/media/dvb/frontends/stv0900_reg.h5000
-rw-r--r--drivers/media/dvb/frontends/stv0900_sw.c3171
-rw-r--r--drivers/media/dvb/frontends/stv090x.c242
-rw-r--r--drivers/media/dvb/frontends/stv090x_priv.h3
-rw-r--r--drivers/media/dvb/frontends/stv090x_reg.h70
-rw-r--r--drivers/media/dvb/frontends/stv6110.c13
-rw-r--r--drivers/media/dvb/frontends/stv6110.h1
-rw-r--r--drivers/media/dvb/frontends/stv6110x.c6
-rw-r--r--drivers/media/dvb/pt1/pt1.c1
-rw-r--r--drivers/media/dvb/pt1/va1j5jf8007s.c57
-rw-r--r--drivers/media/dvb/pt1/va1j5jf8007t.c49
-rw-r--r--drivers/media/dvb/siano/sms-cards.c4
-rw-r--r--drivers/media/dvb/siano/sms-cards.h2
-rw-r--r--drivers/media/dvb/siano/smscoreapi.c2
-rw-r--r--drivers/media/dvb/siano/smssdio.c2
-rw-r--r--drivers/media/dvb/ttpci/budget-av.c2
-rw-r--r--drivers/media/dvb/ttpci/budget-ci.c18
-rw-r--r--drivers/media/dvb/ttusb-dec/ttusb_dec.c2
-rw-r--r--drivers/media/radio/Kconfig12
-rw-r--r--drivers/media/radio/Makefile1
-rw-r--r--drivers/media/radio/radio-mr800.c358
-rw-r--r--drivers/media/radio/tef6862.c232
-rw-r--r--drivers/media/video/Kconfig33
-rw-r--r--drivers/media/video/Makefile2
-rw-r--r--drivers/media/video/adv7180.c323
-rw-r--r--drivers/media/video/au0828/au0828-video.c2
-rw-r--r--drivers/media/video/bt819.c2
-rw-r--r--drivers/media/video/bt8xx/bttv-input.c15
-rw-r--r--drivers/media/video/cx18/cx18-av-core.c14
-rw-r--r--drivers/media/video/cx18/cx18-cards.h3
-rw-r--r--drivers/media/video/cx18/cx18-driver.c60
-rw-r--r--drivers/media/video/cx18/cx18-driver.h62
-rw-r--r--drivers/media/video/cx18/cx18-dvb.c9
-rw-r--r--drivers/media/video/cx18/cx18-fileops.c132
-rw-r--r--drivers/media/video/cx18/cx18-i2c.c25
-rw-r--r--drivers/media/video/cx18/cx18-ioctl.c3
-rw-r--r--drivers/media/video/cx18/cx18-mailbox.c62
-rw-r--r--drivers/media/video/cx18/cx18-mailbox.h6
-rw-r--r--drivers/media/video/cx18/cx18-queue.c346
-rw-r--r--drivers/media/video/cx18/cx18-queue.h41
-rw-r--r--drivers/media/video/cx18/cx18-scb.h4
-rw-r--r--drivers/media/video/cx18/cx18-streams.c92
-rw-r--r--drivers/media/video/cx18/cx18-streams.h10
-rw-r--r--drivers/media/video/cx18/cx18-vbi.c35
-rw-r--r--drivers/media/video/cx18/cx18-vbi.h2
-rw-r--r--drivers/media/video/cx18/cx18-version.h2
-rw-r--r--drivers/media/video/cx18/cx23418.h2
-rw-r--r--drivers/media/video/cx231xx/cx231xx-input.c11
-rw-r--r--drivers/media/video/cx231xx/cx231xx-video.c2
-rw-r--r--drivers/media/video/cx23885/Kconfig2
-rw-r--r--drivers/media/video/cx23885/Makefile3
-rw-r--r--drivers/media/video/cx23885/cx23885-417.c10
-rw-r--r--drivers/media/video/cx23885/cx23885-cards.c155
-rw-r--r--drivers/media/video/cx23885/cx23885-core.c115
-rw-r--r--drivers/media/video/cx23885/cx23885-dvb.c158
-rw-r--r--drivers/media/video/cx23885/cx23885-f300.c177
-rw-r--r--drivers/media/video/cx23885/cx23885-f300.h2
-rw-r--r--drivers/media/video/cx23885/cx23885-input.c427
-rw-r--r--drivers/media/video/cx23885/cx23885-input.h30
-rw-r--r--drivers/media/video/cx23885/cx23885-ioctl.c208
-rw-r--r--drivers/media/video/cx23885/cx23885-ioctl.h39
-rw-r--r--drivers/media/video/cx23885/cx23885-ir.c101
-rw-r--r--drivers/media/video/cx23885/cx23885-ir.h31
-rw-r--r--drivers/media/video/cx23885/cx23885-reg.h5
-rw-r--r--drivers/media/video/cx23885/cx23885-video.c44
-rw-r--r--drivers/media/video/cx23885/cx23885.h31
-rw-r--r--drivers/media/video/cx23885/cx23888-ir.c1239
-rw-r--r--drivers/media/video/cx23885/cx23888-ir.h28
-rw-r--r--drivers/media/video/cx25840/cx25840-audio.c463
-rw-r--r--drivers/media/video/cx25840/cx25840-core.c324
-rw-r--r--drivers/media/video/cx25840/cx25840-core.h22
-rw-r--r--drivers/media/video/cx25840/cx25840-firmware.c10
-rw-r--r--drivers/media/video/cx88/Kconfig2
-rw-r--r--drivers/media/video/cx88/cx88-cards.c19
-rw-r--r--drivers/media/video/cx88/cx88-dvb.c58
-rw-r--r--drivers/media/video/cx88/cx88-input.c47
-rw-r--r--drivers/media/video/cx88/cx88-video.c2
-rw-r--r--drivers/media/video/cx88/cx88.h1
-rw-r--r--drivers/media/video/davinci/vpfe_capture.c47
-rw-r--r--drivers/media/video/em28xx/em28xx-audio.c4
-rw-r--r--drivers/media/video/em28xx/em28xx-cards.c50
-rw-r--r--drivers/media/video/em28xx/em28xx-core.c22
-rw-r--r--drivers/media/video/em28xx/em28xx-dvb.c24
-rw-r--r--drivers/media/video/em28xx/em28xx-input.c27
-rw-r--r--drivers/media/video/em28xx/em28xx-reg.h1
-rw-r--r--drivers/media/video/em28xx/em28xx-video.c8
-rw-r--r--drivers/media/video/em28xx/em28xx.h7
-rw-r--r--drivers/media/video/gspca/Kconfig23
-rw-r--r--drivers/media/video/gspca/Makefile4
-rw-r--r--drivers/media/video/gspca/conex.c12
-rw-r--r--drivers/media/video/gspca/etoms.c10
-rw-r--r--drivers/media/video/gspca/finepix.c23
-rw-r--r--drivers/media/video/gspca/gl860/gl860-mi1320.c55
-rw-r--r--drivers/media/video/gspca/gl860/gl860-mi2020.c69
-rw-r--r--drivers/media/video/gspca/gl860/gl860-ov2640.c140
-rw-r--r--drivers/media/video/gspca/gl860/gl860-ov9655.c43
-rw-r--r--drivers/media/video/gspca/gl860/gl860.c61
-rw-r--r--drivers/media/video/gspca/gl860/gl860.h7
-rw-r--r--drivers/media/video/gspca/gspca.c137
-rw-r--r--drivers/media/video/gspca/gspca.h15
-rw-r--r--drivers/media/video/gspca/jeilinj.c34
-rw-r--r--drivers/media/video/gspca/m5602/m5602_core.c25
-rw-r--r--drivers/media/video/gspca/mars.c11
-rw-r--r--drivers/media/video/gspca/mr97310a.c602
-rw-r--r--drivers/media/video/gspca/ov519.c1495
-rw-r--r--drivers/media/video/gspca/ov534.c1537
-rw-r--r--drivers/media/video/gspca/pac207.c13
-rw-r--r--drivers/media/video/gspca/pac7302.c1272
-rw-r--r--drivers/media/video/gspca/pac7311.c716
-rw-r--r--drivers/media/video/gspca/pac_common.h91
-rw-r--r--drivers/media/video/gspca/sn9c20x.c11
-rw-r--r--drivers/media/video/gspca/sonixb.c21
-rw-r--r--drivers/media/video/gspca/sonixj.c660
-rw-r--r--drivers/media/video/gspca/spca500.c11
-rw-r--r--drivers/media/video/gspca/spca501.c14
-rw-r--r--drivers/media/video/gspca/spca505.c10
-rw-r--r--drivers/media/video/gspca/spca506.c12
-rw-r--r--drivers/media/video/gspca/spca508.c10
-rw-r--r--drivers/media/video/gspca/spca561.c14
-rw-r--r--drivers/media/video/gspca/sq905.c75
-rw-r--r--drivers/media/video/gspca/sq905c.c31
-rw-r--r--drivers/media/video/gspca/stk014.c11
-rw-r--r--drivers/media/video/gspca/stv0680.c364
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx.c11
-rw-r--r--drivers/media/video/gspca/sunplus.c11
-rw-r--r--drivers/media/video/gspca/t613.c7
-rw-r--r--drivers/media/video/gspca/tv8532.c7
-rw-r--r--drivers/media/video/gspca/vc032x.c23
-rw-r--r--drivers/media/video/gspca/w996Xcf.c609
-rw-r--r--drivers/media/video/gspca/zc3xx.c1470
-rw-r--r--drivers/media/video/hdpvr/hdpvr-video.c8
-rw-r--r--drivers/media/video/hexium_gemini.c2
-rw-r--r--drivers/media/video/hexium_orion.c2
-rw-r--r--drivers/media/video/ir-kbd-i2c.c19
-rw-r--r--drivers/media/video/ivtv/ivtv-cards.c16
-rw-r--r--drivers/media/video/ivtv/ivtv-cards.h51
-rw-r--r--drivers/media/video/ivtv/ivtv-driver.c23
-rw-r--r--drivers/media/video/ivtv/ivtv-driver.h6
-rw-r--r--drivers/media/video/ivtv/ivtv-i2c.c153
-rw-r--r--drivers/media/video/ivtv/ivtv-i2c.h1
-rw-r--r--drivers/media/video/mxb.c2
-rw-r--r--drivers/media/video/ov9640.c801
-rw-r--r--drivers/media/video/ov9640.h209
-rw-r--r--drivers/media/video/pms.c1425
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-debugifc.c17
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-devattr.c13
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-devattr.h1
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-encoder.c5
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h1
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-hdw.c63
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-hdw.h2
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-i2c-core.c1
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-v4l2.c15
-rw-r--r--drivers/media/video/pwc/pwc-if.c23
-rw-r--r--drivers/media/video/rj54n1cb0c.c1219
-rw-r--r--drivers/media/video/s2255drv.c2
-rw-r--r--drivers/media/video/saa7110.c2
-rw-r--r--drivers/media/video/saa7134/saa7134-cards.c55
-rw-r--r--drivers/media/video/saa7134/saa7134-core.c2
-rw-r--r--drivers/media/video/saa7134/saa7134-dvb.c66
-rw-r--r--drivers/media/video/saa7134/saa7134-input.c55
-rw-r--r--drivers/media/video/saa7134/saa7134-video.c2
-rw-r--r--drivers/media/video/saa7134/saa7134.h3
-rw-r--r--drivers/media/video/saa7164/saa7164-dvb.c1
-rw-r--r--drivers/media/video/saa717x.c4
-rw-r--r--drivers/media/video/sh_mobile_ceu_camera.c83
-rw-r--r--drivers/media/video/tuner-core.c20
-rw-r--r--drivers/media/video/tvaudio.c2
-rw-r--r--drivers/media/video/tvp514x.c2
-rw-r--r--drivers/media/video/usbvideo/konicawc.c2
-rw-r--r--drivers/media/video/usbvideo/quickcam_messenger.c2
-rw-r--r--drivers/media/video/usbvision/usbvision-video.c2
-rw-r--r--drivers/media/video/uvc/uvc_ctrl.c36
-rw-r--r--drivers/media/video/uvc/uvc_driver.c428
-rw-r--r--drivers/media/video/uvc/uvc_v4l2.c60
-rw-r--r--drivers/media/video/uvc/uvc_video.c26
-rw-r--r--drivers/media/video/uvc/uvcvideo.h23
-rw-r--r--drivers/media/video/v4l2-common.c9
-rw-r--r--drivers/media/video/videobuf-core.c12
-rw-r--r--drivers/media/video/videobuf-dma-contig.c2
-rw-r--r--drivers/media/video/videobuf-dma-sg.c6
-rw-r--r--drivers/media/video/videobuf-dvb.c11
-rw-r--r--drivers/media/video/videobuf-vmalloc.c4
-rw-r--r--drivers/media/video/vpx3220.c2
-rw-r--r--drivers/media/video/zoran/zoran_driver.c2
-rw-r--r--drivers/media/video/zr364xx.c1
-rw-r--r--drivers/staging/go7007/Makefile4
-rw-r--r--drivers/staging/go7007/go7007-driver.c30
-rw-r--r--drivers/staging/go7007/go7007-priv.h8
-rw-r--r--drivers/staging/go7007/go7007-usb.c6
-rw-r--r--drivers/staging/go7007/go7007-v4l2.c109
-rw-r--r--drivers/staging/go7007/s2250-board.c558
-rw-r--r--drivers/staging/go7007/s2250-loader.c12
-rw-r--r--include/linux/videodev2.h7
-rw-r--r--include/media/cx25840.h1
-rw-r--r--include/media/davinci/vpfe_capture.h2
-rw-r--r--include/media/ir-common.h43
-rw-r--r--include/media/v4l2-chip-ident.h23
-rw-r--r--include/media/v4l2-subdev.h103
-rw-r--r--include/media/videobuf-core.h4
-rw-r--r--include/media/videobuf-dma-contig.h2
-rw-r--r--include/media/videobuf-dma-sg.h2
-rw-r--r--include/media/videobuf-dvb.h4
-rw-r--r--include/media/videobuf-vmalloc.h4
291 files changed, 27986 insertions, 11187 deletions
diff --git a/Documentation/DocBook/dvb/dvbapi.xml b/Documentation/DocBook/dvb/dvbapi.xml
index 4fc5b23470a3..63c528fee624 100644
--- a/Documentation/DocBook/dvb/dvbapi.xml
+++ b/Documentation/DocBook/dvb/dvbapi.xml
@@ -30,6 +30,14 @@
30<revhistory> 30<revhistory>
31<!-- Put document revisions here, newest first. --> 31<!-- Put document revisions here, newest first. -->
32<revision> 32<revision>
33 <revnumber>2.0.2</revnumber>
34 <date>2009-10-25</date>
35 <authorinitials>mcc</authorinitials>
36 <revremark>
37 documents FE_SET_FRONTEND_TUNE_MODE and FE_DISHETWORK_SEND_LEGACY_CMD ioctls.
38 </revremark>
39</revision>
40<revision>
33<revnumber>2.0.1</revnumber> 41<revnumber>2.0.1</revnumber>
34<date>2009-09-16</date> 42<date>2009-09-16</date>
35<authorinitials>mcc</authorinitials> 43<authorinitials>mcc</authorinitials>
@@ -85,3 +93,8 @@ Added ISDB-T test originally written by Patrick Boettcher
85 &sub-examples; 93 &sub-examples;
86 </chapter> 94 </chapter>
87<!-- END OF CHAPTERS --> 95<!-- END OF CHAPTERS -->
96 <appendix id="frontend_h">
97 <title>DVB Frontend Header File</title>
98 &sub-frontend-h;
99 </appendix>
100
diff --git a/Documentation/DocBook/dvb/isdbt.xml b/Documentation/DocBook/dvb/dvbproperty.xml
index 92855222fccb..5f57c7ccd4ba 100644
--- a/Documentation/DocBook/dvb/isdbt.xml
+++ b/Documentation/DocBook/dvb/dvbproperty.xml
@@ -1,3 +1,6 @@
1<section id="FE_GET_PROPERTY">
2<title>FE_GET_PROPERTY/FE_SET_PROPERTY</title>
3
1<section id="isdbt"> 4<section id="isdbt">
2 <title>ISDB-T frontend</title> 5 <title>ISDB-T frontend</title>
3 <para>This section describes shortly what are the possible parameters in the Linux 6 <para>This section describes shortly what are the possible parameters in the Linux
@@ -312,3 +315,4 @@
312 </section> 315 </section>
313 </section> 316 </section>
314</section> 317</section>
318</section>
diff --git a/Documentation/DocBook/dvb/frontend.h.xml b/Documentation/DocBook/dvb/frontend.h.xml
new file mode 100644
index 000000000000..b99644f5340a
--- /dev/null
+++ b/Documentation/DocBook/dvb/frontend.h.xml
@@ -0,0 +1,415 @@
1<programlisting>
2/*
3 * frontend.h
4 *
5 * Copyright (C) 2000 Marcus Metzler &lt;marcus@convergence.de&gt;
6 * Ralph Metzler &lt;ralph@convergence.de&gt;
7 * Holger Waechtler &lt;holger@convergence.de&gt;
8 * Andre Draszik &lt;ad@convergence.de&gt;
9 * for convergence integrated media GmbH
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public License
13 * as published by the Free Software Foundation; either version 2.1
14 * of the License, or (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU Lesser General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24 *
25 */
26
27#ifndef _DVBFRONTEND_H_
28#define _DVBFRONTEND_H_
29
30#include &lt;linux/types.h&gt;
31
32typedef enum fe_type {
33 FE_QPSK,
34 FE_QAM,
35 FE_OFDM,
36 FE_ATSC
37} fe_type_t;
38
39
40typedef enum fe_caps {
41 FE_IS_STUPID = 0,
42 FE_CAN_INVERSION_AUTO = 0x1,
43 FE_CAN_FEC_1_2 = 0x2,
44 FE_CAN_FEC_2_3 = 0x4,
45 FE_CAN_FEC_3_4 = 0x8,
46 FE_CAN_FEC_4_5 = 0x10,
47 FE_CAN_FEC_5_6 = 0x20,
48 FE_CAN_FEC_6_7 = 0x40,
49 FE_CAN_FEC_7_8 = 0x80,
50 FE_CAN_FEC_8_9 = 0x100,
51 FE_CAN_FEC_AUTO = 0x200,
52 FE_CAN_QPSK = 0x400,
53 FE_CAN_QAM_16 = 0x800,
54 FE_CAN_QAM_32 = 0x1000,
55 FE_CAN_QAM_64 = 0x2000,
56 FE_CAN_QAM_128 = 0x4000,
57 FE_CAN_QAM_256 = 0x8000,
58 FE_CAN_QAM_AUTO = 0x10000,
59 FE_CAN_TRANSMISSION_MODE_AUTO = 0x20000,
60 FE_CAN_BANDWIDTH_AUTO = 0x40000,
61 FE_CAN_GUARD_INTERVAL_AUTO = 0x80000,
62 FE_CAN_HIERARCHY_AUTO = 0x100000,
63 FE_CAN_8VSB = 0x200000,
64 FE_CAN_16VSB = 0x400000,
65 FE_HAS_EXTENDED_CAPS = 0x800000, /* We need more bitspace for newer APIs, indicate this. */
66 FE_CAN_2G_MODULATION = 0x10000000, /* frontend supports "2nd generation modulation" (DVB-S2) */
67 FE_NEEDS_BENDING = 0x20000000, /* not supported anymore, don't use (frontend requires frequency bending) */
68 FE_CAN_RECOVER = 0x40000000, /* frontend can recover from a cable unplug automatically */
69 FE_CAN_MUTE_TS = 0x80000000 /* frontend can stop spurious TS data output */
70} fe_caps_t;
71
72
73struct dvb_frontend_info {
74 char name[128];
75 fe_type_t type;
76 __u32 frequency_min;
77 __u32 frequency_max;
78 __u32 frequency_stepsize;
79 __u32 frequency_tolerance;
80 __u32 symbol_rate_min;
81 __u32 symbol_rate_max;
82 __u32 symbol_rate_tolerance; /* ppm */
83 __u32 notifier_delay; /* DEPRECATED */
84 fe_caps_t caps;
85};
86
87
88/**
89 * Check out the DiSEqC bus spec available on http://www.eutelsat.org/ for
90 * the meaning of this struct...
91 */
92struct dvb_diseqc_master_cmd {
93 __u8 msg [6]; /* { framing, address, command, data [3] } */
94 __u8 msg_len; /* valid values are 3...6 */
95};
96
97
98struct dvb_diseqc_slave_reply {
99 __u8 msg [4]; /* { framing, data [3] } */
100 __u8 msg_len; /* valid values are 0...4, 0 means no msg */
101 int timeout; /* return from ioctl after timeout ms with */
102}; /* errorcode when no message was received */
103
104
105typedef enum fe_sec_voltage {
106 SEC_VOLTAGE_13,
107 SEC_VOLTAGE_18,
108 SEC_VOLTAGE_OFF
109} fe_sec_voltage_t;
110
111
112typedef enum fe_sec_tone_mode {
113 SEC_TONE_ON,
114 SEC_TONE_OFF
115} fe_sec_tone_mode_t;
116
117
118typedef enum fe_sec_mini_cmd {
119 SEC_MINI_A,
120 SEC_MINI_B
121} fe_sec_mini_cmd_t;
122
123
124typedef enum fe_status {
125 FE_HAS_SIGNAL = 0x01, /* found something above the noise level */
126 FE_HAS_CARRIER = 0x02, /* found a DVB signal */
127 FE_HAS_VITERBI = 0x04, /* FEC is stable */
128 FE_HAS_SYNC = 0x08, /* found sync bytes */
129 FE_HAS_LOCK = 0x10, /* everything's working... */
130 FE_TIMEDOUT = 0x20, /* no lock within the last ~2 seconds */
131 FE_REINIT = 0x40 /* frontend was reinitialized, */
132} fe_status_t; /* application is recommended to reset */
133 /* DiSEqC, tone and parameters */
134
135typedef enum fe_spectral_inversion {
136 INVERSION_OFF,
137 INVERSION_ON,
138 INVERSION_AUTO
139} fe_spectral_inversion_t;
140
141
142typedef enum fe_code_rate {
143 FEC_NONE = 0,
144 FEC_1_2,
145 FEC_2_3,
146 FEC_3_4,
147 FEC_4_5,
148 FEC_5_6,
149 FEC_6_7,
150 FEC_7_8,
151 FEC_8_9,
152 FEC_AUTO,
153 FEC_3_5,
154 FEC_9_10,
155} fe_code_rate_t;
156
157
158typedef enum fe_modulation {
159 QPSK,
160 QAM_16,
161 QAM_32,
162 QAM_64,
163 QAM_128,
164 QAM_256,
165 QAM_AUTO,
166 VSB_8,
167 VSB_16,
168 PSK_8,
169 APSK_16,
170 APSK_32,
171 DQPSK,
172} fe_modulation_t;
173
174typedef enum fe_transmit_mode {
175 TRANSMISSION_MODE_2K,
176 TRANSMISSION_MODE_8K,
177 TRANSMISSION_MODE_AUTO,
178 TRANSMISSION_MODE_4K
179} fe_transmit_mode_t;
180
181typedef enum fe_bandwidth {
182 BANDWIDTH_8_MHZ,
183 BANDWIDTH_7_MHZ,
184 BANDWIDTH_6_MHZ,
185 BANDWIDTH_AUTO
186} fe_bandwidth_t;
187
188
189typedef enum fe_guard_interval {
190 GUARD_INTERVAL_1_32,
191 GUARD_INTERVAL_1_16,
192 GUARD_INTERVAL_1_8,
193 GUARD_INTERVAL_1_4,
194 GUARD_INTERVAL_AUTO
195} fe_guard_interval_t;
196
197
198typedef enum fe_hierarchy {
199 HIERARCHY_NONE,
200 HIERARCHY_1,
201 HIERARCHY_2,
202 HIERARCHY_4,
203 HIERARCHY_AUTO
204} fe_hierarchy_t;
205
206
207struct dvb_qpsk_parameters {
208 __u32 symbol_rate; /* symbol rate in Symbols per second */
209 fe_code_rate_t fec_inner; /* forward error correction (see above) */
210};
211
212struct dvb_qam_parameters {
213 __u32 symbol_rate; /* symbol rate in Symbols per second */
214 fe_code_rate_t fec_inner; /* forward error correction (see above) */
215 fe_modulation_t modulation; /* modulation type (see above) */
216};
217
218struct dvb_vsb_parameters {
219 fe_modulation_t modulation; /* modulation type (see above) */
220};
221
222struct dvb_ofdm_parameters {
223 fe_bandwidth_t bandwidth;
224 fe_code_rate_t code_rate_HP; /* high priority stream code rate */
225 fe_code_rate_t code_rate_LP; /* low priority stream code rate */
226 fe_modulation_t constellation; /* modulation type (see above) */
227 fe_transmit_mode_t transmission_mode;
228 fe_guard_interval_t guard_interval;
229 fe_hierarchy_t hierarchy_information;
230};
231
232
233struct dvb_frontend_parameters {
234 __u32 frequency; /* (absolute) frequency in Hz for QAM/OFDM/ATSC */
235 /* intermediate frequency in kHz for QPSK */
236 fe_spectral_inversion_t inversion;
237 union {
238 struct dvb_qpsk_parameters qpsk;
239 struct dvb_qam_parameters qam;
240 struct dvb_ofdm_parameters ofdm;
241 struct dvb_vsb_parameters vsb;
242 } u;
243};
244
245
246struct dvb_frontend_event {
247 fe_status_t status;
248 struct dvb_frontend_parameters parameters;
249};
250
251/* S2API Commands */
252#define DTV_UNDEFINED 0
253#define DTV_TUNE 1
254#define DTV_CLEAR 2
255#define DTV_FREQUENCY 3
256#define DTV_MODULATION 4
257#define DTV_BANDWIDTH_HZ 5
258#define DTV_INVERSION 6
259#define DTV_DISEQC_MASTER 7
260#define DTV_SYMBOL_RATE 8
261#define DTV_INNER_FEC 9
262#define DTV_VOLTAGE 10
263#define DTV_TONE 11
264#define DTV_PILOT 12
265#define DTV_ROLLOFF 13
266#define DTV_DISEQC_SLAVE_REPLY 14
267
268/* Basic enumeration set for querying unlimited capabilities */
269#define DTV_FE_CAPABILITY_COUNT 15
270#define DTV_FE_CAPABILITY 16
271#define DTV_DELIVERY_SYSTEM 17
272
273/* ISDB-T and ISDB-Tsb */
274#define DTV_ISDBT_PARTIAL_RECEPTION 18
275#define DTV_ISDBT_SOUND_BROADCASTING 19
276
277#define DTV_ISDBT_SB_SUBCHANNEL_ID 20
278#define DTV_ISDBT_SB_SEGMENT_IDX 21
279#define DTV_ISDBT_SB_SEGMENT_COUNT 22
280
281#define DTV_ISDBT_LAYERA_FEC 23
282#define DTV_ISDBT_LAYERA_MODULATION 24
283#define DTV_ISDBT_LAYERA_SEGMENT_COUNT 25
284#define DTV_ISDBT_LAYERA_TIME_INTERLEAVING 26
285
286#define DTV_ISDBT_LAYERB_FEC 27
287#define DTV_ISDBT_LAYERB_MODULATION 28
288#define DTV_ISDBT_LAYERB_SEGMENT_COUNT 29
289#define DTV_ISDBT_LAYERB_TIME_INTERLEAVING 30
290
291#define DTV_ISDBT_LAYERC_FEC 31
292#define DTV_ISDBT_LAYERC_MODULATION 32
293#define DTV_ISDBT_LAYERC_SEGMENT_COUNT 33
294#define DTV_ISDBT_LAYERC_TIME_INTERLEAVING 34
295
296#define DTV_API_VERSION 35
297
298#define DTV_CODE_RATE_HP 36
299#define DTV_CODE_RATE_LP 37
300#define DTV_GUARD_INTERVAL 38
301#define DTV_TRANSMISSION_MODE 39
302#define DTV_HIERARCHY 40
303
304#define DTV_ISDBT_LAYER_ENABLED 41
305
306#define DTV_ISDBS_TS_ID 42
307
308#define DTV_MAX_COMMAND DTV_ISDBS_TS_ID
309
310typedef enum fe_pilot {
311 PILOT_ON,
312 PILOT_OFF,
313 PILOT_AUTO,
314} fe_pilot_t;
315
316typedef enum fe_rolloff {
317 ROLLOFF_35, /* Implied value in DVB-S, default for DVB-S2 */
318 ROLLOFF_20,
319 ROLLOFF_25,
320 ROLLOFF_AUTO,
321} fe_rolloff_t;
322
323typedef enum fe_delivery_system {
324 SYS_UNDEFINED,
325 SYS_DVBC_ANNEX_AC,
326 SYS_DVBC_ANNEX_B,
327 SYS_DVBT,
328 SYS_DSS,
329 SYS_DVBS,
330 SYS_DVBS2,
331 SYS_DVBH,
332 SYS_ISDBT,
333 SYS_ISDBS,
334 SYS_ISDBC,
335 SYS_ATSC,
336 SYS_ATSCMH,
337 SYS_DMBTH,
338 SYS_CMMB,
339 SYS_DAB,
340} fe_delivery_system_t;
341
342struct dtv_cmds_h {
343 char *name; /* A display name for debugging purposes */
344
345 __u32 cmd; /* A unique ID */
346
347 /* Flags */
348 __u32 set:1; /* Either a set or get property */
349 __u32 buffer:1; /* Does this property use the buffer? */
350 __u32 reserved:30; /* Align */
351};
352
353struct dtv_property {
354 __u32 cmd;
355 __u32 reserved[3];
356 union {
357 __u32 data;
358 struct {
359 __u8 data[32];
360 __u32 len;
361 __u32 reserved1[3];
362 void *reserved2;
363 } buffer;
364 } u;
365 int result;
366} __attribute__ ((packed));
367
368/* num of properties cannot exceed DTV_IOCTL_MAX_MSGS per ioctl */
369#define DTV_IOCTL_MAX_MSGS 64
370
371struct dtv_properties {
372 __u32 num;
373 struct dtv_property *props;
374};
375
376#define <link linkend="FE_GET_PROPERTY">FE_SET_PROPERTY</link> _IOW('o', 82, struct dtv_properties)
377#define <link linkend="FE_GET_PROPERTY">FE_GET_PROPERTY</link> _IOR('o', 83, struct dtv_properties)
378
379
380/**
381 * When set, this flag will disable any zigzagging or other "normal" tuning
382 * behaviour. Additionally, there will be no automatic monitoring of the lock
383 * status, and hence no frontend events will be generated. If a frontend device
384 * is closed, this flag will be automatically turned off when the device is
385 * reopened read-write.
386 */
387#define FE_TUNE_MODE_ONESHOT 0x01
388
389
390#define <link linkend="FE_GET_INFO">FE_GET_INFO</link> _IOR('o', 61, struct dvb_frontend_info)
391
392#define <link linkend="FE_DISEQC_RESET_OVERLOAD">FE_DISEQC_RESET_OVERLOAD</link> _IO('o', 62)
393#define <link linkend="FE_DISEQC_SEND_MASTER_CMD">FE_DISEQC_SEND_MASTER_CMD</link> _IOW('o', 63, struct dvb_diseqc_master_cmd)
394#define <link linkend="FE_DISEQC_RECV_SLAVE_REPLY">FE_DISEQC_RECV_SLAVE_REPLY</link> _IOR('o', 64, struct dvb_diseqc_slave_reply)
395#define <link linkend="FE_DISEQC_SEND_BURST">FE_DISEQC_SEND_BURST</link> _IO('o', 65) /* fe_sec_mini_cmd_t */
396
397#define <link linkend="FE_SET_TONE">FE_SET_TONE</link> _IO('o', 66) /* fe_sec_tone_mode_t */
398#define <link linkend="FE_SET_VOLTAGE">FE_SET_VOLTAGE</link> _IO('o', 67) /* fe_sec_voltage_t */
399#define <link linkend="FE_ENABLE_HIGH_LNB_VOLTAGE">FE_ENABLE_HIGH_LNB_VOLTAGE</link> _IO('o', 68) /* int */
400
401#define <link linkend="FE_READ_STATUS">FE_READ_STATUS</link> _IOR('o', 69, fe_status_t)
402#define <link linkend="FE_READ_BER">FE_READ_BER</link> _IOR('o', 70, __u32)
403#define <link linkend="FE_READ_SIGNAL_STRENGTH">FE_READ_SIGNAL_STRENGTH</link> _IOR('o', 71, __u16)
404#define <link linkend="FE_READ_SNR">FE_READ_SNR</link> _IOR('o', 72, __u16)
405#define <link linkend="FE_READ_UNCORRECTED_BLOCKS">FE_READ_UNCORRECTED_BLOCKS</link> _IOR('o', 73, __u32)
406
407#define <link linkend="FE_SET_FRONTEND">FE_SET_FRONTEND</link> _IOW('o', 76, struct dvb_frontend_parameters)
408#define <link linkend="FE_GET_FRONTEND">FE_GET_FRONTEND</link> _IOR('o', 77, struct dvb_frontend_parameters)
409#define <link linkend="FE_SET_FRONTEND_TUNE_MODE">FE_SET_FRONTEND_TUNE_MODE</link> _IO('o', 81) /* unsigned int */
410#define <link linkend="FE_GET_EVENT">FE_GET_EVENT</link> _IOR('o', 78, struct dvb_frontend_event)
411
412#define <link linkend="FE_DISHNETWORK_SEND_LEGACY_CMD">FE_DISHNETWORK_SEND_LEGACY_CMD</link> _IO('o', 80) /* unsigned int */
413
414#endif /*_DVBFRONTEND_H_*/
415</programlisting>
diff --git a/Documentation/DocBook/dvb/frontend.xml b/Documentation/DocBook/dvb/frontend.xml
index 9d89a7b94fd5..300ba1f04177 100644
--- a/Documentation/DocBook/dvb/frontend.xml
+++ b/Documentation/DocBook/dvb/frontend.xml
@@ -73,7 +73,8 @@ a specific frontend type.</para>
73<section id="frontend_info"> 73<section id="frontend_info">
74<title>frontend information</title> 74<title>frontend information</title>
75 75
76<para>Information about the frontend ca be queried with FE_GET_INFO.</para> 76<para>Information about the frontend ca be queried with
77 <link linkend="FE_GET_INFO">FE_GET_INFO</link>.</para>
77 78
78<programlisting> 79<programlisting>
79 struct dvb_frontend_info { 80 struct dvb_frontend_info {
@@ -338,7 +339,7 @@ modulation mode which can be one of the following:
338<entry align="char"> 339<entry align="char">
339<para>This system call opens a named frontend device (/dev/dvb/adapter0/frontend0) 340<para>This system call opens a named frontend device (/dev/dvb/adapter0/frontend0)
340 for subsequent use. Usually the first thing to do after a successful open is to 341 for subsequent use. Usually the first thing to do after a successful open is to
341 find out the frontend type with FE_GET_INFO.</para> 342 find out the frontend type with <link linkend="FE_GET_INFO">FE_GET_INFO</link>.</para>
342<para>The device can be opened in read-only mode, which only allows monitoring of 343<para>The device can be opened in read-only mode, which only allows monitoring of
343 device status and statistics, or read/write mode, which allows any kind of use 344 device status and statistics, or read/write mode, which allows any kind of use
344 (e.g. performing tuning operations.) 345 (e.g. performing tuning operations.)
@@ -478,7 +479,7 @@ modulation mode which can be one of the following:
478 </row></tbody></tgroup></informaltable> 479 </row></tbody></tgroup></informaltable>
479</section> 480</section>
480 481
481<section id="frontend_read_status"> 482<section id="FE_READ_STATUS">
482<title>FE_READ_STATUS</title> 483<title>FE_READ_STATUS</title>
483<para>DESCRIPTION 484<para>DESCRIPTION
484</para> 485</para>
@@ -492,7 +493,7 @@ modulation mode which can be one of the following:
492</para> 493</para>
493<informaltable><tgroup cols="1"><tbody><row><entry 494<informaltable><tgroup cols="1"><tbody><row><entry
494 align="char"> 495 align="char">
495<para>int ioctl(int fd, int request = FE_READ_STATUS, 496<para>int ioctl(int fd, int request = <link linkend="FE_READ_STATUS">FE_READ_STATUS</link>,
496 fe_status_t &#x22C6;status);</para> 497 fe_status_t &#x22C6;status);</para>
497</entry> 498</entry>
498 </row></tbody></tgroup></informaltable> 499 </row></tbody></tgroup></informaltable>
@@ -511,7 +512,7 @@ modulation mode which can be one of the following:
511<para>int request</para> 512<para>int request</para>
512</entry><entry 513</entry><entry
513 align="char"> 514 align="char">
514<para>Equals FE_READ_STATUS for this command.</para> 515<para>Equals <link linkend="FE_READ_STATUS">FE_READ_STATUS</link> for this command.</para>
515</entry> 516</entry>
516 </row><row><entry 517 </row><row><entry
517 align="char"> 518 align="char">
@@ -542,7 +543,7 @@ modulation mode which can be one of the following:
542 </row></tbody></tgroup></informaltable> 543 </row></tbody></tgroup></informaltable>
543</section> 544</section>
544 545
545<section id="frontend_read_ber"> 546<section id="FE_READ_BER">
546<title>FE_READ_BER</title> 547<title>FE_READ_BER</title>
547<para>DESCRIPTION 548<para>DESCRIPTION
548</para> 549</para>
@@ -557,7 +558,7 @@ modulation mode which can be one of the following:
557</para> 558</para>
558<informaltable><tgroup cols="1"><tbody><row><entry 559<informaltable><tgroup cols="1"><tbody><row><entry
559 align="char"> 560 align="char">
560<para>int ioctl(int fd, int request = FE_READ_BER, 561<para>int ioctl(int fd, int request = <link linkend="FE_READ_BER">FE_READ_BER</link>,
561 uint32_t &#x22C6;ber);</para> 562 uint32_t &#x22C6;ber);</para>
562</entry> 563</entry>
563 </row></tbody></tgroup></informaltable> 564 </row></tbody></tgroup></informaltable>
@@ -575,7 +576,7 @@ modulation mode which can be one of the following:
575<para>int request</para> 576<para>int request</para>
576</entry><entry 577</entry><entry
577 align="char"> 578 align="char">
578<para>Equals FE_READ_BER for this command.</para> 579<para>Equals <link linkend="FE_READ_BER">FE_READ_BER</link> for this command.</para>
579</entry> 580</entry>
580 </row><row><entry 581 </row><row><entry
581 align="char"> 582 align="char">
@@ -619,7 +620,7 @@ modulation mode which can be one of the following:
619 </row></tbody></tgroup></informaltable> 620 </row></tbody></tgroup></informaltable>
620</section> 621</section>
621 622
622<section id="frontend_read_snr"> 623<section id="FE_READ_SNR">
623<title>FE_READ_SNR</title> 624<title>FE_READ_SNR</title>
624 625
625<para>DESCRIPTION 626<para>DESCRIPTION
@@ -634,7 +635,7 @@ modulation mode which can be one of the following:
634</para> 635</para>
635<informaltable><tgroup cols="1"><tbody><row><entry 636<informaltable><tgroup cols="1"><tbody><row><entry
636 align="char"> 637 align="char">
637<para>int ioctl(int fd, int request = FE_READ_SNR, int16_t 638<para>int ioctl(int fd, int request = <link linkend="FE_READ_SNR">FE_READ_SNR</link>, int16_t
638 &#x22C6;snr);</para> 639 &#x22C6;snr);</para>
639</entry> 640</entry>
640 </row></tbody></tgroup></informaltable> 641 </row></tbody></tgroup></informaltable>
@@ -652,7 +653,7 @@ modulation mode which can be one of the following:
652<para>int request</para> 653<para>int request</para>
653</entry><entry 654</entry><entry
654 align="char"> 655 align="char">
655<para>Equals FE_READ_SNR for this command.</para> 656<para>Equals <link linkend="FE_READ_SNR">FE_READ_SNR</link> for this command.</para>
656</entry> 657</entry>
657 </row><row><entry 658 </row><row><entry
658 align="char"> 659 align="char">
@@ -697,7 +698,7 @@ modulation mode which can be one of the following:
697 </row></tbody></tgroup></informaltable> 698 </row></tbody></tgroup></informaltable>
698</section> 699</section>
699 700
700<section id="frontend_read_signal_strength"> 701<section id="FE_READ_SIGNAL_STRENGTH">
701<title>FE_READ_SIGNAL_STRENGTH</title> 702<title>FE_READ_SIGNAL_STRENGTH</title>
702<para>DESCRIPTION 703<para>DESCRIPTION
703</para> 704</para>
@@ -712,7 +713,7 @@ modulation mode which can be one of the following:
712<informaltable><tgroup cols="1"><tbody><row><entry 713<informaltable><tgroup cols="1"><tbody><row><entry
713 align="char"> 714 align="char">
714<para>int ioctl( int fd, int request = 715<para>int ioctl( int fd, int request =
715 FE_READ_SIGNAL_STRENGTH, int16_t &#x22C6;strength);</para> 716 <link linkend="FE_READ_SIGNAL_STRENGTH">FE_READ_SIGNAL_STRENGTH</link>, int16_t &#x22C6;strength);</para>
716</entry> 717</entry>
717 </row></tbody></tgroup></informaltable> 718 </row></tbody></tgroup></informaltable>
718 719
@@ -730,7 +731,7 @@ modulation mode which can be one of the following:
730<para>int request</para> 731<para>int request</para>
731</entry><entry 732</entry><entry
732 align="char"> 733 align="char">
733<para>Equals FE_READ_SIGNAL_STRENGTH for this 734<para>Equals <link linkend="FE_READ_SIGNAL_STRENGTH">FE_READ_SIGNAL_STRENGTH</link> for this
734 command.</para> 735 command.</para>
735</entry> 736</entry>
736 </row><row><entry 737 </row><row><entry
@@ -775,7 +776,7 @@ modulation mode which can be one of the following:
775 </row></tbody></tgroup></informaltable> 776 </row></tbody></tgroup></informaltable>
776</section> 777</section>
777 778
778<section id="frontend_read_ub"> 779<section id="FE_READ_UNCORRECTED_BLOCKS">
779<title>FE_READ_UNCORRECTED_BLOCKS</title> 780<title>FE_READ_UNCORRECTED_BLOCKS</title>
780<para>DESCRIPTION 781<para>DESCRIPTION
781</para> 782</para>
@@ -797,7 +798,7 @@ modulation mode which can be one of the following:
797<informaltable><tgroup cols="1"><tbody><row><entry 798<informaltable><tgroup cols="1"><tbody><row><entry
798 align="char"> 799 align="char">
799<para>int ioctl( int fd, int request = 800<para>int ioctl( int fd, int request =
800 FE_READ_UNCORRECTED_BLOCKS, uint32_t &#x22C6;ublocks);</para> 801 <link linkend="FE_READ_UNCORRECTED_BLOCKS">FE_READ_UNCORRECTED_BLOCKS</link>, uint32_t &#x22C6;ublocks);</para>
801</entry> 802</entry>
802 </row></tbody></tgroup></informaltable> 803 </row></tbody></tgroup></informaltable>
803<para>PARAMETERS 804<para>PARAMETERS
@@ -814,7 +815,7 @@ modulation mode which can be one of the following:
814<para>int request</para> 815<para>int request</para>
815</entry><entry 816</entry><entry
816 align="char"> 817 align="char">
817<para>Equals FE_READ_UNCORRECTED_BLOCKS for this 818<para>Equals <link linkend="FE_READ_UNCORRECTED_BLOCKS">FE_READ_UNCORRECTED_BLOCKS</link> for this
818 command.</para> 819 command.</para>
819</entry> 820</entry>
820 </row><row><entry 821 </row><row><entry
@@ -852,7 +853,7 @@ modulation mode which can be one of the following:
852 </row></tbody></tgroup></informaltable> 853 </row></tbody></tgroup></informaltable>
853</section> 854</section>
854 855
855<section id="frontend_set_fe"> 856<section id="FE_SET_FRONTEND">
856<title>FE_SET_FRONTEND</title> 857<title>FE_SET_FRONTEND</title>
857<para>DESCRIPTION 858<para>DESCRIPTION
858</para> 859</para>
@@ -861,8 +862,8 @@ modulation mode which can be one of the following:
861<para>This ioctl call starts a tuning operation using specified parameters. The result 862<para>This ioctl call starts a tuning operation using specified parameters. The result
862 of this call will be successful if the parameters were valid and the tuning could 863 of this call will be successful if the parameters were valid and the tuning could
863 be initiated. The result of the tuning operation in itself, however, will arrive 864 be initiated. The result of the tuning operation in itself, however, will arrive
864 asynchronously as an event (see documentation for FE_GET_EVENT and 865 asynchronously as an event (see documentation for <link linkend="FE_GET_EVENT">FE_GET_EVENT</link> and
865 FrontendEvent.) If a new FE_SET_FRONTEND operation is initiated before 866 FrontendEvent.) If a new <link linkend="FE_SET_FRONTEND">FE_SET_FRONTEND</link> operation is initiated before
866 the previous one was completed, the previous operation will be aborted in favor 867 the previous one was completed, the previous operation will be aborted in favor
867 of the new one. This command requires read/write access to the device.</para> 868 of the new one. This command requires read/write access to the device.</para>
868</entry> 869</entry>
@@ -872,7 +873,7 @@ modulation mode which can be one of the following:
872</para> 873</para>
873<informaltable><tgroup cols="1"><tbody><row><entry 874<informaltable><tgroup cols="1"><tbody><row><entry
874 align="char"> 875 align="char">
875<para>int ioctl(int fd, int request = FE_SET_FRONTEND, 876<para>int ioctl(int fd, int request = <link linkend="FE_SET_FRONTEND">FE_SET_FRONTEND</link>,
876 struct dvb_frontend_parameters &#x22C6;p);</para> 877 struct dvb_frontend_parameters &#x22C6;p);</para>
877</entry> 878</entry>
878 </row></tbody></tgroup></informaltable> 879 </row></tbody></tgroup></informaltable>
@@ -890,7 +891,7 @@ modulation mode which can be one of the following:
890<para>int request</para> 891<para>int request</para>
891</entry><entry 892</entry><entry
892 align="char"> 893 align="char">
893<para>Equals FE_SET_FRONTEND for this command.</para> 894<para>Equals <link linkend="FE_SET_FRONTEND">FE_SET_FRONTEND</link> for this command.</para>
894</entry> 895</entry>
895 </row><row><entry 896 </row><row><entry
896 align="char"> 897 align="char">
@@ -928,7 +929,7 @@ modulation mode which can be one of the following:
928</row></tbody></tgroup></informaltable> 929</row></tbody></tgroup></informaltable>
929</section> 930</section>
930 931
931<section id="frontend_get_fe"> 932<section id="FE_GET_FRONTEND">
932<title>FE_GET_FRONTEND</title> 933<title>FE_GET_FRONTEND</title>
933<para>DESCRIPTION 934<para>DESCRIPTION
934</para> 935</para>
@@ -943,7 +944,7 @@ modulation mode which can be one of the following:
943</para> 944</para>
944<informaltable><tgroup cols="1"><tbody><row><entry 945<informaltable><tgroup cols="1"><tbody><row><entry
945 align="char"> 946 align="char">
946<para>int ioctl(int fd, int request = FE_GET_FRONTEND, 947<para>int ioctl(int fd, int request = <link linkend="FE_GET_FRONTEND">FE_GET_FRONTEND</link>,
947 struct dvb_frontend_parameters &#x22C6;p);</para> 948 struct dvb_frontend_parameters &#x22C6;p);</para>
948</entry> 949</entry>
949 </row></tbody></tgroup></informaltable> 950 </row></tbody></tgroup></informaltable>
@@ -962,7 +963,7 @@ modulation mode which can be one of the following:
962<para>int request</para> 963<para>int request</para>
963</entry><entry 964</entry><entry
964 align="char"> 965 align="char">
965<para>Equals FE_SET_FRONTEND for this command.</para> 966<para>Equals <link linkend="FE_SET_FRONTEND">FE_SET_FRONTEND</link> for this command.</para>
966</entry> 967</entry>
967 </row><row><entry 968 </row><row><entry
968 align="char"> 969 align="char">
@@ -1003,7 +1004,7 @@ modulation mode which can be one of the following:
1003 1004
1004</section> 1005</section>
1005 1006
1006<section id="frontend_get_event"> 1007<section id="FE_GET_EVENT">
1007<title>FE_GET_EVENT</title> 1008<title>FE_GET_EVENT</title>
1008<para>DESCRIPTION 1009<para>DESCRIPTION
1009</para> 1010</para>
@@ -1024,7 +1025,8 @@ modulation mode which can be one of the following:
1024 rather small (room for 8 events), the queue must be serviced regularly to avoid 1025 rather small (room for 8 events), the queue must be serviced regularly to avoid
1025 overflow. If an overflow happens, the oldest event is discarded from the queue, 1026 overflow. If an overflow happens, the oldest event is discarded from the queue,
1026 and an error (EOVERFLOW) occurs the next time the queue is read. After 1027 and an error (EOVERFLOW) occurs the next time the queue is read. After
1027 reporting the error condition in this fashion, subsequent FE_GET_EVENT 1028 reporting the error condition in this fashion, subsequent
1029 <link linkend="FE_GET_EVENT">FE_GET_EVENT</link>
1028 calls will return events from the queue as usual.</para> 1030 calls will return events from the queue as usual.</para>
1029</entry> 1031</entry>
1030 </row><row><entry 1032 </row><row><entry
@@ -1057,7 +1059,7 @@ modulation mode which can be one of the following:
1057<para>int request</para> 1059<para>int request</para>
1058</entry><entry 1060</entry><entry
1059 align="char"> 1061 align="char">
1060<para>Equals FE_GET_EVENT for this command.</para> 1062<para>Equals <link linkend="FE_GET_EVENT">FE_GET_EVENT</link> for this command.</para>
1061</entry> 1063</entry>
1062 </row><row><entry 1064 </row><row><entry
1063 align="char"> 1065 align="char">
@@ -1115,7 +1117,7 @@ modulation mode which can be one of the following:
1115</row></tbody></tgroup></informaltable> 1117</row></tbody></tgroup></informaltable>
1116</section> 1118</section>
1117 1119
1118<section id="frontend_get_info"> 1120<section id="FE_GET_INFO">
1119<title>FE_GET_INFO</title> 1121<title>FE_GET_INFO</title>
1120<para>DESCRIPTION 1122<para>DESCRIPTION
1121</para> 1123</para>
@@ -1130,7 +1132,7 @@ modulation mode which can be one of the following:
1130 1132
1131<informaltable><tgroup cols="1"><tbody><row><entry 1133<informaltable><tgroup cols="1"><tbody><row><entry
1132 align="char"> 1134 align="char">
1133<para> int ioctl(int fd, int request = FE_GET_INFO, struct 1135<para> int ioctl(int fd, int request = <link linkend="FE_GET_INFO">FE_GET_INFO</link>, struct
1134 dvb_frontend_info &#x22C6;info);</para> 1136 dvb_frontend_info &#x22C6;info);</para>
1135</entry> 1137</entry>
1136 </row></tbody></tgroup></informaltable> 1138 </row></tbody></tgroup></informaltable>
@@ -1149,7 +1151,7 @@ modulation mode which can be one of the following:
1149<para>int request</para> 1151<para>int request</para>
1150</entry><entry 1152</entry><entry
1151 align="char"> 1153 align="char">
1152<para>Equals FE_GET_INFO for this command.</para> 1154<para>Equals <link linkend="FE_GET_INFO">FE_GET_INFO</link> for this command.</para>
1153</entry> 1155</entry>
1154 </row><row><entry 1156 </row><row><entry
1155 align="char"> 1157 align="char">
@@ -1181,7 +1183,7 @@ modulation mode which can be one of the following:
1181</row></tbody></tgroup></informaltable> 1183</row></tbody></tgroup></informaltable>
1182</section> 1184</section>
1183 1185
1184<section id="frontend_diseqc_reset_overload"> 1186<section id="FE_DISEQC_RESET_OVERLOAD">
1185<title>FE_DISEQC_RESET_OVERLOAD</title> 1187<title>FE_DISEQC_RESET_OVERLOAD</title>
1186<para>DESCRIPTION 1188<para>DESCRIPTION
1187</para> 1189</para>
@@ -1199,7 +1201,7 @@ modulation mode which can be one of the following:
1199<informaltable><tgroup cols="1"><tbody><row><entry 1201<informaltable><tgroup cols="1"><tbody><row><entry
1200 align="char"> 1202 align="char">
1201<para>int ioctl(int fd, int request = 1203<para>int ioctl(int fd, int request =
1202 FE_DISEQC_RESET_OVERLOAD);</para> 1204 <link linkend="FE_DISEQC_RESET_OVERLOAD">FE_DISEQC_RESET_OVERLOAD</link>);</para>
1203</entry> 1205</entry>
1204 </row></tbody></tgroup></informaltable> 1206 </row></tbody></tgroup></informaltable>
1205<para>PARAMETERS 1207<para>PARAMETERS
@@ -1216,7 +1218,7 @@ modulation mode which can be one of the following:
1216<para>int request</para> 1218<para>int request</para>
1217</entry><entry 1219</entry><entry
1218 align="char"> 1220 align="char">
1219<para>Equals FE_DISEQC_RESET_OVERLOAD for this 1221<para>Equals <link linkend="FE_DISEQC_RESET_OVERLOAD">FE_DISEQC_RESET_OVERLOAD</link> for this
1220 command.</para> 1222 command.</para>
1221</entry> 1223</entry>
1222 </row></tbody></tgroup></informaltable> 1224 </row></tbody></tgroup></informaltable>
@@ -1247,7 +1249,7 @@ modulation mode which can be one of the following:
1247</row></tbody></tgroup></informaltable> 1249</row></tbody></tgroup></informaltable>
1248</section> 1250</section>
1249 1251
1250<section id="frontend_diseqc_send_master_cmd"> 1252<section id="FE_DISEQC_SEND_MASTER_CMD">
1251<title>FE_DISEQC_SEND_MASTER_CMD</title> 1253<title>FE_DISEQC_SEND_MASTER_CMD</title>
1252<para>DESCRIPTION 1254<para>DESCRIPTION
1253</para> 1255</para>
@@ -1261,7 +1263,7 @@ modulation mode which can be one of the following:
1261<informaltable><tgroup cols="1"><tbody><row><entry 1263<informaltable><tgroup cols="1"><tbody><row><entry
1262 align="char"> 1264 align="char">
1263<para>int ioctl(int fd, int request = 1265<para>int ioctl(int fd, int request =
1264 FE_DISEQC_SEND_MASTER_CMD, struct 1266 <link linkend="FE_DISEQC_SEND_MASTER_CMD">FE_DISEQC_SEND_MASTER_CMD</link>, struct
1265 dvb_diseqc_master_cmd &#x22C6;cmd);</para> 1267 dvb_diseqc_master_cmd &#x22C6;cmd);</para>
1266</entry> 1268</entry>
1267 </row></tbody></tgroup></informaltable> 1269 </row></tbody></tgroup></informaltable>
@@ -1280,7 +1282,7 @@ modulation mode which can be one of the following:
1280<para>int request</para> 1282<para>int request</para>
1281</entry><entry 1283</entry><entry
1282 align="char"> 1284 align="char">
1283<para>Equals FE_DISEQC_SEND_MASTER_CMD for this 1285<para>Equals <link linkend="FE_DISEQC_SEND_MASTER_CMD">FE_DISEQC_SEND_MASTER_CMD</link> for this
1284 command.</para> 1286 command.</para>
1285</entry> 1287</entry>
1286 </row><row><entry 1288 </row><row><entry
@@ -1335,7 +1337,7 @@ modulation mode which can be one of the following:
1335</row></tbody></tgroup></informaltable> 1337</row></tbody></tgroup></informaltable>
1336</section> 1338</section>
1337 1339
1338<section id="frontend_diseqc_recv_slave_reply"> 1340<section id="FE_DISEQC_RECV_SLAVE_REPLY">
1339<title>FE_DISEQC_RECV_SLAVE_REPLY</title> 1341<title>FE_DISEQC_RECV_SLAVE_REPLY</title>
1340<para>DESCRIPTION 1342<para>DESCRIPTION
1341</para> 1343</para>
@@ -1350,7 +1352,7 @@ modulation mode which can be one of the following:
1350<informaltable><tgroup cols="1"><tbody><row><entry 1352<informaltable><tgroup cols="1"><tbody><row><entry
1351 align="char"> 1353 align="char">
1352<para>int ioctl(int fd, int request = 1354<para>int ioctl(int fd, int request =
1353 FE_DISEQC_RECV_SLAVE_REPLY, struct 1355 <link linkend="FE_DISEQC_RECV_SLAVE_REPLY">FE_DISEQC_RECV_SLAVE_REPLY</link>, struct
1354 dvb_diseqc_slave_reply &#x22C6;reply);</para> 1356 dvb_diseqc_slave_reply &#x22C6;reply);</para>
1355</entry> 1357</entry>
1356 </row></tbody></tgroup></informaltable> 1358 </row></tbody></tgroup></informaltable>
@@ -1369,7 +1371,7 @@ modulation mode which can be one of the following:
1369<para>int request</para> 1371<para>int request</para>
1370</entry><entry 1372</entry><entry
1371 align="char"> 1373 align="char">
1372<para>Equals FE_DISEQC_RECV_SLAVE_REPLY for this 1374<para>Equals <link linkend="FE_DISEQC_RECV_SLAVE_REPLY">FE_DISEQC_RECV_SLAVE_REPLY</link> for this
1373 command.</para> 1375 command.</para>
1374</entry> 1376</entry>
1375 </row><row><entry 1377 </row><row><entry
@@ -1423,7 +1425,7 @@ modulation mode which can be one of the following:
1423 </row></tbody></tgroup></informaltable> 1425 </row></tbody></tgroup></informaltable>
1424</section> 1426</section>
1425 1427
1426<section id="frontend_diseqc_send_burst"> 1428<section id="FE_DISEQC_SEND_BURST">
1427<title>FE_DISEQC_SEND_BURST</title> 1429<title>FE_DISEQC_SEND_BURST</title>
1428<para>DESCRIPTION 1430<para>DESCRIPTION
1429</para> 1431</para>
@@ -1438,7 +1440,7 @@ modulation mode which can be one of the following:
1438<informaltable><tgroup cols="1"><tbody><row><entry 1440<informaltable><tgroup cols="1"><tbody><row><entry
1439 align="char"> 1441 align="char">
1440<para>int ioctl(int fd, int request = 1442<para>int ioctl(int fd, int request =
1441 FE_DISEQC_SEND_BURST, fe_sec_mini_cmd_t burst);</para> 1443 <link linkend="FE_DISEQC_SEND_BURST">FE_DISEQC_SEND_BURST</link>, fe_sec_mini_cmd_t burst);</para>
1442</entry> 1444</entry>
1443 </row></tbody></tgroup></informaltable> 1445 </row></tbody></tgroup></informaltable>
1444 1446
@@ -1456,7 +1458,7 @@ modulation mode which can be one of the following:
1456<para>int request</para> 1458<para>int request</para>
1457</entry><entry 1459</entry><entry
1458 align="char"> 1460 align="char">
1459<para>Equals FE_DISEQC_SEND_BURST for this command.</para> 1461<para>Equals <link linkend="FE_DISEQC_SEND_BURST">FE_DISEQC_SEND_BURST</link> for this command.</para>
1460</entry> 1462</entry>
1461 </row><row><entry 1463 </row><row><entry
1462 align="char"> 1464 align="char">
@@ -1509,7 +1511,7 @@ modulation mode which can be one of the following:
1509</row></tbody></tgroup></informaltable> 1511</row></tbody></tgroup></informaltable>
1510</section> 1512</section>
1511 1513
1512<section id="frontend_set_tone"> 1514<section id="FE_SET_TONE">
1513<title>FE_SET_TONE</title> 1515<title>FE_SET_TONE</title>
1514<para>DESCRIPTION 1516<para>DESCRIPTION
1515</para> 1517</para>
@@ -1523,7 +1525,7 @@ modulation mode which can be one of the following:
1523</para> 1525</para>
1524<informaltable><tgroup cols="1"><tbody><row><entry 1526<informaltable><tgroup cols="1"><tbody><row><entry
1525 align="char"> 1527 align="char">
1526<para>int ioctl(int fd, int request = FE_SET_TONE, 1528<para>int ioctl(int fd, int request = <link linkend="FE_SET_TONE">FE_SET_TONE</link>,
1527 fe_sec_tone_mode_t tone);</para> 1529 fe_sec_tone_mode_t tone);</para>
1528</entry> 1530</entry>
1529 </row></tbody></tgroup></informaltable> 1531 </row></tbody></tgroup></informaltable>
@@ -1541,7 +1543,7 @@ modulation mode which can be one of the following:
1541<para>int request</para> 1543<para>int request</para>
1542</entry><entry 1544</entry><entry
1543 align="char"> 1545 align="char">
1544<para>Equals FE_SET_TONE for this command.</para> 1546<para>Equals <link linkend="FE_SET_TONE">FE_SET_TONE</link> for this command.</para>
1545</entry> 1547</entry>
1546 </row><row><entry 1548 </row><row><entry
1547 align="char"> 1549 align="char">
@@ -1592,7 +1594,7 @@ modulation mode which can be one of the following:
1592</row></tbody></tgroup></informaltable> 1594</row></tbody></tgroup></informaltable>
1593</section> 1595</section>
1594 1596
1595<section id="fe_set_voltage"> 1597<section id="FE_SET_VOLTAGE">
1596<title>FE_SET_VOLTAGE</title> 1598<title>FE_SET_VOLTAGE</title>
1597<para>DESCRIPTION 1599<para>DESCRIPTION
1598</para> 1600</para>
@@ -1606,7 +1608,7 @@ modulation mode which can be one of the following:
1606</para> 1608</para>
1607<informaltable><tgroup cols="1"><tbody><row><entry 1609<informaltable><tgroup cols="1"><tbody><row><entry
1608 align="char"> 1610 align="char">
1609<para>int ioctl(int fd, int request = FE_SET_VOLTAGE, 1611<para>int ioctl(int fd, int request = <link linkend="FE_SET_VOLTAGE">FE_SET_VOLTAGE</link>,
1610 fe_sec_voltage_t voltage);</para> 1612 fe_sec_voltage_t voltage);</para>
1611</entry> 1613</entry>
1612 </row></tbody></tgroup></informaltable> 1614 </row></tbody></tgroup></informaltable>
@@ -1625,7 +1627,7 @@ modulation mode which can be one of the following:
1625<para>int request</para> 1627<para>int request</para>
1626</entry><entry 1628</entry><entry
1627 align="char"> 1629 align="char">
1628<para>Equals FE_SET_VOLTAGE for this command.</para> 1630<para>Equals <link linkend="FE_SET_VOLTAGE">FE_SET_VOLTAGE</link> for this command.</para>
1629</entry> 1631</entry>
1630 </row><row><entry 1632 </row><row><entry
1631 align="char"> 1633 align="char">
@@ -1677,7 +1679,7 @@ modulation mode which can be one of the following:
1677 </row></tbody></tgroup></informaltable> 1679 </row></tbody></tgroup></informaltable>
1678</section> 1680</section>
1679 1681
1680<section id="frontend_enable_high_lnb_volt"> 1682<section id="FE_ENABLE_HIGH_LNB_VOLTAGE">
1681<title>FE_ENABLE_HIGH_LNB_VOLTAGE</title> 1683<title>FE_ENABLE_HIGH_LNB_VOLTAGE</title>
1682<para>DESCRIPTION 1684<para>DESCRIPTION
1683</para> 1685</para>
@@ -1694,7 +1696,7 @@ modulation mode which can be one of the following:
1694<informaltable><tgroup cols="1"><tbody><row><entry 1696<informaltable><tgroup cols="1"><tbody><row><entry
1695 align="char"> 1697 align="char">
1696<para>int ioctl(int fd, int request = 1698<para>int ioctl(int fd, int request =
1697 FE_ENABLE_HIGH_LNB_VOLTAGE, int high);</para> 1699 <link linkend="FE_ENABLE_HIGH_LNB_VOLTAGE">FE_ENABLE_HIGH_LNB_VOLTAGE</link>, int high);</para>
1698</entry> 1700</entry>
1699 </row></tbody></tgroup></informaltable> 1701 </row></tbody></tgroup></informaltable>
1700 1702
@@ -1712,7 +1714,7 @@ modulation mode which can be one of the following:
1712<para>int request</para> 1714<para>int request</para>
1713</entry><entry 1715</entry><entry
1714 align="char"> 1716 align="char">
1715<para>Equals FE_SET_VOLTAGE for this command.</para> 1717<para>Equals <link linkend="FE_SET_VOLTAGE">FE_SET_VOLTAGE</link> for this command.</para>
1716</entry> 1718</entry>
1717 </row><row><entry 1719 </row><row><entry
1718 align="char"> 1720 align="char">
@@ -1762,5 +1764,82 @@ modulation mode which can be one of the following:
1762</entry> 1764</entry>
1763 </row></tbody></tgroup></informaltable> 1765 </row></tbody></tgroup></informaltable>
1764</section> 1766</section>
1767
1768<section id="FE_SET_FRONTEND_TUNE_MODE">
1769<title>FE_SET_FRONTEND_TUNE_MODE</title>
1770<para>DESCRIPTION</para>
1771<informaltable><tgroup cols="1"><tbody><row>
1772<entry align="char">
1773<para>Allow setting tuner mode flags to the frontend.</para>
1774</entry>
1775</row></tbody></tgroup></informaltable>
1776
1777<para>SYNOPSIS</para>
1778<informaltable><tgroup cols="1"><tbody><row>
1779<entry align="char">
1780<para>int ioctl(int fd, int request =
1781<link linkend="FE_SET_FRONTEND_TUNE_MODE">FE_SET_FRONTEND_TUNE_MODE</link>, unsigned int flags);</para>
1782</entry>
1783</row></tbody></tgroup></informaltable>
1784
1785<para>PARAMETERS</para>
1786<informaltable><tgroup cols="2"><tbody><row>
1787<entry align="char">
1788 <para>unsigned int flags</para>
1789</entry>
1790<entry align="char">
1791<para>
1792FE_TUNE_MODE_ONESHOT When set, this flag will disable any zigzagging or other "normal" tuning behaviour. Additionally, there will be no automatic monitoring of the lock status, and hence no frontend events will be generated. If a frontend device is closed, this flag will be automatically turned off when the device is reopened read-write.
1793</para>
1794</entry>
1795 </row></tbody></tgroup></informaltable>
1796
1797<para>ERRORS</para>
1798<informaltable><tgroup cols="2"><tbody><row>
1799<entry align="char"><para>EINVAL</para></entry>
1800<entry align="char"><para>Invalid argument.</para></entry>
1801 </row></tbody></tgroup></informaltable>
1765</section> 1802</section>
1766&sub-isdbt; 1803
1804<section id="FE_DISHNETWORK_SEND_LEGACY_CMD">
1805 <title>FE_DISHNETWORK_SEND_LEGACY_CMD</title>
1806<para>DESCRIPTION</para>
1807<informaltable><tgroup cols="1"><tbody><row>
1808<entry align="char">
1809<para>WARNING: This is a very obscure legacy command, used only at stv0299 driver. Should not be used on newer drivers.</para>
1810<para>It provides a non-standard method for selecting Diseqc voltage on the frontend, for Dish Network legacy switches.</para>
1811<para>As support for this ioctl were added in 2004, this means that such dishes were already legacy in 2004.</para>
1812</entry>
1813</row></tbody></tgroup></informaltable>
1814
1815<para>SYNOPSIS</para>
1816<informaltable><tgroup cols="1"><tbody><row>
1817<entry align="char">
1818<para>int ioctl(int fd, int request =
1819 <link linkend="FE_DISHNETWORK_SEND_LEGACY_CMD">FE_DISHNETWORK_SEND_LEGACY_CMD</link>, unsigned long cmd);</para>
1820</entry>
1821</row></tbody></tgroup></informaltable>
1822
1823<para>PARAMETERS</para>
1824<informaltable><tgroup cols="2"><tbody><row>
1825<entry align="char">
1826 <para>unsigned long cmd</para>
1827</entry>
1828<entry align="char">
1829<para>
1830sends the specified raw cmd to the dish via DISEqC.
1831</para>
1832</entry>
1833 </row></tbody></tgroup></informaltable>
1834
1835<para>ERRORS</para>
1836<informaltable><tgroup cols="1"><tbody><row>
1837<entry align="char">
1838 <para>There are no errors in use for this call</para>
1839</entry>
1840</row></tbody></tgroup></informaltable>
1841</section>
1842
1843</section>
1844
1845&sub-dvbproperty;
diff --git a/Documentation/DocBook/media-entities.tmpl b/Documentation/DocBook/media-entities.tmpl
index 0eb43c1970bb..bb5ab741220e 100644
--- a/Documentation/DocBook/media-entities.tmpl
+++ b/Documentation/DocBook/media-entities.tmpl
@@ -280,7 +280,7 @@
280<!ENTITY sub-v4l2 SYSTEM "v4l/v4l2.xml"> 280<!ENTITY sub-v4l2 SYSTEM "v4l/v4l2.xml">
281<!ENTITY sub-intro SYSTEM "dvb/intro.xml"> 281<!ENTITY sub-intro SYSTEM "dvb/intro.xml">
282<!ENTITY sub-frontend SYSTEM "dvb/frontend.xml"> 282<!ENTITY sub-frontend SYSTEM "dvb/frontend.xml">
283<!ENTITY sub-isdbt SYSTEM "dvb/isdbt.xml"> 283<!ENTITY sub-dvbproperty SYSTEM "dvb/dvbproperty.xml">
284<!ENTITY sub-demux SYSTEM "dvb/demux.xml"> 284<!ENTITY sub-demux SYSTEM "dvb/demux.xml">
285<!ENTITY sub-video SYSTEM "dvb/video.xml"> 285<!ENTITY sub-video SYSTEM "dvb/video.xml">
286<!ENTITY sub-audio SYSTEM "dvb/audio.xml"> 286<!ENTITY sub-audio SYSTEM "dvb/audio.xml">
@@ -288,6 +288,7 @@
288<!ENTITY sub-net SYSTEM "dvb/net.xml"> 288<!ENTITY sub-net SYSTEM "dvb/net.xml">
289<!ENTITY sub-kdapi SYSTEM "dvb/kdapi.xml"> 289<!ENTITY sub-kdapi SYSTEM "dvb/kdapi.xml">
290<!ENTITY sub-examples SYSTEM "dvb/examples.xml"> 290<!ENTITY sub-examples SYSTEM "dvb/examples.xml">
291<!ENTITY sub-frontend-h SYSTEM "dvb/frontend.h.xml">
291<!ENTITY sub-dvbapi SYSTEM "dvb/dvbapi.xml"> 292<!ENTITY sub-dvbapi SYSTEM "dvb/dvbapi.xml">
292<!ENTITY sub-media SYSTEM "media.xml"> 293<!ENTITY sub-media SYSTEM "media.xml">
293<!ENTITY sub-media-entities SYSTEM "media-entities.tmpl"> 294<!ENTITY sub-media-entities SYSTEM "media-entities.tmpl">
diff --git a/Documentation/DocBook/v4l/controls.xml b/Documentation/DocBook/v4l/controls.xml
index f492accb691d..f46450610412 100644
--- a/Documentation/DocBook/v4l/controls.xml
+++ b/Documentation/DocBook/v4l/controls.xml
@@ -281,10 +281,28 @@ minimum value disables backlight compensation.</entry>
281<constant>V4L2_COLORFX_SEPIA</constant> (2).</entry> 281<constant>V4L2_COLORFX_SEPIA</constant> (2).</entry>
282 </row> 282 </row>
283 <row> 283 <row>
284 <entry><constant>V4L2_CID_ROTATE</constant></entry>
285 <entry>integer</entry>
286 <entry>Rotates the image by specified angle. Common angles are 90,
287 270 and 180. Rotating the image to 90 and 270 will reverse the height
288 and width of the display window. It is necessary to set the new height and
289 width of the picture using the &VIDIOC-S-FMT; ioctl according to
290 the rotation angle selected.</entry>
291 </row>
292 <row>
293 <entry><constant>V4L2_CID_BG_COLOR</constant></entry>
294 <entry>integer</entry>
295 <entry>Sets the background color on the current output device.
296 Background color needs to be specified in the RGB24 format. The
297 supplied 32 bit value is interpreted as bits 0-7 Red color information,
298 bits 8-15 Green color information, bits 16-23 Blue color
299 information and bits 24-31 must be zero.</entry>
300 </row>
301 <row>
284 <entry><constant>V4L2_CID_LASTP1</constant></entry> 302 <entry><constant>V4L2_CID_LASTP1</constant></entry>
285 <entry></entry> 303 <entry></entry>
286 <entry>End of the predefined control IDs (currently 304 <entry>End of the predefined control IDs (currently
287<constant>V4L2_CID_COLORFX</constant> + 1).</entry> 305<constant>V4L2_CID_BG_COLOR</constant> + 1).</entry>
288 </row> 306 </row>
289 <row> 307 <row>
290 <entry><constant>V4L2_CID_PRIVATE_BASE</constant></entry> 308 <entry><constant>V4L2_CID_PRIVATE_BASE</constant></entry>
diff --git a/Documentation/DocBook/v4l/pixfmt.xml b/Documentation/DocBook/v4l/pixfmt.xml
index 7d396a3785f5..885968d6a2fc 100644
--- a/Documentation/DocBook/v4l/pixfmt.xml
+++ b/Documentation/DocBook/v4l/pixfmt.xml
@@ -770,6 +770,11 @@ kernel sources in the file <filename>Documentation/video4linux/cx2341x/README.hm
770 <entry>'S920'</entry> 770 <entry>'S920'</entry>
771 <entry>YUV 4:2:0 format of the gspca sn9c20x driver.</entry> 771 <entry>YUV 4:2:0 format of the gspca sn9c20x driver.</entry>
772 </row> 772 </row>
773 <row id="V4L2-PIX-FMT-STV0680">
774 <entry><constant>V4L2_PIX_FMT_STV0680</constant></entry>
775 <entry>'S680'</entry>
776 <entry>Bayer format of the gspca stv0680 driver.</entry>
777 </row>
773 <row id="V4L2-PIX-FMT-WNVA"> 778 <row id="V4L2-PIX-FMT-WNVA">
774 <entry><constant>V4L2_PIX_FMT_WNVA</constant></entry> 779 <entry><constant>V4L2_PIX_FMT_WNVA</constant></entry>
775 <entry>'WNVA'</entry> 780 <entry>'WNVA'</entry>
diff --git a/Documentation/DocBook/v4l/videodev2.h.xml b/Documentation/DocBook/v4l/videodev2.h.xml
index 26303e58345f..3e282ed9f593 100644
--- a/Documentation/DocBook/v4l/videodev2.h.xml
+++ b/Documentation/DocBook/v4l/videodev2.h.xml
@@ -363,6 +363,7 @@ struct <link linkend="v4l2-pix-format">v4l2_pix_format</link> {
363#define <link linkend="V4L2-PIX-FMT-OV511">V4L2_PIX_FMT_OV511</link> v4l2_fourcc('O', '5', '1', '1') /* ov511 JPEG */ 363#define <link linkend="V4L2-PIX-FMT-OV511">V4L2_PIX_FMT_OV511</link> v4l2_fourcc('O', '5', '1', '1') /* ov511 JPEG */
364#define <link linkend="V4L2-PIX-FMT-OV518">V4L2_PIX_FMT_OV518</link> v4l2_fourcc('O', '5', '1', '8') /* ov518 JPEG */ 364#define <link linkend="V4L2-PIX-FMT-OV518">V4L2_PIX_FMT_OV518</link> v4l2_fourcc('O', '5', '1', '8') /* ov518 JPEG */
365#define <link linkend="V4L2-PIX-FMT-TM6000">V4L2_PIX_FMT_TM6000</link> v4l2_fourcc('T', 'M', '6', '0') /* tm5600/tm60x0 */ 365#define <link linkend="V4L2-PIX-FMT-TM6000">V4L2_PIX_FMT_TM6000</link> v4l2_fourcc('T', 'M', '6', '0') /* tm5600/tm60x0 */
366#define <link linkend="V4L2-PIX-FMT-STV0680">V4L2_PIX_FMT_STV0680</link> v4l2_fourcc('S', '6', '8', '0') /* stv0680 bayer */
366 367
367/* 368/*
368 * F O R M A T E N U M E R A T I O N 369 * F O R M A T E N U M E R A T I O N
@@ -565,6 +566,7 @@ struct <link linkend="v4l2-framebuffer">v4l2_framebuffer</link> {
565#define V4L2_FBUF_CAP_LOCAL_ALPHA 0x0010 566#define V4L2_FBUF_CAP_LOCAL_ALPHA 0x0010
566#define V4L2_FBUF_CAP_GLOBAL_ALPHA 0x0020 567#define V4L2_FBUF_CAP_GLOBAL_ALPHA 0x0020
567#define V4L2_FBUF_CAP_LOCAL_INV_ALPHA 0x0040 568#define V4L2_FBUF_CAP_LOCAL_INV_ALPHA 0x0040
569#define V4L2_FBUF_CAP_SRC_CHROMAKEY 0x0080
568/* Flags for the 'flags' field. */ 570/* Flags for the 'flags' field. */
569#define V4L2_FBUF_FLAG_PRIMARY 0x0001 571#define V4L2_FBUF_FLAG_PRIMARY 0x0001
570#define V4L2_FBUF_FLAG_OVERLAY 0x0002 572#define V4L2_FBUF_FLAG_OVERLAY 0x0002
@@ -572,6 +574,7 @@ struct <link linkend="v4l2-framebuffer">v4l2_framebuffer</link> {
572#define V4L2_FBUF_FLAG_LOCAL_ALPHA 0x0008 574#define V4L2_FBUF_FLAG_LOCAL_ALPHA 0x0008
573#define V4L2_FBUF_FLAG_GLOBAL_ALPHA 0x0010 575#define V4L2_FBUF_FLAG_GLOBAL_ALPHA 0x0010
574#define V4L2_FBUF_FLAG_LOCAL_INV_ALPHA 0x0020 576#define V4L2_FBUF_FLAG_LOCAL_INV_ALPHA 0x0020
577#define V4L2_FBUF_FLAG_SRC_CHROMAKEY 0x0040
575 578
576struct <link linkend="v4l2-clip">v4l2_clip</link> { 579struct <link linkend="v4l2-clip">v4l2_clip</link> {
577 struct <link linkend="v4l2-rect">v4l2_rect</link> c; 580 struct <link linkend="v4l2-rect">v4l2_rect</link> c;
@@ -914,8 +917,10 @@ enum <link linkend="v4l2-colorfx">v4l2_colorfx</link> {
914#define V4L2_CID_AUTOBRIGHTNESS (V4L2_CID_BASE+32) 917#define V4L2_CID_AUTOBRIGHTNESS (V4L2_CID_BASE+32)
915#define V4L2_CID_BAND_STOP_FILTER (V4L2_CID_BASE+33) 918#define V4L2_CID_BAND_STOP_FILTER (V4L2_CID_BASE+33)
916 919
920#define V4L2_CID_ROTATE (V4L2_CID_BASE+34)
921#define V4L2_CID_BG_COLOR (V4L2_CID_BASE+35)
917/* last CID + 1 */ 922/* last CID + 1 */
918#define V4L2_CID_LASTP1 (V4L2_CID_BASE+34) 923#define V4L2_CID_LASTP1 (V4L2_CID_BASE+36)
919 924
920/* MPEG-class control IDs defined by V4L2 */ 925/* MPEG-class control IDs defined by V4L2 */
921#define V4L2_CID_MPEG_BASE (V4L2_CTRL_CLASS_MPEG | 0x900) 926#define V4L2_CID_MPEG_BASE (V4L2_CTRL_CLASS_MPEG | 0x900)
diff --git a/Documentation/DocBook/v4l/vidioc-g-fbuf.xml b/Documentation/DocBook/v4l/vidioc-g-fbuf.xml
index f7017062656e..e7dda4822f04 100644
--- a/Documentation/DocBook/v4l/vidioc-g-fbuf.xml
+++ b/Documentation/DocBook/v4l/vidioc-g-fbuf.xml
@@ -336,6 +336,13 @@ alpha value. Alpha blending makes no sense for destructive overlays.</entry>
336inverted alpha channel of the framebuffer or VGA signal. Alpha 336inverted alpha channel of the framebuffer or VGA signal. Alpha
337blending makes no sense for destructive overlays.</entry> 337blending makes no sense for destructive overlays.</entry>
338 </row> 338 </row>
339 <row>
340 <entry><constant>V4L2_FBUF_CAP_SRC_CHROMAKEY</constant></entry>
341 <entry>0x0080</entry>
342 <entry>The device supports Source Chroma-keying. Framebuffer pixels
343with the chroma-key colors are replaced by video pixels, which is exactly opposite of
344<constant>V4L2_FBUF_CAP_CHROMAKEY</constant></entry>
345 </row>
339 </tbody> 346 </tbody>
340 </tgroup> 347 </tgroup>
341 </table> 348 </table>
@@ -411,6 +418,16 @@ images, but with an inverted alpha value. The blend function is:
411output = framebuffer pixel * (1 - alpha) + video pixel * alpha. The 418output = framebuffer pixel * (1 - alpha) + video pixel * alpha. The
412actual alpha depth depends on the framebuffer pixel format.</entry> 419actual alpha depth depends on the framebuffer pixel format.</entry>
413 </row> 420 </row>
421 <row>
422 <entry><constant>V4L2_FBUF_FLAG_SRC_CHROMAKEY</constant></entry>
423 <entry>0x0040</entry>
424 <entry>Use source chroma-keying. The source chroma-key color is
425determined by the <structfield>chromakey</structfield> field of
426&v4l2-window; and negotiated with the &VIDIOC-S-FMT; ioctl, see <xref
427linkend="overlay" /> and <xref linkend="osd" />.
428Both chroma-keying are mutual exclusive to each other, so same
429<structfield>chromakey</structfield> field of &v4l2-window; is being used.</entry>
430 </row>
414 </tbody> 431 </tbody>
415 </tgroup> 432 </tgroup>
416 </table> 433 </table>
diff --git a/Documentation/video4linux/CARDLIST.cx23885 b/Documentation/video4linux/CARDLIST.cx23885
index 5f33d8486102..7539e8fa1ffd 100644
--- a/Documentation/video4linux/CARDLIST.cx23885
+++ b/Documentation/video4linux/CARDLIST.cx23885
@@ -24,3 +24,5 @@
24 23 -> Magic-Pro ProHDTV Extreme 2 [14f1:8657] 24 23 -> Magic-Pro ProHDTV Extreme 2 [14f1:8657]
25 24 -> Hauppauge WinTV-HVR1850 [0070:8541] 25 24 -> Hauppauge WinTV-HVR1850 [0070:8541]
26 25 -> Compro VideoMate E800 [1858:e800] 26 25 -> Compro VideoMate E800 [1858:e800]
27 26 -> Hauppauge WinTV-HVR1290 [0070:8551]
28 27 -> Mygica X8558 PRO DMB-TH [14f1:8578]
diff --git a/Documentation/video4linux/CARDLIST.cx88 b/Documentation/video4linux/CARDLIST.cx88
index 3385f8b094a5..7ec3c4e4b60f 100644
--- a/Documentation/video4linux/CARDLIST.cx88
+++ b/Documentation/video4linux/CARDLIST.cx88
@@ -81,3 +81,4 @@
81 80 -> Hauppauge WinTV-IR Only [0070:9290] 81 80 -> Hauppauge WinTV-IR Only [0070:9290]
82 81 -> Leadtek WinFast DTV1800 Hybrid [107d:6654] 82 81 -> Leadtek WinFast DTV1800 Hybrid [107d:6654]
83 82 -> WinFast DTV2000 H rev. J [107d:6f2b] 83 82 -> WinFast DTV2000 H rev. J [107d:6f2b]
84 83 -> Prof 7301 DVB-S/S2 [b034:3034]
diff --git a/Documentation/video4linux/CARDLIST.em28xx b/Documentation/video4linux/CARDLIST.em28xx
index b8afef4c0e01..0c166ff003a0 100644
--- a/Documentation/video4linux/CARDLIST.em28xx
+++ b/Documentation/video4linux/CARDLIST.em28xx
@@ -1,5 +1,5 @@
1 0 -> Unknown EM2800 video grabber (em2800) [eb1a:2800] 1 0 -> Unknown EM2800 video grabber (em2800) [eb1a:2800]
2 1 -> Unknown EM2750/28xx video grabber (em2820/em2840) [eb1a:2710,eb1a:2820,eb1a:2821,eb1a:2860,eb1a:2861,eb1a:2870,eb1a:2881,eb1a:2883,eb1a:2868] 2 1 -> Unknown EM2750/28xx video grabber (em2820/em2840) [eb1a:2710,eb1a:2820,eb1a:2821,eb1a:2860,eb1a:2861,eb1a:2862,eb1a:2870,eb1a:2881,eb1a:2883,eb1a:2868]
3 2 -> Terratec Cinergy 250 USB (em2820/em2840) [0ccd:0036] 3 2 -> Terratec Cinergy 250 USB (em2820/em2840) [0ccd:0036]
4 3 -> Pinnacle PCTV USB 2 (em2820/em2840) [2304:0208] 4 3 -> Pinnacle PCTV USB 2 (em2820/em2840) [2304:0208]
5 4 -> Hauppauge WinTV USB 2 (em2820/em2840) [2040:4200,2040:4201] 5 4 -> Hauppauge WinTV USB 2 (em2820/em2840) [2040:4200,2040:4201]
@@ -69,3 +69,4 @@
69 71 -> Silvercrest Webcam 1.3mpix (em2820/em2840) 69 71 -> Silvercrest Webcam 1.3mpix (em2820/em2840)
70 72 -> Gadmei UTV330+ (em2861) 70 72 -> Gadmei UTV330+ (em2861)
71 73 -> Reddo DVB-C USB TV Box (em2870) 71 73 -> Reddo DVB-C USB TV Box (em2870)
72 74 -> Actionmaster/LinXcel/Digitus VC211A (em2800)
diff --git a/Documentation/video4linux/CARDLIST.saa7134 b/Documentation/video4linux/CARDLIST.saa7134
index 2620d60341ee..fce1e7eb0474 100644
--- a/Documentation/video4linux/CARDLIST.saa7134
+++ b/Documentation/video4linux/CARDLIST.saa7134
@@ -172,3 +172,5 @@
172171 -> Beholder BeholdTV X7 [5ace:7595] 172171 -> Beholder BeholdTV X7 [5ace:7595]
173172 -> RoverMedia TV Link Pro FM [19d1:0138] 173172 -> RoverMedia TV Link Pro FM [19d1:0138]
174173 -> Zolid Hybrid TV Tuner PCI [1131:2004] 174173 -> Zolid Hybrid TV Tuner PCI [1131:2004]
175174 -> Asus Europa Hybrid OEM [1043:4847]
176175 -> Leadtek Winfast DTV1000S [107d:6655]
diff --git a/Documentation/video4linux/gspca.txt b/Documentation/video4linux/gspca.txt
index 6b29555b58b7..319d9838e87e 100644
--- a/Documentation/video4linux/gspca.txt
+++ b/Documentation/video4linux/gspca.txt
@@ -7,6 +7,7 @@ The modules are:
7xxxx vend:prod 7xxxx vend:prod
8---- 8----
9spca501 0000:0000 MystFromOri Unknown Camera 9spca501 0000:0000 MystFromOri Unknown Camera
10spca508 0130:0130 Clone Digital Webcam 11043
10m5602 0402:5602 ALi Video Camera Controller 11m5602 0402:5602 ALi Video Camera Controller
11spca501 040a:0002 Kodak DVC-325 12spca501 040a:0002 Kodak DVC-325
12spca500 040a:0300 Kodak EZ200 13spca500 040a:0300 Kodak EZ200
@@ -37,6 +38,7 @@ ov519 041e:405f Creative Live! VISTA VF0330
37ov519 041e:4060 Creative Live! VISTA VF0350 38ov519 041e:4060 Creative Live! VISTA VF0350
38ov519 041e:4061 Creative Live! VISTA VF0400 39ov519 041e:4061 Creative Live! VISTA VF0400
39ov519 041e:4064 Creative Live! VISTA VF0420 40ov519 041e:4064 Creative Live! VISTA VF0420
41ov519 041e:4067 Creative Live! Cam Video IM (VF0350)
40ov519 041e:4068 Creative Live! VISTA VF0470 42ov519 041e:4068 Creative Live! VISTA VF0470
41spca561 0458:7004 Genius VideoCAM Express V2 43spca561 0458:7004 Genius VideoCAM Express V2
42sunplus 0458:7006 Genius Dsc 1.3 Smart 44sunplus 0458:7006 Genius Dsc 1.3 Smart
@@ -68,12 +70,12 @@ zc3xx 046d:08a3 Logitech QC Chat
68zc3xx 046d:08a6 Logitech QCim 70zc3xx 046d:08a6 Logitech QCim
69zc3xx 046d:08a7 Logitech QuickCam Image 71zc3xx 046d:08a7 Logitech QuickCam Image
70zc3xx 046d:08a9 Logitech Notebook Deluxe 72zc3xx 046d:08a9 Logitech Notebook Deluxe
71zc3xx 046d:08aa Labtec Webcam Notebook 73zc3xx 046d:08aa Labtec Webcam Notebook
72zc3xx 046d:08ac Logitech QuickCam Cool 74zc3xx 046d:08ac Logitech QuickCam Cool
73zc3xx 046d:08ad Logitech QCCommunicate STX 75zc3xx 046d:08ad Logitech QCCommunicate STX
74zc3xx 046d:08ae Logitech QuickCam for Notebooks 76zc3xx 046d:08ae Logitech QuickCam for Notebooks
75zc3xx 046d:08af Logitech QuickCam Cool 77zc3xx 046d:08af Logitech QuickCam Cool
76zc3xx 046d:08b9 Logitech QC IM ??? 78zc3xx 046d:08b9 Logitech QuickCam Express
77zc3xx 046d:08d7 Logitech QCam STX 79zc3xx 046d:08d7 Logitech QCam STX
78zc3xx 046d:08d9 Logitech QuickCam IM/Connect 80zc3xx 046d:08d9 Logitech QuickCam IM/Connect
79zc3xx 046d:08d8 Logitech Notebook Deluxe 81zc3xx 046d:08d8 Logitech Notebook Deluxe
@@ -82,7 +84,7 @@ zc3xx 046d:08dd Logitech QuickCam for Notebooks
82spca500 046d:0900 Logitech Inc. ClickSmart 310 84spca500 046d:0900 Logitech Inc. ClickSmart 310
83spca500 046d:0901 Logitech Inc. ClickSmart 510 85spca500 046d:0901 Logitech Inc. ClickSmart 510
84sunplus 046d:0905 Logitech ClickSmart 820 86sunplus 046d:0905 Logitech ClickSmart 820
85tv8532 046d:0920 QC Express 87tv8532 046d:0920 Logitech QuickCam Express
86tv8532 046d:0921 Labtec Webcam 88tv8532 046d:0921 Labtec Webcam
87spca561 046d:0928 Logitech QC Express Etch2 89spca561 046d:0928 Logitech QC Express Etch2
88spca561 046d:0929 Labtec Webcam Elch2 90spca561 046d:0929 Labtec Webcam Elch2
@@ -91,7 +93,7 @@ spca561 046d:092b Labtec Webcam Plus
91spca561 046d:092c Logitech QC chat Elch2 93spca561 046d:092c Logitech QC chat Elch2
92spca561 046d:092d Logitech QC Elch2 94spca561 046d:092d Logitech QC Elch2
93spca561 046d:092e Logitech QC Elch2 95spca561 046d:092e Logitech QC Elch2
94spca561 046d:092f Logitech QuickCam Express Plus 96spca561 046d:092f Logitech QuickCam Express Plus
95sunplus 046d:0960 Logitech ClickSmart 420 97sunplus 046d:0960 Logitech ClickSmart 420
96sunplus 0471:0322 Philips DMVC1300K 98sunplus 0471:0322 Philips DMVC1300K
97zc3xx 0471:0325 Philips SPC 200 NC 99zc3xx 0471:0325 Philips SPC 200 NC
@@ -187,7 +189,6 @@ sonixj 06f8:3004 Hercules Classic Silver
187sonixj 06f8:3008 Hercules Deluxe Optical Glass 189sonixj 06f8:3008 Hercules Deluxe Optical Glass
188pac7311 06f8:3009 Hercules Classic Link 190pac7311 06f8:3009 Hercules Classic Link
189spca508 0733:0110 ViewQuest VQ110 191spca508 0733:0110 ViewQuest VQ110
190spca508 0130:0130 Clone Digital Webcam 11043
191spca501 0733:0401 Intel Create and Share 192spca501 0733:0401 Intel Create and Share
192spca501 0733:0402 ViewQuest M318B 193spca501 0733:0402 ViewQuest M318B
193spca505 0733:0430 Intel PC Camera Pro 194spca505 0733:0430 Intel PC Camera Pro
@@ -202,6 +203,7 @@ spca500 084d:0003 D-Link DSC-350
202spca500 08ca:0103 Aiptek PocketDV 203spca500 08ca:0103 Aiptek PocketDV
203sunplus 08ca:0104 Aiptek PocketDVII 1.3 204sunplus 08ca:0104 Aiptek PocketDVII 1.3
204sunplus 08ca:0106 Aiptek Pocket DV3100+ 205sunplus 08ca:0106 Aiptek Pocket DV3100+
206mr97310a 08ca:0110 Trust Spyc@m 100
205mr97310a 08ca:0111 Aiptek PenCam VGA+ 207mr97310a 08ca:0111 Aiptek PenCam VGA+
206sunplus 08ca:2008 Aiptek Mini PenCam 2 M 208sunplus 08ca:2008 Aiptek Mini PenCam 2 M
207sunplus 08ca:2010 Aiptek PocketCam 3M 209sunplus 08ca:2010 Aiptek PocketCam 3M
@@ -222,7 +224,7 @@ pac207 093a:2460 Qtec Webcam 100
222pac207 093a:2461 HP Webcam 224pac207 093a:2461 HP Webcam
223pac207 093a:2463 Philips SPC 220 NC 225pac207 093a:2463 Philips SPC 220 NC
224pac207 093a:2464 Labtec Webcam 1200 226pac207 093a:2464 Labtec Webcam 1200
225pac207 093a:2468 PAC207 227pac207 093a:2468 Webcam WB-1400T
226pac207 093a:2470 Genius GF112 228pac207 093a:2470 Genius GF112
227pac207 093a:2471 Genius VideoCam ge111 229pac207 093a:2471 Genius VideoCam ge111
228pac207 093a:2472 Genius VideoCam ge110 230pac207 093a:2472 Genius VideoCam ge110
@@ -230,7 +232,7 @@ pac207 093a:2474 Genius iLook 111
230pac207 093a:2476 Genius e-Messenger 112 232pac207 093a:2476 Genius e-Messenger 112
231pac7311 093a:2600 PAC7311 Typhoon 233pac7311 093a:2600 PAC7311 Typhoon
232pac7311 093a:2601 Philips SPC 610 NC 234pac7311 093a:2601 Philips SPC 610 NC
233pac7311 093a:2603 PAC7312 235pac7311 093a:2603 Philips SPC 500 NC
234pac7311 093a:2608 Trust WB-3300p 236pac7311 093a:2608 Trust WB-3300p
235pac7311 093a:260e Gigaware VGA PC Camera, Trust WB-3350p, SIGMA cam 2350 237pac7311 093a:260e Gigaware VGA PC Camera, Trust WB-3350p, SIGMA cam 2350
236pac7311 093a:260f SnakeCam 238pac7311 093a:260f SnakeCam
@@ -239,6 +241,7 @@ pac7311 093a:2621 PAC731x
239pac7311 093a:2622 Genius Eye 312 241pac7311 093a:2622 Genius Eye 312
240pac7311 093a:2624 PAC7302 242pac7311 093a:2624 PAC7302
241pac7311 093a:2626 Labtec 2200 243pac7311 093a:2626 Labtec 2200
244pac7311 093a:2628 Genius iLook 300
242pac7311 093a:2629 Genious iSlim 300 245pac7311 093a:2629 Genious iSlim 300
243pac7311 093a:262a Webcam 300k 246pac7311 093a:262a Webcam 300k
244pac7311 093a:262c Philips SPC 230 NC 247pac7311 093a:262c Philips SPC 230 NC
@@ -250,7 +253,7 @@ vc032x 0ac8:0328 A4Tech PK-130MG
250zc3xx 0ac8:301b Z-Star zc301b 253zc3xx 0ac8:301b Z-Star zc301b
251zc3xx 0ac8:303b Vimicro 0x303b 254zc3xx 0ac8:303b Vimicro 0x303b
252zc3xx 0ac8:305b Z-star Vimicro zc0305b 255zc3xx 0ac8:305b Z-star Vimicro zc0305b
253zc3xx 0ac8:307b Ldlc VC302+Ov7620 256zc3xx 0ac8:307b PC Camera (ZS0211)
254vc032x 0ac8:c001 Sony embedded vimicro 257vc032x 0ac8:c001 Sony embedded vimicro
255vc032x 0ac8:c002 Sony embedded vimicro 258vc032x 0ac8:c002 Sony embedded vimicro
256vc032x 0ac8:c301 Samsung Q1 Ultra Premium 259vc032x 0ac8:c301 Samsung Q1 Ultra Premium
diff --git a/Documentation/video4linux/si4713.txt b/Documentation/video4linux/si4713.txt
index 25abdb78209d..2e7392a4fee1 100644
--- a/Documentation/video4linux/si4713.txt
+++ b/Documentation/video4linux/si4713.txt
@@ -164,7 +164,7 @@ Stereo/Mono and RDS subchannels
164 164
165The device can also be configured using the available sub channels for 165The device can also be configured using the available sub channels for
166transmission. To do that use S/G_MODULATOR ioctl and configure txsubchans properly. 166transmission. To do that use S/G_MODULATOR ioctl and configure txsubchans properly.
167Refer to v4l2-spec for proper use of this ioctl. 167Refer to the V4L2 API specification for proper use of this ioctl.
168 168
169Testing 169Testing
170======= 170=======
diff --git a/Documentation/video4linux/zr364xx.txt b/Documentation/video4linux/zr364xx.txt
index 7f3d1955d214..d98e4d302977 100644
--- a/Documentation/video4linux/zr364xx.txt
+++ b/Documentation/video4linux/zr364xx.txt
@@ -66,3 +66,4 @@ Vendor Product Distributor Model
660x0a17 0x004e Pentax Optio 50 660x0a17 0x004e Pentax Optio 50
670x041e 0x405d Creative DiVi CAM 516 670x041e 0x405d Creative DiVi CAM 516
680x08ca 0x2102 Aiptek DV T300 680x08ca 0x2102 Aiptek DV T300
690x06d6 0x003d Trust Powerc@m 910Z
diff --git a/drivers/media/common/Makefile b/drivers/media/common/Makefile
index 351b98b9b302..169b337b7c9d 100644
--- a/drivers/media/common/Makefile
+++ b/drivers/media/common/Makefile
@@ -1,6 +1,6 @@
1saa7146-objs := saa7146_i2c.o saa7146_core.o 1saa7146-objs := saa7146_i2c.o saa7146_core.o
2saa7146_vv-objs := saa7146_fops.o saa7146_video.o saa7146_hlp.o saa7146_vbi.o 2saa7146_vv-objs := saa7146_fops.o saa7146_video.o saa7146_hlp.o saa7146_vbi.o
3ir-common-objs := ir-functions.o ir-keymaps.o 3ir-common-objs := ir-functions.o ir-keymaps.o ir-keytable.o
4 4
5obj-y += tuners/ 5obj-y += tuners/
6obj-$(CONFIG_VIDEO_SAA7146) += saa7146.o 6obj-$(CONFIG_VIDEO_SAA7146) += saa7146.o
diff --git a/drivers/media/common/ir-functions.c b/drivers/media/common/ir-functions.c
index abd4791acb0e..e616f624ceaa 100644
--- a/drivers/media/common/ir-functions.c
+++ b/drivers/media/common/ir-functions.c
@@ -34,22 +34,19 @@ static int repeat = 1;
34module_param(repeat, int, 0444); 34module_param(repeat, int, 0444);
35MODULE_PARM_DESC(repeat,"auto-repeat for IR keys (default: on)"); 35MODULE_PARM_DESC(repeat,"auto-repeat for IR keys (default: on)");
36 36
37static int debug; /* debug level (0,1,2) */ 37int media_ir_debug; /* media_ir_debug level (0,1,2) */
38module_param(debug, int, 0644); 38module_param_named(debug, media_ir_debug, int, 0644);
39
40#define dprintk(level, fmt, arg...) if (debug >= level) \
41 printk(KERN_DEBUG fmt , ## arg)
42 39
43/* -------------------------------------------------------------------------- */ 40/* -------------------------------------------------------------------------- */
44 41
45static void ir_input_key_event(struct input_dev *dev, struct ir_input_state *ir) 42static void ir_input_key_event(struct input_dev *dev, struct ir_input_state *ir)
46{ 43{
47 if (KEY_RESERVED == ir->keycode) { 44 if (KEY_RESERVED == ir->keycode) {
48 printk(KERN_INFO "%s: unknown key: key=0x%02x raw=0x%02x down=%d\n", 45 printk(KERN_INFO "%s: unknown key: key=0x%02x down=%d\n",
49 dev->name,ir->ir_key,ir->ir_raw,ir->keypressed); 46 dev->name, ir->ir_key, ir->keypressed);
50 return; 47 return;
51 } 48 }
52 dprintk(1,"%s: key event code=%d down=%d\n", 49 IR_dprintk(1,"%s: key event code=%d down=%d\n",
53 dev->name,ir->keycode,ir->keypressed); 50 dev->name,ir->keycode,ir->keypressed);
54 input_report_key(dev,ir->keycode,ir->keypressed); 51 input_report_key(dev,ir->keycode,ir->keypressed);
55 input_sync(dev); 52 input_sync(dev);
@@ -57,39 +54,34 @@ static void ir_input_key_event(struct input_dev *dev, struct ir_input_state *ir)
57 54
58/* -------------------------------------------------------------------------- */ 55/* -------------------------------------------------------------------------- */
59 56
60void ir_input_init(struct input_dev *dev, struct ir_input_state *ir, 57int ir_input_init(struct input_dev *dev, struct ir_input_state *ir,
61 int ir_type, struct ir_scancode_table *ir_codes) 58 int ir_type, struct ir_scancode_table *ir_codes)
62{ 59{
63 int i;
64
65 ir->ir_type = ir_type; 60 ir->ir_type = ir_type;
66 61
67 memset(ir->ir_codes, 0, sizeof(ir->ir_codes)); 62 ir->keytable.size = ir_roundup_tablesize(ir_codes->size);
63 ir->keytable.scan = kzalloc(ir->keytable.size *
64 sizeof(struct ir_scancode), GFP_KERNEL);
65 if (!ir->keytable.scan)
66 return -ENOMEM;
68 67
69 /* 68 IR_dprintk(1, "Allocated space for %d keycode entries (%zd bytes)\n",
70 * FIXME: This is a temporary workaround to use the new IR tables 69 ir->keytable.size,
71 * with the old approach. Later patches will replace this to a 70 ir->keytable.size * sizeof(ir->keytable.scan));
72 * proper method
73 */
74 71
75 if (ir_codes) 72 ir_copy_table(&ir->keytable, ir_codes);
76 for (i = 0; i < ir_codes->size; i++) 73 ir_set_keycode_table(dev, &ir->keytable);
77 if (ir_codes->scan[i].scancode < IR_KEYTAB_SIZE)
78 ir->ir_codes[ir_codes->scan[i].scancode] = ir_codes->scan[i].keycode;
79 74
80 dev->keycode = ir->ir_codes;
81 dev->keycodesize = sizeof(IR_KEYTAB_TYPE);
82 dev->keycodemax = IR_KEYTAB_SIZE;
83 for (i = 0; i < IR_KEYTAB_SIZE; i++)
84 set_bit(ir->ir_codes[i], dev->keybit);
85 clear_bit(0, dev->keybit); 75 clear_bit(0, dev->keybit);
86
87 set_bit(EV_KEY, dev->evbit); 76 set_bit(EV_KEY, dev->evbit);
88 if (repeat) 77 if (repeat)
89 set_bit(EV_REP, dev->evbit); 78 set_bit(EV_REP, dev->evbit);
79
80 return 0;
90} 81}
91EXPORT_SYMBOL_GPL(ir_input_init); 82EXPORT_SYMBOL_GPL(ir_input_init);
92 83
84
93void ir_input_nokey(struct input_dev *dev, struct ir_input_state *ir) 85void ir_input_nokey(struct input_dev *dev, struct ir_input_state *ir)
94{ 86{
95 if (ir->keypressed) { 87 if (ir->keypressed) {
@@ -100,9 +92,9 @@ void ir_input_nokey(struct input_dev *dev, struct ir_input_state *ir)
100EXPORT_SYMBOL_GPL(ir_input_nokey); 92EXPORT_SYMBOL_GPL(ir_input_nokey);
101 93
102void ir_input_keydown(struct input_dev *dev, struct ir_input_state *ir, 94void ir_input_keydown(struct input_dev *dev, struct ir_input_state *ir,
103 u32 ir_key, u32 ir_raw) 95 u32 ir_key)
104{ 96{
105 u32 keycode = IR_KEYCODE(ir->ir_codes, ir_key); 97 u32 keycode = ir_g_keycode_from_table(dev, ir_key);
106 98
107 if (ir->keypressed && ir->keycode != keycode) { 99 if (ir->keypressed && ir->keycode != keycode) {
108 ir->keypressed = 0; 100 ir->keypressed = 0;
@@ -110,7 +102,6 @@ void ir_input_keydown(struct input_dev *dev, struct ir_input_state *ir,
110 } 102 }
111 if (!ir->keypressed) { 103 if (!ir->keypressed) {
112 ir->ir_key = ir_key; 104 ir->ir_key = ir_key;
113 ir->ir_raw = ir_raw;
114 ir->keycode = keycode; 105 ir->keycode = keycode;
115 ir->keypressed = 1; 106 ir->keypressed = 1;
116 ir_input_key_event(dev,ir); 107 ir_input_key_event(dev,ir);
@@ -275,7 +266,7 @@ EXPORT_SYMBOL_GPL(ir_decode_biphase);
275 * saa7134 */ 266 * saa7134 */
276 267
277/* decode raw bit pattern to RC5 code */ 268/* decode raw bit pattern to RC5 code */
278static u32 ir_rc5_decode(unsigned int code) 269u32 ir_rc5_decode(unsigned int code)
279{ 270{
280 unsigned int org_code = code; 271 unsigned int org_code = code;
281 unsigned int pair; 272 unsigned int pair;
@@ -295,15 +286,16 @@ static u32 ir_rc5_decode(unsigned int code)
295 rc5 |= 1; 286 rc5 |= 1;
296 break; 287 break;
297 case 3: 288 case 3:
298 dprintk(1, "ir-common: ir_rc5_decode(%x) bad code\n", org_code); 289 IR_dprintk(1, "ir-common: ir_rc5_decode(%x) bad code\n", org_code);
299 return 0; 290 return 0;
300 } 291 }
301 } 292 }
302 dprintk(1, "ir-common: code=%x, rc5=%x, start=%x, toggle=%x, address=%x, " 293 IR_dprintk(1, "ir-common: code=%x, rc5=%x, start=%x, toggle=%x, address=%x, "
303 "instr=%x\n", rc5, org_code, RC5_START(rc5), 294 "instr=%x\n", rc5, org_code, RC5_START(rc5),
304 RC5_TOGGLE(rc5), RC5_ADDR(rc5), RC5_INSTR(rc5)); 295 RC5_TOGGLE(rc5), RC5_ADDR(rc5), RC5_INSTR(rc5));
305 return rc5; 296 return rc5;
306} 297}
298EXPORT_SYMBOL_GPL(ir_rc5_decode);
307 299
308void ir_rc5_timer_end(unsigned long data) 300void ir_rc5_timer_end(unsigned long data)
309{ 301{
@@ -330,20 +322,20 @@ void ir_rc5_timer_end(unsigned long data)
330 322
331 /* Allow some timer jitter (RC5 is ~24ms anyway so this is ok) */ 323 /* Allow some timer jitter (RC5 is ~24ms anyway so this is ok) */
332 if (gap < 28000) { 324 if (gap < 28000) {
333 dprintk(1, "ir-common: spurious timer_end\n"); 325 IR_dprintk(1, "ir-common: spurious timer_end\n");
334 return; 326 return;
335 } 327 }
336 328
337 if (ir->last_bit < 20) { 329 if (ir->last_bit < 20) {
338 /* ignore spurious codes (caused by light/other remotes) */ 330 /* ignore spurious codes (caused by light/other remotes) */
339 dprintk(1, "ir-common: short code: %x\n", ir->code); 331 IR_dprintk(1, "ir-common: short code: %x\n", ir->code);
340 } else { 332 } else {
341 ir->code = (ir->code << ir->shift_by) | 1; 333 ir->code = (ir->code << ir->shift_by) | 1;
342 rc5 = ir_rc5_decode(ir->code); 334 rc5 = ir_rc5_decode(ir->code);
343 335
344 /* two start bits? */ 336 /* two start bits? */
345 if (RC5_START(rc5) != ir->start) { 337 if (RC5_START(rc5) != ir->start) {
346 dprintk(1, "ir-common: rc5 start bits invalid: %u\n", RC5_START(rc5)); 338 IR_dprintk(1, "ir-common: rc5 start bits invalid: %u\n", RC5_START(rc5));
347 339
348 /* right address? */ 340 /* right address? */
349 } else if (RC5_ADDR(rc5) == ir->addr) { 341 } else if (RC5_ADDR(rc5) == ir->addr) {
@@ -353,11 +345,10 @@ void ir_rc5_timer_end(unsigned long data)
353 /* Good code, decide if repeat/repress */ 345 /* Good code, decide if repeat/repress */
354 if (toggle != RC5_TOGGLE(ir->last_rc5) || 346 if (toggle != RC5_TOGGLE(ir->last_rc5) ||
355 instr != RC5_INSTR(ir->last_rc5)) { 347 instr != RC5_INSTR(ir->last_rc5)) {
356 dprintk(1, "ir-common: instruction %x, toggle %x\n", instr, 348 IR_dprintk(1, "ir-common: instruction %x, toggle %x\n", instr,
357 toggle); 349 toggle);
358 ir_input_nokey(ir->dev, &ir->ir); 350 ir_input_nokey(ir->dev, &ir->ir);
359 ir_input_keydown(ir->dev, &ir->ir, instr, 351 ir_input_keydown(ir->dev, &ir->ir, instr);
360 instr);
361 } 352 }
362 353
363 /* Set/reset key-up timer */ 354 /* Set/reset key-up timer */
@@ -376,7 +367,7 @@ void ir_rc5_timer_keyup(unsigned long data)
376{ 367{
377 struct card_ir *ir = (struct card_ir *)data; 368 struct card_ir *ir = (struct card_ir *)data;
378 369
379 dprintk(1, "ir-common: key released\n"); 370 IR_dprintk(1, "ir-common: key released\n");
380 ir_input_nokey(ir->dev, &ir->ir); 371 ir_input_nokey(ir->dev, &ir->ir);
381} 372}
382EXPORT_SYMBOL_GPL(ir_rc5_timer_keyup); 373EXPORT_SYMBOL_GPL(ir_rc5_timer_keyup);
diff --git a/drivers/media/common/ir-keymaps.c b/drivers/media/common/ir-keymaps.c
index f6790172736a..328c973a0838 100644
--- a/drivers/media/common/ir-keymaps.c
+++ b/drivers/media/common/ir-keymaps.c
@@ -1705,6 +1705,7 @@ static struct ir_scancode ir_codes_winfast[] = {
1705 { 0x37, KEY_RADIO }, /* FM */ 1705 { 0x37, KEY_RADIO }, /* FM */
1706 { 0x38, KEY_DVD }, 1706 { 0x38, KEY_DVD },
1707 1707
1708 { 0x1a, KEY_MODE}, /* change to MCE mode on Y04G0051 */
1708 { 0x3e, KEY_F21 }, /* MCE +VOL, on Y04G0033 */ 1709 { 0x3e, KEY_F21 }, /* MCE +VOL, on Y04G0033 */
1709 { 0x3a, KEY_F22 }, /* MCE -VOL, on Y04G0033 */ 1710 { 0x3a, KEY_F22 }, /* MCE -VOL, on Y04G0033 */
1710 { 0x3b, KEY_F23 }, /* MCE +CH, on Y04G0033 */ 1711 { 0x3b, KEY_F23 }, /* MCE +CH, on Y04G0033 */
@@ -1846,6 +1847,76 @@ struct ir_scancode_table ir_codes_hauppauge_new_table = {
1846}; 1847};
1847EXPORT_SYMBOL_GPL(ir_codes_hauppauge_new_table); 1848EXPORT_SYMBOL_GPL(ir_codes_hauppauge_new_table);
1848 1849
1850/*
1851 * Hauppauge:the newer, gray remotes (seems there are multiple
1852 * slightly different versions), shipped with cx88+ivtv cards.
1853 *
1854 * This table contains the complete RC5 code, instead of just the data part
1855 */
1856static struct ir_scancode ir_codes_rc5_hauppauge_new[] = {
1857 /* Keys 0 to 9 */
1858 { 0x1e00, KEY_0 },
1859 { 0x1e01, KEY_1 },
1860 { 0x1e02, KEY_2 },
1861 { 0x1e03, KEY_3 },
1862 { 0x1e04, KEY_4 },
1863 { 0x1e05, KEY_5 },
1864 { 0x1e06, KEY_6 },
1865 { 0x1e07, KEY_7 },
1866 { 0x1e08, KEY_8 },
1867 { 0x1e09, KEY_9 },
1868
1869 { 0x1e0a, KEY_TEXT }, /* keypad asterisk as well */
1870 { 0x1e0b, KEY_RED }, /* red button */
1871 { 0x1e0c, KEY_RADIO },
1872 { 0x1e0d, KEY_MENU },
1873 { 0x1e0e, KEY_SUBTITLE }, /* also the # key */
1874 { 0x1e0f, KEY_MUTE },
1875 { 0x1e10, KEY_VOLUMEUP },
1876 { 0x1e11, KEY_VOLUMEDOWN },
1877 { 0x1e12, KEY_PREVIOUS }, /* previous channel */
1878 { 0x1e14, KEY_UP },
1879 { 0x1e15, KEY_DOWN },
1880 { 0x1e16, KEY_LEFT },
1881 { 0x1e17, KEY_RIGHT },
1882 { 0x1e18, KEY_VIDEO }, /* Videos */
1883 { 0x1e19, KEY_AUDIO }, /* Music */
1884 /* 0x1e1a: Pictures - presume this means
1885 "Multimedia Home Platform" -
1886 no "PICTURES" key in input.h
1887 */
1888 { 0x1e1a, KEY_MHP },
1889
1890 { 0x1e1b, KEY_EPG }, /* Guide */
1891 { 0x1e1c, KEY_TV },
1892 { 0x1e1e, KEY_NEXTSONG }, /* skip >| */
1893 { 0x1e1f, KEY_EXIT }, /* back/exit */
1894 { 0x1e20, KEY_CHANNELUP }, /* channel / program + */
1895 { 0x1e21, KEY_CHANNELDOWN }, /* channel / program - */
1896 { 0x1e22, KEY_CHANNEL }, /* source (old black remote) */
1897 { 0x1e24, KEY_PREVIOUSSONG }, /* replay |< */
1898 { 0x1e25, KEY_ENTER }, /* OK */
1899 { 0x1e26, KEY_SLEEP }, /* minimize (old black remote) */
1900 { 0x1e29, KEY_BLUE }, /* blue key */
1901 { 0x1e2e, KEY_GREEN }, /* green button */
1902 { 0x1e30, KEY_PAUSE }, /* pause */
1903 { 0x1e32, KEY_REWIND }, /* backward << */
1904 { 0x1e34, KEY_FASTFORWARD }, /* forward >> */
1905 { 0x1e35, KEY_PLAY },
1906 { 0x1e36, KEY_STOP },
1907 { 0x1e37, KEY_RECORD }, /* recording */
1908 { 0x1e38, KEY_YELLOW }, /* yellow key */
1909 { 0x1e3b, KEY_SELECT }, /* top right button */
1910 { 0x1e3c, KEY_ZOOM }, /* full */
1911 { 0x1e3d, KEY_POWER }, /* system power (green button) */
1912};
1913
1914struct ir_scancode_table ir_codes_rc5_hauppauge_new_table = {
1915 .scan = ir_codes_rc5_hauppauge_new,
1916 .size = ARRAY_SIZE(ir_codes_rc5_hauppauge_new),
1917};
1918EXPORT_SYMBOL_GPL(ir_codes_rc5_hauppauge_new_table);
1919
1849static struct ir_scancode ir_codes_npgtech[] = { 1920static struct ir_scancode ir_codes_npgtech[] = {
1850 { 0x1d, KEY_SWITCHVIDEOMODE }, /* switch inputs */ 1921 { 0x1d, KEY_SWITCHVIDEOMODE }, /* switch inputs */
1851 { 0x2a, KEY_FRONT }, 1922 { 0x2a, KEY_FRONT },
@@ -2964,6 +3035,101 @@ struct ir_scancode_table ir_codes_dm1105_nec_table = {
2964}; 3035};
2965EXPORT_SYMBOL_GPL(ir_codes_dm1105_nec_table); 3036EXPORT_SYMBOL_GPL(ir_codes_dm1105_nec_table);
2966 3037
3038static struct ir_scancode ir_codes_tevii_nec[] = {
3039 { 0x0a, KEY_POWER2},
3040 { 0x0c, KEY_MUTE},
3041 { 0x11, KEY_1},
3042 { 0x12, KEY_2},
3043 { 0x13, KEY_3},
3044 { 0x14, KEY_4},
3045 { 0x15, KEY_5},
3046 { 0x16, KEY_6},
3047 { 0x17, KEY_7},
3048 { 0x18, KEY_8},
3049 { 0x19, KEY_9},
3050 { 0x10, KEY_0},
3051 { 0x1c, KEY_MENU},
3052 { 0x0f, KEY_VOLUMEDOWN},
3053 { 0x1a, KEY_LAST},
3054 { 0x0e, KEY_OPEN},
3055 { 0x04, KEY_RECORD},
3056 { 0x09, KEY_VOLUMEUP},
3057 { 0x08, KEY_CHANNELUP},
3058 { 0x07, KEY_PVR},
3059 { 0x0b, KEY_TIME},
3060 { 0x02, KEY_RIGHT},
3061 { 0x03, KEY_LEFT},
3062 { 0x00, KEY_UP},
3063 { 0x1f, KEY_OK},
3064 { 0x01, KEY_DOWN},
3065 { 0x05, KEY_TUNER},
3066 { 0x06, KEY_CHANNELDOWN},
3067 { 0x40, KEY_PLAYPAUSE},
3068 { 0x1e, KEY_REWIND},
3069 { 0x1b, KEY_FAVORITES},
3070 { 0x1d, KEY_BACK},
3071 { 0x4d, KEY_FASTFORWARD},
3072 { 0x44, KEY_EPG},
3073 { 0x4c, KEY_INFO},
3074 { 0x41, KEY_AB},
3075 { 0x43, KEY_AUDIO},
3076 { 0x45, KEY_SUBTITLE},
3077 { 0x4a, KEY_LIST},
3078 { 0x46, KEY_F1},
3079 { 0x47, KEY_F2},
3080 { 0x5e, KEY_F3},
3081 { 0x5c, KEY_F4},
3082 { 0x52, KEY_F5},
3083 { 0x5a, KEY_F6},
3084 { 0x56, KEY_MODE},
3085 { 0x58, KEY_SWITCHVIDEOMODE},
3086};
3087struct ir_scancode_table ir_codes_tevii_nec_table = {
3088 .scan = ir_codes_tevii_nec,
3089 .size = ARRAY_SIZE(ir_codes_tevii_nec),
3090};
3091EXPORT_SYMBOL_GPL(ir_codes_tevii_nec_table);
3092
3093static struct ir_scancode ir_codes_tbs_nec[] = {
3094 { 0x04, KEY_POWER2}, /*power*/
3095 { 0x14, KEY_MUTE}, /*mute*/
3096 { 0x07, KEY_1},
3097 { 0x06, KEY_2},
3098 { 0x05, KEY_3},
3099 { 0x0b, KEY_4},
3100 { 0x0a, KEY_5},
3101 { 0x09, KEY_6},
3102 { 0x0f, KEY_7},
3103 { 0x0e, KEY_8},
3104 { 0x0d, KEY_9},
3105 { 0x12, KEY_0},
3106 { 0x16, KEY_CHANNELUP}, /*ch+*/
3107 { 0x11, KEY_CHANNELDOWN},/*ch-*/
3108 { 0x13, KEY_VOLUMEUP}, /*vol+*/
3109 { 0x0c, KEY_VOLUMEDOWN},/*vol-*/
3110 { 0x03, KEY_RECORD}, /*rec*/
3111 { 0x18, KEY_PAUSE}, /*pause*/
3112 { 0x19, KEY_OK}, /*ok*/
3113 { 0x1a, KEY_CAMERA}, /* snapshot */
3114 { 0x01, KEY_UP},
3115 { 0x10, KEY_LEFT},
3116 { 0x02, KEY_RIGHT},
3117 { 0x08, KEY_DOWN},
3118 { 0x15, KEY_FAVORITES},
3119 { 0x17, KEY_SUBTITLE},
3120 { 0x1d, KEY_ZOOM},
3121 { 0x1f, KEY_EXIT},
3122 { 0x1e, KEY_MENU},
3123 { 0x1c, KEY_EPG},
3124 { 0x00, KEY_PREVIOUS},
3125 { 0x1b, KEY_MODE},
3126};
3127struct ir_scancode_table ir_codes_tbs_nec_table = {
3128 .scan = ir_codes_tbs_nec,
3129 .size = ARRAY_SIZE(ir_codes_tbs_nec),
3130};
3131EXPORT_SYMBOL_GPL(ir_codes_tbs_nec_table);
3132
2967/* Terratec Cinergy Hybrid T USB XS 3133/* Terratec Cinergy Hybrid T USB XS
2968 Devin Heitmueller <dheitmueller@linuxtv.org> 3134 Devin Heitmueller <dheitmueller@linuxtv.org>
2969 */ 3135 */
@@ -3147,3 +3313,4 @@ struct ir_scancode_table ir_codes_gadmei_rm008z_table = {
3147 .size = ARRAY_SIZE(ir_codes_gadmei_rm008z), 3313 .size = ARRAY_SIZE(ir_codes_gadmei_rm008z),
3148}; 3314};
3149EXPORT_SYMBOL_GPL(ir_codes_gadmei_rm008z_table); 3315EXPORT_SYMBOL_GPL(ir_codes_gadmei_rm008z_table);
3316
diff --git a/drivers/media/common/ir-keytable.c b/drivers/media/common/ir-keytable.c
new file mode 100644
index 000000000000..26ce5bc2fdd5
--- /dev/null
+++ b/drivers/media/common/ir-keytable.c
@@ -0,0 +1,429 @@
1/* ir-register.c - handle IR scancode->keycode tables
2 *
3 * Copyright (C) 2009 by Mauro Carvalho Chehab <mchehab@redhat.com>
4 */
5
6#include <linux/usb/input.h>
7
8#include <media/ir-common.h>
9
10#define IR_TAB_MIN_SIZE 32
11#define IR_TAB_MAX_SIZE 1024
12
13/**
14 * ir_seek_table() - returns the element order on the table
15 * @rc_tab: the ir_scancode_table with the keymap to be used
16 * @scancode: the scancode that we're seeking
17 *
18 * This routine is used by the input routines when a key is pressed at the
19 * IR. The scancode is received and needs to be converted into a keycode.
20 * If the key is not found, it returns KEY_UNKNOWN. Otherwise, returns the
21 * corresponding keycode from the table.
22 */
23static int ir_seek_table(struct ir_scancode_table *rc_tab, u32 scancode)
24{
25 int rc;
26 unsigned long flags;
27 struct ir_scancode *keymap = rc_tab->scan;
28
29 spin_lock_irqsave(&rc_tab->lock, flags);
30
31 /* FIXME: replace it by a binary search */
32
33 for (rc = 0; rc < rc_tab->size; rc++)
34 if (keymap[rc].scancode == scancode)
35 goto exit;
36
37 /* Not found */
38 rc = -EINVAL;
39
40exit:
41 spin_unlock_irqrestore(&rc_tab->lock, flags);
42 return rc;
43}
44
45/**
46 * ir_roundup_tablesize() - gets an optimum value for the table size
47 * @n_elems: minimum number of entries to store keycodes
48 *
49 * This routine is used to choose the keycode table size.
50 *
51 * In order to have some empty space for new keycodes,
52 * and knowing in advance that kmalloc allocates only power of two
53 * segments, it optimizes the allocated space to have some spare space
54 * for those new keycodes by using the maximum number of entries that
55 * will be effectively be allocated by kmalloc.
56 * In order to reduce the quantity of table resizes, it has a minimum
57 * table size of IR_TAB_MIN_SIZE.
58 */
59int ir_roundup_tablesize(int n_elems)
60{
61 size_t size;
62
63 if (n_elems < IR_TAB_MIN_SIZE)
64 n_elems = IR_TAB_MIN_SIZE;
65
66 /*
67 * As kmalloc only allocates sizes of power of two, get as
68 * much entries as possible for the allocated memory segment
69 */
70 size = roundup_pow_of_two(n_elems * sizeof(struct ir_scancode));
71 n_elems = size / sizeof(struct ir_scancode);
72
73 return n_elems;
74}
75
76/**
77 * ir_copy_table() - copies a keytable, discarding the unused entries
78 * @destin: destin table
79 * @origin: origin table
80 *
81 * Copies all entries where the keycode is not KEY_UNKNOWN/KEY_RESERVED
82 */
83
84int ir_copy_table(struct ir_scancode_table *destin,
85 const struct ir_scancode_table *origin)
86{
87 int i, j = 0;
88
89 for (i = 0; i < origin->size; i++) {
90 if (origin->scan[i].keycode == KEY_UNKNOWN ||
91 origin->scan[i].keycode == KEY_RESERVED)
92 continue;
93
94 memcpy(&destin->scan[j], &origin->scan[i], sizeof(struct ir_scancode));
95 j++;
96 }
97 destin->size = j;
98
99 IR_dprintk(1, "Copied %d scancodes to the new keycode table\n", destin->size);
100
101 return 0;
102}
103
104/**
105 * ir_getkeycode() - get a keycode at the evdev scancode ->keycode table
106 * @dev: the struct input_dev device descriptor
107 * @scancode: the desired scancode
108 * @keycode: the keycode to be retorned.
109 *
110 * This routine is used to handle evdev EVIOCGKEY ioctl.
111 * If the key is not found, returns -EINVAL, otherwise, returns 0.
112 */
113static int ir_getkeycode(struct input_dev *dev,
114 int scancode, int *keycode)
115{
116 int elem;
117 struct ir_scancode_table *rc_tab = input_get_drvdata(dev);
118
119 elem = ir_seek_table(rc_tab, scancode);
120 if (elem >= 0) {
121 *keycode = rc_tab->scan[elem].keycode;
122 return 0;
123 }
124
125 /*
126 * Scancode not found and table can't be expanded
127 */
128 if (elem < 0 && rc_tab->size == IR_TAB_MAX_SIZE)
129 return -EINVAL;
130
131 /*
132 * If is there extra space, returns KEY_RESERVED,
133 * otherwise, input core won't let ir_setkeycode to work
134 */
135 *keycode = KEY_RESERVED;
136 return 0;
137}
138
139
140/**
141 * ir_is_resize_needed() - Check if the table needs rezise
142 * @table: keycode table that may need to resize
143 * @n_elems: minimum number of entries to store keycodes
144 *
145 * Considering that kmalloc uses power of two storage areas, this
146 * routine detects if the real alloced size will change. If not, it
147 * just returns without doing nothing. Otherwise, it will extend or
148 * reduce the table size to meet the new needs.
149 *
150 * It returns 0 if no resize is needed, 1 otherwise.
151 */
152static int ir_is_resize_needed(struct ir_scancode_table *table, int n_elems)
153{
154 int cur_size = ir_roundup_tablesize(table->size);
155 int new_size = ir_roundup_tablesize(n_elems);
156
157 if (cur_size == new_size)
158 return 0;
159
160 /* Resize is needed */
161 return 1;
162}
163
164/**
165 * ir_delete_key() - remove a keycode from the table
166 * @rc_tab: keycode table
167 * @elem: element to be removed
168 *
169 */
170static void ir_delete_key(struct ir_scancode_table *rc_tab, int elem)
171{
172 unsigned long flags = 0;
173 int newsize = rc_tab->size - 1;
174 int resize = ir_is_resize_needed(rc_tab, newsize);
175 struct ir_scancode *oldkeymap = rc_tab->scan;
176 struct ir_scancode *newkeymap;
177
178 if (resize) {
179 newkeymap = kzalloc(ir_roundup_tablesize(newsize) *
180 sizeof(*newkeymap), GFP_ATOMIC);
181
182 /* There's no memory for resize. Keep the old table */
183 if (!newkeymap)
184 resize = 0;
185 }
186
187 if (!resize) {
188 newkeymap = oldkeymap;
189
190 /* We'll modify the live table. Lock it */
191 spin_lock_irqsave(&rc_tab->lock, flags);
192 }
193
194 /*
195 * Copy the elements before the one that will be deleted
196 * if (!resize), both oldkeymap and newkeymap points
197 * to the same place, so, there's no need to copy
198 */
199 if (resize && elem > 0)
200 memcpy(newkeymap, oldkeymap,
201 elem * sizeof(*newkeymap));
202
203 /*
204 * Copy the other elements overwriting the element to be removed
205 * This operation applies to both resize and non-resize case
206 */
207 if (elem < newsize)
208 memcpy(&newkeymap[elem], &oldkeymap[elem + 1],
209 (newsize - elem) * sizeof(*newkeymap));
210
211 if (resize) {
212 /*
213 * As the copy happened to a temporary table, only here
214 * it needs to lock while replacing the table pointers
215 * to use the new table
216 */
217 spin_lock_irqsave(&rc_tab->lock, flags);
218 rc_tab->size = newsize;
219 rc_tab->scan = newkeymap;
220 spin_unlock_irqrestore(&rc_tab->lock, flags);
221
222 /* Frees the old keytable */
223 kfree(oldkeymap);
224 } else {
225 rc_tab->size = newsize;
226 spin_unlock_irqrestore(&rc_tab->lock, flags);
227 }
228}
229
230/**
231 * ir_insert_key() - insert a keycode at the table
232 * @rc_tab: keycode table
233 * @scancode: the desired scancode
234 * @keycode: the keycode to be retorned.
235 *
236 */
237static int ir_insert_key(struct ir_scancode_table *rc_tab,
238 int scancode, int keycode)
239{
240 unsigned long flags;
241 int elem = rc_tab->size;
242 int newsize = rc_tab->size + 1;
243 int resize = ir_is_resize_needed(rc_tab, newsize);
244 struct ir_scancode *oldkeymap = rc_tab->scan;
245 struct ir_scancode *newkeymap;
246
247 if (resize) {
248 newkeymap = kzalloc(ir_roundup_tablesize(newsize) *
249 sizeof(*newkeymap), GFP_ATOMIC);
250 if (!newkeymap)
251 return -ENOMEM;
252
253 memcpy(newkeymap, oldkeymap,
254 rc_tab->size * sizeof(*newkeymap));
255 } else
256 newkeymap = oldkeymap;
257
258 /* Stores the new code at the table */
259 IR_dprintk(1, "#%d: New scan 0x%04x with key 0x%04x\n",
260 rc_tab->size, scancode, keycode);
261
262 spin_lock_irqsave(&rc_tab->lock, flags);
263 rc_tab->size = newsize;
264 if (resize) {
265 rc_tab->scan = newkeymap;
266 kfree(oldkeymap);
267 }
268 newkeymap[elem].scancode = scancode;
269 newkeymap[elem].keycode = keycode;
270 spin_unlock_irqrestore(&rc_tab->lock, flags);
271
272 return 0;
273}
274
275/**
276 * ir_setkeycode() - set a keycode at the evdev scancode ->keycode table
277 * @dev: the struct input_dev device descriptor
278 * @scancode: the desired scancode
279 * @keycode: the keycode to be retorned.
280 *
281 * This routine is used to handle evdev EVIOCSKEY ioctl.
282 * There's one caveat here: how can we increase the size of the table?
283 * If the key is not found, returns -EINVAL, otherwise, returns 0.
284 */
285static int ir_setkeycode(struct input_dev *dev,
286 int scancode, int keycode)
287{
288 int rc = 0;
289 struct ir_scancode_table *rc_tab = input_get_drvdata(dev);
290 struct ir_scancode *keymap = rc_tab->scan;
291 unsigned long flags;
292
293 /*
294 * Handle keycode table deletions
295 *
296 * If userspace is adding a KEY_UNKNOWN or KEY_RESERVED,
297 * deal as a trial to remove an existing scancode attribution
298 * if table become too big, reduce it to save space
299 */
300 if (keycode == KEY_UNKNOWN || keycode == KEY_RESERVED) {
301 rc = ir_seek_table(rc_tab, scancode);
302 if (rc < 0)
303 return 0;
304
305 IR_dprintk(1, "#%d: Deleting scan 0x%04x\n", rc, scancode);
306 clear_bit(keymap[rc].keycode, dev->keybit);
307 ir_delete_key(rc_tab, rc);
308
309 return 0;
310 }
311
312 /*
313 * Handle keycode replacements
314 *
315 * If the scancode exists, just replace by the new value
316 */
317 rc = ir_seek_table(rc_tab, scancode);
318 if (rc >= 0) {
319 IR_dprintk(1, "#%d: Replacing scan 0x%04x with key 0x%04x\n",
320 rc, scancode, keycode);
321
322 clear_bit(keymap[rc].keycode, dev->keybit);
323
324 spin_lock_irqsave(&rc_tab->lock, flags);
325 keymap[rc].keycode = keycode;
326 spin_unlock_irqrestore(&rc_tab->lock, flags);
327
328 set_bit(keycode, dev->keybit);
329
330 return 0;
331 }
332
333 /*
334 * Handle new scancode inserts
335 *
336 * reallocate table if needed and insert a new keycode
337 */
338
339 /* Avoid growing the table indefinitely */
340 if (rc_tab->size + 1 > IR_TAB_MAX_SIZE)
341 return -EINVAL;
342
343 rc = ir_insert_key(rc_tab, scancode, keycode);
344 if (rc < 0)
345 return rc;
346 set_bit(keycode, dev->keybit);
347
348 return 0;
349}
350
351/**
352 * ir_g_keycode_from_table() - gets the keycode that corresponds to a scancode
353 * @input_dev: the struct input_dev descriptor of the device
354 * @scancode: the scancode that we're seeking
355 *
356 * This routine is used by the input routines when a key is pressed at the
357 * IR. The scancode is received and needs to be converted into a keycode.
358 * If the key is not found, it returns KEY_UNKNOWN. Otherwise, returns the
359 * corresponding keycode from the table.
360 */
361u32 ir_g_keycode_from_table(struct input_dev *dev, u32 scancode)
362{
363 struct ir_scancode_table *rc_tab = input_get_drvdata(dev);
364 struct ir_scancode *keymap = rc_tab->scan;
365 int elem;
366
367 elem = ir_seek_table(rc_tab, scancode);
368 if (elem >= 0) {
369 IR_dprintk(1, "%s: scancode 0x%04x keycode 0x%02x\n",
370 dev->name, scancode, keymap[elem].keycode);
371
372 return rc_tab->scan[elem].keycode;
373 }
374
375 printk(KERN_INFO "%s: unknown key for scancode 0x%04x\n",
376 dev->name, scancode);
377
378 /* Reports userspace that an unknown keycode were got */
379 return KEY_RESERVED;
380}
381
382/**
383 * ir_set_keycode_table() - sets the IR keycode table and add the handlers
384 * for keymap table get/set
385 * @input_dev: the struct input_dev descriptor of the device
386 * @rc_tab: the struct ir_scancode_table table of scancode/keymap
387 *
388 * This routine is used to initialize the input infrastructure to work with
389 * an IR.
390 * It should be called before registering the IR device.
391 */
392int ir_set_keycode_table(struct input_dev *input_dev,
393 struct ir_scancode_table *rc_tab)
394{
395 struct ir_scancode *keymap = rc_tab->scan;
396 int i;
397
398 spin_lock_init(&rc_tab->lock);
399
400 if (rc_tab->scan == NULL || !rc_tab->size)
401 return -EINVAL;
402
403 /* set the bits for the keys */
404 IR_dprintk(1, "key map size: %d\n", rc_tab->size);
405 for (i = 0; i < rc_tab->size; i++) {
406 IR_dprintk(1, "#%d: setting bit for keycode 0x%04x\n",
407 i, keymap[i].keycode);
408 set_bit(keymap[i].keycode, input_dev->keybit);
409 }
410
411 input_dev->getkeycode = ir_getkeycode;
412 input_dev->setkeycode = ir_setkeycode;
413 input_set_drvdata(input_dev, rc_tab);
414
415 return 0;
416}
417
418void ir_input_free(struct input_dev *dev)
419{
420 struct ir_scancode_table *rc_tab = input_get_drvdata(dev);
421
422 IR_dprintk(1, "Freed keycode table\n");
423
424 rc_tab->size = 0;
425 kfree(rc_tab->scan);
426 rc_tab->scan = NULL;
427}
428EXPORT_SYMBOL_GPL(ir_input_free);
429
diff --git a/drivers/media/common/saa7146_video.c b/drivers/media/common/saa7146_video.c
index 552dab442d78..becbaadb3b77 100644
--- a/drivers/media/common/saa7146_video.c
+++ b/drivers/media/common/saa7146_video.c
@@ -1205,6 +1205,13 @@ static int buffer_activate (struct saa7146_dev *dev,
1205 return 0; 1205 return 0;
1206} 1206}
1207 1207
1208static void release_all_pagetables(struct saa7146_dev *dev, struct saa7146_buf *buf)
1209{
1210 saa7146_pgtable_free(dev->pci, &buf->pt[0]);
1211 saa7146_pgtable_free(dev->pci, &buf->pt[1]);
1212 saa7146_pgtable_free(dev->pci, &buf->pt[2]);
1213}
1214
1208static int buffer_prepare(struct videobuf_queue *q, 1215static int buffer_prepare(struct videobuf_queue *q,
1209 struct videobuf_buffer *vb, enum v4l2_field field) 1216 struct videobuf_buffer *vb, enum v4l2_field field)
1210{ 1217{
@@ -1257,16 +1264,12 @@ static int buffer_prepare(struct videobuf_queue *q,
1257 1264
1258 sfmt = format_by_fourcc(dev,buf->fmt->pixelformat); 1265 sfmt = format_by_fourcc(dev,buf->fmt->pixelformat);
1259 1266
1267 release_all_pagetables(dev, buf);
1260 if( 0 != IS_PLANAR(sfmt->trans)) { 1268 if( 0 != IS_PLANAR(sfmt->trans)) {
1261 saa7146_pgtable_free(dev->pci, &buf->pt[0]);
1262 saa7146_pgtable_free(dev->pci, &buf->pt[1]);
1263 saa7146_pgtable_free(dev->pci, &buf->pt[2]);
1264
1265 saa7146_pgtable_alloc(dev->pci, &buf->pt[0]); 1269 saa7146_pgtable_alloc(dev->pci, &buf->pt[0]);
1266 saa7146_pgtable_alloc(dev->pci, &buf->pt[1]); 1270 saa7146_pgtable_alloc(dev->pci, &buf->pt[1]);
1267 saa7146_pgtable_alloc(dev->pci, &buf->pt[2]); 1271 saa7146_pgtable_alloc(dev->pci, &buf->pt[2]);
1268 } else { 1272 } else {
1269 saa7146_pgtable_free(dev->pci, &buf->pt[0]);
1270 saa7146_pgtable_alloc(dev->pci, &buf->pt[0]); 1273 saa7146_pgtable_alloc(dev->pci, &buf->pt[0]);
1271 } 1274 }
1272 1275
@@ -1329,6 +1332,9 @@ static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
1329 struct saa7146_buf *buf = (struct saa7146_buf *)vb; 1332 struct saa7146_buf *buf = (struct saa7146_buf *)vb;
1330 1333
1331 DEB_CAP(("vbuf:%p\n",vb)); 1334 DEB_CAP(("vbuf:%p\n",vb));
1335
1336 release_all_pagetables(dev, buf);
1337
1332 saa7146_dma_free(dev,q,buf); 1338 saa7146_dma_free(dev,q,buf);
1333} 1339}
1334 1340
diff --git a/drivers/media/common/tuners/Kconfig b/drivers/media/common/tuners/Kconfig
index 607d319ce8ed..409a4261e5b5 100644
--- a/drivers/media/common/tuners/Kconfig
+++ b/drivers/media/common/tuners/Kconfig
@@ -172,4 +172,11 @@ config MEDIA_TUNER_MC44S803
172 help 172 help
173 Say Y here to support the Freescale MC44S803 based tuners 173 Say Y here to support the Freescale MC44S803 based tuners
174 174
175config MEDIA_TUNER_MAX2165
176 tristate "Maxim MAX2165 silicon tuner"
177 depends on VIDEO_MEDIA && I2C
178 default m if MEDIA_TUNER_CUSTOMISE
179 help
180 A driver for the silicon tuner MAX2165 from Maxim.
181
175endif # MEDIA_TUNER_CUSTOMISE 182endif # MEDIA_TUNER_CUSTOMISE
diff --git a/drivers/media/common/tuners/Makefile b/drivers/media/common/tuners/Makefile
index 4132b2be79e5..a5438523f30d 100644
--- a/drivers/media/common/tuners/Makefile
+++ b/drivers/media/common/tuners/Makefile
@@ -23,6 +23,7 @@ obj-$(CONFIG_MEDIA_TUNER_MT2131) += mt2131.o
23obj-$(CONFIG_MEDIA_TUNER_MXL5005S) += mxl5005s.o 23obj-$(CONFIG_MEDIA_TUNER_MXL5005S) += mxl5005s.o
24obj-$(CONFIG_MEDIA_TUNER_MXL5007T) += mxl5007t.o 24obj-$(CONFIG_MEDIA_TUNER_MXL5007T) += mxl5007t.o
25obj-$(CONFIG_MEDIA_TUNER_MC44S803) += mc44s803.o 25obj-$(CONFIG_MEDIA_TUNER_MC44S803) += mc44s803.o
26obj-$(CONFIG_MEDIA_TUNER_MAX2165) += max2165.o
26 27
27EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core 28EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
28EXTRA_CFLAGS += -Idrivers/media/dvb/frontends 29EXTRA_CFLAGS += -Idrivers/media/dvb/frontends
diff --git a/drivers/media/common/tuners/max2165.c b/drivers/media/common/tuners/max2165.c
new file mode 100644
index 000000000000..1b486cfb8ed9
--- /dev/null
+++ b/drivers/media/common/tuners/max2165.c
@@ -0,0 +1,442 @@
1/*
2 * Driver for Maxim MAX2165 silicon tuner
3 *
4 * Copyright (c) 2009 David T. L. Wong <davidtlwong@gmail.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 *
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#include <linux/module.h>
23#include <linux/moduleparam.h>
24#include <linux/videodev2.h>
25#include <linux/delay.h>
26#include <linux/dvb/frontend.h>
27#include <linux/i2c.h>
28
29#include "dvb_frontend.h"
30
31#include "max2165.h"
32#include "max2165_priv.h"
33#include "tuner-i2c.h"
34
35#define dprintk(args...) \
36 do { \
37 if (debug) \
38 printk(KERN_DEBUG "max2165: " args); \
39 } while (0)
40
41static int debug;
42module_param(debug, int, 0644);
43MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
44
45static int max2165_write_reg(struct max2165_priv *priv, u8 reg, u8 data)
46{
47 int ret;
48 u8 buf[] = { reg, data };
49 struct i2c_msg msg = { .flags = 0, .buf = buf, .len = 2 };
50
51 msg.addr = priv->config->i2c_address;
52
53 if (debug >= 2)
54 printk(KERN_DEBUG "%s: reg=0x%02X, data=0x%02X\n",
55 __func__, reg, data);
56
57 ret = i2c_transfer(priv->i2c, &msg, 1);
58
59 if (ret != 1)
60 dprintk(KERN_DEBUG "%s: error reg=0x%x, data=0x%x, ret=%i\n",
61 __func__, reg, data, ret);
62
63 return (ret != 1) ? -EIO : 0;
64}
65
66static int max2165_read_reg(struct max2165_priv *priv, u8 reg, u8 *p_data)
67{
68 int ret;
69 u8 dev_addr = priv->config->i2c_address;
70
71 u8 b0[] = { reg };
72 u8 b1[] = { 0 };
73 struct i2c_msg msg[] = {
74 { .addr = dev_addr, .flags = 0, .buf = b0, .len = 1 },
75 { .addr = dev_addr, .flags = I2C_M_RD, .buf = b1, .len = 1 },
76 };
77
78 ret = i2c_transfer(priv->i2c, msg, 2);
79 if (ret != 2) {
80 dprintk(KERN_DEBUG "%s: error reg=0x%x, ret=%i\n",
81 __func__, reg, ret);
82 return -EIO;
83 }
84
85 *p_data = b1[0];
86 if (debug >= 2)
87 printk(KERN_DEBUG "%s: reg=0x%02X, data=0x%02X\n",
88 __func__, reg, b1[0]);
89 return 0;
90}
91
92static int max2165_mask_write_reg(struct max2165_priv *priv, u8 reg,
93 u8 mask, u8 data)
94{
95 int ret;
96 u8 v;
97
98 data &= mask;
99 ret = max2165_read_reg(priv, reg, &v);
100 if (ret != 0)
101 return ret;
102 v &= ~mask;
103 v |= data;
104 ret = max2165_write_reg(priv, reg, v);
105
106 return ret;
107}
108
109static int max2165_read_rom_table(struct max2165_priv *priv)
110{
111 u8 dat[3];
112 int i;
113
114 for (i = 0; i < 3; i++) {
115 max2165_write_reg(priv, REG_ROM_TABLE_ADDR, i + 1);
116 max2165_read_reg(priv, REG_ROM_TABLE_DATA, &dat[i]);
117 }
118
119 priv->tf_ntch_low_cfg = dat[0] >> 4;
120 priv->tf_ntch_hi_cfg = dat[0] & 0x0F;
121 priv->tf_balun_low_ref = dat[1] & 0x0F;
122 priv->tf_balun_hi_ref = dat[1] >> 4;
123 priv->bb_filter_7mhz_cfg = dat[2] & 0x0F;
124 priv->bb_filter_8mhz_cfg = dat[2] >> 4;
125
126 dprintk("tf_ntch_low_cfg = 0x%X\n", priv->tf_ntch_low_cfg);
127 dprintk("tf_ntch_hi_cfg = 0x%X\n", priv->tf_ntch_hi_cfg);
128 dprintk("tf_balun_low_ref = 0x%X\n", priv->tf_balun_low_ref);
129 dprintk("tf_balun_hi_ref = 0x%X\n", priv->tf_balun_hi_ref);
130 dprintk("bb_filter_7mhz_cfg = 0x%X\n", priv->bb_filter_7mhz_cfg);
131 dprintk("bb_filter_8mhz_cfg = 0x%X\n", priv->bb_filter_8mhz_cfg);
132
133 return 0;
134}
135
136static int max2165_set_osc(struct max2165_priv *priv, u8 osc /*MHz*/)
137{
138 u8 v;
139
140 v = (osc / 2);
141 if (v == 2)
142 v = 0x7;
143 else
144 v -= 8;
145
146 max2165_mask_write_reg(priv, REG_PLL_CFG, 0x07, v);
147
148 return 0;
149}
150
151static int max2165_set_bandwidth(struct max2165_priv *priv, u32 bw)
152{
153 u8 val;
154
155 if (bw == BANDWIDTH_8_MHZ)
156 val = priv->bb_filter_8mhz_cfg;
157 else
158 val = priv->bb_filter_7mhz_cfg;
159
160 max2165_mask_write_reg(priv, REG_BASEBAND_CTRL, 0xF0, val << 4);
161
162 return 0;
163}
164
165int fixpt_div32(u32 dividend, u32 divisor, u32 *quotient, u32 *fraction)
166{
167 u32 remainder;
168 u32 q, f = 0;
169 int i;
170
171 if (0 == divisor)
172 return -1;
173
174 q = dividend / divisor;
175 remainder = dividend - q * divisor;
176
177 for (i = 0; i < 31; i++) {
178 remainder <<= 1;
179 if (remainder >= divisor) {
180 f += 1;
181 remainder -= divisor;
182 }
183 f <<= 1;
184 }
185
186 *quotient = q;
187 *fraction = f;
188
189 return 0;
190}
191
192static int max2165_set_rf(struct max2165_priv *priv, u32 freq)
193{
194 u8 tf;
195 u8 tf_ntch;
196 double t;
197 u32 quotient, fraction;
198
199 /* Set PLL divider according to RF frequency */
200 fixpt_div32(freq / 1000, priv->config->osc_clk * 1000,
201 &quotient, &fraction);
202
203 /* 20-bit fraction */
204 fraction >>= 12;
205
206 max2165_write_reg(priv, REG_NDIV_INT, quotient);
207 max2165_mask_write_reg(priv, REG_NDIV_FRAC2, 0x0F, fraction >> 16);
208 max2165_write_reg(priv, REG_NDIV_FRAC1, fraction >> 8);
209 max2165_write_reg(priv, REG_NDIV_FRAC0, fraction);
210
211 /* Norch Filter */
212 tf_ntch = (freq < 725000000) ?
213 priv->tf_ntch_low_cfg : priv->tf_ntch_hi_cfg;
214
215 /* Tracking filter balun */
216 t = priv->tf_balun_low_ref;
217 t += (priv->tf_balun_hi_ref - priv->tf_balun_low_ref)
218 * (freq / 1000 - 470000) / (780000 - 470000);
219
220 tf = t;
221 dprintk("tf = %X\n", tf);
222 tf |= tf_ntch << 4;
223
224 max2165_write_reg(priv, REG_TRACK_FILTER, tf);
225
226 return 0;
227}
228
229static void max2165_debug_status(struct max2165_priv *priv)
230{
231 u8 status, autotune;
232 u8 auto_vco_success, auto_vco_active;
233 u8 pll_locked;
234 u8 dc_offset_low, dc_offset_hi;
235 u8 signal_lv_over_threshold;
236 u8 vco, vco_sub_band, adc;
237
238 max2165_read_reg(priv, REG_STATUS, &status);
239 max2165_read_reg(priv, REG_AUTOTUNE, &autotune);
240
241 auto_vco_success = (status >> 6) & 0x01;
242 auto_vco_active = (status >> 5) & 0x01;
243 pll_locked = (status >> 4) & 0x01;
244 dc_offset_low = (status >> 3) & 0x01;
245 dc_offset_hi = (status >> 2) & 0x01;
246 signal_lv_over_threshold = status & 0x01;
247
248 vco = autotune >> 6;
249 vco_sub_band = (autotune >> 3) & 0x7;
250 adc = autotune & 0x7;
251
252 dprintk("auto VCO active: %d, auto VCO success: %d\n",
253 auto_vco_active, auto_vco_success);
254 dprintk("PLL locked: %d\n", pll_locked);
255 dprintk("DC offset low: %d, DC offset high: %d\n",
256 dc_offset_low, dc_offset_hi);
257 dprintk("Signal lvl over threshold: %d\n", signal_lv_over_threshold);
258 dprintk("VCO: %d, VCO Sub-band: %d, ADC: %d\n", vco, vco_sub_band, adc);
259}
260
261static int max2165_set_params(struct dvb_frontend *fe,
262 struct dvb_frontend_parameters *params)
263{
264 struct max2165_priv *priv = fe->tuner_priv;
265 int ret;
266
267 dprintk("%s() frequency=%d (Hz)\n", __func__, params->frequency);
268 if (fe->ops.info.type == FE_ATSC) {
269 return -EINVAL;
270 } else if (fe->ops.info.type == FE_OFDM) {
271 dprintk("%s() OFDM\n", __func__);
272 switch (params->u.ofdm.bandwidth) {
273 case BANDWIDTH_6_MHZ:
274 return -EINVAL;
275 case BANDWIDTH_7_MHZ:
276 case BANDWIDTH_8_MHZ:
277 priv->frequency = params->frequency;
278 priv->bandwidth = params->u.ofdm.bandwidth;
279 break;
280 default:
281 printk(KERN_ERR "MAX2165 bandwidth not set!\n");
282 return -EINVAL;
283 }
284 } else {
285 printk(KERN_ERR "MAX2165 modulation type not supported!\n");
286 return -EINVAL;
287 }
288
289 dprintk("%s() frequency=%d\n", __func__, priv->frequency);
290
291 if (fe->ops.i2c_gate_ctrl)
292 fe->ops.i2c_gate_ctrl(fe, 1);
293 max2165_set_bandwidth(priv, priv->bandwidth);
294 ret = max2165_set_rf(priv, priv->frequency);
295 mdelay(50);
296 max2165_debug_status(priv);
297 if (fe->ops.i2c_gate_ctrl)
298 fe->ops.i2c_gate_ctrl(fe, 0);
299
300 if (ret != 0)
301 return -EREMOTEIO;
302
303 return 0;
304}
305
306static int max2165_get_frequency(struct dvb_frontend *fe, u32 *freq)
307{
308 struct max2165_priv *priv = fe->tuner_priv;
309 dprintk("%s()\n", __func__);
310 *freq = priv->frequency;
311 return 0;
312}
313
314static int max2165_get_bandwidth(struct dvb_frontend *fe, u32 *bw)
315{
316 struct max2165_priv *priv = fe->tuner_priv;
317 dprintk("%s()\n", __func__);
318
319 *bw = priv->bandwidth;
320 return 0;
321}
322
323static int max2165_get_status(struct dvb_frontend *fe, u32 *status)
324{
325 struct max2165_priv *priv = fe->tuner_priv;
326 u16 lock_status = 0;
327
328 dprintk("%s()\n", __func__);
329
330 if (fe->ops.i2c_gate_ctrl)
331 fe->ops.i2c_gate_ctrl(fe, 1);
332
333 max2165_debug_status(priv);
334 *status = lock_status;
335
336 if (fe->ops.i2c_gate_ctrl)
337 fe->ops.i2c_gate_ctrl(fe, 0);
338
339 return 0;
340}
341
342static int max2165_sleep(struct dvb_frontend *fe)
343{
344 dprintk("%s()\n", __func__);
345 return 0;
346}
347
348static int max2165_init(struct dvb_frontend *fe)
349{
350 struct max2165_priv *priv = fe->tuner_priv;
351 dprintk("%s()\n", __func__);
352
353 if (fe->ops.i2c_gate_ctrl)
354 fe->ops.i2c_gate_ctrl(fe, 1);
355
356 /* Setup initial values */
357 /* Fractional Mode on */
358 max2165_write_reg(priv, REG_NDIV_FRAC2, 0x18);
359 /* LNA on */
360 max2165_write_reg(priv, REG_LNA, 0x01);
361 max2165_write_reg(priv, REG_PLL_CFG, 0x7A);
362 max2165_write_reg(priv, REG_TEST, 0x08);
363 max2165_write_reg(priv, REG_SHUTDOWN, 0x40);
364 max2165_write_reg(priv, REG_VCO_CTRL, 0x84);
365 max2165_write_reg(priv, REG_BASEBAND_CTRL, 0xC3);
366 max2165_write_reg(priv, REG_DC_OFFSET_CTRL, 0x75);
367 max2165_write_reg(priv, REG_DC_OFFSET_DAC, 0x00);
368 max2165_write_reg(priv, REG_ROM_TABLE_ADDR, 0x00);
369
370 max2165_set_osc(priv, priv->config->osc_clk);
371
372 max2165_read_rom_table(priv);
373
374 max2165_set_bandwidth(priv, BANDWIDTH_8_MHZ);
375
376 if (fe->ops.i2c_gate_ctrl)
377 fe->ops.i2c_gate_ctrl(fe, 0);
378
379 return 0;
380}
381
382static int max2165_release(struct dvb_frontend *fe)
383{
384 struct max2165_priv *priv = fe->tuner_priv;
385 dprintk("%s()\n", __func__);
386
387 kfree(priv);
388 fe->tuner_priv = NULL;
389
390 return 0;
391}
392
393static const struct dvb_tuner_ops max2165_tuner_ops = {
394 .info = {
395 .name = "Maxim MAX2165",
396 .frequency_min = 470000000,
397 .frequency_max = 780000000,
398 .frequency_step = 50000,
399 },
400
401 .release = max2165_release,
402 .init = max2165_init,
403 .sleep = max2165_sleep,
404
405 .set_params = max2165_set_params,
406 .set_analog_params = NULL,
407 .get_frequency = max2165_get_frequency,
408 .get_bandwidth = max2165_get_bandwidth,
409 .get_status = max2165_get_status
410};
411
412struct dvb_frontend *max2165_attach(struct dvb_frontend *fe,
413 struct i2c_adapter *i2c,
414 struct max2165_config *cfg)
415{
416 struct max2165_priv *priv = NULL;
417
418 dprintk("%s(%d-%04x)\n", __func__,
419 i2c ? i2c_adapter_id(i2c) : -1,
420 cfg ? cfg->i2c_address : -1);
421
422 priv = kzalloc(sizeof(struct max2165_priv), GFP_KERNEL);
423 if (priv == NULL)
424 return NULL;
425
426 memcpy(&fe->ops.tuner_ops, &max2165_tuner_ops,
427 sizeof(struct dvb_tuner_ops));
428
429 priv->config = cfg;
430 priv->i2c = i2c;
431 fe->tuner_priv = priv;
432
433 max2165_init(fe);
434 max2165_debug_status(priv);
435
436 return fe;
437}
438EXPORT_SYMBOL(max2165_attach);
439
440MODULE_AUTHOR("David T. L. Wong <davidtlwong@gmail.com>");
441MODULE_DESCRIPTION("Maxim MAX2165 silicon tuner driver");
442MODULE_LICENSE("GPL");
diff --git a/drivers/media/common/tuners/max2165.h b/drivers/media/common/tuners/max2165.h
new file mode 100644
index 000000000000..c063c36a93d3
--- /dev/null
+++ b/drivers/media/common/tuners/max2165.h
@@ -0,0 +1,48 @@
1/*
2 * Driver for Maxim MAX2165 silicon tuner
3 *
4 * Copyright (c) 2009 David T. L. Wong <davidtlwong@gmail.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 *
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#ifndef __MAX2165_H__
23#define __MAX2165_H__
24
25struct dvb_frontend;
26struct i2c_adapter;
27
28struct max2165_config {
29 u8 i2c_address;
30 u8 osc_clk; /* in MHz, selectable values: 4,16,18,20,22,24,26,28 */
31};
32
33#if defined(CONFIG_MEDIA_TUNER_MAX2165) || \
34 (defined(CONFIG_MEDIA_TUNER_MAX2165_MODULE) && defined(MODULE))
35extern struct dvb_frontend *max2165_attach(struct dvb_frontend *fe,
36 struct i2c_adapter *i2c,
37 struct max2165_config *cfg);
38#else
39static inline struct dvb_frontend *max2165_attach(struct dvb_frontend *fe,
40 struct i2c_adapter *i2c,
41 struct max2165_config *cfg)
42{
43 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
44 return NULL;
45}
46#endif
47
48#endif
diff --git a/drivers/media/common/tuners/max2165_priv.h b/drivers/media/common/tuners/max2165_priv.h
new file mode 100644
index 000000000000..91bbe021a08d
--- /dev/null
+++ b/drivers/media/common/tuners/max2165_priv.h
@@ -0,0 +1,60 @@
1/*
2 * Driver for Maxim MAX2165 silicon tuner
3 *
4 * Copyright (c) 2009 David T. L. Wong <davidtlwong@gmail.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 *
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#ifndef __MAX2165_PRIV_H__
23#define __MAX2165_PRIV_H__
24
25#define REG_NDIV_INT 0x00
26#define REG_NDIV_FRAC2 0x01
27#define REG_NDIV_FRAC1 0x02
28#define REG_NDIV_FRAC0 0x03
29#define REG_TRACK_FILTER 0x04
30#define REG_LNA 0x05
31#define REG_PLL_CFG 0x06
32#define REG_TEST 0x07
33#define REG_SHUTDOWN 0x08
34#define REG_VCO_CTRL 0x09
35#define REG_BASEBAND_CTRL 0x0A
36#define REG_DC_OFFSET_CTRL 0x0B
37#define REG_DC_OFFSET_DAC 0x0C
38#define REG_ROM_TABLE_ADDR 0x0D
39
40/* Read Only Registers */
41#define REG_ROM_TABLE_DATA 0x10
42#define REG_STATUS 0x11
43#define REG_AUTOTUNE 0x12
44
45struct max2165_priv {
46 struct max2165_config *config;
47 struct i2c_adapter *i2c;
48
49 u32 frequency;
50 u32 bandwidth;
51
52 u8 tf_ntch_low_cfg;
53 u8 tf_ntch_hi_cfg;
54 u8 tf_balun_low_ref;
55 u8 tf_balun_hi_ref;
56 u8 bb_filter_7mhz_cfg;
57 u8 bb_filter_8mhz_cfg;
58};
59
60#endif
diff --git a/drivers/media/common/tuners/mxl5005s.c b/drivers/media/common/tuners/mxl5005s.c
index 0803dab58fff..605e28b73263 100644
--- a/drivers/media/common/tuners/mxl5005s.c
+++ b/drivers/media/common/tuners/mxl5005s.c
@@ -2789,7 +2789,10 @@ static u16 MXL_TuneRF(struct dvb_frontend *fe, u32 RF_Freq)
2789 2789
2790 /* add for 2.6.5 Special setting for QAM */ 2790 /* add for 2.6.5 Special setting for QAM */
2791 if (state->Mod_Type == MXL_QAM) { 2791 if (state->Mod_Type == MXL_QAM) {
2792 if (state->RF_IN < 680000000) 2792 if (state->config->qam_gain != 0)
2793 status += MXL_ControlWrite(fe, RFSYN_CHP_GAIN,
2794 state->config->qam_gain);
2795 else if (state->RF_IN < 680000000)
2793 status += MXL_ControlWrite(fe, RFSYN_CHP_GAIN, 3); 2796 status += MXL_ControlWrite(fe, RFSYN_CHP_GAIN, 3);
2794 else 2797 else
2795 status += MXL_ControlWrite(fe, RFSYN_CHP_GAIN, 2); 2798 status += MXL_ControlWrite(fe, RFSYN_CHP_GAIN, 2);
diff --git a/drivers/media/common/tuners/mxl5005s.h b/drivers/media/common/tuners/mxl5005s.h
index 7ac6815b30aa..fc8a1ffc53b4 100644
--- a/drivers/media/common/tuners/mxl5005s.h
+++ b/drivers/media/common/tuners/mxl5005s.h
@@ -108,6 +108,10 @@ struct mxl5005s_config {
108#define MXL_LOW_IF 1 108#define MXL_LOW_IF 1
109 u8 if_mode; 109 u8 if_mode;
110 110
111 /* Some boards need to override the built-in logic for determining
112 the gain when in QAM mode (the HVR-1600 is one such case) */
113 u8 qam_gain;
114
111 /* Stuff I don't know what to do with */ 115 /* Stuff I don't know what to do with */
112 u8 AgcMasterByte; 116 u8 AgcMasterByte;
113}; 117};
diff --git a/drivers/media/common/tuners/mxl5007t.c b/drivers/media/common/tuners/mxl5007t.c
index 2d02698d4f4f..7eb1bf75cd07 100644
--- a/drivers/media/common/tuners/mxl5007t.c
+++ b/drivers/media/common/tuners/mxl5007t.c
@@ -196,7 +196,7 @@ static void copy_reg_bits(struct reg_pair_t *reg_pair1,
196 i = j = 0; 196 i = j = 0;
197 197
198 while (reg_pair1[i].reg || reg_pair1[i].val) { 198 while (reg_pair1[i].reg || reg_pair1[i].val) {
199 while (reg_pair2[j].reg || reg_pair2[j].reg) { 199 while (reg_pair2[j].reg || reg_pair2[j].val) {
200 if (reg_pair1[i].reg != reg_pair2[j].reg) { 200 if (reg_pair1[i].reg != reg_pair2[j].reg) {
201 j++; 201 j++;
202 continue; 202 continue;
diff --git a/drivers/media/common/tuners/tda18271-common.c b/drivers/media/common/tuners/tda18271-common.c
index 155c93eb75da..e1f678281a58 100644
--- a/drivers/media/common/tuners/tda18271-common.c
+++ b/drivers/media/common/tuners/tda18271-common.c
@@ -326,12 +326,24 @@ int tda18271_init_regs(struct dvb_frontend *fe)
326 regs[R_EB22] = 0x48; 326 regs[R_EB22] = 0x48;
327 regs[R_EB23] = 0xb0; 327 regs[R_EB23] = 0xb0;
328 328
329 if (priv->small_i2c) { 329 switch (priv->small_i2c) {
330 case TDA18271_08_BYTE_CHUNK_INIT:
331 tda18271_write_regs(fe, 0x00, 0x08);
332 tda18271_write_regs(fe, 0x08, 0x08);
333 tda18271_write_regs(fe, 0x10, 0x08);
334 tda18271_write_regs(fe, 0x18, 0x08);
335 tda18271_write_regs(fe, 0x20, 0x07);
336 break;
337 case TDA18271_16_BYTE_CHUNK_INIT:
330 tda18271_write_regs(fe, 0x00, 0x10); 338 tda18271_write_regs(fe, 0x00, 0x10);
331 tda18271_write_regs(fe, 0x10, 0x10); 339 tda18271_write_regs(fe, 0x10, 0x10);
332 tda18271_write_regs(fe, 0x20, 0x07); 340 tda18271_write_regs(fe, 0x20, 0x07);
333 } else 341 break;
342 case TDA18271_39_BYTE_CHUNK_INIT:
343 default:
334 tda18271_write_regs(fe, 0x00, TDA18271_NUM_REGS); 344 tda18271_write_regs(fe, 0x00, TDA18271_NUM_REGS);
345 break;
346 }
335 347
336 /* setup agc1 gain */ 348 /* setup agc1 gain */
337 regs[R_EB17] = 0x00; 349 regs[R_EB17] = 0x00;
diff --git a/drivers/media/common/tuners/tda18271-fe.c b/drivers/media/common/tuners/tda18271-fe.c
index 3a50ce96fcb9..b2e15456d5f3 100644
--- a/drivers/media/common/tuners/tda18271-fe.c
+++ b/drivers/media/common/tuners/tda18271-fe.c
@@ -256,8 +256,9 @@ static int tda18271c2_rf_tracking_filters_correction(struct dvb_frontend *fe,
256 struct tda18271_priv *priv = fe->tuner_priv; 256 struct tda18271_priv *priv = fe->tuner_priv;
257 struct tda18271_rf_tracking_filter_cal *map = priv->rf_cal_state; 257 struct tda18271_rf_tracking_filter_cal *map = priv->rf_cal_state;
258 unsigned char *regs = priv->tda18271_regs; 258 unsigned char *regs = priv->tda18271_regs;
259 int tm_current, rfcal_comp, approx, i, ret; 259 int i, ret;
260 u8 dc_over_dt, rf_tab; 260 u8 tm_current, dc_over_dt, rf_tab;
261 s32 rfcal_comp, approx;
261 262
262 /* power up */ 263 /* power up */
263 ret = tda18271_set_standby_mode(fe, 0, 0, 0); 264 ret = tda18271_set_standby_mode(fe, 0, 0, 0);
@@ -277,11 +278,11 @@ static int tda18271c2_rf_tracking_filters_correction(struct dvb_frontend *fe,
277 return i; 278 return i;
278 279
279 if ((0 == map[i].rf3) || (freq / 1000 < map[i].rf2)) { 280 if ((0 == map[i].rf3) || (freq / 1000 < map[i].rf2)) {
280 approx = map[i].rf_a1 * 281 approx = map[i].rf_a1 * (s32)(freq / 1000 - map[i].rf1) +
281 (freq / 1000 - map[i].rf1) + map[i].rf_b1 + rf_tab; 282 map[i].rf_b1 + rf_tab;
282 } else { 283 } else {
283 approx = map[i].rf_a2 * 284 approx = map[i].rf_a2 * (s32)(freq / 1000 - map[i].rf2) +
284 (freq / 1000 - map[i].rf2) + map[i].rf_b2 + rf_tab; 285 map[i].rf_b2 + rf_tab;
285 } 286 }
286 287
287 if (approx < 0) 288 if (approx < 0)
@@ -292,9 +293,9 @@ static int tda18271c2_rf_tracking_filters_correction(struct dvb_frontend *fe,
292 tda18271_lookup_map(fe, RF_CAL_DC_OVER_DT, &freq, &dc_over_dt); 293 tda18271_lookup_map(fe, RF_CAL_DC_OVER_DT, &freq, &dc_over_dt);
293 294
294 /* calculate temperature compensation */ 295 /* calculate temperature compensation */
295 rfcal_comp = dc_over_dt * (tm_current - priv->tm_rfcal) / 1000; 296 rfcal_comp = dc_over_dt * (s32)(tm_current - priv->tm_rfcal) / 1000;
296 297
297 regs[R_EB14] = approx + rfcal_comp; 298 regs[R_EB14] = (unsigned char)(approx + rfcal_comp);
298 ret = tda18271_write_regs(fe, R_EB14, 1); 299 ret = tda18271_write_regs(fe, R_EB14, 1);
299fail: 300fail:
300 return ret; 301 return ret;
@@ -572,6 +573,7 @@ static int tda18271_rf_tracking_filters_init(struct dvb_frontend *fe, u32 freq)
572 struct tda18271_rf_tracking_filter_cal *map = priv->rf_cal_state; 573 struct tda18271_rf_tracking_filter_cal *map = priv->rf_cal_state;
573 unsigned char *regs = priv->tda18271_regs; 574 unsigned char *regs = priv->tda18271_regs;
574 int bcal, rf, i; 575 int bcal, rf, i;
576 s32 divisor, dividend;
575#define RF1 0 577#define RF1 0
576#define RF2 1 578#define RF2 1
577#define RF3 2 579#define RF3 2
@@ -610,20 +612,22 @@ static int tda18271_rf_tracking_filters_init(struct dvb_frontend *fe, u32 freq)
610 switch (rf) { 612 switch (rf) {
611 case RF1: 613 case RF1:
612 map[i].rf_a1 = 0; 614 map[i].rf_a1 = 0;
613 map[i].rf_b1 = prog_cal[RF1] - prog_tab[RF1]; 615 map[i].rf_b1 = (s32)(prog_cal[RF1] - prog_tab[RF1]);
614 map[i].rf1 = rf_freq[RF1] / 1000; 616 map[i].rf1 = rf_freq[RF1] / 1000;
615 break; 617 break;
616 case RF2: 618 case RF2:
617 map[i].rf_a1 = (prog_cal[RF2] - prog_tab[RF2] - 619 dividend = (s32)(prog_cal[RF2] - prog_tab[RF2]) -
618 prog_cal[RF1] + prog_tab[RF1]) / 620 (s32)(prog_cal[RF1] + prog_tab[RF1]);
619 (s32)((rf_freq[RF2] - rf_freq[RF1]) / 1000); 621 divisor = (s32)(rf_freq[RF2] - rf_freq[RF1]) / 1000;
622 map[i].rf_a1 = (dividend / divisor);
620 map[i].rf2 = rf_freq[RF2] / 1000; 623 map[i].rf2 = rf_freq[RF2] / 1000;
621 break; 624 break;
622 case RF3: 625 case RF3:
623 map[i].rf_a2 = (prog_cal[RF3] - prog_tab[RF3] - 626 dividend = (s32)(prog_cal[RF3] - prog_tab[RF3]) -
624 prog_cal[RF2] + prog_tab[RF2]) / 627 (s32)(prog_cal[RF2] + prog_tab[RF2]);
625 (s32)((rf_freq[RF3] - rf_freq[RF2]) / 1000); 628 divisor = (s32)(rf_freq[RF3] - rf_freq[RF2]) / 1000;
626 map[i].rf_b2 = prog_cal[RF2] - prog_tab[RF2]; 629 map[i].rf_a2 = (dividend / divisor);
630 map[i].rf_b2 = (s32)(prog_cal[RF2] - prog_tab[RF2]);
627 map[i].rf3 = rf_freq[RF3] / 1000; 631 map[i].rf3 = rf_freq[RF3] / 1000;
628 break; 632 break;
629 default: 633 default:
@@ -1181,6 +1185,48 @@ static int tda18271_get_id(struct dvb_frontend *fe)
1181 return ret; 1185 return ret;
1182} 1186}
1183 1187
1188static int tda18271_setup_configuration(struct dvb_frontend *fe,
1189 struct tda18271_config *cfg)
1190{
1191 struct tda18271_priv *priv = fe->tuner_priv;
1192
1193 priv->gate = (cfg) ? cfg->gate : TDA18271_GATE_AUTO;
1194 priv->role = (cfg) ? cfg->role : TDA18271_MASTER;
1195 priv->config = (cfg) ? cfg->config : 0;
1196 priv->small_i2c = (cfg) ?
1197 cfg->small_i2c : TDA18271_39_BYTE_CHUNK_INIT;
1198 priv->output_opt = (cfg) ?
1199 cfg->output_opt : TDA18271_OUTPUT_LT_XT_ON;
1200
1201 return 0;
1202}
1203
1204static inline int tda18271_need_cal_on_startup(struct tda18271_config *cfg)
1205{
1206 /* tda18271_cal_on_startup == -1 when cal module option is unset */
1207 return ((tda18271_cal_on_startup == -1) ?
1208 /* honor configuration setting */
1209 ((cfg) && (cfg->rf_cal_on_startup)) :
1210 /* module option overrides configuration setting */
1211 (tda18271_cal_on_startup)) ? 1 : 0;
1212}
1213
1214static int tda18271_set_config(struct dvb_frontend *fe, void *priv_cfg)
1215{
1216 struct tda18271_config *cfg = (struct tda18271_config *) priv_cfg;
1217
1218 tda18271_setup_configuration(fe, cfg);
1219
1220 if (tda18271_need_cal_on_startup(cfg))
1221 tda18271_init(fe);
1222
1223 /* override default std map with values in config struct */
1224 if ((cfg) && (cfg->std_map))
1225 tda18271_update_std_map(fe, cfg->std_map);
1226
1227 return 0;
1228}
1229
1184static struct dvb_tuner_ops tda18271_tuner_ops = { 1230static struct dvb_tuner_ops tda18271_tuner_ops = {
1185 .info = { 1231 .info = {
1186 .name = "NXP TDA18271HD", 1232 .name = "NXP TDA18271HD",
@@ -1193,6 +1239,7 @@ static struct dvb_tuner_ops tda18271_tuner_ops = {
1193 .set_params = tda18271_set_params, 1239 .set_params = tda18271_set_params,
1194 .set_analog_params = tda18271_set_analog_params, 1240 .set_analog_params = tda18271_set_analog_params,
1195 .release = tda18271_release, 1241 .release = tda18271_release,
1242 .set_config = tda18271_set_config,
1196 .get_frequency = tda18271_get_frequency, 1243 .get_frequency = tda18271_get_frequency,
1197 .get_bandwidth = tda18271_get_bandwidth, 1244 .get_bandwidth = tda18271_get_bandwidth,
1198}; 1245};
@@ -1213,33 +1260,14 @@ struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe, u8 addr,
1213 case 0: 1260 case 0:
1214 goto fail; 1261 goto fail;
1215 case 1: 1262 case 1:
1216 {
1217 /* new tuner instance */ 1263 /* new tuner instance */
1218 int rf_cal_on_startup; 1264 fe->tuner_priv = priv;
1219 1265
1220 priv->gate = (cfg) ? cfg->gate : TDA18271_GATE_AUTO; 1266 tda18271_setup_configuration(fe, cfg);
1221 priv->role = (cfg) ? cfg->role : TDA18271_MASTER;
1222 priv->config = (cfg) ? cfg->config : 0;
1223 priv->small_i2c = (cfg) ? cfg->small_i2c : 0;
1224 priv->output_opt = (cfg) ?
1225 cfg->output_opt : TDA18271_OUTPUT_LT_XT_ON;
1226
1227 /* tda18271_cal_on_startup == -1 when cal
1228 * module option is unset */
1229 if (tda18271_cal_on_startup == -1) {
1230 /* honor attach-time configuration */
1231 rf_cal_on_startup =
1232 ((cfg) && (cfg->rf_cal_on_startup)) ? 1 : 0;
1233 } else {
1234 /* module option overrides attach configuration */
1235 rf_cal_on_startup = tda18271_cal_on_startup;
1236 }
1237 1267
1238 priv->cal_initialized = false; 1268 priv->cal_initialized = false;
1239 mutex_init(&priv->lock); 1269 mutex_init(&priv->lock);
1240 1270
1241 fe->tuner_priv = priv;
1242
1243 if (tda_fail(tda18271_get_id(fe))) 1271 if (tda_fail(tda18271_get_id(fe)))
1244 goto fail; 1272 goto fail;
1245 1273
@@ -1249,12 +1277,12 @@ struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe, u8 addr,
1249 mutex_lock(&priv->lock); 1277 mutex_lock(&priv->lock);
1250 tda18271_init_regs(fe); 1278 tda18271_init_regs(fe);
1251 1279
1252 if ((rf_cal_on_startup) && (priv->id == TDA18271HDC2)) 1280 if ((tda18271_need_cal_on_startup(cfg)) &&
1281 (priv->id == TDA18271HDC2))
1253 tda18271c2_rf_cal_init(fe); 1282 tda18271c2_rf_cal_init(fe);
1254 1283
1255 mutex_unlock(&priv->lock); 1284 mutex_unlock(&priv->lock);
1256 break; 1285 break;
1257 }
1258 default: 1286 default:
1259 /* existing tuner instance */ 1287 /* existing tuner instance */
1260 fe->tuner_priv = priv; 1288 fe->tuner_priv = priv;
@@ -1271,7 +1299,11 @@ struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe, u8 addr,
1271 priv->small_i2c = cfg->small_i2c; 1299 priv->small_i2c = cfg->small_i2c;
1272 if (cfg->output_opt) 1300 if (cfg->output_opt)
1273 priv->output_opt = cfg->output_opt; 1301 priv->output_opt = cfg->output_opt;
1302 if (cfg->std_map)
1303 tda18271_update_std_map(fe, cfg->std_map);
1274 } 1304 }
1305 if (tda18271_need_cal_on_startup(cfg))
1306 tda18271_init(fe);
1275 break; 1307 break;
1276 } 1308 }
1277 1309
@@ -1298,7 +1330,7 @@ EXPORT_SYMBOL_GPL(tda18271_attach);
1298MODULE_DESCRIPTION("NXP TDA18271HD analog / digital tuner driver"); 1330MODULE_DESCRIPTION("NXP TDA18271HD analog / digital tuner driver");
1299MODULE_AUTHOR("Michael Krufky <mkrufky@linuxtv.org>"); 1331MODULE_AUTHOR("Michael Krufky <mkrufky@linuxtv.org>");
1300MODULE_LICENSE("GPL"); 1332MODULE_LICENSE("GPL");
1301MODULE_VERSION("0.3"); 1333MODULE_VERSION("0.4");
1302 1334
1303/* 1335/*
1304 * Overrides for Emacs so that we follow Linus's tabbing style. 1336 * Overrides for Emacs so that we follow Linus's tabbing style.
diff --git a/drivers/media/common/tuners/tda18271-maps.c b/drivers/media/common/tuners/tda18271-maps.c
index e21fdeff3ddf..e7f84c705da8 100644
--- a/drivers/media/common/tuners/tda18271-maps.c
+++ b/drivers/media/common/tuners/tda18271-maps.c
@@ -978,6 +978,7 @@ static struct tda18271_cid_target_map tda18271_cid_target[] = {
978int tda18271_lookup_cid_target(struct dvb_frontend *fe, 978int tda18271_lookup_cid_target(struct dvb_frontend *fe,
979 u32 *freq, u8 *cid_target, u16 *count_limit) 979 u32 *freq, u8 *cid_target, u16 *count_limit)
980{ 980{
981 struct tda18271_priv *priv = fe->tuner_priv;
981 int i = 0; 982 int i = 0;
982 983
983 while ((tda18271_cid_target[i].rfmax * 1000) < *freq) { 984 while ((tda18271_cid_target[i].rfmax * 1000) < *freq) {
diff --git a/drivers/media/common/tuners/tda18271-priv.h b/drivers/media/common/tuners/tda18271-priv.h
index 2bee229acd91..9589ab0576d2 100644
--- a/drivers/media/common/tuners/tda18271-priv.h
+++ b/drivers/media/common/tuners/tda18271-priv.h
@@ -80,10 +80,10 @@ struct tda18271_rf_tracking_filter_cal {
80 u32 rf1; 80 u32 rf1;
81 u32 rf2; 81 u32 rf2;
82 u32 rf3; 82 u32 rf3;
83 int rf_a1; 83 s32 rf_a1;
84 int rf_b1; 84 s32 rf_b1;
85 int rf_a2; 85 s32 rf_a2;
86 int rf_b2; 86 s32 rf_b2;
87}; 87};
88 88
89enum tda18271_pll { 89enum tda18271_pll {
@@ -109,11 +109,12 @@ struct tda18271_priv {
109 enum tda18271_i2c_gate gate; 109 enum tda18271_i2c_gate gate;
110 enum tda18271_ver id; 110 enum tda18271_ver id;
111 enum tda18271_output_options output_opt; 111 enum tda18271_output_options output_opt;
112 enum tda18271_small_i2c small_i2c;
112 113
113 unsigned int config; /* interface to saa713x / tda829x */ 114 unsigned int config; /* interface to saa713x / tda829x */
114 unsigned int tm_rfcal;
115 unsigned int cal_initialized:1; 115 unsigned int cal_initialized:1;
116 unsigned int small_i2c:1; 116
117 u8 tm_rfcal;
117 118
118 struct tda18271_map_layout *maps; 119 struct tda18271_map_layout *maps;
119 struct tda18271_std_map std; 120 struct tda18271_std_map std;
@@ -135,27 +136,37 @@ extern int tda18271_debug;
135#define DBG_ADV 8 136#define DBG_ADV 8
136#define DBG_CAL 16 137#define DBG_CAL 16
137 138
138#define tda_printk(kern, fmt, arg...) \ 139#define tda_printk(st, kern, fmt, arg...) do {\
139 printk(kern "%s: " fmt, __func__, ##arg) 140 if (st) { \
140 141 struct tda18271_priv *state = st; \
141#define tda_dprintk(lvl, fmt, arg...) do {\ 142 printk(kern "%s: [%d-%04x|%s] " fmt, __func__, \
143 i2c_adapter_id(state->i2c_props.adap), \
144 state->i2c_props.addr, \
145 (state->role == TDA18271_MASTER) \
146 ? "M" : "S", ##arg); \
147 } else \
148 printk(kern "%s: " fmt, __func__, ##arg); \
149} while (0)
150
151#define tda_dprintk(st, lvl, fmt, arg...) do {\
142 if (tda18271_debug & lvl) \ 152 if (tda18271_debug & lvl) \
143 tda_printk(KERN_DEBUG, fmt, ##arg); } while (0) 153 tda_printk(st, KERN_DEBUG, fmt, ##arg); } while (0)
144 154
145#define tda_info(fmt, arg...) printk(KERN_INFO fmt, ##arg) 155#define tda_info(fmt, arg...) printk(KERN_INFO fmt, ##arg)
146#define tda_warn(fmt, arg...) tda_printk(KERN_WARNING, fmt, ##arg) 156#define tda_warn(fmt, arg...) tda_printk(priv, KERN_WARNING, fmt, ##arg)
147#define tda_err(fmt, arg...) tda_printk(KERN_ERR, fmt, ##arg) 157#define tda_err(fmt, arg...) tda_printk(priv, KERN_ERR, fmt, ##arg)
148#define tda_dbg(fmt, arg...) tda_dprintk(DBG_INFO, fmt, ##arg) 158#define tda_dbg(fmt, arg...) tda_dprintk(priv, DBG_INFO, fmt, ##arg)
149#define tda_map(fmt, arg...) tda_dprintk(DBG_MAP, fmt, ##arg) 159#define tda_map(fmt, arg...) tda_dprintk(priv, DBG_MAP, fmt, ##arg)
150#define tda_reg(fmt, arg...) tda_dprintk(DBG_REG, fmt, ##arg) 160#define tda_reg(fmt, arg...) tda_dprintk(priv, DBG_REG, fmt, ##arg)
151#define tda_cal(fmt, arg...) tda_dprintk(DBG_CAL, fmt, ##arg) 161#define tda_cal(fmt, arg...) tda_dprintk(priv, DBG_CAL, fmt, ##arg)
152 162
153#define tda_fail(ret) \ 163#define tda_fail(ret) \
154({ \ 164({ \
155 int __ret; \ 165 int __ret; \
156 __ret = (ret < 0); \ 166 __ret = (ret < 0); \
157 if (__ret) \ 167 if (__ret) \
158 tda_printk(KERN_ERR, "error %d on line %d\n", ret, __LINE__);\ 168 tda_printk(priv, KERN_ERR, \
169 "error %d on line %d\n", ret, __LINE__); \
159 __ret; \ 170 __ret; \
160}) 171})
161 172
diff --git a/drivers/media/common/tuners/tda18271.h b/drivers/media/common/tuners/tda18271.h
index 323f2912128d..d7fcc36dc6e6 100644
--- a/drivers/media/common/tuners/tda18271.h
+++ b/drivers/media/common/tuners/tda18271.h
@@ -78,6 +78,12 @@ enum tda18271_output_options {
78 TDA18271_OUTPUT_XT_OFF = 2, 78 TDA18271_OUTPUT_XT_OFF = 2,
79}; 79};
80 80
81enum tda18271_small_i2c {
82 TDA18271_39_BYTE_CHUNK_INIT = 0,
83 TDA18271_16_BYTE_CHUNK_INIT = 1,
84 TDA18271_08_BYTE_CHUNK_INIT = 2,
85};
86
81struct tda18271_config { 87struct tda18271_config {
82 /* override default if freq / std settings (optional) */ 88 /* override default if freq / std settings (optional) */
83 struct tda18271_std_map *std_map; 89 struct tda18271_std_map *std_map;
@@ -91,12 +97,12 @@ struct tda18271_config {
91 /* output options that can be disabled */ 97 /* output options that can be disabled */
92 enum tda18271_output_options output_opt; 98 enum tda18271_output_options output_opt;
93 99
100 /* some i2c providers cant write all 39 registers at once */
101 enum tda18271_small_i2c small_i2c;
102
94 /* force rf tracking filter calibration on startup */ 103 /* force rf tracking filter calibration on startup */
95 unsigned int rf_cal_on_startup:1; 104 unsigned int rf_cal_on_startup:1;
96 105
97 /* some i2c providers cant write all 39 registers at once */
98 unsigned int small_i2c:1;
99
100 /* interface to saa713x / tda829x */ 106 /* interface to saa713x / tda829x */
101 unsigned int config; 107 unsigned int config;
102}; 108};
diff --git a/drivers/media/common/tuners/tda8290.c b/drivers/media/common/tuners/tda8290.c
index 064d14c8d7b2..c190b0dedee4 100644
--- a/drivers/media/common/tuners/tda8290.c
+++ b/drivers/media/common/tuners/tda8290.c
@@ -33,6 +33,7 @@ module_param(debug, int, 0644);
33MODULE_PARM_DESC(debug, "enable verbose debug messages"); 33MODULE_PARM_DESC(debug, "enable verbose debug messages");
34 34
35static int deemphasis_50; 35static int deemphasis_50;
36module_param(deemphasis_50, int, 0644);
36MODULE_PARM_DESC(deemphasis_50, "0 - 75us deemphasis; 1 - 50us deemphasis"); 37MODULE_PARM_DESC(deemphasis_50, "0 - 75us deemphasis; 1 - 50us deemphasis");
37 38
38/* ---------------------------------------------------------------------- */ 39/* ---------------------------------------------------------------------- */
diff --git a/drivers/media/common/tuners/tda9887.c b/drivers/media/common/tuners/tda9887.c
index 544cdbe88a6c..a71c100c95df 100644
--- a/drivers/media/common/tuners/tda9887.c
+++ b/drivers/media/common/tuners/tda9887.c
@@ -463,7 +463,7 @@ static int tda9887_set_insmod(struct dvb_frontend *fe)
463 buf[1] &= ~cQSS; 463 buf[1] &= ~cQSS;
464 } 464 }
465 465
466 if (adjust >= 0x00 && adjust < 0x20) { 466 if (adjust < 0x20) {
467 buf[2] &= ~cTopMask; 467 buf[2] &= ~cTopMask;
468 buf[2] |= adjust; 468 buf[2] |= adjust;
469 } 469 }
diff --git a/drivers/media/common/tuners/xc5000.c b/drivers/media/common/tuners/xc5000.c
index f4ffcdc9b848..432003dded7c 100644
--- a/drivers/media/common/tuners/xc5000.c
+++ b/drivers/media/common/tuners/xc5000.c
@@ -61,6 +61,7 @@ struct xc5000_priv {
61 u32 bandwidth; 61 u32 bandwidth;
62 u8 video_standard; 62 u8 video_standard;
63 u8 rf_mode; 63 u8 rf_mode;
64 u8 radio_input;
64}; 65};
65 66
66/* Misc Defines */ 67/* Misc Defines */
@@ -632,8 +633,12 @@ static int xc5000_set_params(struct dvb_frontend *fe,
632 struct xc5000_priv *priv = fe->tuner_priv; 633 struct xc5000_priv *priv = fe->tuner_priv;
633 int ret; 634 int ret;
634 635
635 if (xc5000_is_firmware_loaded(fe) != XC_RESULT_SUCCESS) 636 if (xc5000_is_firmware_loaded(fe) != XC_RESULT_SUCCESS) {
636 xc_load_fw_and_init_tuner(fe); 637 if (xc_load_fw_and_init_tuner(fe) != XC_RESULT_SUCCESS) {
638 dprintk(1, "Unable to load firmware and init tuner\n");
639 return -EINVAL;
640 }
641 }
637 642
638 dprintk(1, "%s() frequency=%d (Hz)\n", __func__, params->frequency); 643 dprintk(1, "%s() frequency=%d (Hz)\n", __func__, params->frequency);
639 644
@@ -739,15 +744,12 @@ static int xc5000_is_firmware_loaded(struct dvb_frontend *fe)
739 return ret; 744 return ret;
740} 745}
741 746
742static int xc5000_set_analog_params(struct dvb_frontend *fe, 747static int xc5000_set_tv_freq(struct dvb_frontend *fe,
743 struct analog_parameters *params) 748 struct analog_parameters *params)
744{ 749{
745 struct xc5000_priv *priv = fe->tuner_priv; 750 struct xc5000_priv *priv = fe->tuner_priv;
746 int ret; 751 int ret;
747 752
748 if (xc5000_is_firmware_loaded(fe) != XC_RESULT_SUCCESS)
749 xc_load_fw_and_init_tuner(fe);
750
751 dprintk(1, "%s() frequency=%d (in units of 62.5khz)\n", 753 dprintk(1, "%s() frequency=%d (in units of 62.5khz)\n",
752 __func__, params->frequency); 754 __func__, params->frequency);
753 755
@@ -827,6 +829,86 @@ tune_channel:
827 return 0; 829 return 0;
828} 830}
829 831
832static int xc5000_set_radio_freq(struct dvb_frontend *fe,
833 struct analog_parameters *params)
834{
835 struct xc5000_priv *priv = fe->tuner_priv;
836 int ret = -EINVAL;
837 u8 radio_input;
838
839 dprintk(1, "%s() frequency=%d (in units of khz)\n",
840 __func__, params->frequency);
841
842 if (priv->radio_input == XC5000_RADIO_NOT_CONFIGURED) {
843 dprintk(1, "%s() radio input not configured\n", __func__);
844 return -EINVAL;
845 }
846
847 if (priv->radio_input == XC5000_RADIO_FM1)
848 radio_input = FM_Radio_INPUT1;
849 else if (priv->radio_input == XC5000_RADIO_FM2)
850 radio_input = FM_Radio_INPUT2;
851 else {
852 dprintk(1, "%s() unknown radio input %d\n", __func__,
853 priv->radio_input);
854 return -EINVAL;
855 }
856
857 priv->freq_hz = params->frequency * 125 / 2;
858
859 priv->rf_mode = XC_RF_MODE_AIR;
860
861 ret = xc_SetTVStandard(priv, XC5000_Standard[radio_input].VideoMode,
862 XC5000_Standard[radio_input].AudioMode);
863
864 if (ret != XC_RESULT_SUCCESS) {
865 printk(KERN_ERR "xc5000: xc_SetTVStandard failed\n");
866 return -EREMOTEIO;
867 }
868
869 ret = xc_SetSignalSource(priv, priv->rf_mode);
870 if (ret != XC_RESULT_SUCCESS) {
871 printk(KERN_ERR
872 "xc5000: xc_SetSignalSource(%d) failed\n",
873 priv->rf_mode);
874 return -EREMOTEIO;
875 }
876
877 xc_tune_channel(priv, priv->freq_hz, XC_TUNE_ANALOG);
878
879 return 0;
880}
881
882static int xc5000_set_analog_params(struct dvb_frontend *fe,
883 struct analog_parameters *params)
884{
885 struct xc5000_priv *priv = fe->tuner_priv;
886 int ret = -EINVAL;
887
888 if (priv->i2c_props.adap == NULL)
889 return -EINVAL;
890
891 if (xc5000_is_firmware_loaded(fe) != XC_RESULT_SUCCESS) {
892 if (xc_load_fw_and_init_tuner(fe) != XC_RESULT_SUCCESS) {
893 dprintk(1, "Unable to load firmware and init tuner\n");
894 return -EINVAL;
895 }
896 }
897
898 switch (params->mode) {
899 case V4L2_TUNER_RADIO:
900 ret = xc5000_set_radio_freq(fe, params);
901 break;
902 case V4L2_TUNER_ANALOG_TV:
903 case V4L2_TUNER_DIGITAL_TV:
904 ret = xc5000_set_tv_freq(fe, params);
905 break;
906 }
907
908 return ret;
909}
910
911
830static int xc5000_get_frequency(struct dvb_frontend *fe, u32 *freq) 912static int xc5000_get_frequency(struct dvb_frontend *fe, u32 *freq)
831{ 913{
832 struct xc5000_priv *priv = fe->tuner_priv; 914 struct xc5000_priv *priv = fe->tuner_priv;
@@ -1000,6 +1082,9 @@ struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe,
1000 priv->if_khz = cfg->if_khz; 1082 priv->if_khz = cfg->if_khz;
1001 } 1083 }
1002 1084
1085 if (priv->radio_input == 0)
1086 priv->radio_input = cfg->radio_input;
1087
1003 /* Check if firmware has been loaded. It is possible that another 1088 /* Check if firmware has been loaded. It is possible that another
1004 instance of the driver has loaded the firmware. 1089 instance of the driver has loaded the firmware.
1005 */ 1090 */
diff --git a/drivers/media/common/tuners/xc5000.h b/drivers/media/common/tuners/xc5000.h
index f4c146698a00..e6d7236c9ea1 100644
--- a/drivers/media/common/tuners/xc5000.h
+++ b/drivers/media/common/tuners/xc5000.h
@@ -30,11 +30,17 @@ struct i2c_adapter;
30struct xc5000_config { 30struct xc5000_config {
31 u8 i2c_address; 31 u8 i2c_address;
32 u32 if_khz; 32 u32 if_khz;
33 u8 radio_input;
33}; 34};
34 35
35/* xc5000 callback command */ 36/* xc5000 callback command */
36#define XC5000_TUNER_RESET 0 37#define XC5000_TUNER_RESET 0
37 38
39/* Possible Radio inputs */
40#define XC5000_RADIO_NOT_CONFIGURED 0
41#define XC5000_RADIO_FM1 1
42#define XC5000_RADIO_FM2 2
43
38/* For each bridge framework, when it attaches either analog or digital, 44/* For each bridge framework, when it attaches either analog or digital,
39 * it has to store a reference back to its _core equivalent structure, 45 * it has to store a reference back to its _core equivalent structure,
40 * so that it can service the hardware by steering gpio's etc. 46 * so that it can service the hardware by steering gpio's etc.
diff --git a/drivers/media/dvb/bt8xx/dvb-bt8xx.c b/drivers/media/dvb/bt8xx/dvb-bt8xx.c
index b1857c19bbd2..78fc469f0f69 100644
--- a/drivers/media/dvb/bt8xx/dvb-bt8xx.c
+++ b/drivers/media/dvb/bt8xx/dvb-bt8xx.c
@@ -215,7 +215,7 @@ static int cx24108_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend
215 freq = 2150000; /* satellite IF is 950..2150MHz */ 215 freq = 2150000; /* satellite IF is 950..2150MHz */
216 216
217 /* decide which VCO to use for the input frequency */ 217 /* decide which VCO to use for the input frequency */
218 for(i = 1; (i < ARRAY_SIZE(osci)) && (osci[i] < freq); i++); 218 for(i = 1; (i < ARRAY_SIZE(osci) - 1) && (osci[i] < freq); i++);
219 printk("cx24108 debug: select vco #%d (f=%d)\n",i,freq); 219 printk("cx24108 debug: select vco #%d (f=%d)\n",i,freq);
220 band=bandsel[i]; 220 band=bandsel[i];
221 /* the gain values must be set by SetSymbolrate */ 221 /* the gain values must be set by SetSymbolrate */
diff --git a/drivers/media/dvb/dm1105/dm1105.c b/drivers/media/dvb/dm1105/dm1105.c
index 2d099e271751..53e3f2a7d31a 100644
--- a/drivers/media/dvb/dm1105/dm1105.c
+++ b/drivers/media/dvb/dm1105/dm1105.c
@@ -510,7 +510,7 @@ static void dm1105_emit_key(struct work_struct *work)
510 510
511 data = (ircom >> 8) & 0x7f; 511 data = (ircom >> 8) & 0x7f;
512 512
513 ir_input_keydown(ir->input_dev, &ir->ir, data, data); 513 ir_input_keydown(ir->input_dev, &ir->ir, data);
514 ir_input_nokey(ir->input_dev, &ir->ir); 514 ir_input_nokey(ir->input_dev, &ir->ir);
515} 515}
516 516
@@ -589,7 +589,12 @@ int __devinit dm1105_ir_init(struct dm1105dvb *dm1105)
589 snprintf(dm1105->ir.input_phys, sizeof(dm1105->ir.input_phys), 589 snprintf(dm1105->ir.input_phys, sizeof(dm1105->ir.input_phys),
590 "pci-%s/ir0", pci_name(dm1105->pdev)); 590 "pci-%s/ir0", pci_name(dm1105->pdev));
591 591
592 ir_input_init(input_dev, &dm1105->ir.ir, ir_type, ir_codes); 592 err = ir_input_init(input_dev, &dm1105->ir.ir, ir_type, ir_codes);
593 if (err < 0) {
594 input_free_device(input_dev);
595 return err;
596 }
597
593 input_dev->name = "DVB on-card IR receiver"; 598 input_dev->name = "DVB on-card IR receiver";
594 input_dev->phys = dm1105->ir.input_phys; 599 input_dev->phys = dm1105->ir.input_phys;
595 input_dev->id.bustype = BUS_PCI; 600 input_dev->id.bustype = BUS_PCI;
@@ -608,6 +613,7 @@ int __devinit dm1105_ir_init(struct dm1105dvb *dm1105)
608 613
609 err = input_register_device(input_dev); 614 err = input_register_device(input_dev);
610 if (err) { 615 if (err) {
616 ir_input_free(input_dev);
611 input_free_device(input_dev); 617 input_free_device(input_dev);
612 return err; 618 return err;
613 } 619 }
@@ -617,8 +623,8 @@ int __devinit dm1105_ir_init(struct dm1105dvb *dm1105)
617 623
618void __devexit dm1105_ir_exit(struct dm1105dvb *dm1105) 624void __devexit dm1105_ir_exit(struct dm1105dvb *dm1105)
619{ 625{
626 ir_input_free(dm1105->ir.input_dev);
620 input_unregister_device(dm1105->ir.input_dev); 627 input_unregister_device(dm1105->ir.input_dev);
621
622} 628}
623 629
624static int __devinit dm1105dvb_hw_init(struct dm1105dvb *dm1105dvb) 630static int __devinit dm1105dvb_hw_init(struct dm1105dvb *dm1105dvb)
diff --git a/drivers/media/dvb/dvb-core/dvb_demux.c b/drivers/media/dvb/dvb-core/dvb_demux.c
index 91c537bca8ad..b78cfb7d1897 100644
--- a/drivers/media/dvb/dvb-core/dvb_demux.c
+++ b/drivers/media/dvb/dvb-core/dvb_demux.c
@@ -30,6 +30,7 @@
30#include <linux/string.h> 30#include <linux/string.h>
31#include <linux/crc32.h> 31#include <linux/crc32.h>
32#include <asm/uaccess.h> 32#include <asm/uaccess.h>
33#include <asm/div64.h>
33 34
34#include "dvb_demux.h" 35#include "dvb_demux.h"
35 36
@@ -44,6 +45,11 @@ module_param(dvb_demux_tscheck, int, 0644);
44MODULE_PARM_DESC(dvb_demux_tscheck, 45MODULE_PARM_DESC(dvb_demux_tscheck,
45 "enable transport stream continuity and TEI check"); 46 "enable transport stream continuity and TEI check");
46 47
48static int dvb_demux_speedcheck;
49module_param(dvb_demux_speedcheck, int, 0644);
50MODULE_PARM_DESC(dvb_demux_speedcheck,
51 "enable transport stream speed check");
52
47#define dprintk_tscheck(x...) do { \ 53#define dprintk_tscheck(x...) do { \
48 if (dvb_demux_tscheck && printk_ratelimit()) \ 54 if (dvb_demux_tscheck && printk_ratelimit()) \
49 printk(x); \ 55 printk(x); \
@@ -387,6 +393,39 @@ static void dvb_dmx_swfilter_packet(struct dvb_demux *demux, const u8 *buf)
387 u16 pid = ts_pid(buf); 393 u16 pid = ts_pid(buf);
388 int dvr_done = 0; 394 int dvr_done = 0;
389 395
396 if (dvb_demux_speedcheck) {
397 struct timespec cur_time, delta_time;
398 u64 speed_bytes, speed_timedelta;
399
400 demux->speed_pkts_cnt++;
401
402 /* show speed every SPEED_PKTS_INTERVAL packets */
403 if (!(demux->speed_pkts_cnt % SPEED_PKTS_INTERVAL)) {
404 cur_time = current_kernel_time();
405
406 if (demux->speed_last_time.tv_sec != 0 &&
407 demux->speed_last_time.tv_nsec != 0) {
408 delta_time = timespec_sub(cur_time,
409 demux->speed_last_time);
410 speed_bytes = (u64)demux->speed_pkts_cnt
411 * 188 * 8;
412 /* convert to 1024 basis */
413 speed_bytes = 1000 * div64_u64(speed_bytes,
414 1024);
415 speed_timedelta =
416 (u64)timespec_to_ns(&delta_time);
417 speed_timedelta = div64_u64(speed_timedelta,
418 1000000); /* nsec -> usec */
419 printk(KERN_INFO "TS speed %llu Kbits/sec \n",
420 div64_u64(speed_bytes,
421 speed_timedelta));
422 };
423
424 demux->speed_last_time = cur_time;
425 demux->speed_pkts_cnt = 0;
426 };
427 };
428
390 if (dvb_demux_tscheck) { 429 if (dvb_demux_tscheck) {
391 if (!demux->cnt_storage) 430 if (!demux->cnt_storage)
392 demux->cnt_storage = vmalloc(MAX_PID + 1); 431 demux->cnt_storage = vmalloc(MAX_PID + 1);
diff --git a/drivers/media/dvb/dvb-core/dvb_demux.h b/drivers/media/dvb/dvb-core/dvb_demux.h
index 2fe05d03240d..a7d876fd02dd 100644
--- a/drivers/media/dvb/dvb-core/dvb_demux.h
+++ b/drivers/media/dvb/dvb-core/dvb_demux.h
@@ -44,6 +44,8 @@
44 44
45#define MAX_PID 0x1fff 45#define MAX_PID 0x1fff
46 46
47#define SPEED_PKTS_INTERVAL 50000
48
47struct dvb_demux_filter { 49struct dvb_demux_filter {
48 struct dmx_section_filter filter; 50 struct dmx_section_filter filter;
49 u8 maskandmode[DMX_MAX_FILTER_SIZE]; 51 u8 maskandmode[DMX_MAX_FILTER_SIZE];
@@ -131,6 +133,9 @@ struct dvb_demux {
131 spinlock_t lock; 133 spinlock_t lock;
132 134
133 uint8_t *cnt_storage; /* for TS continuity check */ 135 uint8_t *cnt_storage; /* for TS continuity check */
136
137 struct timespec speed_last_time; /* for TS speed check */
138 uint32_t speed_pkts_cnt; /* for TS speed check */
134}; 139};
135 140
136int dvb_dmx_init(struct dvb_demux *dvbdemux); 141int dvb_dmx_init(struct dvb_demux *dvbdemux);
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c
index 98082416aa52..07461222a7f5 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.c
@@ -895,104 +895,27 @@ static int dvb_frontend_clear_cache(struct dvb_frontend *fe)
895} 895}
896 896
897static struct dtv_cmds_h dtv_cmds[] = { 897static struct dtv_cmds_h dtv_cmds[] = {
898 [DTV_TUNE] = { 898 _DTV_CMD(DTV_TUNE, 1, 0),
899 .name = "DTV_TUNE", 899 _DTV_CMD(DTV_CLEAR, 1, 0),
900 .cmd = DTV_TUNE,
901 .set = 1,
902 },
903 [DTV_CLEAR] = {
904 .name = "DTV_CLEAR",
905 .cmd = DTV_CLEAR,
906 .set = 1,
907 },
908 900
909 /* Set */ 901 /* Set */
910 [DTV_FREQUENCY] = { 902 _DTV_CMD(DTV_FREQUENCY, 1, 0),
911 .name = "DTV_FREQUENCY", 903 _DTV_CMD(DTV_BANDWIDTH_HZ, 1, 0),
912 .cmd = DTV_FREQUENCY, 904 _DTV_CMD(DTV_MODULATION, 1, 0),
913 .set = 1, 905 _DTV_CMD(DTV_INVERSION, 1, 0),
914 }, 906 _DTV_CMD(DTV_DISEQC_MASTER, 1, 1),
915 [DTV_BANDWIDTH_HZ] = { 907 _DTV_CMD(DTV_SYMBOL_RATE, 1, 0),
916 .name = "DTV_BANDWIDTH_HZ", 908 _DTV_CMD(DTV_INNER_FEC, 1, 0),
917 .cmd = DTV_BANDWIDTH_HZ, 909 _DTV_CMD(DTV_VOLTAGE, 1, 0),
918 .set = 1, 910 _DTV_CMD(DTV_TONE, 1, 0),
919 }, 911 _DTV_CMD(DTV_PILOT, 1, 0),
920 [DTV_MODULATION] = { 912 _DTV_CMD(DTV_ROLLOFF, 1, 0),
921 .name = "DTV_MODULATION", 913 _DTV_CMD(DTV_DELIVERY_SYSTEM, 1, 0),
922 .cmd = DTV_MODULATION, 914 _DTV_CMD(DTV_HIERARCHY, 1, 0),
923 .set = 1, 915 _DTV_CMD(DTV_CODE_RATE_HP, 1, 0),
924 }, 916 _DTV_CMD(DTV_CODE_RATE_LP, 1, 0),
925 [DTV_INVERSION] = { 917 _DTV_CMD(DTV_GUARD_INTERVAL, 1, 0),
926 .name = "DTV_INVERSION", 918 _DTV_CMD(DTV_TRANSMISSION_MODE, 1, 0),
927 .cmd = DTV_INVERSION,
928 .set = 1,
929 },
930 [DTV_DISEQC_MASTER] = {
931 .name = "DTV_DISEQC_MASTER",
932 .cmd = DTV_DISEQC_MASTER,
933 .set = 1,
934 .buffer = 1,
935 },
936 [DTV_SYMBOL_RATE] = {
937 .name = "DTV_SYMBOL_RATE",
938 .cmd = DTV_SYMBOL_RATE,
939 .set = 1,
940 },
941 [DTV_INNER_FEC] = {
942 .name = "DTV_INNER_FEC",
943 .cmd = DTV_INNER_FEC,
944 .set = 1,
945 },
946 [DTV_VOLTAGE] = {
947 .name = "DTV_VOLTAGE",
948 .cmd = DTV_VOLTAGE,
949 .set = 1,
950 },
951 [DTV_TONE] = {
952 .name = "DTV_TONE",
953 .cmd = DTV_TONE,
954 .set = 1,
955 },
956 [DTV_PILOT] = {
957 .name = "DTV_PILOT",
958 .cmd = DTV_PILOT,
959 .set = 1,
960 },
961 [DTV_ROLLOFF] = {
962 .name = "DTV_ROLLOFF",
963 .cmd = DTV_ROLLOFF,
964 .set = 1,
965 },
966 [DTV_DELIVERY_SYSTEM] = {
967 .name = "DTV_DELIVERY_SYSTEM",
968 .cmd = DTV_DELIVERY_SYSTEM,
969 .set = 1,
970 },
971 [DTV_HIERARCHY] = {
972 .name = "DTV_HIERARCHY",
973 .cmd = DTV_HIERARCHY,
974 .set = 1,
975 },
976 [DTV_CODE_RATE_HP] = {
977 .name = "DTV_CODE_RATE_HP",
978 .cmd = DTV_CODE_RATE_HP,
979 .set = 1,
980 },
981 [DTV_CODE_RATE_LP] = {
982 .name = "DTV_CODE_RATE_LP",
983 .cmd = DTV_CODE_RATE_LP,
984 .set = 1,
985 },
986 [DTV_GUARD_INTERVAL] = {
987 .name = "DTV_GUARD_INTERVAL",
988 .cmd = DTV_GUARD_INTERVAL,
989 .set = 1,
990 },
991 [DTV_TRANSMISSION_MODE] = {
992 .name = "DTV_TRANSMISSION_MODE",
993 .cmd = DTV_TRANSMISSION_MODE,
994 .set = 1,
995 },
996 919
997 _DTV_CMD(DTV_ISDBT_PARTIAL_RECEPTION, 1, 0), 920 _DTV_CMD(DTV_ISDBT_PARTIAL_RECEPTION, 1, 0),
998 _DTV_CMD(DTV_ISDBT_SOUND_BROADCASTING, 1, 0), 921 _DTV_CMD(DTV_ISDBT_SOUND_BROADCASTING, 1, 0),
@@ -1035,43 +958,13 @@ static struct dtv_cmds_h dtv_cmds[] = {
1035 _DTV_CMD(DTV_ISDBS_TS_ID, 1, 0), 958 _DTV_CMD(DTV_ISDBS_TS_ID, 1, 0),
1036 959
1037 /* Get */ 960 /* Get */
1038 [DTV_DISEQC_SLAVE_REPLY] = { 961 _DTV_CMD(DTV_DISEQC_SLAVE_REPLY, 0, 1),
1039 .name = "DTV_DISEQC_SLAVE_REPLY", 962 _DTV_CMD(DTV_API_VERSION, 0, 0),
1040 .cmd = DTV_DISEQC_SLAVE_REPLY, 963 _DTV_CMD(DTV_CODE_RATE_HP, 0, 0),
1041 .set = 0, 964 _DTV_CMD(DTV_CODE_RATE_LP, 0, 0),
1042 .buffer = 1, 965 _DTV_CMD(DTV_GUARD_INTERVAL, 0, 0),
1043 }, 966 _DTV_CMD(DTV_TRANSMISSION_MODE, 0, 0),
1044 967 _DTV_CMD(DTV_HIERARCHY, 0, 0),
1045 [DTV_API_VERSION] = {
1046 .name = "DTV_API_VERSION",
1047 .cmd = DTV_API_VERSION,
1048 .set = 0,
1049 },
1050 [DTV_CODE_RATE_HP] = {
1051 .name = "DTV_CODE_RATE_HP",
1052 .cmd = DTV_CODE_RATE_HP,
1053 .set = 0,
1054 },
1055 [DTV_CODE_RATE_LP] = {
1056 .name = "DTV_CODE_RATE_LP",
1057 .cmd = DTV_CODE_RATE_LP,
1058 .set = 0,
1059 },
1060 [DTV_GUARD_INTERVAL] = {
1061 .name = "DTV_GUARD_INTERVAL",
1062 .cmd = DTV_GUARD_INTERVAL,
1063 .set = 0,
1064 },
1065 [DTV_TRANSMISSION_MODE] = {
1066 .name = "DTV_TRANSMISSION_MODE",
1067 .cmd = DTV_TRANSMISSION_MODE,
1068 .set = 0,
1069 },
1070 [DTV_HIERARCHY] = {
1071 .name = "DTV_HIERARCHY",
1072 .cmd = DTV_HIERARCHY,
1073 .set = 0,
1074 },
1075}; 968};
1076 969
1077static void dtv_property_dump(struct dtv_property *tvp) 970static void dtv_property_dump(struct dtv_property *tvp)
@@ -1712,7 +1605,18 @@ static int dvb_frontend_ioctl_legacy(struct inode *inode, struct file *file,
1712 struct dvb_device *dvbdev = file->private_data; 1605 struct dvb_device *dvbdev = file->private_data;
1713 struct dvb_frontend *fe = dvbdev->priv; 1606 struct dvb_frontend *fe = dvbdev->priv;
1714 struct dvb_frontend_private *fepriv = fe->frontend_priv; 1607 struct dvb_frontend_private *fepriv = fe->frontend_priv;
1715 int err = -EOPNOTSUPP; 1608 int cb_err, err = -EOPNOTSUPP;
1609
1610 if (fe->dvb->fe_ioctl_override) {
1611 cb_err = fe->dvb->fe_ioctl_override(fe, cmd, parg,
1612 DVB_FE_IOCTL_PRE);
1613 if (cb_err < 0)
1614 return cb_err;
1615 if (cb_err > 0)
1616 return 0;
1617 /* fe_ioctl_override returning 0 allows
1618 * dvb-core to continue handling the ioctl */
1619 }
1716 1620
1717 switch (cmd) { 1621 switch (cmd) {
1718 case FE_GET_INFO: { 1622 case FE_GET_INFO: {
@@ -1978,6 +1882,13 @@ static int dvb_frontend_ioctl_legacy(struct inode *inode, struct file *file,
1978 break; 1882 break;
1979 }; 1883 };
1980 1884
1885 if (fe->dvb->fe_ioctl_override) {
1886 cb_err = fe->dvb->fe_ioctl_override(fe, cmd, parg,
1887 DVB_FE_IOCTL_POST);
1888 if (cb_err < 0)
1889 return cb_err;
1890 }
1891
1981 return err; 1892 return err;
1982} 1893}
1983 1894
diff --git a/drivers/media/dvb/dvb-core/dvbdev.h b/drivers/media/dvb/dvb-core/dvbdev.h
index 01fc70484743..f7b499d4a3c0 100644
--- a/drivers/media/dvb/dvb-core/dvbdev.h
+++ b/drivers/media/dvb/dvb-core/dvbdev.h
@@ -54,6 +54,8 @@
54 module_param_array(adapter_nr, short, NULL, 0444); \ 54 module_param_array(adapter_nr, short, NULL, 0444); \
55 MODULE_PARM_DESC(adapter_nr, "DVB adapter numbers") 55 MODULE_PARM_DESC(adapter_nr, "DVB adapter numbers")
56 56
57struct dvb_frontend;
58
57struct dvb_adapter { 59struct dvb_adapter {
58 int num; 60 int num;
59 struct list_head list_head; 61 struct list_head list_head;
@@ -69,6 +71,32 @@ struct dvb_adapter {
69 int mfe_shared; /* indicates mutually exclusive frontends */ 71 int mfe_shared; /* indicates mutually exclusive frontends */
70 struct dvb_device *mfe_dvbdev; /* frontend device in use */ 72 struct dvb_device *mfe_dvbdev; /* frontend device in use */
71 struct mutex mfe_lock; /* access lock for thread creation */ 73 struct mutex mfe_lock; /* access lock for thread creation */
74
75 /* Allow the adapter/bridge driver to perform an action before and/or
76 * after the core handles an ioctl:
77 *
78 * DVB_FE_IOCTL_PRE indicates that the ioctl has not yet been handled.
79 * DVB_FE_IOCTL_POST indicates that the ioctl has been handled.
80 *
81 * When DVB_FE_IOCTL_PRE is passed to the callback as the stage arg:
82 *
83 * return 0 to allow dvb-core to handle the ioctl.
84 * return a positive int to prevent dvb-core from handling the ioctl,
85 * and exit without error.
86 * return a negative int to prevent dvb-core from handling the ioctl,
87 * and return that value as an error.
88 *
89 * When DVB_FE_IOCTL_POST is passed to the callback as the stage arg:
90 *
91 * return 0 to allow the dvb_frontend ioctl handler to exit normally.
92 * return a negative int to cause the dvb_frontend ioctl handler to
93 * return that value as an error.
94 */
95#define DVB_FE_IOCTL_PRE 0
96#define DVB_FE_IOCTL_POST 1
97 int (*fe_ioctl_override)(struct dvb_frontend *fe,
98 unsigned int cmd, void *parg,
99 unsigned int stage);
72}; 100};
73 101
74 102
diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig
index 0e4b97fba384..2dee1bf73577 100644
--- a/drivers/media/dvb/dvb-usb/Kconfig
+++ b/drivers/media/dvb/dvb-usb/Kconfig
@@ -322,3 +322,11 @@ config DVB_USB_FRIIO
322 depends on DVB_USB 322 depends on DVB_USB
323 help 323 help
324 Say Y here to support the Japanese DTV receiver Friio. 324 Say Y here to support the Japanese DTV receiver Friio.
325
326config DVB_USB_EC168
327 tristate "E3C EC168 DVB-T USB2.0 support"
328 depends on DVB_USB && EXPERIMENTAL
329 select DVB_EC100
330 select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE
331 help
332 Say Y here to support the E3C EC168 DVB-T USB2.0 receiver.
diff --git a/drivers/media/dvb/dvb-usb/Makefile b/drivers/media/dvb/dvb-usb/Makefile
index 85b83a43d55d..72c92cb69a22 100644
--- a/drivers/media/dvb/dvb-usb/Makefile
+++ b/drivers/media/dvb/dvb-usb/Makefile
@@ -82,6 +82,9 @@ obj-$(CONFIG_DVB_USB_CE6230) += dvb-usb-ce6230.o
82dvb-usb-friio-objs = friio.o friio-fe.o 82dvb-usb-friio-objs = friio.o friio-fe.o
83obj-$(CONFIG_DVB_USB_FRIIO) += dvb-usb-friio.o 83obj-$(CONFIG_DVB_USB_FRIIO) += dvb-usb-friio.o
84 84
85dvb-usb-ec168-objs = ec168.o
86obj-$(CONFIG_DVB_USB_EC168) += dvb-usb-ec168.o
87
85EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/ 88EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/
86# due to tuner-xc3028 89# due to tuner-xc3028
87EXTRA_CFLAGS += -Idrivers/media/common/tuners 90EXTRA_CFLAGS += -Idrivers/media/common/tuners
diff --git a/drivers/media/dvb/dvb-usb/af9015.c b/drivers/media/dvb/dvb-usb/af9015.c
index cf042b309b46..8b60a601fb82 100644
--- a/drivers/media/dvb/dvb-usb/af9015.c
+++ b/drivers/media/dvb/dvb-usb/af9015.c
@@ -730,7 +730,7 @@ static int af9015_read_config(struct usb_device *udev)
730 goto error; 730 goto error;
731 deb_info("%s: IR mode:%d\n", __func__, val); 731 deb_info("%s: IR mode:%d\n", __func__, val);
732 for (i = 0; i < af9015_properties_count; i++) { 732 for (i = 0; i < af9015_properties_count; i++) {
733 if (val == AF9015_IR_MODE_DISABLED || val == 0x04) { 733 if (val == AF9015_IR_MODE_DISABLED) {
734 af9015_properties[i].rc_key_map = NULL; 734 af9015_properties[i].rc_key_map = NULL;
735 af9015_properties[i].rc_key_map_size = 0; 735 af9015_properties[i].rc_key_map_size = 0;
736 } else if (dvb_usb_af9015_remote) { 736 } else if (dvb_usb_af9015_remote) {
@@ -868,6 +868,16 @@ static int af9015_read_config(struct usb_device *udev)
868 af9015_config.ir_table_size = 868 af9015_config.ir_table_size =
869 ARRAY_SIZE(af9015_ir_table_avermedia); 869 ARRAY_SIZE(af9015_ir_table_avermedia);
870 break; 870 break;
871 case USB_VID_MSI_2:
872 af9015_properties[i].rc_key_map =
873 af9015_rc_keys_msi_digivox_iii;
874 af9015_properties[i].rc_key_map_size =
875 ARRAY_SIZE(af9015_rc_keys_msi_digivox_iii);
876 af9015_config.ir_table =
877 af9015_ir_table_msi_digivox_iii;
878 af9015_config.ir_table_size =
879 ARRAY_SIZE(af9015_ir_table_msi_digivox_iii);
880 break;
871 } 881 }
872 } 882 }
873 } 883 }
@@ -1283,6 +1293,8 @@ static struct usb_device_id af9015_usb_table[] = {
1283 {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_MC810)}, 1293 {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_MC810)},
1284 {USB_DEVICE(USB_VID_KYE, USB_PID_GENIUS_TVGO_DVB_T03)}, 1294 {USB_DEVICE(USB_VID_KYE, USB_PID_GENIUS_TVGO_DVB_T03)},
1285/* 25 */{USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_399U_2)}, 1295/* 25 */{USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_399U_2)},
1296 {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_PC160_T)},
1297 {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_SVEON_STV20)},
1286 {0}, 1298 {0},
1287}; 1299};
1288MODULE_DEVICE_TABLE(usb, af9015_usb_table); 1300MODULE_DEVICE_TABLE(usb, af9015_usb_table);
@@ -1296,7 +1308,7 @@ static struct dvb_usb_device_properties af9015_properties[] = {
1296 .firmware = "dvb-usb-af9015.fw", 1308 .firmware = "dvb-usb-af9015.fw",
1297 .no_reconnect = 1, 1309 .no_reconnect = 1,
1298 1310
1299 .size_of_priv = sizeof(struct af9015_state), \ 1311 .size_of_priv = sizeof(struct af9015_state),
1300 1312
1301 .num_adapters = 2, 1313 .num_adapters = 2,
1302 .adapter = { 1314 .adapter = {
@@ -1402,7 +1414,7 @@ static struct dvb_usb_device_properties af9015_properties[] = {
1402 .firmware = "dvb-usb-af9015.fw", 1414 .firmware = "dvb-usb-af9015.fw",
1403 .no_reconnect = 1, 1415 .no_reconnect = 1,
1404 1416
1405 .size_of_priv = sizeof(struct af9015_state), \ 1417 .size_of_priv = sizeof(struct af9015_state),
1406 1418
1407 .num_adapters = 2, 1419 .num_adapters = 2,
1408 .adapter = { 1420 .adapter = {
@@ -1508,7 +1520,7 @@ static struct dvb_usb_device_properties af9015_properties[] = {
1508 .firmware = "dvb-usb-af9015.fw", 1520 .firmware = "dvb-usb-af9015.fw",
1509 .no_reconnect = 1, 1521 .no_reconnect = 1,
1510 1522
1511 .size_of_priv = sizeof(struct af9015_state), \ 1523 .size_of_priv = sizeof(struct af9015_state),
1512 1524
1513 .num_adapters = 2, 1525 .num_adapters = 2,
1514 .adapter = { 1526 .adapter = {
@@ -1554,7 +1566,7 @@ static struct dvb_usb_device_properties af9015_properties[] = {
1554 1566
1555 .i2c_algo = &af9015_i2c_algo, 1567 .i2c_algo = &af9015_i2c_algo,
1556 1568
1557 .num_device_descs = 4, /* max 9 */ 1569 .num_device_descs = 6, /* max 9 */
1558 .devices = { 1570 .devices = {
1559 { 1571 {
1560 .name = "AverMedia AVerTV Volar GPS 805 (A805)", 1572 .name = "AverMedia AVerTV Volar GPS 805 (A805)",
@@ -1577,6 +1589,17 @@ static struct dvb_usb_device_properties af9015_properties[] = {
1577 .cold_ids = {&af9015_usb_table[24], NULL}, 1589 .cold_ids = {&af9015_usb_table[24], NULL},
1578 .warm_ids = {NULL}, 1590 .warm_ids = {NULL},
1579 }, 1591 },
1592 {
1593 .name = "KWorld PlusTV DVB-T PCI Pro Card " \
1594 "(DVB-T PC160-T)",
1595 .cold_ids = {&af9015_usb_table[26], NULL},
1596 .warm_ids = {NULL},
1597 },
1598 {
1599 .name = "Sveon STV20 Tuner USB DVB-T HDTV",
1600 .cold_ids = {&af9015_usb_table[27], NULL},
1601 .warm_ids = {NULL},
1602 },
1580 } 1603 }
1581 }, 1604 },
1582}; 1605};
diff --git a/drivers/media/dvb/dvb-usb/af9015.h b/drivers/media/dvb/dvb-usb/af9015.h
index c41f30e4a1b8..931c8515830d 100644
--- a/drivers/media/dvb/dvb-usb/af9015.h
+++ b/drivers/media/dvb/dvb-usb/af9015.h
@@ -95,6 +95,7 @@ enum af9015_ir_mode {
95 AF9015_IR_MODE_HID, 95 AF9015_IR_MODE_HID,
96 AF9015_IR_MODE_RLC, 96 AF9015_IR_MODE_RLC,
97 AF9015_IR_MODE_RC6, 97 AF9015_IR_MODE_RC6,
98 AF9015_IR_MODE_POLLING, /* just guess */
98}; 99};
99 100
100struct af9015_state { 101struct af9015_state {
@@ -119,6 +120,7 @@ enum af9015_remote {
119/* 5 */ AF9015_REMOTE_AVERMEDIA_KS, 120/* 5 */ AF9015_REMOTE_AVERMEDIA_KS,
120}; 121};
121 122
123/* LeadTek - Y04G0051 */
122/* Leadtek WinFast DTV Dongle Gold */ 124/* Leadtek WinFast DTV Dongle Gold */
123static struct dvb_usb_rc_key af9015_rc_keys_leadtek[] = { 125static struct dvb_usb_rc_key af9015_rc_keys_leadtek[] = {
124 { 0x001e, KEY_1 }, 126 { 0x001e, KEY_1 },
@@ -131,64 +133,96 @@ static struct dvb_usb_rc_key af9015_rc_keys_leadtek[] = {
131 { 0x0025, KEY_8 }, 133 { 0x0025, KEY_8 },
132 { 0x0026, KEY_9 }, 134 { 0x0026, KEY_9 },
133 { 0x0027, KEY_0 }, 135 { 0x0027, KEY_0 },
134 { 0x0028, KEY_ENTER }, 136 { 0x0028, KEY_OK },
135 { 0x004f, KEY_VOLUMEUP }, 137 { 0x004f, KEY_RIGHT },
136 { 0x0050, KEY_VOLUMEDOWN }, 138 { 0x0050, KEY_LEFT },
137 { 0x0051, KEY_CHANNELDOWN }, 139 { 0x0051, KEY_DOWN },
138 { 0x0052, KEY_CHANNELUP }, 140 { 0x0052, KEY_UP },
141 { 0x011a, KEY_POWER2 },
142 { 0x04b4, KEY_TV },
143 { 0x04b3, KEY_RED },
144 { 0x04b2, KEY_GREEN },
145 { 0x04b1, KEY_YELLOW },
146 { 0x04b0, KEY_BLUE },
147 { 0x003d, KEY_TEXT },
148 { 0x0113, KEY_SLEEP },
149 { 0x0010, KEY_MUTE },
150 { 0x0105, KEY_ESC },
151 { 0x0009, KEY_SCREEN },
152 { 0x010f, KEY_MENU },
153 { 0x003f, KEY_CHANNEL },
154 { 0x0013, KEY_REWIND },
155 { 0x0012, KEY_PLAY },
156 { 0x0011, KEY_FASTFORWARD },
157 { 0x0005, KEY_PREVIOUS },
158 { 0x0029, KEY_STOP },
159 { 0x002b, KEY_NEXT },
160 { 0x0041, KEY_EPG },
161 { 0x0019, KEY_VIDEO },
162 { 0x0016, KEY_AUDIO },
163 { 0x0037, KEY_DOT },
164 { 0x002a, KEY_AGAIN },
165 { 0x002c, KEY_CAMERA },
166 { 0x003c, KEY_NEW },
167 { 0x0115, KEY_RECORD },
168 { 0x010b, KEY_TIME },
169 { 0x0043, KEY_VOLUMEUP },
170 { 0x0042, KEY_VOLUMEDOWN },
171 { 0x004b, KEY_CHANNELUP },
172 { 0x004e, KEY_CHANNELDOWN },
139}; 173};
140 174
141static u8 af9015_ir_table_leadtek[] = { 175static u8 af9015_ir_table_leadtek[] = {
142 0x03, 0xfc, 0x00, 0xff, 0x1a, 0x01, 0x00, 176 0x03, 0xfc, 0x00, 0xff, 0x1a, 0x01, 0x00, /* KEY_POWER2 */
143 0x03, 0xfc, 0x56, 0xa9, 0x00, 0x00, 0x00, 177 0x03, 0xfc, 0x56, 0xa9, 0xb4, 0x04, 0x00, /* KEY_TV */
144 0x03, 0xfc, 0x4b, 0xb4, 0x00, 0x00, 0x00, 178 0x03, 0xfc, 0x4b, 0xb4, 0xb3, 0x04, 0x00, /* KEY_RED */
145 0x03, 0xfc, 0x4c, 0xb3, 0xb2, 0x04, 0x00, 179 0x03, 0xfc, 0x4c, 0xb3, 0xb2, 0x04, 0x00, /* KEY_GREEN */
146 0x03, 0xfc, 0x4d, 0xb2, 0x00, 0x00, 0x00, 180 0x03, 0xfc, 0x4d, 0xb2, 0xb1, 0x04, 0x00, /* KEY_YELLOW */
147 0x03, 0xfc, 0x4e, 0xb1, 0x00, 0x00, 0x00, 181 0x03, 0xfc, 0x4e, 0xb1, 0xb0, 0x04, 0x00, /* KEY_BLUE */
148 0x03, 0xfc, 0x1f, 0xe0, 0x3d, 0x00, 0x00, 182 0x03, 0xfc, 0x1f, 0xe0, 0x3d, 0x00, 0x00, /* KEY_TEXT */
149 0x03, 0xfc, 0x40, 0xbf, 0x13, 0x01, 0x00, 183 0x03, 0xfc, 0x40, 0xbf, 0x13, 0x01, 0x00, /* KEY_SLEEP */
150 0x03, 0xfc, 0x14, 0xeb, 0x10, 0x00, 0x00, 184 0x03, 0xfc, 0x14, 0xeb, 0x10, 0x00, 0x00, /* KEY_MUTE */
151 0x03, 0xfc, 0x49, 0xb6, 0x05, 0x01, 0x00, 185 0x03, 0xfc, 0x49, 0xb6, 0x05, 0x01, 0x00, /* KEY_ESC */
152 0x03, 0xfc, 0x50, 0xaf, 0x29, 0x00, 0x00, 186 0x03, 0xfc, 0x50, 0xaf, 0x29, 0x00, 0x00, /* KEY_STOP (1)*/
153 0x03, 0xfc, 0x0c, 0xf3, 0x52, 0x00, 0x00, 187 0x03, 0xfc, 0x0c, 0xf3, 0x52, 0x00, 0x00, /* KEY_UP */
154 0x03, 0xfc, 0x03, 0xfc, 0x09, 0x00, 0x00, 188 0x03, 0xfc, 0x03, 0xfc, 0x09, 0x00, 0x00, /* KEY_SCREEN */
155 0x03, 0xfc, 0x08, 0xf7, 0x50, 0x00, 0x00, 189 0x03, 0xfc, 0x08, 0xf7, 0x50, 0x00, 0x00, /* KEY_LEFT */
156 0x03, 0xfc, 0x13, 0xec, 0x28, 0x00, 0x00, 190 0x03, 0xfc, 0x13, 0xec, 0x28, 0x00, 0x00, /* KEY_OK (1) */
157 0x03, 0xfc, 0x04, 0xfb, 0x4f, 0x00, 0x00, 191 0x03, 0xfc, 0x04, 0xfb, 0x4f, 0x00, 0x00, /* KEY_RIGHT */
158 0x03, 0xfc, 0x4f, 0xb0, 0x0f, 0x01, 0x00, 192 0x03, 0xfc, 0x4f, 0xb0, 0x0f, 0x01, 0x00, /* KEY_MENU */
159 0x03, 0xfc, 0x10, 0xef, 0x51, 0x00, 0x00, 193 0x03, 0xfc, 0x10, 0xef, 0x51, 0x00, 0x00, /* KEY_DOWN */
160 0x03, 0xfc, 0x51, 0xae, 0x3f, 0x00, 0x00, 194 0x03, 0xfc, 0x51, 0xae, 0x3f, 0x00, 0x00, /* KEY_CHANNEL */
161 0x03, 0xfc, 0x42, 0xbd, 0x13, 0x00, 0x00, 195 0x03, 0xfc, 0x42, 0xbd, 0x13, 0x00, 0x00, /* KEY_REWIND */
162 0x03, 0xfc, 0x43, 0xbc, 0x00, 0x00, 0x00, 196 0x03, 0xfc, 0x43, 0xbc, 0x12, 0x00, 0x00, /* KEY_PLAY */
163 0x03, 0xfc, 0x44, 0xbb, 0x11, 0x00, 0x00, 197 0x03, 0xfc, 0x44, 0xbb, 0x11, 0x00, 0x00, /* KEY_FASTFORWARD */
164 0x03, 0xfc, 0x52, 0xad, 0x19, 0x00, 0x00, 198 0x03, 0xfc, 0x52, 0xad, 0x19, 0x00, 0x00, /* KEY_VIDEO (1) */
165 0x03, 0xfc, 0x54, 0xab, 0x05, 0x00, 0x00, 199 0x03, 0xfc, 0x54, 0xab, 0x05, 0x00, 0x00, /* KEY_PREVIOUS */
166 0x03, 0xfc, 0x46, 0xb9, 0x29, 0x00, 0x00, 200 0x03, 0xfc, 0x46, 0xb9, 0x29, 0x00, 0x00, /* KEY_STOP (2) */
167 0x03, 0xfc, 0x55, 0xaa, 0x2b, 0x00, 0x00, 201 0x03, 0xfc, 0x55, 0xaa, 0x2b, 0x00, 0x00, /* KEY_NEXT */
168 0x03, 0xfc, 0x53, 0xac, 0x41, 0x00, 0x00, 202 0x03, 0xfc, 0x53, 0xac, 0x41, 0x00, 0x00, /* KEY_EPG */
169 0x03, 0xfc, 0x05, 0xfa, 0x1e, 0x00, 0x00, 203 0x03, 0xfc, 0x05, 0xfa, 0x1e, 0x00, 0x00, /* KEY_1 */
170 0x03, 0xfc, 0x06, 0xf9, 0x1f, 0x00, 0x00, 204 0x03, 0xfc, 0x06, 0xf9, 0x1f, 0x00, 0x00, /* KEY_2 */
171 0x03, 0xfc, 0x07, 0xf8, 0x20, 0x00, 0x00, 205 0x03, 0xfc, 0x07, 0xf8, 0x20, 0x00, 0x00, /* KEY_3 */
172 0x03, 0xfc, 0x1e, 0xe1, 0x19, 0x00, 0x00, 206 0x03, 0xfc, 0x1e, 0xe1, 0x19, 0x00, 0x00, /* KEY_VIDEO (2) */
173 0x03, 0xfc, 0x09, 0xf6, 0x21, 0x00, 0x00, 207 0x03, 0xfc, 0x09, 0xf6, 0x21, 0x00, 0x00, /* KEY_4 */
174 0x03, 0xfc, 0x0a, 0xf5, 0x22, 0x00, 0x00, 208 0x03, 0xfc, 0x0a, 0xf5, 0x22, 0x00, 0x00, /* KEY_5 */
175 0x03, 0xfc, 0x0b, 0xf4, 0x23, 0x00, 0x00, 209 0x03, 0xfc, 0x0b, 0xf4, 0x23, 0x00, 0x00, /* KEY_6 */
176 0x03, 0xfc, 0x1b, 0xe4, 0x16, 0x00, 0x00, 210 0x03, 0xfc, 0x1b, 0xe4, 0x16, 0x00, 0x00, /* KEY_AUDIO */
177 0x03, 0xfc, 0x0d, 0xf2, 0x24, 0x00, 0x00, 211 0x03, 0xfc, 0x0d, 0xf2, 0x24, 0x00, 0x00, /* KEY_7 */
178 0x03, 0xfc, 0x0e, 0xf1, 0x25, 0x00, 0x00, 212 0x03, 0xfc, 0x0e, 0xf1, 0x25, 0x00, 0x00, /* KEY_8 */
179 0x03, 0xfc, 0x0f, 0xf0, 0x26, 0x00, 0x00, 213 0x03, 0xfc, 0x0f, 0xf0, 0x26, 0x00, 0x00, /* KEY_9 */
180 0x03, 0xfc, 0x16, 0xe9, 0x28, 0x00, 0x00, 214 0x03, 0xfc, 0x16, 0xe9, 0x28, 0x00, 0x00, /* KEY_OK (2) */
181 0x03, 0xfc, 0x41, 0xbe, 0x37, 0x00, 0x00, 215 0x03, 0xfc, 0x41, 0xbe, 0x37, 0x00, 0x00, /* KEY_DOT */
182 0x03, 0xfc, 0x12, 0xed, 0x27, 0x00, 0x00, 216 0x03, 0xfc, 0x12, 0xed, 0x27, 0x00, 0x00, /* KEY_0 */
183 0x03, 0xfc, 0x11, 0xee, 0x2a, 0x00, 0x00, 217 0x03, 0xfc, 0x11, 0xee, 0x2a, 0x00, 0x00, /* KEY_AGAIN */
184 0x03, 0xfc, 0x48, 0xb7, 0x2c, 0x00, 0x00, 218 0x03, 0xfc, 0x48, 0xb7, 0x2c, 0x00, 0x00, /* KEY_CAMERA */
185 0x03, 0xfc, 0x4a, 0xb5, 0x3c, 0x00, 0x00, 219 0x03, 0xfc, 0x4a, 0xb5, 0x3c, 0x00, 0x00, /* KEY_NEW */
186 0x03, 0xfc, 0x47, 0xb8, 0x15, 0x01, 0x00, 220 0x03, 0xfc, 0x47, 0xb8, 0x15, 0x01, 0x00, /* KEY_RECORD */
187 0x03, 0xfc, 0x45, 0xba, 0x0b, 0x01, 0x00, 221 0x03, 0xfc, 0x45, 0xba, 0x0b, 0x01, 0x00, /* KEY_TIME */
188 0x03, 0xfc, 0x5e, 0xa1, 0x43, 0x00, 0x00, 222 0x03, 0xfc, 0x5e, 0xa1, 0x43, 0x00, 0x00, /* KEY_VOLUMEUP */
189 0x03, 0xfc, 0x5a, 0xa5, 0x42, 0x00, 0x00, 223 0x03, 0xfc, 0x5a, 0xa5, 0x42, 0x00, 0x00, /* KEY_VOLUMEDOWN */
190 0x03, 0xfc, 0x5b, 0xa4, 0x4b, 0x00, 0x00, 224 0x03, 0xfc, 0x5b, 0xa4, 0x4b, 0x00, 0x00, /* KEY_CHANNELUP */
191 0x03, 0xfc, 0x5f, 0xa0, 0x4e, 0x00, 0x00, 225 0x03, 0xfc, 0x5f, 0xa0, 0x4e, 0x00, 0x00, /* KEY_CHANNELDOWN */
192}; 226};
193 227
194/* TwinHan AzureWave AD-TU700(704J) */ 228/* TwinHan AzureWave AD-TU700(704J) */
@@ -746,4 +780,75 @@ static u8 af9015_ir_table_trekstor[] = {
746 0x00, 0xff, 0x84, 0x7b, 0x27, 0x07, 0x00, 780 0x00, 0xff, 0x84, 0x7b, 0x27, 0x07, 0x00,
747}; 781};
748 782
783/* MSI DIGIVOX mini III */
784static struct dvb_usb_rc_key af9015_rc_keys_msi_digivox_iii[] = {
785 { 0x0713, KEY_POWER }, /* [red power button] */
786 { 0x073b, KEY_VIDEO }, /* Source */
787 { 0x073e, KEY_ZOOM }, /* Zoom */
788 { 0x070b, KEY_POWER2 }, /* ShutDown */
789 { 0x071e, KEY_1 },
790 { 0x071f, KEY_2 },
791 { 0x0720, KEY_3 },
792 { 0x0721, KEY_4 },
793 { 0x0722, KEY_5 },
794 { 0x0723, KEY_6 },
795 { 0x0724, KEY_7 },
796 { 0x0725, KEY_8 },
797 { 0x0726, KEY_9 },
798 { 0x0727, KEY_0 },
799 { 0x0752, KEY_CHANNELUP }, /* CH+ */
800 { 0x0751, KEY_CHANNELDOWN }, /* CH- */
801 { 0x0750, KEY_VOLUMEUP }, /* Vol+ */
802 { 0x074f, KEY_VOLUMEDOWN }, /* Vol- */
803 { 0x0705, KEY_ESC }, /* [back up arrow] */
804 { 0x0708, KEY_OK }, /* [enter arrow] */
805 { 0x073f, KEY_RECORD }, /* Rec */
806 { 0x0716, KEY_STOP }, /* Stop */
807 { 0x072a, KEY_PLAY }, /* Play */
808 { 0x073c, KEY_MUTE }, /* Mute */
809 { 0x0718, KEY_UP },
810 { 0x0707, KEY_DOWN },
811 { 0x070f, KEY_LEFT },
812 { 0x0715, KEY_RIGHT },
813 { 0x0736, KEY_RED },
814 { 0x0737, KEY_GREEN },
815 { 0x072d, KEY_YELLOW },
816 { 0x072e, KEY_BLUE },
817};
818
819static u8 af9015_ir_table_msi_digivox_iii[] = {
820 0x61, 0xd6, 0x43, 0xbc, 0x13, 0x07, 0x00, /* KEY_POWER */
821 0x61, 0xd6, 0x01, 0xfe, 0x3b, 0x07, 0x00, /* KEY_VIDEO */
822 0x61, 0xd6, 0x0b, 0xf4, 0x3e, 0x07, 0x00, /* KEY_ZOOM */
823 0x61, 0xd6, 0x03, 0xfc, 0x0b, 0x07, 0x00, /* KEY_POWER2 */
824 0x61, 0xd6, 0x04, 0xfb, 0x1e, 0x07, 0x00, /* KEY_1 */
825 0x61, 0xd6, 0x08, 0xf7, 0x1f, 0x07, 0x00, /* KEY_2 */
826 0x61, 0xd6, 0x02, 0xfd, 0x20, 0x07, 0x00, /* KEY_3 */
827 0x61, 0xd6, 0x0f, 0xf0, 0x21, 0x07, 0x00, /* KEY_4 */
828 0x61, 0xd6, 0x05, 0xfa, 0x22, 0x07, 0x00, /* KEY_5 */
829 0x61, 0xd6, 0x06, 0xf9, 0x23, 0x07, 0x00, /* KEY_6 */
830 0x61, 0xd6, 0x0c, 0xf3, 0x24, 0x07, 0x00, /* KEY_7 */
831 0x61, 0xd6, 0x0d, 0xf2, 0x25, 0x07, 0x00, /* KEY_8 */
832 0x61, 0xd6, 0x0a, 0xf5, 0x26, 0x07, 0x00, /* KEY_9 */
833 0x61, 0xd6, 0x11, 0xee, 0x27, 0x07, 0x00, /* KEY_0 */
834 0x61, 0xd6, 0x09, 0xf6, 0x52, 0x07, 0x00, /* KEY_CHANNELUP */
835 0x61, 0xd6, 0x07, 0xf8, 0x51, 0x07, 0x00, /* KEY_CHANNELDOWN */
836 0x61, 0xd6, 0x0e, 0xf1, 0x50, 0x07, 0x00, /* KEY_VOLUMEUP */
837 0x61, 0xd6, 0x13, 0xec, 0x4f, 0x07, 0x00, /* KEY_VOLUMEDOWN */
838 0x61, 0xd6, 0x10, 0xef, 0x05, 0x07, 0x00, /* KEY_ESC */
839 0x61, 0xd6, 0x12, 0xed, 0x08, 0x07, 0x00, /* KEY_OK */
840 0x61, 0xd6, 0x14, 0xeb, 0x3f, 0x07, 0x00, /* KEY_RECORD */
841 0x61, 0xd6, 0x15, 0xea, 0x16, 0x07, 0x00, /* KEY_STOP */
842 0x61, 0xd6, 0x16, 0xe9, 0x2a, 0x07, 0x00, /* KEY_PLAY */
843 0x61, 0xd6, 0x17, 0xe8, 0x3c, 0x07, 0x00, /* KEY_MUTE */
844 0x61, 0xd6, 0x18, 0xe7, 0x18, 0x07, 0x00, /* KEY_UP */
845 0x61, 0xd6, 0x19, 0xe6, 0x07, 0x07, 0x00, /* KEY_DOWN */
846 0x61, 0xd6, 0x1a, 0xe5, 0x0f, 0x07, 0x00, /* KEY_LEFT */
847 0x61, 0xd6, 0x1b, 0xe4, 0x15, 0x07, 0x00, /* KEY_RIGHT */
848 0x61, 0xd6, 0x1c, 0xe3, 0x36, 0x07, 0x00, /* KEY_RED */
849 0x61, 0xd6, 0x1d, 0xe2, 0x37, 0x07, 0x00, /* KEY_GREEN */
850 0x61, 0xd6, 0x1e, 0xe1, 0x2d, 0x07, 0x00, /* KEY_YELLOW */
851 0x61, 0xd6, 0x1f, 0xe0, 0x2e, 0x07, 0x00, /* KEY_BLUE */
852};
853
749#endif 854#endif
diff --git a/drivers/media/dvb/dvb-usb/cxusb.c b/drivers/media/dvb/dvb-usb/cxusb.c
index 2a53dd096eef..05fb28e9c69e 100644
--- a/drivers/media/dvb/dvb-usb/cxusb.c
+++ b/drivers/media/dvb/dvb-usb/cxusb.c
@@ -36,9 +36,11 @@
36#include "tuner-xc2028.h" 36#include "tuner-xc2028.h"
37#include "tuner-simple.h" 37#include "tuner-simple.h"
38#include "mxl5005s.h" 38#include "mxl5005s.h"
39#include "max2165.h"
39#include "dib7000p.h" 40#include "dib7000p.h"
40#include "dib0070.h" 41#include "dib0070.h"
41#include "lgs8gxx.h" 42#include "lgs8gxx.h"
43#include "atbm8830.h"
42 44
43/* debug */ 45/* debug */
44static int dvb_usb_cxusb_debug; 46static int dvb_usb_cxusb_debug;
@@ -714,6 +716,11 @@ static struct mxl5005s_config d680_dmb_tuner = {
714 .AgcMasterByte = 0x00, 716 .AgcMasterByte = 0x00,
715}; 717};
716 718
719static struct max2165_config mygica_d689_max2165_cfg = {
720 .i2c_address = 0x60,
721 .osc_clk = 20
722};
723
717/* Callbacks for DVB USB */ 724/* Callbacks for DVB USB */
718static int cxusb_fmd1216me_tuner_attach(struct dvb_usb_adapter *adap) 725static int cxusb_fmd1216me_tuner_attach(struct dvb_usb_adapter *adap)
719{ 726{
@@ -813,6 +820,14 @@ static int cxusb_d680_dmb_tuner_attach(struct dvb_usb_adapter *adap)
813 return (fe == NULL) ? -EIO : 0; 820 return (fe == NULL) ? -EIO : 0;
814} 821}
815 822
823static int cxusb_mygica_d689_tuner_attach(struct dvb_usb_adapter *adap)
824{
825 struct dvb_frontend *fe;
826 fe = dvb_attach(max2165_attach, adap->fe,
827 &adap->dev->i2c_adap, &mygica_d689_max2165_cfg);
828 return (fe == NULL) ? -EIO : 0;
829}
830
816static int cxusb_cx22702_frontend_attach(struct dvb_usb_adapter *adap) 831static int cxusb_cx22702_frontend_attach(struct dvb_usb_adapter *adap)
817{ 832{
818 u8 b; 833 u8 b;
@@ -1160,6 +1175,55 @@ static int cxusb_d680_dmb_frontend_attach(struct dvb_usb_adapter *adap)
1160 return 0; 1175 return 0;
1161} 1176}
1162 1177
1178static struct atbm8830_config mygica_d689_atbm8830_cfg = {
1179 .prod = ATBM8830_PROD_8830,
1180 .demod_address = 0x40,
1181 .serial_ts = 0,
1182 .ts_sampling_edge = 1,
1183 .ts_clk_gated = 0,
1184 .osc_clk_freq = 30400, /* in kHz */
1185 .if_freq = 0, /* zero IF */
1186 .zif_swap_iq = 1,
1187};
1188
1189static int cxusb_mygica_d689_frontend_attach(struct dvb_usb_adapter *adap)
1190{
1191 struct dvb_usb_device *d = adap->dev;
1192
1193 /* Select required USB configuration */
1194 if (usb_set_interface(d->udev, 0, 0) < 0)
1195 err("set interface failed");
1196
1197 /* Unblock all USB pipes */
1198 usb_clear_halt(d->udev,
1199 usb_sndbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint));
1200 usb_clear_halt(d->udev,
1201 usb_rcvbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint));
1202 usb_clear_halt(d->udev,
1203 usb_rcvbulkpipe(d->udev, d->props.adapter[0].stream.endpoint));
1204
1205
1206 /* Reset the tuner */
1207 if (cxusb_d680_dmb_gpio_tuner(d, 0x07, 0) < 0) {
1208 err("clear tuner gpio failed");
1209 return -EIO;
1210 }
1211 msleep(100);
1212 if (cxusb_d680_dmb_gpio_tuner(d, 0x07, 1) < 0) {
1213 err("set tuner gpio failed");
1214 return -EIO;
1215 }
1216 msleep(100);
1217
1218 /* Attach frontend */
1219 adap->fe = dvb_attach(atbm8830_attach, &mygica_d689_atbm8830_cfg,
1220 &d->i2c_adap);
1221 if (adap->fe == NULL)
1222 return -EIO;
1223
1224 return 0;
1225}
1226
1163/* 1227/*
1164 * DViCO has shipped two devices with the same USB ID, but only one of them 1228 * DViCO has shipped two devices with the same USB ID, but only one of them
1165 * needs a firmware download. Check the device class details to see if they 1229 * needs a firmware download. Check the device class details to see if they
@@ -1240,6 +1304,7 @@ static struct dvb_usb_device_properties cxusb_bluebird_nano2_properties;
1240static struct dvb_usb_device_properties cxusb_bluebird_nano2_needsfirmware_properties; 1304static struct dvb_usb_device_properties cxusb_bluebird_nano2_needsfirmware_properties;
1241static struct dvb_usb_device_properties cxusb_aver_a868r_properties; 1305static struct dvb_usb_device_properties cxusb_aver_a868r_properties;
1242static struct dvb_usb_device_properties cxusb_d680_dmb_properties; 1306static struct dvb_usb_device_properties cxusb_d680_dmb_properties;
1307static struct dvb_usb_device_properties cxusb_mygica_d689_properties;
1243 1308
1244static int cxusb_probe(struct usb_interface *intf, 1309static int cxusb_probe(struct usb_interface *intf,
1245 const struct usb_device_id *id) 1310 const struct usb_device_id *id)
@@ -1268,6 +1333,8 @@ static int cxusb_probe(struct usb_interface *intf,
1268 THIS_MODULE, NULL, adapter_nr) || 1333 THIS_MODULE, NULL, adapter_nr) ||
1269 0 == dvb_usb_device_init(intf, &cxusb_d680_dmb_properties, 1334 0 == dvb_usb_device_init(intf, &cxusb_d680_dmb_properties,
1270 THIS_MODULE, NULL, adapter_nr) || 1335 THIS_MODULE, NULL, adapter_nr) ||
1336 0 == dvb_usb_device_init(intf, &cxusb_mygica_d689_properties,
1337 THIS_MODULE, NULL, adapter_nr) ||
1271 0) 1338 0)
1272 return 0; 1339 return 0;
1273 1340
@@ -1294,6 +1361,7 @@ static struct usb_device_id cxusb_table [] = {
1294 { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_A868R) }, 1361 { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_A868R) },
1295 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_4_REV_2) }, 1362 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_4_REV_2) },
1296 { USB_DEVICE(USB_VID_CONEXANT, USB_PID_CONEXANT_D680_DMB) }, 1363 { USB_DEVICE(USB_VID_CONEXANT, USB_PID_CONEXANT_D680_DMB) },
1364 { USB_DEVICE(USB_VID_CONEXANT, USB_PID_MYGICA_D689) },
1297 {} /* Terminating entry */ 1365 {} /* Terminating entry */
1298}; 1366};
1299MODULE_DEVICE_TABLE (usb, cxusb_table); 1367MODULE_DEVICE_TABLE (usb, cxusb_table);
@@ -1837,6 +1905,55 @@ static struct dvb_usb_device_properties cxusb_d680_dmb_properties = {
1837 } 1905 }
1838}; 1906};
1839 1907
1908static struct dvb_usb_device_properties cxusb_mygica_d689_properties = {
1909 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1910
1911 .usb_ctrl = CYPRESS_FX2,
1912
1913 .size_of_priv = sizeof(struct cxusb_state),
1914
1915 .num_adapters = 1,
1916 .adapter = {
1917 {
1918 .streaming_ctrl = cxusb_d680_dmb_streaming_ctrl,
1919 .frontend_attach = cxusb_mygica_d689_frontend_attach,
1920 .tuner_attach = cxusb_mygica_d689_tuner_attach,
1921
1922 /* parameter for the MPEG2-data transfer */
1923 .stream = {
1924 .type = USB_BULK,
1925 .count = 5,
1926 .endpoint = 0x02,
1927 .u = {
1928 .bulk = {
1929 .buffersize = 8192,
1930 }
1931 }
1932 },
1933 },
1934 },
1935
1936 .power_ctrl = cxusb_d680_dmb_power_ctrl,
1937
1938 .i2c_algo = &cxusb_i2c_algo,
1939
1940 .generic_bulk_ctrl_endpoint = 0x01,
1941
1942 .rc_interval = 100,
1943 .rc_key_map = d680_dmb_rc_keys,
1944 .rc_key_map_size = ARRAY_SIZE(d680_dmb_rc_keys),
1945 .rc_query = cxusb_d680_dmb_rc_query,
1946
1947 .num_device_descs = 1,
1948 .devices = {
1949 {
1950 "Mygica D689 DMB-TH",
1951 { NULL },
1952 { &cxusb_table[19], NULL },
1953 },
1954 }
1955};
1956
1840static struct usb_driver cxusb_driver = { 1957static struct usb_driver cxusb_driver = {
1841 .name = "dvb_usb_cxusb", 1958 .name = "dvb_usb_cxusb",
1842 .probe = cxusb_probe, 1959 .probe = cxusb_probe,
diff --git a/drivers/media/dvb/dvb-usb/dib0700_devices.c b/drivers/media/dvb/dvb-usb/dib0700_devices.c
index 6bd8951ea02b..684146f98eb7 100644
--- a/drivers/media/dvb/dvb-usb/dib0700_devices.c
+++ b/drivers/media/dvb/dvb-usb/dib0700_devices.c
@@ -558,8 +558,7 @@ static int dib0700_rc_query_legacy(struct dvb_usb_device *d, u32 *event,
558struct dib0700_rc_response { 558struct dib0700_rc_response {
559 u8 report_id; 559 u8 report_id;
560 u8 data_state; 560 u8 data_state;
561 u8 system_msb; 561 u16 system;
562 u8 system_lsb;
563 u8 data; 562 u8 data;
564 u8 not_data; 563 u8 not_data;
565}; 564};
@@ -589,37 +588,50 @@ static int dib0700_rc_query_v1_20(struct dvb_usb_device *d, u32 *event,
589 return 0; 588 return 0;
590 } 589 }
591 590
592 if (actlen != sizeof(buf)) {
593 /* We didn't get back the 6 byte message we expected */
594 err("Unexpected RC response size [%d]", actlen);
595 return -1;
596 }
597 591
598 poll_reply.report_id = buf[0]; 592 switch (dvb_usb_dib0700_ir_proto) {
599 poll_reply.data_state = buf[1]; 593 case 0:
600 poll_reply.system_msb = buf[2]; 594 poll_reply.report_id = 0;
601 poll_reply.system_lsb = buf[3]; 595 poll_reply.data_state = 1;
602 poll_reply.data = buf[4]; 596 poll_reply.system = buf[2];
603 poll_reply.not_data = buf[5]; 597 poll_reply.data = buf[4];
598 poll_reply.not_data = buf[5];
599
600 /* NEC protocol sends repeat code as 0 0 0 FF */
601 if ((poll_reply.system == 0x00) && (poll_reply.data == 0x00)
602 && (poll_reply.not_data == 0xff)) {
603 poll_reply.data_state = 2;
604 break;
605 }
606 break;
607 default:
608 if (actlen != sizeof(buf)) {
609 /* We didn't get back the 6 byte message we expected */
610 err("Unexpected RC response size [%d]", actlen);
611 return -1;
612 }
613
614 poll_reply.report_id = buf[0];
615 poll_reply.data_state = buf[1];
616 poll_reply.system = (buf[2] << 8) | buf[3];
617 poll_reply.data = buf[4];
618 poll_reply.not_data = buf[5];
604 619
605 /* 620 break;
606 info("rid=%02x ds=%02x sm=%02x sl=%02x d=%02x nd=%02x\n", 621 }
607 poll_reply.report_id, poll_reply.data_state,
608 poll_reply.system_msb, poll_reply.system_lsb,
609 poll_reply.data, poll_reply.not_data);
610 */
611 622
612 if ((poll_reply.data + poll_reply.not_data) != 0xff) { 623 if ((poll_reply.data + poll_reply.not_data) != 0xff) {
613 /* Key failed integrity check */ 624 /* Key failed integrity check */
614 err("key failed integrity check: %02x %02x %02x %02x", 625 err("key failed integrity check: %04x %02x %02x",
615 poll_reply.system_msb, poll_reply.system_lsb, 626 poll_reply.system,
616 poll_reply.data, poll_reply.not_data); 627 poll_reply.data, poll_reply.not_data);
617 return -1; 628 return -1;
618 } 629 }
619 630
631
620 /* Find the key in the map */ 632 /* Find the key in the map */
621 for (i = 0; i < d->props.rc_key_map_size; i++) { 633 for (i = 0; i < d->props.rc_key_map_size; i++) {
622 if (rc5_custom(&keymap[i]) == poll_reply.system_lsb && 634 if (rc5_custom(&keymap[i]) == (poll_reply.system & 0xff) &&
623 rc5_data(&keymap[i]) == poll_reply.data) { 635 rc5_data(&keymap[i]) == poll_reply.data) {
624 *event = keymap[i].event; 636 *event = keymap[i].event;
625 found = 1; 637 found = 1;
@@ -628,8 +640,8 @@ static int dib0700_rc_query_v1_20(struct dvb_usb_device *d, u32 *event,
628 } 640 }
629 641
630 if (found == 0) { 642 if (found == 0) {
631 err("Unknown remote controller key: %02x %02x %02x %02x", 643 err("Unknown remote controller key: %04x %02x %02x",
632 poll_reply.system_msb, poll_reply.system_lsb, 644 poll_reply.system,
633 poll_reply.data, poll_reply.not_data); 645 poll_reply.data, poll_reply.not_data);
634 d->last_event = 0; 646 d->last_event = 0;
635 return 0; 647 return 0;
@@ -874,6 +886,49 @@ static struct dvb_usb_rc_key dib0700_rc_keys[] = {
874 { 0x1d37, KEY_RECORD }, 886 { 0x1d37, KEY_RECORD },
875 { 0x1d3b, KEY_GOTO }, 887 { 0x1d3b, KEY_GOTO },
876 { 0x1d3d, KEY_POWER }, 888 { 0x1d3d, KEY_POWER },
889
890 /* Key codes for the Pixelview SBTVD remote (proto NEC) */
891 { 0x8613, KEY_MUTE },
892 { 0x8612, KEY_POWER },
893 { 0x8601, KEY_1 },
894 { 0x8602, KEY_2 },
895 { 0x8603, KEY_3 },
896 { 0x8604, KEY_4 },
897 { 0x8605, KEY_5 },
898 { 0x8606, KEY_6 },
899 { 0x8607, KEY_7 },
900 { 0x8608, KEY_8 },
901 { 0x8609, KEY_9 },
902 { 0x8600, KEY_0 },
903 { 0x860d, KEY_CHANNELUP },
904 { 0x8619, KEY_CHANNELDOWN },
905 { 0x8610, KEY_VOLUMEUP },
906 { 0x860c, KEY_VOLUMEDOWN },
907
908 { 0x860a, KEY_CAMERA },
909 { 0x860b, KEY_ZOOM },
910 { 0x861b, KEY_BACKSPACE },
911 { 0x8615, KEY_ENTER },
912
913 { 0x861d, KEY_UP },
914 { 0x861e, KEY_DOWN },
915 { 0x860e, KEY_LEFT },
916 { 0x860f, KEY_RIGHT },
917
918 { 0x8618, KEY_RECORD },
919 { 0x861a, KEY_STOP },
920
921 /* Key codes for the EvolutePC TVWay+ remote (proto NEC) */
922 { 0x7a00, KEY_MENU },
923 { 0x7a01, KEY_RECORD },
924 { 0x7a02, KEY_PLAY },
925 { 0x7a03, KEY_STOP },
926 { 0x7a10, KEY_CHANNELUP },
927 { 0x7a11, KEY_CHANNELDOWN },
928 { 0x7a12, KEY_VOLUMEUP },
929 { 0x7a13, KEY_VOLUMEDOWN },
930 { 0x7a40, KEY_POWER },
931 { 0x7a41, KEY_MUTE },
877}; 932};
878 933
879/* STK7700P: Hauppauge Nova-T Stick, AVerMedia Volar */ 934/* STK7700P: Hauppauge Nova-T Stick, AVerMedia Volar */
@@ -1133,6 +1188,7 @@ static struct dib0070_config dib7770p_dib0070_config = {
1133 .clock_khz = 12000, 1188 .clock_khz = 12000,
1134 .clock_pad_drive = 0, 1189 .clock_pad_drive = 0,
1135 .flip_chip = 1, 1190 .flip_chip = 1,
1191 .charge_pump = 2,
1136}; 1192};
1137 1193
1138static int dib7070_set_param_override(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep) 1194static int dib7070_set_param_override(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep)
@@ -1209,6 +1265,16 @@ static int dib7070p_tuner_attach(struct dvb_usb_adapter *adap)
1209 return 0; 1265 return 0;
1210} 1266}
1211 1267
1268static int stk70x0p_pid_filter(struct dvb_usb_adapter *adapter, int index, u16 pid, int onoff)
1269{
1270 return dib7000p_pid_filter(adapter->fe, index, pid, onoff);
1271}
1272
1273static int stk70x0p_pid_filter_ctrl(struct dvb_usb_adapter *adapter, int onoff)
1274{
1275 return dib7000p_pid_filter_ctrl(adapter->fe, onoff);
1276}
1277
1212static struct dibx000_bandwidth_config dib7070_bw_config_12_mhz = { 1278static struct dibx000_bandwidth_config dib7070_bw_config_12_mhz = {
1213 60000, 15000, // internal, sampling 1279 60000, 15000, // internal, sampling
1214 1, 20, 3, 1, 0, // pll_cfg: prediv, ratio, range, reset, bypass 1280 1, 20, 3, 1, 0, // pll_cfg: prediv, ratio, range, reset, bypass
@@ -1500,6 +1566,15 @@ static int dib807x_tuner_attach(struct dvb_usb_adapter *adap)
1500 return 0; 1566 return 0;
1501} 1567}
1502 1568
1569static int stk807x_pid_filter(struct dvb_usb_adapter *adapter, int index, u16 pid, int onoff)
1570{
1571 return dib8000_pid_filter(adapter->fe, index, pid, onoff);
1572}
1573
1574static int stk807x_pid_filter_ctrl(struct dvb_usb_adapter *adapter, int onoff)
1575{
1576 return dib8000_pid_filter_ctrl(adapter->fe, onoff);
1577}
1503 1578
1504/* STK807x */ 1579/* STK807x */
1505static int stk807x_frontend_attach(struct dvb_usb_adapter *adap) 1580static int stk807x_frontend_attach(struct dvb_usb_adapter *adap)
@@ -1861,6 +1936,7 @@ struct usb_device_id dib0700_usb_id_table[] = {
1861 { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK807XPVR) }, 1936 { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK807XPVR) },
1862 { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK807XP) }, 1937 { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK807XP) },
1863 { USB_DEVICE(USB_VID_PIXELVIEW, USB_PID_PIXELVIEW_SBTVD) }, 1938 { USB_DEVICE(USB_VID_PIXELVIEW, USB_PID_PIXELVIEW_SBTVD) },
1939 { USB_DEVICE(USB_VID_EVOLUTEPC, USB_PID_TVWAY_PLUS) },
1864 { 0 } /* Terminating entry */ 1940 { 0 } /* Terminating entry */
1865}; 1941};
1866MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table); 1942MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table);
@@ -1895,6 +1971,10 @@ struct dvb_usb_device_properties dib0700_devices[] = {
1895 .num_adapters = 1, 1971 .num_adapters = 1,
1896 .adapter = { 1972 .adapter = {
1897 { 1973 {
1974 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
1975 .pid_filter_count = 32,
1976 .pid_filter = stk70x0p_pid_filter,
1977 .pid_filter_ctrl = stk70x0p_pid_filter_ctrl,
1898 .frontend_attach = stk7700p_frontend_attach, 1978 .frontend_attach = stk7700p_frontend_attach,
1899 .tuner_attach = stk7700p_tuner_attach, 1979 .tuner_attach = stk7700p_tuner_attach,
1900 1980
@@ -1976,11 +2056,19 @@ struct dvb_usb_device_properties dib0700_devices[] = {
1976 .num_adapters = 2, 2056 .num_adapters = 2,
1977 .adapter = { 2057 .adapter = {
1978 { 2058 {
2059 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
2060 .pid_filter_count = 32,
2061 .pid_filter = stk70x0p_pid_filter,
2062 .pid_filter_ctrl = stk70x0p_pid_filter_ctrl,
1979 .frontend_attach = stk7700d_frontend_attach, 2063 .frontend_attach = stk7700d_frontend_attach,
1980 .tuner_attach = stk7700d_tuner_attach, 2064 .tuner_attach = stk7700d_tuner_attach,
1981 2065
1982 DIB0700_DEFAULT_STREAMING_CONFIG(0x02), 2066 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
1983 }, { 2067 }, {
2068 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
2069 .pid_filter_count = 32,
2070 .pid_filter = stk70x0p_pid_filter,
2071 .pid_filter_ctrl = stk70x0p_pid_filter_ctrl,
1984 .frontend_attach = stk7700d_frontend_attach, 2072 .frontend_attach = stk7700d_frontend_attach,
1985 .tuner_attach = stk7700d_tuner_attach, 2073 .tuner_attach = stk7700d_tuner_attach,
1986 2074
@@ -2023,6 +2111,10 @@ struct dvb_usb_device_properties dib0700_devices[] = {
2023 .num_adapters = 1, 2111 .num_adapters = 1,
2024 .adapter = { 2112 .adapter = {
2025 { 2113 {
2114 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
2115 .pid_filter_count = 32,
2116 .pid_filter = stk70x0p_pid_filter,
2117 .pid_filter_ctrl = stk70x0p_pid_filter_ctrl,
2026 .frontend_attach = stk7700P2_frontend_attach, 2118 .frontend_attach = stk7700P2_frontend_attach,
2027 .tuner_attach = stk7700d_tuner_attach, 2119 .tuner_attach = stk7700d_tuner_attach,
2028 2120
@@ -2055,6 +2147,10 @@ struct dvb_usb_device_properties dib0700_devices[] = {
2055 .num_adapters = 1, 2147 .num_adapters = 1,
2056 .adapter = { 2148 .adapter = {
2057 { 2149 {
2150 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
2151 .pid_filter_count = 32,
2152 .pid_filter = stk70x0p_pid_filter,
2153 .pid_filter_ctrl = stk70x0p_pid_filter_ctrl,
2058 .frontend_attach = stk7070p_frontend_attach, 2154 .frontend_attach = stk7070p_frontend_attach,
2059 .tuner_attach = dib7070p_tuner_attach, 2155 .tuner_attach = dib7070p_tuner_attach,
2060 2156
@@ -2122,6 +2218,10 @@ struct dvb_usb_device_properties dib0700_devices[] = {
2122 .num_adapters = 1, 2218 .num_adapters = 1,
2123 .adapter = { 2219 .adapter = {
2124 { 2220 {
2221 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
2222 .pid_filter_count = 32,
2223 .pid_filter = stk70x0p_pid_filter,
2224 .pid_filter_ctrl = stk70x0p_pid_filter_ctrl,
2125 .frontend_attach = stk7070p_frontend_attach, 2225 .frontend_attach = stk7070p_frontend_attach,
2126 .tuner_attach = dib7070p_tuner_attach, 2226 .tuner_attach = dib7070p_tuner_attach,
2127 2227
@@ -2157,6 +2257,10 @@ struct dvb_usb_device_properties dib0700_devices[] = {
2157 .num_adapters = 2, 2257 .num_adapters = 2,
2158 .adapter = { 2258 .adapter = {
2159 { 2259 {
2260 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
2261 .pid_filter_count = 32,
2262 .pid_filter = stk70x0p_pid_filter,
2263 .pid_filter_ctrl = stk70x0p_pid_filter_ctrl,
2160 .frontend_attach = stk7070pd_frontend_attach0, 2264 .frontend_attach = stk7070pd_frontend_attach0,
2161 .tuner_attach = dib7070p_tuner_attach, 2265 .tuner_attach = dib7070p_tuner_attach,
2162 2266
@@ -2164,6 +2268,10 @@ struct dvb_usb_device_properties dib0700_devices[] = {
2164 2268
2165 .size_of_priv = sizeof(struct dib0700_adapter_state), 2269 .size_of_priv = sizeof(struct dib0700_adapter_state),
2166 }, { 2270 }, {
2271 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
2272 .pid_filter_count = 32,
2273 .pid_filter = stk70x0p_pid_filter,
2274 .pid_filter_ctrl = stk70x0p_pid_filter_ctrl,
2167 .frontend_attach = stk7070pd_frontend_attach1, 2275 .frontend_attach = stk7070pd_frontend_attach1,
2168 .tuner_attach = dib7070p_tuner_attach, 2276 .tuner_attach = dib7070p_tuner_attach,
2169 2277
@@ -2210,6 +2318,10 @@ struct dvb_usb_device_properties dib0700_devices[] = {
2210 .num_adapters = 1, 2318 .num_adapters = 1,
2211 .adapter = { 2319 .adapter = {
2212 { 2320 {
2321 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
2322 .pid_filter_count = 32,
2323 .pid_filter = stk70x0p_pid_filter,
2324 .pid_filter_ctrl = stk70x0p_pid_filter_ctrl,
2213 .frontend_attach = stk7700ph_frontend_attach, 2325 .frontend_attach = stk7700ph_frontend_attach,
2214 .tuner_attach = stk7700ph_tuner_attach, 2326 .tuner_attach = stk7700ph_tuner_attach,
2215 2327
@@ -2322,6 +2434,10 @@ struct dvb_usb_device_properties dib0700_devices[] = {
2322 .num_adapters = 1, 2434 .num_adapters = 1,
2323 .adapter = { 2435 .adapter = {
2324 { 2436 {
2437 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
2438 .pid_filter_count = 32,
2439 .pid_filter = stk70x0p_pid_filter,
2440 .pid_filter_ctrl = stk70x0p_pid_filter_ctrl,
2325 .frontend_attach = stk7070p_frontend_attach, 2441 .frontend_attach = stk7070p_frontend_attach,
2326 .tuner_attach = dib7770p_tuner_attach, 2442 .tuner_attach = dib7770p_tuner_attach,
2327 2443
@@ -2353,6 +2469,10 @@ struct dvb_usb_device_properties dib0700_devices[] = {
2353 .num_adapters = 1, 2469 .num_adapters = 1,
2354 .adapter = { 2470 .adapter = {
2355 { 2471 {
2472 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
2473 .pid_filter_count = 32,
2474 .pid_filter = stk807x_pid_filter,
2475 .pid_filter_ctrl = stk807x_pid_filter_ctrl,
2356 .frontend_attach = stk807x_frontend_attach, 2476 .frontend_attach = stk807x_frontend_attach,
2357 .tuner_attach = dib807x_tuner_attach, 2477 .tuner_attach = dib807x_tuner_attach,
2358 2478
@@ -2363,7 +2483,7 @@ struct dvb_usb_device_properties dib0700_devices[] = {
2363 }, 2483 },
2364 }, 2484 },
2365 2485
2366 .num_device_descs = 2, 2486 .num_device_descs = 3,
2367 .devices = { 2487 .devices = {
2368 { "DiBcom STK807xP reference design", 2488 { "DiBcom STK807xP reference design",
2369 { &dib0700_usb_id_table[62], NULL }, 2489 { &dib0700_usb_id_table[62], NULL },
@@ -2373,6 +2493,10 @@ struct dvb_usb_device_properties dib0700_devices[] = {
2373 { &dib0700_usb_id_table[63], NULL }, 2493 { &dib0700_usb_id_table[63], NULL },
2374 { NULL }, 2494 { NULL },
2375 }, 2495 },
2496 { "EvolutePC TVWay+",
2497 { &dib0700_usb_id_table[64], NULL },
2498 { NULL },
2499 },
2376 }, 2500 },
2377 2501
2378 .rc_interval = DEFAULT_RC_INTERVAL, 2502 .rc_interval = DEFAULT_RC_INTERVAL,
@@ -2384,6 +2508,10 @@ struct dvb_usb_device_properties dib0700_devices[] = {
2384 .num_adapters = 2, 2508 .num_adapters = 2,
2385 .adapter = { 2509 .adapter = {
2386 { 2510 {
2511 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
2512 .pid_filter_count = 32,
2513 .pid_filter = stk807x_pid_filter,
2514 .pid_filter_ctrl = stk807x_pid_filter_ctrl,
2387 .frontend_attach = stk807xpvr_frontend_attach0, 2515 .frontend_attach = stk807xpvr_frontend_attach0,
2388 .tuner_attach = dib807x_tuner_attach, 2516 .tuner_attach = dib807x_tuner_attach,
2389 2517
@@ -2393,6 +2521,10 @@ struct dvb_usb_device_properties dib0700_devices[] = {
2393 sizeof(struct dib0700_adapter_state), 2521 sizeof(struct dib0700_adapter_state),
2394 }, 2522 },
2395 { 2523 {
2524 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
2525 .pid_filter_count = 32,
2526 .pid_filter = stk807x_pid_filter,
2527 .pid_filter_ctrl = stk807x_pid_filter_ctrl,
2396 .frontend_attach = stk807xpvr_frontend_attach1, 2528 .frontend_attach = stk807xpvr_frontend_attach1,
2397 .tuner_attach = dib807x_tuner_attach, 2529 .tuner_attach = dib807x_tuner_attach,
2398 2530
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c b/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c
index 8a7d87bcd1d9..df1ec3e69f4a 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c
@@ -88,6 +88,7 @@ int dvb_usb_adapter_dvb_init(struct dvb_usb_adapter *adap, short *adapter_nums)
88 goto err; 88 goto err;
89 } 89 }
90 adap->dvb_adap.priv = adap; 90 adap->dvb_adap.priv = adap;
91 adap->dvb_adap.fe_ioctl_override = adap->props.fe_ioctl_override;
91 92
92 if (adap->dev->props.read_mac_address) { 93 if (adap->dev->props.read_mac_address) {
93 if (adap->dev->props.read_mac_address(adap->dev,adap->dvb_adap.proposed_mac) == 0) 94 if (adap->dev->props.read_mac_address(adap->dev,adap->dvb_adap.proposed_mac) == 0)
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
index a548c14c1944..f1602d4ace6d 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
@@ -27,6 +27,7 @@
27#define USB_VID_DIBCOM 0x10b8 27#define USB_VID_DIBCOM 0x10b8
28#define USB_VID_DPOSH 0x1498 28#define USB_VID_DPOSH 0x1498
29#define USB_VID_DVICO 0x0fe9 29#define USB_VID_DVICO 0x0fe9
30#define USB_VID_E3C 0x18b4
30#define USB_VID_ELGATO 0x0fd9 31#define USB_VID_ELGATO 0x0fd9
31#define USB_VID_EMPIA 0xeb1a 32#define USB_VID_EMPIA 0xeb1a
32#define USB_VID_GENPIX 0x09c0 33#define USB_VID_GENPIX 0x09c0
@@ -61,6 +62,7 @@
61#define USB_VID_XTENSIONS 0x1ae7 62#define USB_VID_XTENSIONS 0x1ae7
62#define USB_VID_HUMAX_COEX 0x10b9 63#define USB_VID_HUMAX_COEX 0x10b9
63#define USB_VID_774 0x7a69 64#define USB_VID_774 0x7a69
65#define USB_VID_EVOLUTEPC 0x1e59
64 66
65/* Product IDs */ 67/* Product IDs */
66#define USB_PID_ADSTECH_USB2_COLD 0xa333 68#define USB_PID_ADSTECH_USB2_COLD 0xa333
@@ -103,6 +105,11 @@
103#define USB_PID_DIBCOM_STK7770P 0x1e80 105#define USB_PID_DIBCOM_STK7770P 0x1e80
104#define USB_PID_DPOSH_M9206_COLD 0x9206 106#define USB_PID_DPOSH_M9206_COLD 0x9206
105#define USB_PID_DPOSH_M9206_WARM 0xa090 107#define USB_PID_DPOSH_M9206_WARM 0xa090
108#define USB_PID_E3C_EC168 0x1689
109#define USB_PID_E3C_EC168_2 0xfffa
110#define USB_PID_E3C_EC168_3 0xfffb
111#define USB_PID_E3C_EC168_4 0x1001
112#define USB_PID_E3C_EC168_5 0x1002
106#define USB_PID_UNIWILL_STK7700P 0x6003 113#define USB_PID_UNIWILL_STK7700P 0x6003
107#define USB_PID_GENIUS_TVGO_DVB_T03 0x4012 114#define USB_PID_GENIUS_TVGO_DVB_T03 0x4012
108#define USB_PID_GRANDTEC_DVBT_USB_COLD 0x0fa0 115#define USB_PID_GRANDTEC_DVBT_USB_COLD 0x0fa0
@@ -115,6 +122,7 @@
115#define USB_PID_KWORLD_395U_3 0xe395 122#define USB_PID_KWORLD_395U_3 0xe395
116#define USB_PID_KWORLD_MC810 0xc810 123#define USB_PID_KWORLD_MC810 0xc810
117#define USB_PID_KWORLD_PC160_2T 0xc160 124#define USB_PID_KWORLD_PC160_2T 0xc160
125#define USB_PID_KWORLD_PC160_T 0xc161
118#define USB_PID_KWORLD_VSTREAM_COLD 0x17de 126#define USB_PID_KWORLD_VSTREAM_COLD 0x17de
119#define USB_PID_KWORLD_VSTREAM_WARM 0x17df 127#define USB_PID_KWORLD_VSTREAM_WARM 0x17df
120#define USB_PID_TERRATEC_CINERGY_T_USB_XE 0x0055 128#define USB_PID_TERRATEC_CINERGY_T_USB_XE 0x0055
@@ -271,10 +279,13 @@
271#define USB_PID_TELESTAR_STARSTICK_2 0x8000 279#define USB_PID_TELESTAR_STARSTICK_2 0x8000
272#define USB_PID_MSI_DIGI_VOX_MINI_III 0x8807 280#define USB_PID_MSI_DIGI_VOX_MINI_III 0x8807
273#define USB_PID_SONY_PLAYTV 0x0003 281#define USB_PID_SONY_PLAYTV 0x0003
282#define USB_PID_MYGICA_D689 0xd811
274#define USB_PID_ELGATO_EYETV_DTT 0x0021 283#define USB_PID_ELGATO_EYETV_DTT 0x0021
275#define USB_PID_ELGATO_EYETV_DTT_Dlx 0x0020 284#define USB_PID_ELGATO_EYETV_DTT_Dlx 0x0020
276#define USB_PID_DVB_T_USB_STICK_HIGH_SPEED_COLD 0x5000 285#define USB_PID_DVB_T_USB_STICK_HIGH_SPEED_COLD 0x5000
277#define USB_PID_DVB_T_USB_STICK_HIGH_SPEED_WARM 0x5001 286#define USB_PID_DVB_T_USB_STICK_HIGH_SPEED_WARM 0x5001
278#define USB_PID_FRIIO_WHITE 0x0001 287#define USB_PID_FRIIO_WHITE 0x0001
288#define USB_PID_TVWAY_PLUS 0x0002
289#define USB_PID_SVEON_STV20 0xe39d
279 290
280#endif 291#endif
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb.h b/drivers/media/dvb/dvb-usb/dvb-usb.h
index fe2b87efb3f1..0143aef19ecd 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb.h
+++ b/drivers/media/dvb/dvb-usb/dvb-usb.h
@@ -162,6 +162,9 @@ struct dvb_usb_adapter_properties {
162 struct usb_data_stream_properties stream; 162 struct usb_data_stream_properties stream;
163 163
164 int size_of_priv; 164 int size_of_priv;
165
166 int (*fe_ioctl_override) (struct dvb_frontend *,
167 unsigned int, void *, unsigned int);
165}; 168};
166 169
167/** 170/**
diff --git a/drivers/media/dvb/dvb-usb/ec168.c b/drivers/media/dvb/dvb-usb/ec168.c
new file mode 100644
index 000000000000..52f5d4f0f230
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/ec168.c
@@ -0,0 +1,440 @@
1/*
2 * E3C EC168 DVB USB driver
3 *
4 * Copyright (C) 2009 Antti Palosaari <crope@iki.fi>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 *
20 */
21
22#include "ec168.h"
23#include "ec100.h"
24#include "mxl5005s.h"
25
26/* debug */
27static int dvb_usb_ec168_debug;
28module_param_named(debug, dvb_usb_ec168_debug, int, 0644);
29MODULE_PARM_DESC(debug, "set debugging level" DVB_USB_DEBUG_STATUS);
30DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
31
32static struct ec100_config ec168_ec100_config;
33
34static int ec168_rw_udev(struct usb_device *udev, struct ec168_req *req)
35{
36 int ret;
37 unsigned int pipe;
38 u8 request, requesttype;
39 u8 buf[req->size];
40
41 switch (req->cmd) {
42 case DOWNLOAD_FIRMWARE:
43 case GPIO:
44 case WRITE_I2C:
45 case STREAMING_CTRL:
46 requesttype = (USB_TYPE_VENDOR | USB_DIR_OUT);
47 request = req->cmd;
48 break;
49 case READ_I2C:
50 requesttype = (USB_TYPE_VENDOR | USB_DIR_IN);
51 request = req->cmd;
52 break;
53 case GET_CONFIG:
54 requesttype = (USB_TYPE_VENDOR | USB_DIR_IN);
55 request = CONFIG;
56 break;
57 case SET_CONFIG:
58 requesttype = (USB_TYPE_VENDOR | USB_DIR_OUT);
59 request = CONFIG;
60 break;
61 case WRITE_DEMOD:
62 requesttype = (USB_TYPE_VENDOR | USB_DIR_OUT);
63 request = DEMOD_RW;
64 break;
65 case READ_DEMOD:
66 requesttype = (USB_TYPE_VENDOR | USB_DIR_IN);
67 request = DEMOD_RW;
68 break;
69 default:
70 err("unknown command:%02x", req->cmd);
71 ret = -EPERM;
72 goto error;
73 }
74
75 if (requesttype == (USB_TYPE_VENDOR | USB_DIR_OUT)) {
76 /* write */
77 memcpy(buf, req->data, req->size);
78 pipe = usb_sndctrlpipe(udev, 0);
79 } else {
80 /* read */
81 pipe = usb_rcvctrlpipe(udev, 0);
82 }
83
84 msleep(1); /* avoid I2C errors */
85
86 ret = usb_control_msg(udev, pipe, request, requesttype, req->value,
87 req->index, buf, sizeof(buf), EC168_USB_TIMEOUT);
88
89 ec168_debug_dump(request, requesttype, req->value, req->index, buf,
90 req->size, deb_xfer);
91
92 if (ret < 0)
93 goto error;
94 else
95 ret = 0;
96
97 /* read request, copy returned data to return buf */
98 if (!ret && requesttype == (USB_TYPE_VENDOR | USB_DIR_IN))
99 memcpy(req->data, buf, req->size);
100
101 return ret;
102error:
103 deb_info("%s: failed:%d\n", __func__, ret);
104 return ret;
105}
106
107static int ec168_ctrl_msg(struct dvb_usb_device *d, struct ec168_req *req)
108{
109 return ec168_rw_udev(d->udev, req);
110}
111
112/* I2C */
113static int ec168_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
114 int num)
115{
116 struct dvb_usb_device *d = i2c_get_adapdata(adap);
117 struct ec168_req req;
118 int i = 0;
119 int ret;
120
121 if (num > 2)
122 return -EINVAL;
123
124 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
125 return -EAGAIN;
126
127 while (i < num) {
128 if (num > i + 1 && (msg[i+1].flags & I2C_M_RD)) {
129 if (msg[i].addr == ec168_ec100_config.demod_address) {
130 req.cmd = READ_DEMOD;
131 req.value = 0;
132 req.index = 0xff00 + msg[i].buf[0]; /* reg */
133 req.size = msg[i+1].len; /* bytes to read */
134 req.data = &msg[i+1].buf[0];
135 ret = ec168_ctrl_msg(d, &req);
136 i += 2;
137 } else {
138 err("I2C read not implemented");
139 ret = -ENOSYS;
140 i += 2;
141 }
142 } else {
143 if (msg[i].addr == ec168_ec100_config.demod_address) {
144 req.cmd = WRITE_DEMOD;
145 req.value = msg[i].buf[1]; /* val */
146 req.index = 0xff00 + msg[i].buf[0]; /* reg */
147 req.size = 0;
148 req.data = NULL;
149 ret = ec168_ctrl_msg(d, &req);
150 i += 1;
151 } else {
152 req.cmd = WRITE_I2C;
153 req.value = msg[i].buf[0]; /* val */
154 req.index = 0x0100 + msg[i].addr; /* I2C addr */
155 req.size = msg[i].len-1;
156 req.data = &msg[i].buf[1];
157 ret = ec168_ctrl_msg(d, &req);
158 i += 1;
159 }
160 }
161 if (ret)
162 goto error;
163
164 }
165 ret = i;
166
167error:
168 mutex_unlock(&d->i2c_mutex);
169 return i;
170}
171
172
173static u32 ec168_i2c_func(struct i2c_adapter *adapter)
174{
175 return I2C_FUNC_I2C;
176}
177
178static struct i2c_algorithm ec168_i2c_algo = {
179 .master_xfer = ec168_i2c_xfer,
180 .functionality = ec168_i2c_func,
181};
182
183/* Callbacks for DVB USB */
184static struct ec100_config ec168_ec100_config = {
185 .demod_address = 0xff, /* not real address, demod is integrated */
186};
187
188static int ec168_ec100_frontend_attach(struct dvb_usb_adapter *adap)
189{
190 deb_info("%s:\n", __func__);
191 adap->fe = dvb_attach(ec100_attach, &ec168_ec100_config,
192 &adap->dev->i2c_adap);
193 if (adap->fe == NULL)
194 return -ENODEV;
195
196 return 0;
197}
198
199static struct mxl5005s_config ec168_mxl5003s_config = {
200 .i2c_address = 0xc6,
201 .if_freq = IF_FREQ_4570000HZ,
202 .xtal_freq = CRYSTAL_FREQ_16000000HZ,
203 .agc_mode = MXL_SINGLE_AGC,
204 .tracking_filter = MXL_TF_OFF,
205 .rssi_enable = MXL_RSSI_ENABLE,
206 .cap_select = MXL_CAP_SEL_ENABLE,
207 .div_out = MXL_DIV_OUT_4,
208 .clock_out = MXL_CLOCK_OUT_DISABLE,
209 .output_load = MXL5005S_IF_OUTPUT_LOAD_200_OHM,
210 .top = MXL5005S_TOP_25P2,
211 .mod_mode = MXL_DIGITAL_MODE,
212 .if_mode = MXL_ZERO_IF,
213 .AgcMasterByte = 0x00,
214};
215
216static int ec168_mxl5003s_tuner_attach(struct dvb_usb_adapter *adap)
217{
218 deb_info("%s:\n", __func__);
219 return dvb_attach(mxl5005s_attach, adap->fe, &adap->dev->i2c_adap,
220 &ec168_mxl5003s_config) == NULL ? -ENODEV : 0;
221}
222
223static int ec168_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
224{
225 struct ec168_req req = {STREAMING_CTRL, 0x7f01, 0x0202, 0, NULL};
226 deb_info("%s: onoff:%d\n", __func__, onoff);
227 if (onoff)
228 req.index = 0x0102;
229 return ec168_ctrl_msg(adap->dev, &req);
230}
231
232static int ec168_download_firmware(struct usb_device *udev,
233 const struct firmware *fw)
234{
235 int i, len, packets, remainder, ret;
236 u16 addr = 0x0000; /* firmware start address */
237 struct ec168_req req = {DOWNLOAD_FIRMWARE, 0, 0, 0, NULL};
238 deb_info("%s:\n", __func__);
239
240 #define FW_PACKET_MAX_DATA 2048
241 packets = fw->size / FW_PACKET_MAX_DATA;
242 remainder = fw->size % FW_PACKET_MAX_DATA;
243 len = FW_PACKET_MAX_DATA;
244 for (i = 0; i <= packets; i++) {
245 if (i == packets) /* set size of the last packet */
246 len = remainder;
247
248 req.size = len;
249 req.data = (u8 *)(fw->data + i * FW_PACKET_MAX_DATA);
250 req.index = addr;
251 addr += FW_PACKET_MAX_DATA;
252
253 ret = ec168_rw_udev(udev, &req);
254 if (ret) {
255 err("firmware download failed:%d packet:%d", ret, i);
256 goto error;
257 }
258 }
259 req.size = 0;
260
261 /* set "warm"? */
262 req.cmd = SET_CONFIG;
263 req.value = 0;
264 req.index = 0x0001;
265 ret = ec168_rw_udev(udev, &req);
266 if (ret)
267 goto error;
268
269 /* really needed - no idea what does */
270 req.cmd = GPIO;
271 req.value = 0;
272 req.index = 0x0206;
273 ret = ec168_rw_udev(udev, &req);
274 if (ret)
275 goto error;
276
277 /* activate tuner I2C? */
278 req.cmd = WRITE_I2C;
279 req.value = 0;
280 req.index = 0x00c6;
281 ret = ec168_rw_udev(udev, &req);
282 if (ret)
283 goto error;
284
285 return ret;
286error:
287 deb_info("%s: failed:%d\n", __func__, ret);
288 return ret;
289}
290
291static int ec168_identify_state(struct usb_device *udev,
292 struct dvb_usb_device_properties *props,
293 struct dvb_usb_device_description **desc, int *cold)
294{
295 int ret;
296 u8 reply;
297 struct ec168_req req = {GET_CONFIG, 0, 1, sizeof(reply), &reply};
298 deb_info("%s:\n", __func__);
299
300 ret = ec168_rw_udev(udev, &req);
301 if (ret)
302 goto error;
303
304 deb_info("%s: reply:%02x\n", __func__, reply);
305
306 if (reply == 0x01)
307 *cold = 0;
308 else
309 *cold = 1;
310
311 return ret;
312error:
313 deb_info("%s: failed:%d\n", __func__, ret);
314 return ret;
315}
316
317/* DVB USB Driver stuff */
318static struct dvb_usb_device_properties ec168_properties;
319
320static int ec168_probe(struct usb_interface *intf,
321 const struct usb_device_id *id)
322{
323 int ret;
324 deb_info("%s: interface:%d\n", __func__,
325 intf->cur_altsetting->desc.bInterfaceNumber);
326
327 ret = dvb_usb_device_init(intf, &ec168_properties, THIS_MODULE, NULL,
328 adapter_nr);
329 if (ret)
330 goto error;
331
332 return ret;
333error:
334 deb_info("%s: failed:%d\n", __func__, ret);
335 return ret;
336}
337
338#define E3C_EC168_1689 0
339#define E3C_EC168_FFFA 1
340#define E3C_EC168_FFFB 2
341#define E3C_EC168_1001 3
342#define E3C_EC168_1002 4
343
344static struct usb_device_id ec168_id[] = {
345 [E3C_EC168_1689] =
346 {USB_DEVICE(USB_VID_E3C, USB_PID_E3C_EC168)},
347 [E3C_EC168_FFFA] =
348 {USB_DEVICE(USB_VID_E3C, USB_PID_E3C_EC168_2)},
349 [E3C_EC168_FFFB] =
350 {USB_DEVICE(USB_VID_E3C, USB_PID_E3C_EC168_3)},
351 [E3C_EC168_1001] =
352 {USB_DEVICE(USB_VID_E3C, USB_PID_E3C_EC168_4)},
353 [E3C_EC168_1002] =
354 {USB_DEVICE(USB_VID_E3C, USB_PID_E3C_EC168_5)},
355 {} /* terminating entry */
356};
357
358MODULE_DEVICE_TABLE(usb, ec168_id);
359
360static struct dvb_usb_device_properties ec168_properties = {
361 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
362
363 .usb_ctrl = DEVICE_SPECIFIC,
364 .download_firmware = ec168_download_firmware,
365 .firmware = "dvb-usb-ec168.fw",
366 .no_reconnect = 1,
367
368 .size_of_priv = 0,
369
370 .num_adapters = 1,
371 .adapter = {
372 {
373 .streaming_ctrl = ec168_streaming_ctrl,
374 .frontend_attach = ec168_ec100_frontend_attach,
375 .tuner_attach = ec168_mxl5003s_tuner_attach,
376 .stream = {
377 .type = USB_BULK,
378 .count = 6,
379 .endpoint = 0x82,
380 .u = {
381 .bulk = {
382 .buffersize = (32*512),
383 }
384 }
385 },
386 }
387 },
388
389 .identify_state = ec168_identify_state,
390
391 .i2c_algo = &ec168_i2c_algo,
392
393 .num_device_descs = 1,
394 .devices = {
395 {
396 .name = "E3C EC168 DVB-T USB2.0 reference design",
397 .cold_ids = {
398 &ec168_id[E3C_EC168_1689],
399 &ec168_id[E3C_EC168_FFFA],
400 &ec168_id[E3C_EC168_FFFB],
401 &ec168_id[E3C_EC168_1001],
402 &ec168_id[E3C_EC168_1002],
403 NULL},
404 .warm_ids = {NULL},
405 },
406 }
407};
408
409static struct usb_driver ec168_driver = {
410 .name = "dvb_usb_ec168",
411 .probe = ec168_probe,
412 .disconnect = dvb_usb_device_exit,
413 .id_table = ec168_id,
414};
415
416/* module stuff */
417static int __init ec168_module_init(void)
418{
419 int ret;
420 deb_info("%s:\n", __func__);
421 ret = usb_register(&ec168_driver);
422 if (ret)
423 err("module init failed:%d", ret);
424
425 return ret;
426}
427
428static void __exit ec168_module_exit(void)
429{
430 deb_info("%s:\n", __func__);
431 /* deregister this driver from the USB subsystem */
432 usb_deregister(&ec168_driver);
433}
434
435module_init(ec168_module_init);
436module_exit(ec168_module_exit);
437
438MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
439MODULE_DESCRIPTION("E3C EC168 DVB-T USB2.0 driver");
440MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/ec168.h b/drivers/media/dvb/dvb-usb/ec168.h
new file mode 100644
index 000000000000..e7e0b831314e
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/ec168.h
@@ -0,0 +1,73 @@
1/*
2 * E3C EC168 DVB USB driver
3 *
4 * Copyright (C) 2009 Antti Palosaari <crope@iki.fi>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 *
20 */
21
22#ifndef EC168_H
23#define EC168_H
24
25#define DVB_USB_LOG_PREFIX "ec168"
26#include "dvb-usb.h"
27
28#define deb_info(args...) dprintk(dvb_usb_ec168_debug, 0x01, args)
29#define deb_rc(args...) dprintk(dvb_usb_ec168_debug, 0x02, args)
30#define deb_xfer(args...) dprintk(dvb_usb_ec168_debug, 0x04, args)
31#define deb_reg(args...) dprintk(dvb_usb_ec168_debug, 0x08, args)
32#define deb_i2c(args...) dprintk(dvb_usb_ec168_debug, 0x10, args)
33#define deb_fw(args...) dprintk(dvb_usb_ec168_debug, 0x20, args)
34
35#define ec168_debug_dump(r, t, v, i, b, l, func) { \
36 int loop_; \
37 func("%02x %02x %02x %02x %02x %02x %02x %02x", \
38 t, r, v & 0xff, v >> 8, i & 0xff, i >> 8, l & 0xff, l >> 8); \
39 if (t == (USB_TYPE_VENDOR | USB_DIR_OUT)) \
40 func(" >>> "); \
41 else \
42 func(" <<< "); \
43 for (loop_ = 0; loop_ < l; loop_++) \
44 func("%02x ", b[loop_]); \
45 func("\n");\
46}
47
48#define EC168_USB_TIMEOUT 1000
49
50struct ec168_req {
51 u8 cmd; /* [1] */
52 u16 value; /* [2|3] */
53 u16 index; /* [4|5] */
54 u16 size; /* [6|7] */
55 u8 *data;
56};
57
58enum ec168_cmd {
59 DOWNLOAD_FIRMWARE = 0x00,
60 CONFIG = 0x01,
61 DEMOD_RW = 0x03,
62 GPIO = 0x04,
63 STREAMING_CTRL = 0x10,
64 READ_I2C = 0x20,
65 WRITE_I2C = 0x21,
66 HID_DOWNLOAD = 0x30,
67 GET_CONFIG,
68 SET_CONFIG,
69 READ_DEMOD,
70 WRITE_DEMOD,
71};
72
73#endif
diff --git a/drivers/media/dvb/dvb-usb/friio-fe.c b/drivers/media/dvb/dvb-usb/friio-fe.c
index c4dfe25cf60d..9cbbe42ca44b 100644
--- a/drivers/media/dvb/dvb-usb/friio-fe.c
+++ b/drivers/media/dvb/dvb-usb/friio-fe.c
@@ -232,12 +232,6 @@ static int jdvbt90502_read_status(struct dvb_frontend *fe, fe_status_t *state)
232 return 0; 232 return 0;
233} 233}
234 234
235static int jdvbt90502_read_ber(struct dvb_frontend *fe, u32 *ber)
236{
237 *ber = 0;
238 return 0;
239}
240
241static int jdvbt90502_read_signal_strength(struct dvb_frontend *fe, 235static int jdvbt90502_read_signal_strength(struct dvb_frontend *fe,
242 u16 *strength) 236 u16 *strength)
243{ 237{
@@ -264,26 +258,26 @@ static int jdvbt90502_read_signal_strength(struct dvb_frontend *fe,
264 return 0; 258 return 0;
265} 259}
266 260
267static int jdvbt90502_read_snr(struct dvb_frontend *fe, u16 *snr)
268{
269 *snr = 0x0101;
270 return 0;
271}
272
273static int jdvbt90502_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
274{
275 *ucblocks = 0;
276 return 0;
277}
278 261
279static int jdvbt90502_get_tune_settings(struct dvb_frontend *fe, 262/* filter out un-supported properties to notify users */
280 struct dvb_frontend_tune_settings *fs) 263static int jdvbt90502_set_property(struct dvb_frontend *fe,
264 struct dtv_property *tvp)
281{ 265{
282 fs->min_delay_ms = 500; 266 int r = 0;
283 fs->step_size = 0; 267
284 fs->max_drift = 0; 268 switch (tvp->cmd) {
285 269 case DTV_DELIVERY_SYSTEM:
286 return 0; 270 if (tvp->u.data != SYS_ISDBT)
271 r = -EINVAL;
272 break;
273 case DTV_CLEAR:
274 case DTV_TUNE:
275 case DTV_FREQUENCY:
276 break;
277 default:
278 r = -EINVAL;
279 }
280 return r;
287} 281}
288 282
289static int jdvbt90502_get_frontend(struct dvb_frontend *fe, 283static int jdvbt90502_get_frontend(struct dvb_frontend *fe,
@@ -314,6 +308,9 @@ static int jdvbt90502_set_frontend(struct dvb_frontend *fe,
314 308
315 deb_fe("%s: Freq:%d\n", __func__, p->frequency); 309 deb_fe("%s: Freq:%d\n", __func__, p->frequency);
316 310
311 /* for recovery from DTV_CLEAN */
312 fe->dtv_property_cache.delivery_system = SYS_ISDBT;
313
317 ret = jdvbt90502_pll_set_freq(state, p->frequency); 314 ret = jdvbt90502_pll_set_freq(state, p->frequency);
318 if (ret) { 315 if (ret) {
319 deb_fe("%s:ret == %d\n", __func__, ret); 316 deb_fe("%s:ret == %d\n", __func__, ret);
@@ -323,12 +320,6 @@ static int jdvbt90502_set_frontend(struct dvb_frontend *fe,
323 return 0; 320 return 0;
324} 321}
325 322
326static int jdvbt90502_sleep(struct dvb_frontend *fe)
327{
328 deb_fe("%s called.\n", __func__);
329 return 0;
330}
331
332 323
333/** 324/**
334 * (reg, val) commad list to initialize this module. 325 * (reg, val) commad list to initialize this module.
@@ -394,6 +385,7 @@ static int jdvbt90502_init(struct dvb_frontend *fe)
394 if (ret != 1) 385 if (ret != 1)
395 goto error; 386 goto error;
396 } 387 }
388 fe->dtv_property_cache.delivery_system = SYS_ISDBT;
397 msleep(100); 389 msleep(100);
398 390
399 return 0; 391 return 0;
@@ -468,16 +460,13 @@ static struct dvb_frontend_ops jdvbt90502_ops = {
468 .release = jdvbt90502_release, 460 .release = jdvbt90502_release,
469 461
470 .init = jdvbt90502_init, 462 .init = jdvbt90502_init,
471 .sleep = jdvbt90502_sleep,
472 .write = _jdvbt90502_write, 463 .write = _jdvbt90502_write,
473 464
465 .set_property = jdvbt90502_set_property,
466
474 .set_frontend = jdvbt90502_set_frontend, 467 .set_frontend = jdvbt90502_set_frontend,
475 .get_frontend = jdvbt90502_get_frontend, 468 .get_frontend = jdvbt90502_get_frontend,
476 .get_tune_settings = jdvbt90502_get_tune_settings,
477 469
478 .read_status = jdvbt90502_read_status, 470 .read_status = jdvbt90502_read_status,
479 .read_ber = jdvbt90502_read_ber,
480 .read_signal_strength = jdvbt90502_read_signal_strength, 471 .read_signal_strength = jdvbt90502_read_signal_strength,
481 .read_snr = jdvbt90502_read_snr,
482 .read_ucblocks = jdvbt90502_read_ucblocks,
483}; 472};
diff --git a/drivers/media/dvb/firewire/Kconfig b/drivers/media/dvb/firewire/Kconfig
index 69028253e984..4afa29256df1 100644
--- a/drivers/media/dvb/firewire/Kconfig
+++ b/drivers/media/dvb/firewire/Kconfig
@@ -1,6 +1,6 @@
1config DVB_FIREDTV 1config DVB_FIREDTV
2 tristate "FireDTV and FloppyDTV" 2 tristate "FireDTV and FloppyDTV"
3 depends on DVB_CORE && IEEE1394 3 depends on DVB_CORE && (FIREWIRE || IEEE1394)
4 help 4 help
5 Support for DVB receivers from Digital Everywhere 5 Support for DVB receivers from Digital Everywhere
6 which are connected via IEEE 1394 (FireWire). 6 which are connected via IEEE 1394 (FireWire).
@@ -13,8 +13,11 @@ config DVB_FIREDTV
13 13
14if DVB_FIREDTV 14if DVB_FIREDTV
15 15
16config DVB_FIREDTV_FIREWIRE
17 def_bool FIREWIRE = y || (FIREWIRE = m && DVB_FIREDTV = m)
18
16config DVB_FIREDTV_IEEE1394 19config DVB_FIREDTV_IEEE1394
17 def_bool IEEE1394 20 def_bool IEEE1394 = y || (IEEE1394 = m && DVB_FIREDTV = m)
18 21
19config DVB_FIREDTV_INPUT 22config DVB_FIREDTV_INPUT
20 def_bool INPUT = y || (INPUT = m && DVB_FIREDTV = m) 23 def_bool INPUT = y || (INPUT = m && DVB_FIREDTV = m)
diff --git a/drivers/media/dvb/firewire/Makefile b/drivers/media/dvb/firewire/Makefile
index 2034695ba194..da84203d51c6 100644
--- a/drivers/media/dvb/firewire/Makefile
+++ b/drivers/media/dvb/firewire/Makefile
@@ -1,6 +1,7 @@
1obj-$(CONFIG_DVB_FIREDTV) += firedtv.o 1obj-$(CONFIG_DVB_FIREDTV) += firedtv.o
2 2
3firedtv-y := firedtv-avc.o firedtv-ci.o firedtv-dvb.o firedtv-fe.o 3firedtv-y := firedtv-avc.o firedtv-ci.o firedtv-dvb.o firedtv-fe.o
4firedtv-$(CONFIG_DVB_FIREDTV_FIREWIRE) += firedtv-fw.o
4firedtv-$(CONFIG_DVB_FIREDTV_IEEE1394) += firedtv-1394.o 5firedtv-$(CONFIG_DVB_FIREDTV_IEEE1394) += firedtv-1394.o
5firedtv-$(CONFIG_DVB_FIREDTV_INPUT) += firedtv-rc.o 6firedtv-$(CONFIG_DVB_FIREDTV_INPUT) += firedtv-rc.o
6 7
diff --git a/drivers/media/dvb/firewire/firedtv-1394.c b/drivers/media/dvb/firewire/firedtv-1394.c
index 2b6eeeab5b25..7c5459c27b75 100644
--- a/drivers/media/dvb/firewire/firedtv-1394.c
+++ b/drivers/media/dvb/firewire/firedtv-1394.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * FireDTV driver (formerly known as FireSAT) 2 * FireDTV driver -- ieee1394 I/O backend
3 * 3 *
4 * Copyright (C) 2004 Andreas Monitzer <andy@monitzer.com> 4 * Copyright (C) 2004 Andreas Monitzer <andy@monitzer.com>
5 * Copyright (C) 2007-2008 Ben Backx <ben@bbackx.com> 5 * Copyright (C) 2007-2008 Ben Backx <ben@bbackx.com>
@@ -26,13 +26,16 @@
26#include <iso.h> 26#include <iso.h>
27#include <nodemgr.h> 27#include <nodemgr.h>
28 28
29#include <dvb_demux.h>
30
29#include "firedtv.h" 31#include "firedtv.h"
30 32
31static LIST_HEAD(node_list); 33static LIST_HEAD(node_list);
32static DEFINE_SPINLOCK(node_list_lock); 34static DEFINE_SPINLOCK(node_list_lock);
33 35
34#define FIREWIRE_HEADER_SIZE 4 36#define CIP_HEADER_SIZE 8
35#define CIP_HEADER_SIZE 8 37#define MPEG2_TS_HEADER_SIZE 4
38#define MPEG2_TS_SOURCE_PACKET_SIZE (4 + 188)
36 39
37static void rawiso_activity_cb(struct hpsb_iso *iso) 40static void rawiso_activity_cb(struct hpsb_iso *iso)
38{ 41{
@@ -62,20 +65,20 @@ static void rawiso_activity_cb(struct hpsb_iso *iso)
62 buf = dma_region_i(&iso->data_buf, unsigned char, 65 buf = dma_region_i(&iso->data_buf, unsigned char,
63 iso->infos[packet].offset + CIP_HEADER_SIZE); 66 iso->infos[packet].offset + CIP_HEADER_SIZE);
64 count = (iso->infos[packet].len - CIP_HEADER_SIZE) / 67 count = (iso->infos[packet].len - CIP_HEADER_SIZE) /
65 (188 + FIREWIRE_HEADER_SIZE); 68 MPEG2_TS_SOURCE_PACKET_SIZE;
66 69
67 /* ignore empty packet */ 70 /* ignore empty packet */
68 if (iso->infos[packet].len <= CIP_HEADER_SIZE) 71 if (iso->infos[packet].len <= CIP_HEADER_SIZE)
69 continue; 72 continue;
70 73
71 while (count--) { 74 while (count--) {
72 if (buf[FIREWIRE_HEADER_SIZE] == 0x47) 75 if (buf[MPEG2_TS_HEADER_SIZE] == 0x47)
73 dvb_dmx_swfilter_packets(&fdtv->demux, 76 dvb_dmx_swfilter_packets(&fdtv->demux,
74 &buf[FIREWIRE_HEADER_SIZE], 1); 77 &buf[MPEG2_TS_HEADER_SIZE], 1);
75 else 78 else
76 dev_err(fdtv->device, 79 dev_err(fdtv->device,
77 "skipping invalid packet\n"); 80 "skipping invalid packet\n");
78 buf += 188 + FIREWIRE_HEADER_SIZE; 81 buf += MPEG2_TS_SOURCE_PACKET_SIZE;
79 } 82 }
80 } 83 }
81out: 84out:
@@ -87,15 +90,20 @@ static inline struct node_entry *node_of(struct firedtv *fdtv)
87 return container_of(fdtv->device, struct unit_directory, device)->ne; 90 return container_of(fdtv->device, struct unit_directory, device)->ne;
88} 91}
89 92
90static int node_lock(struct firedtv *fdtv, u64 addr, void *data, __be32 arg) 93static int node_lock(struct firedtv *fdtv, u64 addr, __be32 data[])
91{ 94{
92 return hpsb_node_lock(node_of(fdtv), addr, EXTCODE_COMPARE_SWAP, data, 95 int ret;
93 (__force quadlet_t)arg); 96
97 ret = hpsb_node_lock(node_of(fdtv), addr, EXTCODE_COMPARE_SWAP,
98 (__force quadlet_t *)&data[1], (__force quadlet_t)data[0]);
99 data[0] = data[1];
100
101 return ret;
94} 102}
95 103
96static int node_read(struct firedtv *fdtv, u64 addr, void *data, size_t len) 104static int node_read(struct firedtv *fdtv, u64 addr, void *data)
97{ 105{
98 return hpsb_node_read(node_of(fdtv), addr, data, len); 106 return hpsb_node_read(node_of(fdtv), addr, data, 4);
99} 107}
100 108
101static int node_write(struct firedtv *fdtv, u64 addr, void *data, size_t len) 109static int node_write(struct firedtv *fdtv, u64 addr, void *data, size_t len)
@@ -212,6 +220,7 @@ static int node_probe(struct device *dev)
212 goto fail; 220 goto fail;
213 221
214 avc_register_remote_control(fdtv); 222 avc_register_remote_control(fdtv);
223
215 return 0; 224 return 0;
216fail: 225fail:
217 spin_lock_irq(&node_list_lock); 226 spin_lock_irq(&node_list_lock);
@@ -220,6 +229,7 @@ fail:
220 fdtv_unregister_rc(fdtv); 229 fdtv_unregister_rc(fdtv);
221fail_free: 230fail_free:
222 kfree(fdtv); 231 kfree(fdtv);
232
223 return err; 233 return err;
224} 234}
225 235
@@ -233,10 +243,9 @@ static int node_remove(struct device *dev)
233 list_del(&fdtv->list); 243 list_del(&fdtv->list);
234 spin_unlock_irq(&node_list_lock); 244 spin_unlock_irq(&node_list_lock);
235 245
236 cancel_work_sync(&fdtv->remote_ctrl_work);
237 fdtv_unregister_rc(fdtv); 246 fdtv_unregister_rc(fdtv);
238
239 kfree(fdtv); 247 kfree(fdtv);
248
240 return 0; 249 return 0;
241} 250}
242 251
@@ -252,6 +261,7 @@ static int node_update(struct unit_directory *ud)
252 261
253static struct hpsb_protocol_driver fdtv_driver = { 262static struct hpsb_protocol_driver fdtv_driver = {
254 .name = "firedtv", 263 .name = "firedtv",
264 .id_table = fdtv_id_table,
255 .update = node_update, 265 .update = node_update,
256 .driver = { 266 .driver = {
257 .probe = node_probe, 267 .probe = node_probe,
@@ -264,12 +274,11 @@ static struct hpsb_highlevel fdtv_highlevel = {
264 .fcp_request = fcp_request, 274 .fcp_request = fcp_request,
265}; 275};
266 276
267int __init fdtv_1394_init(struct ieee1394_device_id id_table[]) 277int __init fdtv_1394_init(void)
268{ 278{
269 int ret; 279 int ret;
270 280
271 hpsb_register_highlevel(&fdtv_highlevel); 281 hpsb_register_highlevel(&fdtv_highlevel);
272 fdtv_driver.id_table = id_table;
273 ret = hpsb_register_protocol(&fdtv_driver); 282 ret = hpsb_register_protocol(&fdtv_driver);
274 if (ret) { 283 if (ret) {
275 printk(KERN_ERR "firedtv: failed to register protocol\n"); 284 printk(KERN_ERR "firedtv: failed to register protocol\n");
diff --git a/drivers/media/dvb/firewire/firedtv-avc.c b/drivers/media/dvb/firewire/firedtv-avc.c
index 485d061319ab..50c42a4b972b 100644
--- a/drivers/media/dvb/firewire/firedtv-avc.c
+++ b/drivers/media/dvb/firewire/firedtv-avc.c
@@ -1236,14 +1236,14 @@ int avc_ca_get_mmi(struct firedtv *fdtv, char *mmi_object, unsigned int *len)
1236 1236
1237#define CMP_OUTPUT_PLUG_CONTROL_REG_0 0xfffff0000904ULL 1237#define CMP_OUTPUT_PLUG_CONTROL_REG_0 0xfffff0000904ULL
1238 1238
1239static int cmp_read(struct firedtv *fdtv, void *buf, u64 addr, size_t len) 1239static int cmp_read(struct firedtv *fdtv, u64 addr, __be32 *data)
1240{ 1240{
1241 int ret; 1241 int ret;
1242 1242
1243 if (mutex_lock_interruptible(&fdtv->avc_mutex)) 1243 if (mutex_lock_interruptible(&fdtv->avc_mutex))
1244 return -EINTR; 1244 return -EINTR;
1245 1245
1246 ret = fdtv->backend->read(fdtv, addr, buf, len); 1246 ret = fdtv->backend->read(fdtv, addr, data);
1247 if (ret < 0) 1247 if (ret < 0)
1248 dev_err(fdtv->device, "CMP: read I/O error\n"); 1248 dev_err(fdtv->device, "CMP: read I/O error\n");
1249 1249
@@ -1251,14 +1251,14 @@ static int cmp_read(struct firedtv *fdtv, void *buf, u64 addr, size_t len)
1251 return ret; 1251 return ret;
1252} 1252}
1253 1253
1254static int cmp_lock(struct firedtv *fdtv, void *data, u64 addr, __be32 arg) 1254static int cmp_lock(struct firedtv *fdtv, u64 addr, __be32 data[])
1255{ 1255{
1256 int ret; 1256 int ret;
1257 1257
1258 if (mutex_lock_interruptible(&fdtv->avc_mutex)) 1258 if (mutex_lock_interruptible(&fdtv->avc_mutex))
1259 return -EINTR; 1259 return -EINTR;
1260 1260
1261 ret = fdtv->backend->lock(fdtv, addr, data, arg); 1261 ret = fdtv->backend->lock(fdtv, addr, data);
1262 if (ret < 0) 1262 if (ret < 0)
1263 dev_err(fdtv->device, "CMP: lock I/O error\n"); 1263 dev_err(fdtv->device, "CMP: lock I/O error\n");
1264 1264
@@ -1288,25 +1288,25 @@ static inline void set_opcr(__be32 *opcr, u32 value, u32 mask, u32 shift)
1288 1288
1289int cmp_establish_pp_connection(struct firedtv *fdtv, int plug, int channel) 1289int cmp_establish_pp_connection(struct firedtv *fdtv, int plug, int channel)
1290{ 1290{
1291 __be32 old_opcr, opcr; 1291 __be32 old_opcr, opcr[2];
1292 u64 opcr_address = CMP_OUTPUT_PLUG_CONTROL_REG_0 + (plug << 2); 1292 u64 opcr_address = CMP_OUTPUT_PLUG_CONTROL_REG_0 + (plug << 2);
1293 int attempts = 0; 1293 int attempts = 0;
1294 int ret; 1294 int ret;
1295 1295
1296 ret = cmp_read(fdtv, &opcr, opcr_address, 4); 1296 ret = cmp_read(fdtv, opcr_address, opcr);
1297 if (ret < 0) 1297 if (ret < 0)
1298 return ret; 1298 return ret;
1299 1299
1300repeat: 1300repeat:
1301 if (!get_opcr_online(opcr)) { 1301 if (!get_opcr_online(*opcr)) {
1302 dev_err(fdtv->device, "CMP: output offline\n"); 1302 dev_err(fdtv->device, "CMP: output offline\n");
1303 return -EBUSY; 1303 return -EBUSY;
1304 } 1304 }
1305 1305
1306 old_opcr = opcr; 1306 old_opcr = *opcr;
1307 1307
1308 if (get_opcr_p2p_connections(opcr)) { 1308 if (get_opcr_p2p_connections(*opcr)) {
1309 if (get_opcr_channel(opcr) != channel) { 1309 if (get_opcr_channel(*opcr) != channel) {
1310 dev_err(fdtv->device, "CMP: cannot change channel\n"); 1310 dev_err(fdtv->device, "CMP: cannot change channel\n");
1311 return -EBUSY; 1311 return -EBUSY;
1312 } 1312 }
@@ -1314,11 +1314,11 @@ repeat:
1314 1314
1315 /* We don't allocate isochronous resources. */ 1315 /* We don't allocate isochronous resources. */
1316 } else { 1316 } else {
1317 set_opcr_channel(&opcr, channel); 1317 set_opcr_channel(opcr, channel);
1318 set_opcr_data_rate(&opcr, 2); /* S400 */ 1318 set_opcr_data_rate(opcr, 2); /* S400 */
1319 1319
1320 /* FIXME: this is for the worst case - optimize */ 1320 /* FIXME: this is for the worst case - optimize */
1321 set_opcr_overhead_id(&opcr, 0); 1321 set_opcr_overhead_id(opcr, 0);
1322 1322
1323 /* 1323 /*
1324 * FIXME: allocate isochronous channel and bandwidth at IRM 1324 * FIXME: allocate isochronous channel and bandwidth at IRM
@@ -1326,13 +1326,16 @@ repeat:
1326 */ 1326 */
1327 } 1327 }
1328 1328
1329 set_opcr_p2p_connections(&opcr, get_opcr_p2p_connections(opcr) + 1); 1329 set_opcr_p2p_connections(opcr, get_opcr_p2p_connections(*opcr) + 1);
1330 1330
1331 ret = cmp_lock(fdtv, &opcr, opcr_address, old_opcr); 1331 opcr[1] = *opcr;
1332 opcr[0] = old_opcr;
1333
1334 ret = cmp_lock(fdtv, opcr_address, opcr);
1332 if (ret < 0) 1335 if (ret < 0)
1333 return ret; 1336 return ret;
1334 1337
1335 if (old_opcr != opcr) { 1338 if (old_opcr != *opcr) {
1336 /* 1339 /*
1337 * FIXME: if old_opcr.P2P_Connections > 0, 1340 * FIXME: if old_opcr.P2P_Connections > 0,
1338 * deallocate isochronous channel and bandwidth at IRM 1341 * deallocate isochronous channel and bandwidth at IRM
@@ -1350,27 +1353,30 @@ repeat:
1350 1353
1351void cmp_break_pp_connection(struct firedtv *fdtv, int plug, int channel) 1354void cmp_break_pp_connection(struct firedtv *fdtv, int plug, int channel)
1352{ 1355{
1353 __be32 old_opcr, opcr; 1356 __be32 old_opcr, opcr[2];
1354 u64 opcr_address = CMP_OUTPUT_PLUG_CONTROL_REG_0 + (plug << 2); 1357 u64 opcr_address = CMP_OUTPUT_PLUG_CONTROL_REG_0 + (plug << 2);
1355 int attempts = 0; 1358 int attempts = 0;
1356 1359
1357 if (cmp_read(fdtv, &opcr, opcr_address, 4) < 0) 1360 if (cmp_read(fdtv, opcr_address, opcr) < 0)
1358 return; 1361 return;
1359 1362
1360repeat: 1363repeat:
1361 if (!get_opcr_online(opcr) || !get_opcr_p2p_connections(opcr) || 1364 if (!get_opcr_online(*opcr) || !get_opcr_p2p_connections(*opcr) ||
1362 get_opcr_channel(opcr) != channel) { 1365 get_opcr_channel(*opcr) != channel) {
1363 dev_err(fdtv->device, "CMP: no connection to break\n"); 1366 dev_err(fdtv->device, "CMP: no connection to break\n");
1364 return; 1367 return;
1365 } 1368 }
1366 1369
1367 old_opcr = opcr; 1370 old_opcr = *opcr;
1368 set_opcr_p2p_connections(&opcr, get_opcr_p2p_connections(opcr) - 1); 1371 set_opcr_p2p_connections(opcr, get_opcr_p2p_connections(*opcr) - 1);
1372
1373 opcr[1] = *opcr;
1374 opcr[0] = old_opcr;
1369 1375
1370 if (cmp_lock(fdtv, &opcr, opcr_address, old_opcr) < 0) 1376 if (cmp_lock(fdtv, opcr_address, opcr) < 0)
1371 return; 1377 return;
1372 1378
1373 if (old_opcr != opcr) { 1379 if (old_opcr != *opcr) {
1374 /* 1380 /*
1375 * FIXME: if old_opcr.P2P_Connections == 1, i.e. we were last 1381 * FIXME: if old_opcr.P2P_Connections == 1, i.e. we were last
1376 * owner, deallocate isochronous channel and bandwidth at IRM 1382 * owner, deallocate isochronous channel and bandwidth at IRM
diff --git a/drivers/media/dvb/firewire/firedtv-dvb.c b/drivers/media/dvb/firewire/firedtv-dvb.c
index 5742fde79d99..fc9996c13e13 100644
--- a/drivers/media/dvb/firewire/firedtv-dvb.c
+++ b/drivers/media/dvb/firewire/firedtv-dvb.c
@@ -297,7 +297,7 @@ struct firedtv *fdtv_alloc(struct device *dev,
297#define AVC_UNIT_SPEC_ID_ENTRY 0x00a02d 297#define AVC_UNIT_SPEC_ID_ENTRY 0x00a02d
298#define AVC_SW_VERSION_ENTRY 0x010001 298#define AVC_SW_VERSION_ENTRY 0x010001
299 299
300static struct ieee1394_device_id fdtv_id_table[] = { 300const struct ieee1394_device_id fdtv_id_table[] = {
301 { 301 {
302 /* FloppyDTV S/CI and FloppyDTV S2 */ 302 /* FloppyDTV S/CI and FloppyDTV S2 */
303 .match_flags = MATCH_FLAGS, 303 .match_flags = MATCH_FLAGS,
@@ -346,12 +346,23 @@ MODULE_DEVICE_TABLE(ieee1394, fdtv_id_table);
346 346
347static int __init fdtv_init(void) 347static int __init fdtv_init(void)
348{ 348{
349 return fdtv_1394_init(fdtv_id_table); 349 int ret;
350
351 ret = fdtv_fw_init();
352 if (ret < 0)
353 return ret;
354
355 ret = fdtv_1394_init();
356 if (ret < 0)
357 fdtv_fw_exit();
358
359 return ret;
350} 360}
351 361
352static void __exit fdtv_exit(void) 362static void __exit fdtv_exit(void)
353{ 363{
354 fdtv_1394_exit(); 364 fdtv_1394_exit();
365 fdtv_fw_exit();
355} 366}
356 367
357module_init(fdtv_init); 368module_init(fdtv_init);
diff --git a/drivers/media/dvb/firewire/firedtv-fw.c b/drivers/media/dvb/firewire/firedtv-fw.c
new file mode 100644
index 000000000000..fe44789ab037
--- /dev/null
+++ b/drivers/media/dvb/firewire/firedtv-fw.c
@@ -0,0 +1,376 @@
1/*
2 * FireDTV driver -- firewire I/O backend
3 */
4
5#include <linux/device.h>
6#include <linux/errno.h>
7#include <linux/firewire.h>
8#include <linux/firewire-constants.h>
9#include <linux/kernel.h>
10#include <linux/list.h>
11#include <linux/mm.h>
12#include <linux/slab.h>
13#include <linux/spinlock.h>
14#include <linux/types.h>
15
16#include <asm/page.h>
17
18#include <dvb_demux.h>
19
20#include "firedtv.h"
21
22static LIST_HEAD(node_list);
23static DEFINE_SPINLOCK(node_list_lock);
24
25static inline struct fw_device *device_of(struct firedtv *fdtv)
26{
27 return fw_device(fdtv->device->parent);
28}
29
30static int node_req(struct firedtv *fdtv, u64 addr, void *data, size_t len,
31 int tcode)
32{
33 struct fw_device *device = device_of(fdtv);
34 int rcode, generation = device->generation;
35
36 smp_rmb(); /* node_id vs. generation */
37
38 rcode = fw_run_transaction(device->card, tcode, device->node_id,
39 generation, device->max_speed, addr, data, len);
40
41 return rcode != RCODE_COMPLETE ? -EIO : 0;
42}
43
44static int node_lock(struct firedtv *fdtv, u64 addr, __be32 data[])
45{
46 return node_req(fdtv, addr, data, 8, TCODE_LOCK_COMPARE_SWAP);
47}
48
49static int node_read(struct firedtv *fdtv, u64 addr, void *data)
50{
51 return node_req(fdtv, addr, data, 4, TCODE_READ_QUADLET_REQUEST);
52}
53
54static int node_write(struct firedtv *fdtv, u64 addr, void *data, size_t len)
55{
56 return node_req(fdtv, addr, data, len, TCODE_WRITE_BLOCK_REQUEST);
57}
58
59#define ISO_HEADER_SIZE 4
60#define CIP_HEADER_SIZE 8
61#define MPEG2_TS_HEADER_SIZE 4
62#define MPEG2_TS_SOURCE_PACKET_SIZE (4 + 188)
63
64#define MAX_PACKET_SIZE 1024 /* 776, rounded up to 2^n */
65#define PACKETS_PER_PAGE (PAGE_SIZE / MAX_PACKET_SIZE)
66#define N_PACKETS 64 /* buffer size */
67#define N_PAGES DIV_ROUND_UP(N_PACKETS, PACKETS_PER_PAGE)
68#define IRQ_INTERVAL 16
69
70struct firedtv_receive_context {
71 struct fw_iso_context *context;
72 struct fw_iso_buffer buffer;
73 int interrupt_packet;
74 int current_packet;
75 char *pages[N_PAGES];
76};
77
78static int queue_iso(struct firedtv_receive_context *ctx, int index)
79{
80 struct fw_iso_packet p;
81
82 p.payload_length = MAX_PACKET_SIZE;
83 p.interrupt = !(++ctx->interrupt_packet & (IRQ_INTERVAL - 1));
84 p.skip = 0;
85 p.header_length = ISO_HEADER_SIZE;
86
87 return fw_iso_context_queue(ctx->context, &p, &ctx->buffer,
88 index * MAX_PACKET_SIZE);
89}
90
91static void handle_iso(struct fw_iso_context *context, u32 cycle,
92 size_t header_length, void *header, void *data)
93{
94 struct firedtv *fdtv = data;
95 struct firedtv_receive_context *ctx = fdtv->backend_data;
96 __be32 *h, *h_end;
97 int length, err, i = ctx->current_packet;
98 char *p, *p_end;
99
100 for (h = header, h_end = h + header_length / 4; h < h_end; h++) {
101 length = be32_to_cpup(h) >> 16;
102 if (unlikely(length > MAX_PACKET_SIZE)) {
103 dev_err(fdtv->device, "length = %d\n", length);
104 length = MAX_PACKET_SIZE;
105 }
106
107 p = ctx->pages[i / PACKETS_PER_PAGE]
108 + (i % PACKETS_PER_PAGE) * MAX_PACKET_SIZE;
109 p_end = p + length;
110
111 for (p += CIP_HEADER_SIZE + MPEG2_TS_HEADER_SIZE; p < p_end;
112 p += MPEG2_TS_SOURCE_PACKET_SIZE)
113 dvb_dmx_swfilter_packets(&fdtv->demux, p, 1);
114
115 err = queue_iso(ctx, i);
116 if (unlikely(err))
117 dev_err(fdtv->device, "requeue failed\n");
118
119 i = (i + 1) & (N_PACKETS - 1);
120 }
121 ctx->current_packet = i;
122}
123
124static int start_iso(struct firedtv *fdtv)
125{
126 struct firedtv_receive_context *ctx;
127 struct fw_device *device = device_of(fdtv);
128 int i, err;
129
130 ctx = kmalloc(sizeof(*ctx), GFP_KERNEL);
131 if (!ctx)
132 return -ENOMEM;
133
134 ctx->context = fw_iso_context_create(device->card,
135 FW_ISO_CONTEXT_RECEIVE, fdtv->isochannel,
136 device->max_speed, ISO_HEADER_SIZE, handle_iso, fdtv);
137 if (IS_ERR(ctx->context)) {
138 err = PTR_ERR(ctx->context);
139 goto fail_free;
140 }
141
142 err = fw_iso_buffer_init(&ctx->buffer, device->card,
143 N_PAGES, DMA_FROM_DEVICE);
144 if (err)
145 goto fail_context_destroy;
146
147 ctx->interrupt_packet = 0;
148 ctx->current_packet = 0;
149
150 for (i = 0; i < N_PAGES; i++)
151 ctx->pages[i] = page_address(ctx->buffer.pages[i]);
152
153 for (i = 0; i < N_PACKETS; i++) {
154 err = queue_iso(ctx, i);
155 if (err)
156 goto fail;
157 }
158
159 err = fw_iso_context_start(ctx->context, -1, 0,
160 FW_ISO_CONTEXT_MATCH_ALL_TAGS);
161 if (err)
162 goto fail;
163
164 fdtv->backend_data = ctx;
165
166 return 0;
167fail:
168 fw_iso_buffer_destroy(&ctx->buffer, device->card);
169fail_context_destroy:
170 fw_iso_context_destroy(ctx->context);
171fail_free:
172 kfree(ctx);
173
174 return err;
175}
176
177static void stop_iso(struct firedtv *fdtv)
178{
179 struct firedtv_receive_context *ctx = fdtv->backend_data;
180
181 fw_iso_context_stop(ctx->context);
182 fw_iso_buffer_destroy(&ctx->buffer, device_of(fdtv)->card);
183 fw_iso_context_destroy(ctx->context);
184 kfree(ctx);
185}
186
187static const struct firedtv_backend backend = {
188 .lock = node_lock,
189 .read = node_read,
190 .write = node_write,
191 .start_iso = start_iso,
192 .stop_iso = stop_iso,
193};
194
195static void handle_fcp(struct fw_card *card, struct fw_request *request,
196 int tcode, int destination, int source, int generation,
197 int speed, unsigned long long offset,
198 void *payload, size_t length, void *callback_data)
199{
200 struct firedtv *f, *fdtv = NULL;
201 struct fw_device *device;
202 unsigned long flags;
203 int su;
204
205 if ((tcode != TCODE_WRITE_QUADLET_REQUEST &&
206 tcode != TCODE_WRITE_BLOCK_REQUEST) ||
207 offset != CSR_REGISTER_BASE + CSR_FCP_RESPONSE ||
208 length == 0 ||
209 (((u8 *)payload)[0] & 0xf0) != 0) {
210 fw_send_response(card, request, RCODE_TYPE_ERROR);
211 return;
212 }
213
214 su = ((u8 *)payload)[1] & 0x7;
215
216 spin_lock_irqsave(&node_list_lock, flags);
217 list_for_each_entry(f, &node_list, list) {
218 device = device_of(f);
219 if (device->generation != generation)
220 continue;
221
222 smp_rmb(); /* node_id vs. generation */
223
224 if (device->card == card &&
225 device->node_id == source &&
226 (f->subunit == su || (f->subunit == 0 && su == 0x7))) {
227 fdtv = f;
228 break;
229 }
230 }
231 spin_unlock_irqrestore(&node_list_lock, flags);
232
233 if (fdtv) {
234 avc_recv(fdtv, payload, length);
235 fw_send_response(card, request, RCODE_COMPLETE);
236 }
237}
238
239static struct fw_address_handler fcp_handler = {
240 .length = CSR_FCP_END - CSR_FCP_RESPONSE,
241 .address_callback = handle_fcp,
242};
243
244static const struct fw_address_region fcp_region = {
245 .start = CSR_REGISTER_BASE + CSR_FCP_RESPONSE,
246 .end = CSR_REGISTER_BASE + CSR_FCP_END,
247};
248
249/* Adjust the template string if models with longer names appear. */
250#define MAX_MODEL_NAME_LEN ((int)DIV_ROUND_UP(sizeof("FireDTV ????"), 4))
251
252static size_t model_name(u32 *directory, __be32 *buffer)
253{
254 struct fw_csr_iterator ci;
255 int i, length, key, value, last_key = 0;
256 u32 *block = NULL;
257
258 fw_csr_iterator_init(&ci, directory);
259 while (fw_csr_iterator_next(&ci, &key, &value)) {
260 if (last_key == CSR_MODEL &&
261 key == (CSR_DESCRIPTOR | CSR_LEAF))
262 block = ci.p - 1 + value;
263 last_key = key;
264 }
265
266 if (block == NULL)
267 return 0;
268
269 length = min((int)(block[0] >> 16) - 2, MAX_MODEL_NAME_LEN);
270 if (length <= 0)
271 return 0;
272
273 /* fast-forward to text string */
274 block += 3;
275
276 for (i = 0; i < length; i++)
277 buffer[i] = cpu_to_be32(block[i]);
278
279 return length * 4;
280}
281
282static int node_probe(struct device *dev)
283{
284 struct firedtv *fdtv;
285 __be32 name[MAX_MODEL_NAME_LEN];
286 int name_len, err;
287
288 name_len = model_name(fw_unit(dev)->directory, name);
289
290 fdtv = fdtv_alloc(dev, &backend, (char *)name, name_len);
291 if (!fdtv)
292 return -ENOMEM;
293
294 err = fdtv_register_rc(fdtv, dev);
295 if (err)
296 goto fail_free;
297
298 spin_lock_irq(&node_list_lock);
299 list_add_tail(&fdtv->list, &node_list);
300 spin_unlock_irq(&node_list_lock);
301
302 err = avc_identify_subunit(fdtv);
303 if (err)
304 goto fail;
305
306 err = fdtv_dvb_register(fdtv);
307 if (err)
308 goto fail;
309
310 avc_register_remote_control(fdtv);
311
312 return 0;
313fail:
314 spin_lock_irq(&node_list_lock);
315 list_del(&fdtv->list);
316 spin_unlock_irq(&node_list_lock);
317 fdtv_unregister_rc(fdtv);
318fail_free:
319 kfree(fdtv);
320
321 return err;
322}
323
324static int node_remove(struct device *dev)
325{
326 struct firedtv *fdtv = dev_get_drvdata(dev);
327
328 fdtv_dvb_unregister(fdtv);
329
330 spin_lock_irq(&node_list_lock);
331 list_del(&fdtv->list);
332 spin_unlock_irq(&node_list_lock);
333
334 fdtv_unregister_rc(fdtv);
335
336 kfree(fdtv);
337 return 0;
338}
339
340static void node_update(struct fw_unit *unit)
341{
342 struct firedtv *fdtv = dev_get_drvdata(&unit->device);
343
344 if (fdtv->isochannel >= 0)
345 cmp_establish_pp_connection(fdtv, fdtv->subunit,
346 fdtv->isochannel);
347}
348
349static struct fw_driver fdtv_driver = {
350 .driver = {
351 .owner = THIS_MODULE,
352 .name = "firedtv",
353 .bus = &fw_bus_type,
354 .probe = node_probe,
355 .remove = node_remove,
356 },
357 .update = node_update,
358 .id_table = fdtv_id_table,
359};
360
361int __init fdtv_fw_init(void)
362{
363 int ret;
364
365 ret = fw_core_add_address_handler(&fcp_handler, &fcp_region);
366 if (ret < 0)
367 return ret;
368
369 return driver_register(&fdtv_driver.driver);
370}
371
372void fdtv_fw_exit(void)
373{
374 driver_unregister(&fdtv_driver.driver);
375 fw_core_remove_address_handler(&fcp_handler);
376}
diff --git a/drivers/media/dvb/firewire/firedtv-rc.c b/drivers/media/dvb/firewire/firedtv-rc.c
index 27bca2e283df..599d66e5843d 100644
--- a/drivers/media/dvb/firewire/firedtv-rc.c
+++ b/drivers/media/dvb/firewire/firedtv-rc.c
@@ -14,6 +14,7 @@
14#include <linux/kernel.h> 14#include <linux/kernel.h>
15#include <linux/string.h> 15#include <linux/string.h>
16#include <linux/types.h> 16#include <linux/types.h>
17#include <linux/workqueue.h>
17 18
18#include "firedtv.h" 19#include "firedtv.h"
19 20
@@ -163,6 +164,7 @@ fail:
163 164
164void fdtv_unregister_rc(struct firedtv *fdtv) 165void fdtv_unregister_rc(struct firedtv *fdtv)
165{ 166{
167 cancel_work_sync(&fdtv->remote_ctrl_work);
166 kfree(fdtv->remote_ctrl_dev->keycode); 168 kfree(fdtv->remote_ctrl_dev->keycode);
167 input_unregister_device(fdtv->remote_ctrl_dev); 169 input_unregister_device(fdtv->remote_ctrl_dev);
168} 170}
diff --git a/drivers/media/dvb/firewire/firedtv.h b/drivers/media/dvb/firewire/firedtv.h
index d48530b81e61..35080dbb3c66 100644
--- a/drivers/media/dvb/firewire/firedtv.h
+++ b/drivers/media/dvb/firewire/firedtv.h
@@ -16,6 +16,7 @@
16#include <linux/dvb/dmx.h> 16#include <linux/dvb/dmx.h>
17#include <linux/dvb/frontend.h> 17#include <linux/dvb/frontend.h>
18#include <linux/list.h> 18#include <linux/list.h>
19#include <linux/mod_devicetable.h>
19#include <linux/mutex.h> 20#include <linux/mutex.h>
20#include <linux/spinlock_types.h> 21#include <linux/spinlock_types.h>
21#include <linux/types.h> 22#include <linux/types.h>
@@ -72,8 +73,8 @@ struct input_dev;
72struct firedtv; 73struct firedtv;
73 74
74struct firedtv_backend { 75struct firedtv_backend {
75 int (*lock)(struct firedtv *fdtv, u64 addr, void *data, __be32 arg); 76 int (*lock)(struct firedtv *fdtv, u64 addr, __be32 data[]);
76 int (*read)(struct firedtv *fdtv, u64 addr, void *data, size_t len); 77 int (*read)(struct firedtv *fdtv, u64 addr, void *data);
77 int (*write)(struct firedtv *fdtv, u64 addr, void *data, size_t len); 78 int (*write)(struct firedtv *fdtv, u64 addr, void *data, size_t len);
78 int (*start_iso)(struct firedtv *fdtv); 79 int (*start_iso)(struct firedtv *fdtv);
79 void (*stop_iso)(struct firedtv *fdtv); 80 void (*stop_iso)(struct firedtv *fdtv);
@@ -119,10 +120,10 @@ struct firedtv {
119 120
120/* firedtv-1394.c */ 121/* firedtv-1394.c */
121#ifdef CONFIG_DVB_FIREDTV_IEEE1394 122#ifdef CONFIG_DVB_FIREDTV_IEEE1394
122int fdtv_1394_init(struct ieee1394_device_id id_table[]); 123int fdtv_1394_init(void);
123void fdtv_1394_exit(void); 124void fdtv_1394_exit(void);
124#else 125#else
125static inline int fdtv_1394_init(struct ieee1394_device_id it[]) { return 0; } 126static inline int fdtv_1394_init(void) { return 0; }
126static inline void fdtv_1394_exit(void) {} 127static inline void fdtv_1394_exit(void) {}
127#endif 128#endif
128 129
@@ -163,10 +164,20 @@ struct firedtv *fdtv_alloc(struct device *dev,
163 const struct firedtv_backend *backend, 164 const struct firedtv_backend *backend,
164 const char *name, size_t name_len); 165 const char *name, size_t name_len);
165extern const char *fdtv_model_names[]; 166extern const char *fdtv_model_names[];
167extern const struct ieee1394_device_id fdtv_id_table[];
166 168
167/* firedtv-fe.c */ 169/* firedtv-fe.c */
168void fdtv_frontend_init(struct firedtv *fdtv); 170void fdtv_frontend_init(struct firedtv *fdtv);
169 171
172/* firedtv-fw.c */
173#ifdef CONFIG_DVB_FIREDTV_FIREWIRE
174int fdtv_fw_init(void);
175void fdtv_fw_exit(void);
176#else
177static inline int fdtv_fw_init(void) { return 0; }
178static inline void fdtv_fw_exit(void) {}
179#endif
180
170/* firedtv-rc.c */ 181/* firedtv-rc.c */
171#ifdef CONFIG_DVB_FIREDTV_INPUT 182#ifdef CONFIG_DVB_FIREDTV_INPUT
172int fdtv_register_rc(struct firedtv *fdtv, struct device *dev); 183int fdtv_register_rc(struct firedtv *fdtv, struct device *dev);
diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig
index d7c4837fa71c..58aac018f109 100644
--- a/drivers/media/dvb/frontends/Kconfig
+++ b/drivers/media/dvb/frontends/Kconfig
@@ -201,6 +201,13 @@ config DVB_SI21XX
201 help 201 help
202 A DVB-S tuner module. Say Y when you want to support this frontend. 202 A DVB-S tuner module. Say Y when you want to support this frontend.
203 203
204config DVB_DS3000
205 tristate "Montage Tehnology DS3000 based"
206 depends on DVB_CORE && I2C
207 default m if DVB_FE_CUSTOMISE
208 help
209 A DVB-S/S2 tuner module. Say Y when you want to support this frontend.
210
204comment "DVB-T (terrestrial) frontends" 211comment "DVB-T (terrestrial) frontends"
205 depends on DVB_CORE 212 depends on DVB_CORE
206 213
@@ -342,6 +349,13 @@ config DVB_AF9013
342 help 349 help
343 Say Y when you want to support this frontend. 350 Say Y when you want to support this frontend.
344 351
352config DVB_EC100
353 tristate "E3C EC100"
354 depends on DVB_CORE && I2C
355 default m if DVB_FE_CUSTOMISE
356 help
357 Say Y when you want to support this frontend.
358
345comment "DVB-C (cable) frontends" 359comment "DVB-C (cable) frontends"
346 depends on DVB_CORE 360 depends on DVB_CORE
347 361
@@ -557,6 +571,13 @@ config DVB_LGS8GXX
557 help 571 help
558 A DMB-TH tuner module. Say Y when you want to support this frontend. 572 A DMB-TH tuner module. Say Y when you want to support this frontend.
559 573
574config DVB_ATBM8830
575 tristate "AltoBeam ATBM8830/8831 DMB-TH demodulator"
576 depends on DVB_CORE && I2C
577 default m if DVB_FE_CUSTOMISE
578 help
579 A DMB-TH tuner module. Say Y when you want to support this frontend.
580
560comment "Tools to develop new frontends" 581comment "Tools to develop new frontends"
561 582
562config DVB_DUMMY_FE 583config DVB_DUMMY_FE
diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile
index 3523767e7a76..823482535d11 100644
--- a/drivers/media/dvb/frontends/Makefile
+++ b/drivers/media/dvb/frontends/Makefile
@@ -64,6 +64,7 @@ obj-$(CONFIG_DVB_TUNER_CX24113) += cx24113.o
64obj-$(CONFIG_DVB_S5H1411) += s5h1411.o 64obj-$(CONFIG_DVB_S5H1411) += s5h1411.o
65obj-$(CONFIG_DVB_LGS8GL5) += lgs8gl5.o 65obj-$(CONFIG_DVB_LGS8GL5) += lgs8gl5.o
66obj-$(CONFIG_DVB_LGS8GXX) += lgs8gxx.o 66obj-$(CONFIG_DVB_LGS8GXX) += lgs8gxx.o
67obj-$(CONFIG_DVB_ATBM8830) += atbm8830.o
67obj-$(CONFIG_DVB_DUMMY_FE) += dvb_dummy_fe.o 68obj-$(CONFIG_DVB_DUMMY_FE) += dvb_dummy_fe.o
68obj-$(CONFIG_DVB_AF9013) += af9013.o 69obj-$(CONFIG_DVB_AF9013) += af9013.o
69obj-$(CONFIG_DVB_CX24116) += cx24116.o 70obj-$(CONFIG_DVB_CX24116) += cx24116.o
@@ -76,3 +77,5 @@ obj-$(CONFIG_DVB_STV0900) += stv0900.o
76obj-$(CONFIG_DVB_STV090x) += stv090x.o 77obj-$(CONFIG_DVB_STV090x) += stv090x.o
77obj-$(CONFIG_DVB_STV6110x) += stv6110x.o 78obj-$(CONFIG_DVB_STV6110x) += stv6110x.o
78obj-$(CONFIG_DVB_ISL6423) += isl6423.o 79obj-$(CONFIG_DVB_ISL6423) += isl6423.o
80obj-$(CONFIG_DVB_EC100) += ec100.o
81obj-$(CONFIG_DVB_DS3000) += ds3000.o
diff --git a/drivers/media/dvb/frontends/atbm8830.c b/drivers/media/dvb/frontends/atbm8830.c
new file mode 100644
index 000000000000..59881a5944eb
--- /dev/null
+++ b/drivers/media/dvb/frontends/atbm8830.c
@@ -0,0 +1,495 @@
1/*
2 * Support for AltoBeam GB20600 (a.k.a DMB-TH) demodulator
3 * ATBM8830, ATBM8831
4 *
5 * Copyright (C) 2009 David T.L. Wong <davidtlwong@gmail.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#include <asm/div64.h>
23#include "dvb_frontend.h"
24
25#include "atbm8830.h"
26#include "atbm8830_priv.h"
27
28#define dprintk(args...) \
29 do { \
30 if (debug) \
31 printk(KERN_DEBUG "atbm8830: " args); \
32 } while (0)
33
34static int debug;
35
36module_param(debug, int, 0644);
37MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
38
39static int atbm8830_write_reg(struct atbm_state *priv, u16 reg, u8 data)
40{
41 int ret = 0;
42 u8 dev_addr;
43 u8 buf1[] = { reg >> 8, reg & 0xFF };
44 u8 buf2[] = { data };
45 struct i2c_msg msg1 = { .flags = 0, .buf = buf1, .len = 2 };
46 struct i2c_msg msg2 = { .flags = 0, .buf = buf2, .len = 1 };
47
48 dev_addr = priv->config->demod_address;
49 msg1.addr = dev_addr;
50 msg2.addr = dev_addr;
51
52 if (debug >= 2)
53 printk(KERN_DEBUG "%s: reg=0x%04X, data=0x%02X\n",
54 __func__, reg, data);
55
56 ret = i2c_transfer(priv->i2c, &msg1, 1);
57 if (ret != 1)
58 return -EIO;
59
60 ret = i2c_transfer(priv->i2c, &msg2, 1);
61 return (ret != 1) ? -EIO : 0;
62}
63
64static int atbm8830_read_reg(struct atbm_state *priv, u16 reg, u8 *p_data)
65{
66 int ret;
67 u8 dev_addr;
68
69 u8 buf1[] = { reg >> 8, reg & 0xFF };
70 u8 buf2[] = { 0 };
71 struct i2c_msg msg1 = { .flags = 0, .buf = buf1, .len = 2 };
72 struct i2c_msg msg2 = { .flags = I2C_M_RD, .buf = buf2, .len = 1 };
73
74 dev_addr = priv->config->demod_address;
75 msg1.addr = dev_addr;
76 msg2.addr = dev_addr;
77
78 ret = i2c_transfer(priv->i2c, &msg1, 1);
79 if (ret != 1) {
80 dprintk(KERN_DEBUG "%s: error reg=0x%04x, ret=%i\n",
81 __func__, reg, ret);
82 return -EIO;
83 }
84
85 ret = i2c_transfer(priv->i2c, &msg2, 1);
86 if (ret != 1)
87 return -EIO;
88
89 *p_data = buf2[0];
90 if (debug >= 2)
91 printk(KERN_DEBUG "%s: reg=0x%04X, data=0x%02X\n",
92 __func__, reg, buf2[0]);
93
94 return 0;
95}
96
97/* Lock register latch so that multi-register read is atomic */
98static inline int atbm8830_reglatch_lock(struct atbm_state *priv, int lock)
99{
100 return atbm8830_write_reg(priv, REG_READ_LATCH, lock ? 1 : 0);
101}
102
103static int set_osc_freq(struct atbm_state *priv, u32 freq /*in kHz*/)
104{
105 u32 val;
106 u64 t;
107
108 /* 0x100000 * freq / 30.4MHz */
109 t = (u64)0x100000 * freq;
110 do_div(t, 30400);
111 val = t;
112
113 atbm8830_write_reg(priv, REG_OSC_CLK, val);
114 atbm8830_write_reg(priv, REG_OSC_CLK + 1, val >> 8);
115 atbm8830_write_reg(priv, REG_OSC_CLK + 2, val >> 16);
116
117 return 0;
118}
119
120static int set_if_freq(struct atbm_state *priv, u32 freq /*in kHz*/)
121{
122
123 u32 fs = priv->config->osc_clk_freq;
124 u64 t;
125 u32 val;
126 u8 dat;
127
128 if (freq != 0) {
129 /* 2 * PI * (freq - fs) / fs * (2 ^ 22) */
130 t = (u64) 2 * 31416 * (freq - fs);
131 t <<= 22;
132 do_div(t, fs);
133 do_div(t, 1000);
134 val = t;
135
136 atbm8830_write_reg(priv, REG_TUNER_BASEBAND, 1);
137 atbm8830_write_reg(priv, REG_IF_FREQ, val);
138 atbm8830_write_reg(priv, REG_IF_FREQ+1, val >> 8);
139 atbm8830_write_reg(priv, REG_IF_FREQ+2, val >> 16);
140
141 atbm8830_read_reg(priv, REG_ADC_CONFIG, &dat);
142 dat &= 0xFC;
143 atbm8830_write_reg(priv, REG_ADC_CONFIG, dat);
144 } else {
145 /* Zero IF */
146 atbm8830_write_reg(priv, REG_TUNER_BASEBAND, 0);
147
148 atbm8830_read_reg(priv, REG_ADC_CONFIG, &dat);
149 dat &= 0xFC;
150 dat |= 0x02;
151 atbm8830_write_reg(priv, REG_ADC_CONFIG, dat);
152
153 if (priv->config->zif_swap_iq)
154 atbm8830_write_reg(priv, REG_SWAP_I_Q, 0x03);
155 else
156 atbm8830_write_reg(priv, REG_SWAP_I_Q, 0x01);
157 }
158
159 return 0;
160}
161
162static int is_locked(struct atbm_state *priv, u8 *locked)
163{
164 u8 status;
165
166 atbm8830_read_reg(priv, REG_LOCK_STATUS, &status);
167
168 if (locked != NULL)
169 *locked = (status == 1);
170 return 0;
171}
172
173
174static int set_static_channel_mode(struct atbm_state *priv)
175{
176 int i;
177
178 for (i = 0; i < 5; i++)
179 atbm8830_write_reg(priv, 0x099B + i, 0x08);
180
181 atbm8830_write_reg(priv, 0x095B, 0x7F);
182 atbm8830_write_reg(priv, 0x09CB, 0x01);
183 atbm8830_write_reg(priv, 0x09CC, 0x7F);
184 atbm8830_write_reg(priv, 0x09CD, 0x7F);
185 atbm8830_write_reg(priv, 0x0E01, 0x20);
186
187 /* For single carrier */
188 atbm8830_write_reg(priv, 0x0B03, 0x0A);
189 atbm8830_write_reg(priv, 0x0935, 0x10);
190 atbm8830_write_reg(priv, 0x0936, 0x08);
191 atbm8830_write_reg(priv, 0x093E, 0x08);
192 atbm8830_write_reg(priv, 0x096E, 0x06);
193
194 /* frame_count_max0 */
195 atbm8830_write_reg(priv, 0x0B09, 0x00);
196 /* frame_count_max1 */
197 atbm8830_write_reg(priv, 0x0B0A, 0x08);
198
199 return 0;
200}
201
202static int set_ts_config(struct atbm_state *priv)
203{
204 const struct atbm8830_config *cfg = priv->config;
205
206 /*Set parallel/serial ts mode*/
207 atbm8830_write_reg(priv, REG_TS_SERIAL, cfg->serial_ts ? 1 : 0);
208 atbm8830_write_reg(priv, REG_TS_CLK_MODE, cfg->serial_ts ? 1 : 0);
209 /*Set ts sampling edge*/
210 atbm8830_write_reg(priv, REG_TS_SAMPLE_EDGE,
211 cfg->ts_sampling_edge ? 1 : 0);
212 /*Set ts clock freerun*/
213 atbm8830_write_reg(priv, REG_TS_CLK_FREERUN,
214 cfg->ts_clk_gated ? 0 : 1);
215
216 return 0;
217}
218
219static int atbm8830_init(struct dvb_frontend *fe)
220{
221 struct atbm_state *priv = fe->demodulator_priv;
222 const struct atbm8830_config *cfg = priv->config;
223
224 /*Set oscillator frequency*/
225 set_osc_freq(priv, cfg->osc_clk_freq);
226
227 /*Set IF frequency*/
228 set_if_freq(priv, cfg->if_freq);
229
230
231 /*Set static channel mode*/
232 set_static_channel_mode(priv);
233
234 set_ts_config(priv);
235 /*Turn off DSP reset*/
236 atbm8830_write_reg(priv, 0x000A, 0);
237
238 /*SW version test*/
239 atbm8830_write_reg(priv, 0x020C, 11);
240
241 /* Run */
242 atbm8830_write_reg(priv, REG_DEMOD_RUN, 1);
243
244 return 0;
245}
246
247
248static void atbm8830_release(struct dvb_frontend *fe)
249{
250 struct atbm_state *state = fe->demodulator_priv;
251 dprintk("%s\n", __func__);
252
253 kfree(state);
254}
255
256static int atbm8830_set_fe(struct dvb_frontend *fe,
257 struct dvb_frontend_parameters *fe_params)
258{
259 struct atbm_state *priv = fe->demodulator_priv;
260 int i;
261 u8 locked = 0;
262 dprintk("%s\n", __func__);
263
264 /* set frequency */
265 if (fe->ops.tuner_ops.set_params) {
266 if (fe->ops.i2c_gate_ctrl)
267 fe->ops.i2c_gate_ctrl(fe, 1);
268 fe->ops.tuner_ops.set_params(fe, fe_params);
269 if (fe->ops.i2c_gate_ctrl)
270 fe->ops.i2c_gate_ctrl(fe, 0);
271 }
272
273 /* start auto lock */
274 for (i = 0; i < 10; i++) {
275 mdelay(100);
276 dprintk("Try %d\n", i);
277 is_locked(priv, &locked);
278 if (locked != 0) {
279 dprintk("ATBM8830 locked!\n");
280 break;
281 }
282 }
283
284 return 0;
285}
286
287static int atbm8830_get_fe(struct dvb_frontend *fe,
288 struct dvb_frontend_parameters *fe_params)
289{
290 dprintk("%s\n", __func__);
291
292 /* TODO: get real readings from device */
293 /* inversion status */
294 fe_params->inversion = INVERSION_OFF;
295
296 /* bandwidth */
297 fe_params->u.ofdm.bandwidth = BANDWIDTH_8_MHZ;
298
299 fe_params->u.ofdm.code_rate_HP = FEC_AUTO;
300 fe_params->u.ofdm.code_rate_LP = FEC_AUTO;
301
302 fe_params->u.ofdm.constellation = QAM_AUTO;
303
304 /* transmission mode */
305 fe_params->u.ofdm.transmission_mode = TRANSMISSION_MODE_AUTO;
306
307 /* guard interval */
308 fe_params->u.ofdm.guard_interval = GUARD_INTERVAL_AUTO;
309
310 /* hierarchy */
311 fe_params->u.ofdm.hierarchy_information = HIERARCHY_NONE;
312
313 return 0;
314}
315
316static int atbm8830_get_tune_settings(struct dvb_frontend *fe,
317 struct dvb_frontend_tune_settings *fesettings)
318{
319 fesettings->min_delay_ms = 0;
320 fesettings->step_size = 0;
321 fesettings->max_drift = 0;
322 return 0;
323}
324
325static int atbm8830_read_status(struct dvb_frontend *fe, fe_status_t *fe_status)
326{
327 struct atbm_state *priv = fe->demodulator_priv;
328 u8 locked = 0;
329 u8 agc_locked = 0;
330
331 dprintk("%s\n", __func__);
332 *fe_status = 0;
333
334 is_locked(priv, &locked);
335 if (locked) {
336 *fe_status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
337 FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
338 }
339 dprintk("%s: fe_status=0x%x\n", __func__, *fe_status);
340
341 atbm8830_read_reg(priv, REG_AGC_LOCK, &agc_locked);
342 dprintk("AGC Lock: %d\n", agc_locked);
343
344 return 0;
345}
346
347static int atbm8830_read_ber(struct dvb_frontend *fe, u32 *ber)
348{
349 struct atbm_state *priv = fe->demodulator_priv;
350 u32 frame_err;
351 u8 t;
352
353 dprintk("%s\n", __func__);
354
355 atbm8830_reglatch_lock(priv, 1);
356
357 atbm8830_read_reg(priv, REG_FRAME_ERR_CNT + 1, &t);
358 frame_err = t & 0x7F;
359 frame_err <<= 8;
360 atbm8830_read_reg(priv, REG_FRAME_ERR_CNT, &t);
361 frame_err |= t;
362
363 atbm8830_reglatch_lock(priv, 0);
364
365 *ber = frame_err * 100 / 32767;
366
367 dprintk("%s: ber=0x%x\n", __func__, *ber);
368 return 0;
369}
370
371static int atbm8830_read_signal_strength(struct dvb_frontend *fe, u16 *signal)
372{
373 struct atbm_state *priv = fe->demodulator_priv;
374 u32 pwm;
375 u8 t;
376
377 dprintk("%s\n", __func__);
378 atbm8830_reglatch_lock(priv, 1);
379
380 atbm8830_read_reg(priv, REG_AGC_PWM_VAL + 1, &t);
381 pwm = t & 0x03;
382 pwm <<= 8;
383 atbm8830_read_reg(priv, REG_AGC_PWM_VAL, &t);
384 pwm |= t;
385
386 atbm8830_reglatch_lock(priv, 0);
387
388 dprintk("AGC PWM = 0x%02X\n", pwm);
389 pwm = 0x400 - pwm;
390
391 *signal = pwm * 0x10000 / 0x400;
392
393 return 0;
394}
395
396static int atbm8830_read_snr(struct dvb_frontend *fe, u16 *snr)
397{
398 dprintk("%s\n", __func__);
399 *snr = 0;
400 return 0;
401}
402
403static int atbm8830_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
404{
405 dprintk("%s\n", __func__);
406 *ucblocks = 0;
407 return 0;
408}
409
410static int atbm8830_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
411{
412 struct atbm_state *priv = fe->demodulator_priv;
413
414 return atbm8830_write_reg(priv, REG_I2C_GATE, enable ? 1 : 0);
415}
416
417static struct dvb_frontend_ops atbm8830_ops = {
418 .info = {
419 .name = "AltoBeam ATBM8830/8831 DMB-TH",
420 .type = FE_OFDM,
421 .frequency_min = 474000000,
422 .frequency_max = 858000000,
423 .frequency_stepsize = 10000,
424 .caps =
425 FE_CAN_FEC_AUTO |
426 FE_CAN_QAM_AUTO |
427 FE_CAN_TRANSMISSION_MODE_AUTO |
428 FE_CAN_GUARD_INTERVAL_AUTO
429 },
430
431 .release = atbm8830_release,
432
433 .init = atbm8830_init,
434 .sleep = NULL,
435 .write = NULL,
436 .i2c_gate_ctrl = atbm8830_i2c_gate_ctrl,
437
438 .set_frontend = atbm8830_set_fe,
439 .get_frontend = atbm8830_get_fe,
440 .get_tune_settings = atbm8830_get_tune_settings,
441
442 .read_status = atbm8830_read_status,
443 .read_ber = atbm8830_read_ber,
444 .read_signal_strength = atbm8830_read_signal_strength,
445 .read_snr = atbm8830_read_snr,
446 .read_ucblocks = atbm8830_read_ucblocks,
447};
448
449struct dvb_frontend *atbm8830_attach(const struct atbm8830_config *config,
450 struct i2c_adapter *i2c)
451{
452 struct atbm_state *priv = NULL;
453 u8 data = 0;
454
455 dprintk("%s()\n", __func__);
456
457 if (config == NULL || i2c == NULL)
458 return NULL;
459
460 priv = kzalloc(sizeof(struct atbm_state), GFP_KERNEL);
461 if (priv == NULL)
462 goto error_out;
463
464 priv->config = config;
465 priv->i2c = i2c;
466
467 /* check if the demod is there */
468 if (atbm8830_read_reg(priv, REG_CHIP_ID, &data) != 0) {
469 dprintk("%s atbm8830/8831 not found at i2c addr 0x%02X\n",
470 __func__, priv->config->demod_address);
471 goto error_out;
472 }
473 dprintk("atbm8830 chip id: 0x%02X\n", data);
474
475 memcpy(&priv->frontend.ops, &atbm8830_ops,
476 sizeof(struct dvb_frontend_ops));
477 priv->frontend.demodulator_priv = priv;
478
479 atbm8830_init(&priv->frontend);
480
481 atbm8830_i2c_gate_ctrl(&priv->frontend, 1);
482
483 return &priv->frontend;
484
485error_out:
486 dprintk("%s() error_out\n", __func__);
487 kfree(priv);
488 return NULL;
489
490}
491EXPORT_SYMBOL(atbm8830_attach);
492
493MODULE_DESCRIPTION("AltoBeam ATBM8830/8831 GB20600 demodulator driver");
494MODULE_AUTHOR("David T. L. Wong <davidtlwong@gmail.com>");
495MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/atbm8830.h b/drivers/media/dvb/frontends/atbm8830.h
new file mode 100644
index 000000000000..e8149f393300
--- /dev/null
+++ b/drivers/media/dvb/frontends/atbm8830.h
@@ -0,0 +1,76 @@
1/*
2 * Support for AltoBeam GB20600 (a.k.a DMB-TH) demodulator
3 * ATBM8830, ATBM8831
4 *
5 * Copyright (C) 2009 David T.L. Wong <davidtlwong@gmail.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#ifndef __ATBM8830_H__
23#define __ATBM8830_H__
24
25#include <linux/dvb/frontend.h>
26#include <linux/i2c.h>
27
28#define ATBM8830_PROD_8830 0
29#define ATBM8830_PROD_8831 1
30
31struct atbm8830_config {
32
33 /* product type */
34 u8 prod;
35
36 /* the demodulator's i2c address */
37 u8 demod_address;
38
39 /* parallel or serial transport stream */
40 u8 serial_ts;
41
42 /* transport stream clock output only when receving valid stream */
43 u8 ts_clk_gated;
44
45 /* Decoder sample TS data at rising edge of clock */
46 u8 ts_sampling_edge;
47
48 /* Oscillator clock frequency */
49 u32 osc_clk_freq; /* in kHz */
50
51 /* IF frequency */
52 u32 if_freq; /* in kHz */
53
54 /* Swap I/Q for zero IF */
55 u8 zif_swap_iq;
56
57 /* Tuner AGC settings */
58 u8 agc_min;
59 u8 agc_max;
60 u8 agc_hold_loop;
61};
62
63#if defined(CONFIG_DVB_ATBM8830) || \
64 (defined(CONFIG_DVB_ATBM8830_MODULE) && defined(MODULE))
65extern struct dvb_frontend *atbm8830_attach(const struct atbm8830_config *config,
66 struct i2c_adapter *i2c);
67#else
68static inline
69struct dvb_frontend *atbm8830_attach(const struct atbm8830_config *config,
70 struct i2c_adapter *i2c) {
71 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
72 return NULL;
73}
74#endif /* CONFIG_DVB_ATBM8830 */
75
76#endif /* __ATBM8830_H__ */
diff --git a/drivers/media/dvb/frontends/atbm8830_priv.h b/drivers/media/dvb/frontends/atbm8830_priv.h
new file mode 100644
index 000000000000..ce960f76092a
--- /dev/null
+++ b/drivers/media/dvb/frontends/atbm8830_priv.h
@@ -0,0 +1,75 @@
1/*
2 * Support for AltoBeam GB20600 (a.k.a DMB-TH) demodulator
3 * ATBM8830, ATBM8831
4 *
5 * Copyright (C) 2009 David T.L. Wong <davidtlwong@gmail.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#ifndef __ATBM8830_PRIV_H
23#define __ATBM8830_PRIV_H
24
25struct atbm_state {
26 struct i2c_adapter *i2c;
27 /* configuration settings */
28 const struct atbm8830_config *config;
29 struct dvb_frontend frontend;
30};
31
32#define REG_CHIP_ID 0x0000
33#define REG_TUNER_BASEBAND 0x0001
34#define REG_DEMOD_RUN 0x0004
35#define REG_DSP_RESET 0x0005
36#define REG_RAM_RESET 0x0006
37#define REG_ADC_RESET 0x0007
38#define REG_TSPORT_RESET 0x0008
39#define REG_BLKERR_POL 0x000C
40#define REG_I2C_GATE 0x0103
41#define REG_TS_SAMPLE_EDGE 0x0301
42#define REG_TS_PKT_LEN_204 0x0302
43#define REG_TS_PKT_LEN_AUTO 0x0303
44#define REG_TS_SERIAL 0x0305
45#define REG_TS_CLK_FREERUN 0x0306
46#define REG_TS_VALID_MODE 0x0307
47#define REG_TS_CLK_MODE 0x030B /* 1 for serial, 0 for parallel */
48
49#define REG_TS_ERRBIT_USE 0x030C
50#define REG_LOCK_STATUS 0x030D
51#define REG_ADC_CONFIG 0x0602
52#define REG_CARRIER_OFFSET 0x0827 /* 0x0827-0x0829 little endian */
53#define REG_DETECTED_PN_MODE 0x082D
54#define REG_READ_LATCH 0x084D
55#define REG_IF_FREQ 0x0A00 /* 0x0A00-0x0A02 little endian */
56#define REG_OSC_CLK 0x0A03 /* 0x0A03-0x0A05 little endian */
57#define REG_BYPASS_CCI 0x0A06
58#define REG_ANALOG_LUMA_DETECTED 0x0A25
59#define REG_ANALOG_AUDIO_DETECTED 0x0A26
60#define REG_ANALOG_CHROMA_DETECTED 0x0A39
61#define REG_FRAME_ERR_CNT 0x0B04
62#define REG_USE_EXT_ADC 0x0C00
63#define REG_SWAP_I_Q 0x0C01
64#define REG_TPS_MANUAL 0x0D01
65#define REG_TPS_CONFIG 0x0D02
66#define REG_BYPASS_DEINTERLEAVER 0x0E00
67#define REG_AGC_TARGET 0x1003 /* 0x1003-0x1005 little endian */
68#define REG_AGC_MIN 0x1020
69#define REG_AGC_MAX 0x1023
70#define REG_AGC_LOCK 0x1027
71#define REG_AGC_PWM_VAL 0x1028 /* 0x1028-0x1029 little endian */
72#define REG_AGC_HOLD_LOOP 0x1031
73
74#endif
75
diff --git a/drivers/media/dvb/frontends/au8522_decoder.c b/drivers/media/dvb/frontends/au8522_decoder.c
index 7c6431fe33e0..2dc2723b724a 100644
--- a/drivers/media/dvb/frontends/au8522_decoder.c
+++ b/drivers/media/dvb/frontends/au8522_decoder.c
@@ -23,7 +23,6 @@
23/* Developer notes: 23/* Developer notes:
24 * 24 *
25 * VBI support is not yet working 25 * VBI support is not yet working
26 * Saturation and hue setting are not yet working
27 * Enough is implemented here for CVBS and S-Video inputs, but the actual 26 * Enough is implemented here for CVBS and S-Video inputs, but the actual
28 * analog demodulator code isn't implemented (not needed for xc5000 since it 27 * analog demodulator code isn't implemented (not needed for xc5000 since it
29 * has its own demodulator and outputs CVBS) 28 * has its own demodulator and outputs CVBS)
@@ -236,8 +235,10 @@ static void setup_decoder_defaults(struct au8522_state *state, u8 input_mode)
236 state->contrast = 0x79; 235 state->contrast = 0x79;
237 au8522_writereg(state, AU8522_TVDEC_SATURATION_CB_REG00CH, 0x80); 236 au8522_writereg(state, AU8522_TVDEC_SATURATION_CB_REG00CH, 0x80);
238 au8522_writereg(state, AU8522_TVDEC_SATURATION_CR_REG00DH, 0x80); 237 au8522_writereg(state, AU8522_TVDEC_SATURATION_CR_REG00DH, 0x80);
238 state->saturation = 0x80;
239 au8522_writereg(state, AU8522_TVDEC_HUE_H_REG00EH, 0x00); 239 au8522_writereg(state, AU8522_TVDEC_HUE_H_REG00EH, 0x00);
240 au8522_writereg(state, AU8522_TVDEC_HUE_L_REG00FH, 0x00); 240 au8522_writereg(state, AU8522_TVDEC_HUE_L_REG00FH, 0x00);
241 state->hue = 0x00;
241 242
242 /* Other decoder registers */ 243 /* Other decoder registers */
243 au8522_writereg(state, AU8522_TVDEC_INT_MASK_REG010H, 0x00); 244 au8522_writereg(state, AU8522_TVDEC_INT_MASK_REG010H, 0x00);
@@ -504,7 +505,19 @@ static int au8522_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
504 ctrl->value); 505 ctrl->value);
505 break; 506 break;
506 case V4L2_CID_SATURATION: 507 case V4L2_CID_SATURATION:
508 state->saturation = ctrl->value;
509 au8522_writereg(state, AU8522_TVDEC_SATURATION_CB_REG00CH,
510 ctrl->value);
511 au8522_writereg(state, AU8522_TVDEC_SATURATION_CR_REG00DH,
512 ctrl->value);
513 break;
507 case V4L2_CID_HUE: 514 case V4L2_CID_HUE:
515 state->hue = ctrl->value;
516 au8522_writereg(state, AU8522_TVDEC_HUE_H_REG00EH,
517 ctrl->value >> 8);
518 au8522_writereg(state, AU8522_TVDEC_HUE_L_REG00FH,
519 ctrl->value & 0xFF);
520 break;
508 case V4L2_CID_AUDIO_VOLUME: 521 case V4L2_CID_AUDIO_VOLUME:
509 case V4L2_CID_AUDIO_BASS: 522 case V4L2_CID_AUDIO_BASS:
510 case V4L2_CID_AUDIO_TREBLE: 523 case V4L2_CID_AUDIO_TREBLE:
@@ -534,7 +547,11 @@ static int au8522_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
534 ctrl->value = state->contrast; 547 ctrl->value = state->contrast;
535 break; 548 break;
536 case V4L2_CID_SATURATION: 549 case V4L2_CID_SATURATION:
550 ctrl->value = state->saturation;
551 break;
537 case V4L2_CID_HUE: 552 case V4L2_CID_HUE:
553 ctrl->value = state->hue;
554 break;
538 case V4L2_CID_AUDIO_VOLUME: 555 case V4L2_CID_AUDIO_VOLUME:
539 case V4L2_CID_AUDIO_BASS: 556 case V4L2_CID_AUDIO_BASS:
540 case V4L2_CID_AUDIO_TREBLE: 557 case V4L2_CID_AUDIO_TREBLE:
@@ -632,8 +649,9 @@ static int au8522_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
632 case V4L2_CID_BRIGHTNESS: 649 case V4L2_CID_BRIGHTNESS:
633 return v4l2_ctrl_query_fill(qc, 0, 255, 1, 128); 650 return v4l2_ctrl_query_fill(qc, 0, 255, 1, 128);
634 case V4L2_CID_SATURATION: 651 case V4L2_CID_SATURATION:
652 return v4l2_ctrl_query_fill(qc, 0, 255, 1, 128);
635 case V4L2_CID_HUE: 653 case V4L2_CID_HUE:
636 /* Not yet implemented */ 654 return v4l2_ctrl_query_fill(qc, -32768, 32768, 1, 0);
637 default: 655 default:
638 break; 656 break;
639 } 657 }
diff --git a/drivers/media/dvb/frontends/au8522_priv.h b/drivers/media/dvb/frontends/au8522_priv.h
index f328f2b3ad3d..c74c4e72fe91 100644
--- a/drivers/media/dvb/frontends/au8522_priv.h
+++ b/drivers/media/dvb/frontends/au8522_priv.h
@@ -62,6 +62,8 @@ struct au8522_state {
62 u32 rev; 62 u32 rev;
63 u8 brightness; 63 u8 brightness;
64 u8 contrast; 64 u8 contrast;
65 u8 saturation;
66 s16 hue;
65}; 67};
66 68
67/* These are routines shared by both the VSB/QAM demodulator and the analog 69/* These are routines shared by both the VSB/QAM demodulator and the analog
diff --git a/drivers/media/dvb/frontends/dib7000p.c b/drivers/media/dvb/frontends/dib7000p.c
index 0781f94e05d2..750ae61a20f4 100644
--- a/drivers/media/dvb/frontends/dib7000p.c
+++ b/drivers/media/dvb/frontends/dib7000p.c
@@ -108,7 +108,7 @@ static int dib7000p_set_output_mode(struct dib7000p_state *state, int mode)
108 108
109 outreg = 0; 109 outreg = 0;
110 fifo_threshold = 1792; 110 fifo_threshold = 1792;
111 smo_mode = (dib7000p_read_word(state, 235) & 0x0010) | (1 << 1); 111 smo_mode = (dib7000p_read_word(state, 235) & 0x0050) | (1 << 1);
112 112
113 dprintk( "setting output mode for demod %p to %d", 113 dprintk( "setting output mode for demod %p to %d",
114 &state->demod, mode); 114 &state->demod, mode);
@@ -162,18 +162,19 @@ static int dib7000p_set_diversity_in(struct dvb_frontend *demod, int onoff)
162 if (state->div_force_off) { 162 if (state->div_force_off) {
163 dprintk( "diversity combination deactivated - forced by COFDM parameters"); 163 dprintk( "diversity combination deactivated - forced by COFDM parameters");
164 onoff = 0; 164 onoff = 0;
165 } 165 dib7000p_write_word(state, 207, 0);
166 } else
167 dib7000p_write_word(state, 207, (state->div_sync_wait << 4) | (1 << 2) | (2 << 0));
168
166 state->div_state = (u8)onoff; 169 state->div_state = (u8)onoff;
167 170
168 if (onoff) { 171 if (onoff) {
169 dib7000p_write_word(state, 204, 6); 172 dib7000p_write_word(state, 204, 6);
170 dib7000p_write_word(state, 205, 16); 173 dib7000p_write_word(state, 205, 16);
171 /* P_dvsy_sync_mode = 0, P_dvsy_sync_enable=1, P_dvcb_comb_mode=2 */ 174 /* P_dvsy_sync_mode = 0, P_dvsy_sync_enable=1, P_dvcb_comb_mode=2 */
172 dib7000p_write_word(state, 207, (state->div_sync_wait << 4) | (1 << 2) | (2 << 0));
173 } else { 175 } else {
174 dib7000p_write_word(state, 204, 1); 176 dib7000p_write_word(state, 204, 1);
175 dib7000p_write_word(state, 205, 0); 177 dib7000p_write_word(state, 205, 0);
176 dib7000p_write_word(state, 207, 0);
177 } 178 }
178 179
179 return 0; 180 return 0;
@@ -1188,7 +1189,7 @@ static int dib7000p_read_status(struct dvb_frontend *fe, fe_status_t *stat)
1188 *stat |= FE_HAS_VITERBI; 1189 *stat |= FE_HAS_VITERBI;
1189 if (lock & 0x0010) 1190 if (lock & 0x0010)
1190 *stat |= FE_HAS_SYNC; 1191 *stat |= FE_HAS_SYNC;
1191 if (lock & 0x0008) 1192 if ((lock & 0x0038) == 0x38)
1192 *stat |= FE_HAS_LOCK; 1193 *stat |= FE_HAS_LOCK;
1193 1194
1194 return 0; 1195 return 0;
@@ -1302,6 +1303,24 @@ struct i2c_adapter * dib7000p_get_i2c_master(struct dvb_frontend *demod, enum di
1302} 1303}
1303EXPORT_SYMBOL(dib7000p_get_i2c_master); 1304EXPORT_SYMBOL(dib7000p_get_i2c_master);
1304 1305
1306int dib7000p_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff)
1307{
1308 struct dib7000p_state *state = fe->demodulator_priv;
1309 u16 val = dib7000p_read_word(state, 235) & 0xffef;
1310 val |= (onoff & 0x1) << 4;
1311 dprintk("PID filter enabled %d", onoff);
1312 return dib7000p_write_word(state, 235, val);
1313}
1314EXPORT_SYMBOL(dib7000p_pid_filter_ctrl);
1315
1316int dib7000p_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff)
1317{
1318 struct dib7000p_state *state = fe->demodulator_priv;
1319 dprintk("PID filter: index %x, PID %d, OnOff %d", id, pid, onoff);
1320 return dib7000p_write_word(state, 241 + id, onoff ? (1 << 13) | pid : 0);
1321}
1322EXPORT_SYMBOL(dib7000p_pid_filter);
1323
1305int dib7000p_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, struct dib7000p_config cfg[]) 1324int dib7000p_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, struct dib7000p_config cfg[])
1306{ 1325{
1307 struct dib7000p_state st = { .i2c_adap = i2c }; 1326 struct dib7000p_state st = { .i2c_adap = i2c };
@@ -1314,8 +1333,10 @@ int dib7000p_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 defau
1314 /* designated i2c address */ 1333 /* designated i2c address */
1315 new_addr = (0x40 + k) << 1; 1334 new_addr = (0x40 + k) << 1;
1316 st.i2c_addr = new_addr; 1335 st.i2c_addr = new_addr;
1336 dib7000p_write_word(&st, 1287, 0x0003); /* sram lead in, rdy */
1317 if (dib7000p_identify(&st) != 0) { 1337 if (dib7000p_identify(&st) != 0) {
1318 st.i2c_addr = default_addr; 1338 st.i2c_addr = default_addr;
1339 dib7000p_write_word(&st, 1287, 0x0003); /* sram lead in, rdy */
1319 if (dib7000p_identify(&st) != 0) { 1340 if (dib7000p_identify(&st) != 0) {
1320 dprintk("DiB7000P #%d: not identified\n", k); 1341 dprintk("DiB7000P #%d: not identified\n", k);
1321 return -EIO; 1342 return -EIO;
@@ -1372,6 +1393,8 @@ struct dvb_frontend * dib7000p_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr,
1372 demod->demodulator_priv = st; 1393 demod->demodulator_priv = st;
1373 memcpy(&st->demod.ops, &dib7000p_ops, sizeof(struct dvb_frontend_ops)); 1394 memcpy(&st->demod.ops, &dib7000p_ops, sizeof(struct dvb_frontend_ops));
1374 1395
1396 dib7000p_write_word(st, 1287, 0x0003); /* sram lead in, rdy */
1397
1375 if (dib7000p_identify(st) != 0) 1398 if (dib7000p_identify(st) != 0)
1376 goto error; 1399 goto error;
1377 1400
diff --git a/drivers/media/dvb/frontends/dib7000p.h b/drivers/media/dvb/frontends/dib7000p.h
index 02a4c82f0c70..805dd13a97ee 100644
--- a/drivers/media/dvb/frontends/dib7000p.h
+++ b/drivers/media/dvb/frontends/dib7000p.h
@@ -51,6 +51,8 @@ extern int dib7000p_i2c_enumeration(struct i2c_adapter *i2c,
51extern int dib7000p_set_gpio(struct dvb_frontend *, u8 num, u8 dir, u8 val); 51extern int dib7000p_set_gpio(struct dvb_frontend *, u8 num, u8 dir, u8 val);
52extern int dib7000p_set_wbd_ref(struct dvb_frontend *, u16 value); 52extern int dib7000p_set_wbd_ref(struct dvb_frontend *, u16 value);
53extern int dib7000pc_detection(struct i2c_adapter *i2c_adap); 53extern int dib7000pc_detection(struct i2c_adapter *i2c_adap);
54extern int dib7000p_pid_filter(struct dvb_frontend *, u8 id, u16 pid, u8 onoff);
55extern int dib7000p_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff);
54#else 56#else
55static inline 57static inline
56struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, 58struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr,
@@ -95,6 +97,17 @@ static inline int dib7000pc_detection(struct i2c_adapter *i2c_adap)
95 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); 97 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
96 return -ENODEV; 98 return -ENODEV;
97} 99}
100static inline int dib7000p_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff)
101{
102 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
103 return -ENODEV;
104}
105
106static inline int dib7000p_pid_filter_ctrl(struct dvb_frontend *fe, uint8_t onoff)
107{
108 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
109 return -ENODEV;
110}
98#endif 111#endif
99 112
100#endif 113#endif
diff --git a/drivers/media/dvb/frontends/dib8000.c b/drivers/media/dvb/frontends/dib8000.c
index 852c790d09d9..898400d331a3 100644
--- a/drivers/media/dvb/frontends/dib8000.c
+++ b/drivers/media/dvb/frontends/dib8000.c
@@ -954,7 +954,7 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear
954 u8 guard, crate, constellation, timeI; 954 u8 guard, crate, constellation, timeI;
955 u8 permu_seg[] = { 6, 5, 7, 4, 8, 3, 9, 2, 10, 1, 11, 0, 12 }; 955 u8 permu_seg[] = { 6, 5, 7, 4, 8, 3, 9, 2, 10, 1, 11, 0, 12 };
956 u16 i, coeff[4], P_cfr_left_edge = 0, P_cfr_right_edge = 0, seg_mask13 = 0x1fff; // All 13 segments enabled 956 u16 i, coeff[4], P_cfr_left_edge = 0, P_cfr_right_edge = 0, seg_mask13 = 0x1fff; // All 13 segments enabled
957 const s16 *ncoeff, *ana_fe; 957 const s16 *ncoeff = NULL, *ana_fe;
958 u16 tmcc_pow = 0; 958 u16 tmcc_pow = 0;
959 u16 coff_pow = 0x2800; 959 u16 coff_pow = 0x2800;
960 u16 init_prbs = 0xfff; 960 u16 init_prbs = 0xfff;
@@ -2121,7 +2121,7 @@ static int dib8000_read_snr(struct dvb_frontend *fe, u16 * snr)
2121 else 2121 else
2122 result -= intlog10(2) * 10 * noise_exp - 100; 2122 result -= intlog10(2) * 10 * noise_exp - 100;
2123 2123
2124 *snr = result / (1 << 24); 2124 *snr = result / ((1 << 24) / 10);
2125 return 0; 2125 return 0;
2126} 2126}
2127 2127
@@ -2195,6 +2195,25 @@ struct i2c_adapter *dib8000_get_i2c_master(struct dvb_frontend *fe, enum dibx000
2195 2195
2196EXPORT_SYMBOL(dib8000_get_i2c_master); 2196EXPORT_SYMBOL(dib8000_get_i2c_master);
2197 2197
2198int dib8000_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff)
2199{
2200 struct dib8000_state *st = fe->demodulator_priv;
2201 u16 val = dib8000_read_word(st, 299) & 0xffef;
2202 val |= (onoff & 0x1) << 4;
2203
2204 dprintk("pid filter enabled %d", onoff);
2205 return dib8000_write_word(st, 299, val);
2206}
2207EXPORT_SYMBOL(dib8000_pid_filter_ctrl);
2208
2209int dib8000_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff)
2210{
2211 struct dib8000_state *st = fe->demodulator_priv;
2212 dprintk("Index %x, PID %d, OnOff %d", id, pid, onoff);
2213 return dib8000_write_word(st, 305 + id, onoff ? (1 << 13) | pid : 0);
2214}
2215EXPORT_SYMBOL(dib8000_pid_filter);
2216
2198static const struct dvb_frontend_ops dib8000_ops = { 2217static const struct dvb_frontend_ops dib8000_ops = {
2199 .info = { 2218 .info = {
2200 .name = "DiBcom 8000 ISDB-T", 2219 .name = "DiBcom 8000 ISDB-T",
diff --git a/drivers/media/dvb/frontends/dib8000.h b/drivers/media/dvb/frontends/dib8000.h
index a86de340dd54..8c89482b738a 100644
--- a/drivers/media/dvb/frontends/dib8000.h
+++ b/drivers/media/dvb/frontends/dib8000.h
@@ -44,6 +44,8 @@ extern int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, u
44 44
45extern int dib8000_set_gpio(struct dvb_frontend *, u8 num, u8 dir, u8 val); 45extern int dib8000_set_gpio(struct dvb_frontend *, u8 num, u8 dir, u8 val);
46extern int dib8000_set_wbd_ref(struct dvb_frontend *, u16 value); 46extern int dib8000_set_wbd_ref(struct dvb_frontend *, u16 value);
47extern int dib8000_pid_filter_ctrl(struct dvb_frontend *, u8 onoff);
48extern int dib8000_pid_filter(struct dvb_frontend *, u8 id, u16 pid, u8 onoff);
47#else 49#else
48static inline struct dvb_frontend *dib8000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib8000_config *cfg) 50static inline struct dvb_frontend *dib8000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib8000_config *cfg)
49{ 51{
@@ -74,6 +76,18 @@ int dib8000_set_wbd_ref(struct dvb_frontend *fe, u16 value)
74 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); 76 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
75 return -ENODEV; 77 return -ENODEV;
76} 78}
79
80int dib8000_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff)
81{
82 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
83 return -ENODEV;
84}
85
86int dib8000_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff)
87{
88 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
89 return -ENODEV;
90}
77#endif 91#endif
78 92
79#endif 93#endif
diff --git a/drivers/media/dvb/frontends/ds3000.c b/drivers/media/dvb/frontends/ds3000.c
new file mode 100644
index 000000000000..cff3535566fe
--- /dev/null
+++ b/drivers/media/dvb/frontends/ds3000.c
@@ -0,0 +1,1367 @@
1/*
2 Montage Technology DS3000/TS2020 - DVBS/S2 Demodulator/Tuner driver
3 Copyright (C) 2009 Konstantin Dimitrov <kosio.dimitrov@gmail.com>
4
5 Copyright (C) 2009 TurboSight.com
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#include <linux/slab.h>
23#include <linux/kernel.h>
24#include <linux/module.h>
25#include <linux/moduleparam.h>
26#include <linux/init.h>
27#include <linux/firmware.h>
28
29#include "dvb_frontend.h"
30#include "ds3000.h"
31
32static int debug;
33
34#define dprintk(args...) \
35 do { \
36 if (debug) \
37 printk(args); \
38 } while (0)
39
40/* as of March 2009 current DS3000 firmware version is 1.78 */
41/* DS3000 FW v1.78 MD5: a32d17910c4f370073f9346e71d34b80 */
42#define DS3000_DEFAULT_FIRMWARE "dvb-fe-ds3000.fw"
43
44#define DS3000_SAMPLE_RATE 96000 /* in kHz */
45#define DS3000_XTAL_FREQ 27000 /* in kHz */
46
47/* Register values to initialise the demod in DVB-S mode */
48static u8 ds3000_dvbs_init_tab[] = {
49 0x23, 0x05,
50 0x08, 0x03,
51 0x0c, 0x00,
52 0x21, 0x54,
53 0x25, 0x82,
54 0x27, 0x31,
55 0x30, 0x08,
56 0x31, 0x40,
57 0x32, 0x32,
58 0x33, 0x35,
59 0x35, 0xff,
60 0x3a, 0x00,
61 0x37, 0x10,
62 0x38, 0x10,
63 0x39, 0x02,
64 0x42, 0x60,
65 0x4a, 0x40,
66 0x4b, 0x04,
67 0x4d, 0x91,
68 0x5d, 0xc8,
69 0x50, 0x77,
70 0x51, 0x77,
71 0x52, 0x36,
72 0x53, 0x36,
73 0x56, 0x01,
74 0x63, 0x43,
75 0x64, 0x30,
76 0x65, 0x40,
77 0x68, 0x26,
78 0x69, 0x4c,
79 0x70, 0x20,
80 0x71, 0x70,
81 0x72, 0x04,
82 0x73, 0x00,
83 0x70, 0x40,
84 0x71, 0x70,
85 0x72, 0x04,
86 0x73, 0x00,
87 0x70, 0x60,
88 0x71, 0x70,
89 0x72, 0x04,
90 0x73, 0x00,
91 0x70, 0x80,
92 0x71, 0x70,
93 0x72, 0x04,
94 0x73, 0x00,
95 0x70, 0xa0,
96 0x71, 0x70,
97 0x72, 0x04,
98 0x73, 0x00,
99 0x70, 0x1f,
100 0x76, 0x00,
101 0x77, 0xd1,
102 0x78, 0x0c,
103 0x79, 0x80,
104 0x7f, 0x04,
105 0x7c, 0x00,
106 0x80, 0x86,
107 0x81, 0xa6,
108 0x85, 0x04,
109 0xcd, 0xf4,
110 0x90, 0x33,
111 0xa0, 0x44,
112 0xc0, 0x18,
113 0xc3, 0x10,
114 0xc4, 0x08,
115 0xc5, 0x80,
116 0xc6, 0x80,
117 0xc7, 0x0a,
118 0xc8, 0x1a,
119 0xc9, 0x80,
120 0xfe, 0x92,
121 0xe0, 0xf8,
122 0xe6, 0x8b,
123 0xd0, 0x40,
124 0xf8, 0x20,
125 0xfa, 0x0f,
126 0xfd, 0x20,
127 0xad, 0x20,
128 0xae, 0x07,
129 0xb8, 0x00,
130};
131
132/* Register values to initialise the demod in DVB-S2 mode */
133static u8 ds3000_dvbs2_init_tab[] = {
134 0x23, 0x0f,
135 0x08, 0x07,
136 0x0c, 0x00,
137 0x21, 0x54,
138 0x25, 0x82,
139 0x27, 0x31,
140 0x30, 0x08,
141 0x31, 0x32,
142 0x32, 0x32,
143 0x33, 0x35,
144 0x35, 0xff,
145 0x3a, 0x00,
146 0x37, 0x10,
147 0x38, 0x10,
148 0x39, 0x02,
149 0x42, 0x60,
150 0x4a, 0x80,
151 0x4b, 0x04,
152 0x4d, 0x81,
153 0x5d, 0x88,
154 0x50, 0x36,
155 0x51, 0x36,
156 0x52, 0x36,
157 0x53, 0x36,
158 0x63, 0x60,
159 0x64, 0x10,
160 0x65, 0x10,
161 0x68, 0x04,
162 0x69, 0x29,
163 0x70, 0x20,
164 0x71, 0x70,
165 0x72, 0x04,
166 0x73, 0x00,
167 0x70, 0x40,
168 0x71, 0x70,
169 0x72, 0x04,
170 0x73, 0x00,
171 0x70, 0x60,
172 0x71, 0x70,
173 0x72, 0x04,
174 0x73, 0x00,
175 0x70, 0x80,
176 0x71, 0x70,
177 0x72, 0x04,
178 0x73, 0x00,
179 0x70, 0xa0,
180 0x71, 0x70,
181 0x72, 0x04,
182 0x73, 0x00,
183 0x70, 0x1f,
184 0xa0, 0x44,
185 0xc0, 0x08,
186 0xc1, 0x10,
187 0xc2, 0x08,
188 0xc3, 0x10,
189 0xc4, 0x08,
190 0xc5, 0xf0,
191 0xc6, 0xf0,
192 0xc7, 0x0a,
193 0xc8, 0x1a,
194 0xc9, 0x80,
195 0xca, 0x23,
196 0xcb, 0x24,
197 0xce, 0x74,
198 0x90, 0x03,
199 0x76, 0x80,
200 0x77, 0x42,
201 0x78, 0x0a,
202 0x79, 0x80,
203 0xad, 0x40,
204 0xae, 0x07,
205 0x7f, 0xd4,
206 0x7c, 0x00,
207 0x80, 0xa8,
208 0x81, 0xda,
209 0x7c, 0x01,
210 0x80, 0xda,
211 0x81, 0xec,
212 0x7c, 0x02,
213 0x80, 0xca,
214 0x81, 0xeb,
215 0x7c, 0x03,
216 0x80, 0xba,
217 0x81, 0xdb,
218 0x85, 0x08,
219 0x86, 0x00,
220 0x87, 0x02,
221 0x89, 0x80,
222 0x8b, 0x44,
223 0x8c, 0xaa,
224 0x8a, 0x10,
225 0xba, 0x00,
226 0xf5, 0x04,
227 0xfe, 0x44,
228 0xd2, 0x32,
229 0xb8, 0x00,
230};
231
232/* DS3000 doesn't need some parameters as input and auto-detects them */
233/* save input from the application of those parameters */
234struct ds3000_tuning {
235 u32 frequency;
236 u32 symbol_rate;
237 fe_spectral_inversion_t inversion;
238 enum fe_code_rate fec;
239
240 /* input values */
241 u8 inversion_val;
242 fe_modulation_t delivery;
243 u8 rolloff;
244};
245
246struct ds3000_state {
247 struct i2c_adapter *i2c;
248 const struct ds3000_config *config;
249
250 struct dvb_frontend frontend;
251
252 struct ds3000_tuning dcur;
253 struct ds3000_tuning dnxt;
254
255 u8 skip_fw_load;
256
257 /* previous uncorrected block counter for DVB-S2 */
258 u16 prevUCBS2;
259};
260
261static int ds3000_writereg(struct ds3000_state *state, int reg, int data)
262{
263 u8 buf[] = { reg, data };
264 struct i2c_msg msg = { .addr = state->config->demod_address,
265 .flags = 0, .buf = buf, .len = 2 };
266 int err;
267
268 dprintk("%s: write reg 0x%02x, value 0x%02x\n", __func__, reg, data);
269
270 err = i2c_transfer(state->i2c, &msg, 1);
271 if (err != 1) {
272 printk(KERN_ERR "%s: writereg error(err == %i, reg == 0x%02x,"
273 " value == 0x%02x)\n", __func__, err, reg, data);
274 return -EREMOTEIO;
275 }
276
277 return 0;
278}
279
280static int ds3000_tuner_writereg(struct ds3000_state *state, int reg, int data)
281{
282 u8 buf[] = { reg, data };
283 struct i2c_msg msg = { .addr = 0x60,
284 .flags = 0, .buf = buf, .len = 2 };
285 int err;
286
287 dprintk("%s: write reg 0x%02x, value 0x%02x\n", __func__, reg, data);
288
289 ds3000_writereg(state, 0x03, 0x11);
290 err = i2c_transfer(state->i2c, &msg, 1);
291 if (err != 1) {
292 printk("%s: writereg error(err == %i, reg == 0x%02x,"
293 " value == 0x%02x)\n", __func__, err, reg, data);
294 return -EREMOTEIO;
295 }
296
297 return 0;
298}
299
300/* I2C write for 8k firmware load */
301static int ds3000_writeFW(struct ds3000_state *state, int reg,
302 const u8 *data, u16 len)
303{
304 int i, ret = -EREMOTEIO;
305 struct i2c_msg msg;
306 u8 *buf;
307
308 buf = kmalloc(3, GFP_KERNEL);
309 if (buf == NULL) {
310 printk(KERN_ERR "Unable to kmalloc\n");
311 ret = -ENOMEM;
312 goto error;
313 }
314
315 *(buf) = reg;
316
317 msg.addr = state->config->demod_address;
318 msg.flags = 0;
319 msg.buf = buf;
320 msg.len = 3;
321
322 for (i = 0; i < len; i += 2) {
323 memcpy(buf + 1, data + i, 2);
324
325 dprintk("%s: write reg 0x%02x, len = %d\n", __func__, reg, len);
326
327 ret = i2c_transfer(state->i2c, &msg, 1);
328 if (ret != 1) {
329 printk(KERN_ERR "%s: write error(err == %i, "
330 "reg == 0x%02x\n", __func__, ret, reg);
331 ret = -EREMOTEIO;
332 }
333 }
334
335error:
336 kfree(buf);
337
338 return ret;
339}
340
341static int ds3000_readreg(struct ds3000_state *state, u8 reg)
342{
343 int ret;
344 u8 b0[] = { reg };
345 u8 b1[] = { 0 };
346 struct i2c_msg msg[] = {
347 {
348 .addr = state->config->demod_address,
349 .flags = 0,
350 .buf = b0,
351 .len = 1
352 }, {
353 .addr = state->config->demod_address,
354 .flags = I2C_M_RD,
355 .buf = b1,
356 .len = 1
357 }
358 };
359
360 ret = i2c_transfer(state->i2c, msg, 2);
361
362 if (ret != 2) {
363 printk(KERN_ERR "%s: reg=0x%x(error=%d)\n", __func__, reg, ret);
364 return ret;
365 }
366
367 dprintk("%s: read reg 0x%02x, value 0x%02x\n", __func__, reg, b1[0]);
368
369 return b1[0];
370}
371
372static int ds3000_tuner_readreg(struct ds3000_state *state, u8 reg)
373{
374 int ret;
375 u8 b0[] = { reg };
376 u8 b1[] = { 0 };
377 struct i2c_msg msg[] = {
378 {
379 .addr = 0x60,
380 .flags = 0,
381 .buf = b0,
382 .len = 1
383 }, {
384 .addr = 0x60,
385 .flags = I2C_M_RD,
386 .buf = b1,
387 .len = 1
388 }
389 };
390
391 ds3000_writereg(state, 0x03, 0x12);
392 ret = i2c_transfer(state->i2c, msg, 2);
393
394 if (ret != 2) {
395 printk(KERN_ERR "%s: reg=0x%x(error=%d)\n", __func__, reg, ret);
396 return ret;
397 }
398
399 dprintk("%s: read reg 0x%02x, value 0x%02x\n", __func__, reg, b1[0]);
400
401 return b1[0];
402}
403
404static int ds3000_set_inversion(struct ds3000_state *state,
405 fe_spectral_inversion_t inversion)
406{
407 dprintk("%s(%d)\n", __func__, inversion);
408
409 switch (inversion) {
410 case INVERSION_OFF:
411 case INVERSION_ON:
412 case INVERSION_AUTO:
413 break;
414 default:
415 return -EINVAL;
416 }
417
418 state->dnxt.inversion = inversion;
419
420 return 0;
421}
422
423static int ds3000_set_symbolrate(struct ds3000_state *state, u32 rate)
424{
425 int ret = 0;
426
427 dprintk("%s()\n", __func__);
428
429 dprintk("%s() symbol_rate = %d\n", __func__, state->dnxt.symbol_rate);
430
431 /* check if symbol rate is within limits */
432 if ((state->dnxt.symbol_rate >
433 state->frontend.ops.info.symbol_rate_max) ||
434 (state->dnxt.symbol_rate <
435 state->frontend.ops.info.symbol_rate_min))
436 ret = -EOPNOTSUPP;
437
438 state->dnxt.symbol_rate = rate;
439
440 return ret;
441}
442
443static int ds3000_load_firmware(struct dvb_frontend *fe,
444 const struct firmware *fw);
445
446static int ds3000_firmware_ondemand(struct dvb_frontend *fe)
447{
448 struct ds3000_state *state = fe->demodulator_priv;
449 const struct firmware *fw;
450 int ret = 0;
451
452 dprintk("%s()\n", __func__);
453
454 if (ds3000_readreg(state, 0xb2) <= 0)
455 return ret;
456
457 if (state->skip_fw_load)
458 return 0;
459 /* Load firmware */
460 /* request the firmware, this will block until someone uploads it */
461 printk(KERN_INFO "%s: Waiting for firmware upload (%s)...\n", __func__,
462 DS3000_DEFAULT_FIRMWARE);
463 ret = request_firmware(&fw, DS3000_DEFAULT_FIRMWARE,
464 state->i2c->dev.parent);
465 printk(KERN_INFO "%s: Waiting for firmware upload(2)...\n", __func__);
466 if (ret) {
467 printk(KERN_ERR "%s: No firmware uploaded (timeout or file not "
468 "found?)\n", __func__);
469 return ret;
470 }
471
472 /* Make sure we don't recurse back through here during loading */
473 state->skip_fw_load = 1;
474
475 ret = ds3000_load_firmware(fe, fw);
476 if (ret)
477 printk("%s: Writing firmware to device failed\n", __func__);
478
479 release_firmware(fw);
480
481 dprintk("%s: Firmware upload %s\n", __func__,
482 ret == 0 ? "complete" : "failed");
483
484 /* Ensure firmware is always loaded if required */
485 state->skip_fw_load = 0;
486
487 return ret;
488}
489
490static int ds3000_load_firmware(struct dvb_frontend *fe,
491 const struct firmware *fw)
492{
493 struct ds3000_state *state = fe->demodulator_priv;
494
495 dprintk("%s\n", __func__);
496 dprintk("Firmware is %zu bytes (%02x %02x .. %02x %02x)\n",
497 fw->size,
498 fw->data[0],
499 fw->data[1],
500 fw->data[fw->size - 2],
501 fw->data[fw->size - 1]);
502
503 /* Begin the firmware load process */
504 ds3000_writereg(state, 0xb2, 0x01);
505 /* write the entire firmware */
506 ds3000_writeFW(state, 0xb0, fw->data, fw->size);
507 ds3000_writereg(state, 0xb2, 0x00);
508
509 return 0;
510}
511
512static void ds3000_dump_registers(struct dvb_frontend *fe)
513{
514 struct ds3000_state *state = fe->demodulator_priv;
515 int x, y, reg = 0, val;
516
517 for (y = 0; y < 16; y++) {
518 dprintk("%s: %02x: ", __func__, y);
519 for (x = 0; x < 16; x++) {
520 reg = (y << 4) + x;
521 val = ds3000_readreg(state, reg);
522 if (x != 15)
523 dprintk("%02x ", val);
524 else
525 dprintk("%02x\n", val);
526 }
527 }
528 dprintk("%s: -- DS3000 DUMP DONE --\n", __func__);
529}
530
531static int ds3000_read_status(struct dvb_frontend *fe, fe_status_t* status)
532{
533 struct ds3000_state *state = fe->demodulator_priv;
534 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
535 int lock;
536
537 *status = 0;
538
539 switch (c->delivery_system) {
540 case SYS_DVBS:
541 lock = ds3000_readreg(state, 0xd1);
542 if ((lock & 0x07) == 0x07)
543 *status = FE_HAS_SIGNAL | FE_HAS_CARRIER |
544 FE_HAS_VITERBI | FE_HAS_SYNC |
545 FE_HAS_LOCK;
546
547 break;
548 case SYS_DVBS2:
549 lock = ds3000_readreg(state, 0x0d);
550 if ((lock & 0x8f) == 0x8f)
551 *status = FE_HAS_SIGNAL | FE_HAS_CARRIER |
552 FE_HAS_VITERBI | FE_HAS_SYNC |
553 FE_HAS_LOCK;
554
555 break;
556 default:
557 return 1;
558 }
559
560 dprintk("%s: status = 0x%02x\n", __func__, lock);
561
562 return 0;
563}
564
565#define FE_IS_TUNED (FE_HAS_SIGNAL + FE_HAS_LOCK)
566static int ds3000_is_tuned(struct dvb_frontend *fe)
567{
568 fe_status_t tunerstat;
569
570 ds3000_read_status(fe, &tunerstat);
571
572 return ((tunerstat & FE_IS_TUNED) == FE_IS_TUNED);
573}
574
575/* read DS3000 BER value */
576static int ds3000_read_ber(struct dvb_frontend *fe, u32* ber)
577{
578 struct ds3000_state *state = fe->demodulator_priv;
579 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
580 u8 data;
581 u32 ber_reading, lpdc_frames;
582
583 dprintk("%s()\n", __func__);
584
585 switch (c->delivery_system) {
586 case SYS_DVBS:
587 /* set the number of bytes checked during
588 BER estimation */
589 ds3000_writereg(state, 0xf9, 0x04);
590 /* read BER estimation status */
591 data = ds3000_readreg(state, 0xf8);
592 /* check if BER estimation is ready */
593 if ((data & 0x10) == 0) {
594 /* this is the number of error bits,
595 to calculate the bit error rate
596 divide to 8388608 */
597 *ber = (ds3000_readreg(state, 0xf7) << 8) |
598 ds3000_readreg(state, 0xf6);
599 /* start counting error bits */
600 /* need to be set twice
601 otherwise it fails sometimes */
602 data |= 0x10;
603 ds3000_writereg(state, 0xf8, data);
604 ds3000_writereg(state, 0xf8, data);
605 } else
606 /* used to indicate that BER estimation
607 is not ready, i.e. BER is unknown */
608 *ber = 0xffffffff;
609 break;
610 case SYS_DVBS2:
611 /* read the number of LPDC decoded frames */
612 lpdc_frames = (ds3000_readreg(state, 0xd7) << 16) |
613 (ds3000_readreg(state, 0xd6) << 8) |
614 ds3000_readreg(state, 0xd5);
615 /* read the number of packets with bad CRC */
616 ber_reading = (ds3000_readreg(state, 0xf8) << 8) |
617 ds3000_readreg(state, 0xf7);
618 if (lpdc_frames > 750) {
619 /* clear LPDC frame counters */
620 ds3000_writereg(state, 0xd1, 0x01);
621 /* clear bad packets counter */
622 ds3000_writereg(state, 0xf9, 0x01);
623 /* enable bad packets counter */
624 ds3000_writereg(state, 0xf9, 0x00);
625 /* enable LPDC frame counters */
626 ds3000_writereg(state, 0xd1, 0x00);
627 *ber = ber_reading;
628 } else
629 /* used to indicate that BER estimation is not ready,
630 i.e. BER is unknown */
631 *ber = 0xffffffff;
632 break;
633 default:
634 return 1;
635 }
636
637 return 0;
638}
639
640/* read TS2020 signal strength */
641static int ds3000_read_signal_strength(struct dvb_frontend *fe,
642 u16 *signal_strength)
643{
644 struct ds3000_state *state = fe->demodulator_priv;
645 u16 sig_reading, sig_strength;
646 u8 rfgain, bbgain;
647
648 dprintk("%s()\n", __func__);
649
650 rfgain = ds3000_tuner_readreg(state, 0x3d) & 0x1f;
651 bbgain = ds3000_tuner_readreg(state, 0x21) & 0x1f;
652
653 if (rfgain > 15)
654 rfgain = 15;
655 if (bbgain > 13)
656 bbgain = 13;
657
658 sig_reading = rfgain * 2 + bbgain * 3;
659
660 sig_strength = 40 + (64 - sig_reading) * 50 / 64 ;
661
662 /* cook the value to be suitable for szap-s2 human readable output */
663 *signal_strength = sig_strength * 1000;
664
665 dprintk("%s: raw / cooked = 0x%04x / 0x%04x\n", __func__,
666 sig_reading, *signal_strength);
667
668 return 0;
669}
670
671/* calculate DS3000 snr value in dB */
672static int ds3000_read_snr(struct dvb_frontend *fe, u16 *snr)
673{
674 struct ds3000_state *state = fe->demodulator_priv;
675 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
676 u8 snr_reading, snr_value;
677 u32 dvbs2_signal_reading, dvbs2_noise_reading, tmp;
678 static const u16 dvbs_snr_tab[] = { /* 20 x Table (rounded up) */
679 0x0000, 0x1b13, 0x2aea, 0x3627, 0x3ede, 0x45fe, 0x4c03,
680 0x513a, 0x55d4, 0x59f2, 0x5dab, 0x6111, 0x6431, 0x6717,
681 0x69c9, 0x6c4e, 0x6eac, 0x70e8, 0x7304, 0x7505
682 };
683 static const u16 dvbs2_snr_tab[] = { /* 80 x Table (rounded up) */
684 0x0000, 0x0bc2, 0x12a3, 0x1785, 0x1b4e, 0x1e65, 0x2103,
685 0x2347, 0x2546, 0x2710, 0x28ae, 0x2a28, 0x2b83, 0x2cc5,
686 0x2df1, 0x2f09, 0x3010, 0x3109, 0x31f4, 0x32d2, 0x33a6,
687 0x3470, 0x3531, 0x35ea, 0x369b, 0x3746, 0x37ea, 0x3888,
688 0x3920, 0x39b3, 0x3a42, 0x3acc, 0x3b51, 0x3bd3, 0x3c51,
689 0x3ccb, 0x3d42, 0x3db6, 0x3e27, 0x3e95, 0x3f00, 0x3f68,
690 0x3fcf, 0x4033, 0x4094, 0x40f4, 0x4151, 0x41ac, 0x4206,
691 0x425e, 0x42b4, 0x4308, 0x435b, 0x43ac, 0x43fc, 0x444a,
692 0x4497, 0x44e2, 0x452d, 0x4576, 0x45bd, 0x4604, 0x4649,
693 0x468e, 0x46d1, 0x4713, 0x4755, 0x4795, 0x47d4, 0x4813,
694 0x4851, 0x488d, 0x48c9, 0x4904, 0x493f, 0x4978, 0x49b1,
695 0x49e9, 0x4a20, 0x4a57
696 };
697
698 dprintk("%s()\n", __func__);
699
700 switch (c->delivery_system) {
701 case SYS_DVBS:
702 snr_reading = ds3000_readreg(state, 0xff);
703 snr_reading /= 8;
704 if (snr_reading == 0)
705 *snr = 0x0000;
706 else {
707 if (snr_reading > 20)
708 snr_reading = 20;
709 snr_value = dvbs_snr_tab[snr_reading - 1] * 10 / 23026;
710 /* cook the value to be suitable for szap-s2
711 human readable output */
712 *snr = snr_value * 8 * 655;
713 }
714 dprintk("%s: raw / cooked = 0x%02x / 0x%04x\n", __func__,
715 snr_reading, *snr);
716 break;
717 case SYS_DVBS2:
718 dvbs2_noise_reading = (ds3000_readreg(state, 0x8c) & 0x3f) +
719 (ds3000_readreg(state, 0x8d) << 4);
720 dvbs2_signal_reading = ds3000_readreg(state, 0x8e);
721 tmp = dvbs2_signal_reading * dvbs2_signal_reading >> 1;
722 if (dvbs2_signal_reading == 0) {
723 *snr = 0x0000;
724 return 0;
725 }
726 if (dvbs2_noise_reading == 0) {
727 snr_value = 0x0013;
728 /* cook the value to be suitable for szap-s2
729 human readable output */
730 *snr = 0xffff;
731 return 0;
732 }
733 if (tmp > dvbs2_noise_reading) {
734 snr_reading = tmp / dvbs2_noise_reading;
735 if (snr_reading > 80)
736 snr_reading = 80;
737 snr_value = dvbs2_snr_tab[snr_reading - 1] / 1000;
738 /* cook the value to be suitable for szap-s2
739 human readable output */
740 *snr = snr_value * 5 * 655;
741 } else {
742 snr_reading = dvbs2_noise_reading / tmp;
743 if (snr_reading > 80)
744 snr_reading = 80;
745 *snr = -(dvbs2_snr_tab[snr_reading] / 1000);
746 }
747 dprintk("%s: raw / cooked = 0x%02x / 0x%04x\n", __func__,
748 snr_reading, *snr);
749 break;
750 default:
751 return 1;
752 }
753
754 return 0;
755}
756
757/* read DS3000 uncorrected blocks */
758static int ds3000_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
759{
760 struct ds3000_state *state = fe->demodulator_priv;
761 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
762 u8 data;
763 u16 _ucblocks;
764
765 dprintk("%s()\n", __func__);
766
767 switch (c->delivery_system) {
768 case SYS_DVBS:
769 *ucblocks = (ds3000_readreg(state, 0xf5) << 8) |
770 ds3000_readreg(state, 0xf4);
771 data = ds3000_readreg(state, 0xf8);
772 /* clear packet counters */
773 data &= ~0x20;
774 ds3000_writereg(state, 0xf8, data);
775 /* enable packet counters */
776 data |= 0x20;
777 ds3000_writereg(state, 0xf8, data);
778 break;
779 case SYS_DVBS2:
780 _ucblocks = (ds3000_readreg(state, 0xe2) << 8) |
781 ds3000_readreg(state, 0xe1);
782 if (_ucblocks > state->prevUCBS2)
783 *ucblocks = _ucblocks - state->prevUCBS2;
784 else
785 *ucblocks = state->prevUCBS2 - _ucblocks;
786 state->prevUCBS2 = _ucblocks;
787 break;
788 default:
789 return 1;
790 }
791
792 return 0;
793}
794
795/* Overwrite the current tuning params, we are about to tune */
796static void ds3000_clone_params(struct dvb_frontend *fe)
797{
798 struct ds3000_state *state = fe->demodulator_priv;
799 memcpy(&state->dcur, &state->dnxt, sizeof(state->dcur));
800}
801
802static int ds3000_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
803{
804 struct ds3000_state *state = fe->demodulator_priv;
805 u8 data;
806
807 dprintk("%s(%d)\n", __func__, tone);
808 if ((tone != SEC_TONE_ON) && (tone != SEC_TONE_OFF)) {
809 printk(KERN_ERR "%s: Invalid, tone=%d\n", __func__, tone);
810 return -EINVAL;
811 }
812
813 data = ds3000_readreg(state, 0xa2);
814 data &= ~0xc0;
815 ds3000_writereg(state, 0xa2, data);
816
817 switch (tone) {
818 case SEC_TONE_ON:
819 dprintk("%s: setting tone on\n", __func__);
820 data = ds3000_readreg(state, 0xa1);
821 data &= ~0x43;
822 data |= 0x04;
823 ds3000_writereg(state, 0xa1, data);
824 break;
825 case SEC_TONE_OFF:
826 dprintk("%s: setting tone off\n", __func__);
827 data = ds3000_readreg(state, 0xa2);
828 data |= 0x80;
829 ds3000_writereg(state, 0xa2, data);
830 break;
831 }
832
833 return 0;
834}
835
836static int ds3000_send_diseqc_msg(struct dvb_frontend *fe,
837 struct dvb_diseqc_master_cmd *d)
838{
839 struct ds3000_state *state = fe->demodulator_priv;
840 int i;
841 u8 data;
842
843 /* Dump DiSEqC message */
844 dprintk("%s(", __func__);
845 for (i = 0 ; i < d->msg_len;) {
846 dprintk("0x%02x", d->msg[i]);
847 if (++i < d->msg_len)
848 dprintk(", ");
849 }
850
851 /* enable DiSEqC message send pin */
852 data = ds3000_readreg(state, 0xa2);
853 data &= ~0xc0;
854 ds3000_writereg(state, 0xa2, data);
855
856 /* DiSEqC message */
857 for (i = 0; i < d->msg_len; i++)
858 ds3000_writereg(state, 0xa3 + i, d->msg[i]);
859
860 data = ds3000_readreg(state, 0xa1);
861 /* clear DiSEqC message length and status,
862 enable DiSEqC message send */
863 data &= ~0xf8;
864 /* set DiSEqC mode, modulation active during 33 pulses,
865 set DiSEqC message length */
866 data |= ((d->msg_len - 1) << 3) | 0x07;
867 ds3000_writereg(state, 0xa1, data);
868
869 /* wait up to 150ms for DiSEqC transmission to complete */
870 for (i = 0; i < 15; i++) {
871 data = ds3000_readreg(state, 0xa1);
872 if ((data & 0x40) == 0)
873 break;
874 msleep(10);
875 }
876
877 /* DiSEqC timeout after 150ms */
878 if (i == 15) {
879 data = ds3000_readreg(state, 0xa1);
880 data &= ~0x80;
881 data |= 0x40;
882 ds3000_writereg(state, 0xa1, data);
883
884 data = ds3000_readreg(state, 0xa2);
885 data &= ~0xc0;
886 data |= 0x80;
887 ds3000_writereg(state, 0xa2, data);
888
889 return 1;
890 }
891
892 data = ds3000_readreg(state, 0xa2);
893 data &= ~0xc0;
894 data |= 0x80;
895 ds3000_writereg(state, 0xa2, data);
896
897 return 0;
898}
899
900/* Send DiSEqC burst */
901static int ds3000_diseqc_send_burst(struct dvb_frontend *fe,
902 fe_sec_mini_cmd_t burst)
903{
904 struct ds3000_state *state = fe->demodulator_priv;
905 int i;
906 u8 data;
907
908 dprintk("%s()\n", __func__);
909
910 data = ds3000_readreg(state, 0xa2);
911 data &= ~0xc0;
912 ds3000_writereg(state, 0xa2, data);
913
914 /* DiSEqC burst */
915 if (burst == SEC_MINI_A)
916 /* Unmodulated tone burst */
917 ds3000_writereg(state, 0xa1, 0x02);
918 else if (burst == SEC_MINI_B)
919 /* Modulated tone burst */
920 ds3000_writereg(state, 0xa1, 0x01);
921 else
922 return -EINVAL;
923
924 msleep(13);
925 for (i = 0; i < 5; i++) {
926 data = ds3000_readreg(state, 0xa1);
927 if ((data & 0x40) == 0)
928 break;
929 msleep(1);
930 }
931
932 if (i == 5) {
933 data = ds3000_readreg(state, 0xa1);
934 data &= ~0x80;
935 data |= 0x40;
936 ds3000_writereg(state, 0xa1, data);
937
938 data = ds3000_readreg(state, 0xa2);
939 data &= ~0xc0;
940 data |= 0x80;
941 ds3000_writereg(state, 0xa2, data);
942
943 return 1;
944 }
945
946 data = ds3000_readreg(state, 0xa2);
947 data &= ~0xc0;
948 data |= 0x80;
949 ds3000_writereg(state, 0xa2, data);
950
951 return 0;
952}
953
954static void ds3000_release(struct dvb_frontend *fe)
955{
956 struct ds3000_state *state = fe->demodulator_priv;
957 dprintk("%s\n", __func__);
958 kfree(state);
959}
960
961static struct dvb_frontend_ops ds3000_ops;
962
963struct dvb_frontend *ds3000_attach(const struct ds3000_config *config,
964 struct i2c_adapter *i2c)
965{
966 struct ds3000_state *state = NULL;
967 int ret;
968
969 dprintk("%s\n", __func__);
970
971 /* allocate memory for the internal state */
972 state = kmalloc(sizeof(struct ds3000_state), GFP_KERNEL);
973 if (state == NULL) {
974 printk(KERN_ERR "Unable to kmalloc\n");
975 goto error2;
976 }
977
978 /* setup the state */
979 memset(state, 0, sizeof(struct ds3000_state));
980
981 state->config = config;
982 state->i2c = i2c;
983 state->prevUCBS2 = 0;
984
985 /* check if the demod is present */
986 ret = ds3000_readreg(state, 0x00) & 0xfe;
987 if (ret != 0xe0) {
988 printk(KERN_ERR "Invalid probe, probably not a DS3000\n");
989 goto error3;
990 }
991
992 printk(KERN_INFO "DS3000 chip version: %d.%d attached.\n",
993 ds3000_readreg(state, 0x02),
994 ds3000_readreg(state, 0x01));
995
996 memcpy(&state->frontend.ops, &ds3000_ops,
997 sizeof(struct dvb_frontend_ops));
998 state->frontend.demodulator_priv = state;
999 return &state->frontend;
1000
1001error3:
1002 kfree(state);
1003error2:
1004 return NULL;
1005}
1006EXPORT_SYMBOL(ds3000_attach);
1007
1008static int ds3000_set_property(struct dvb_frontend *fe,
1009 struct dtv_property *tvp)
1010{
1011 dprintk("%s(..)\n", __func__);
1012 return 0;
1013}
1014
1015static int ds3000_get_property(struct dvb_frontend *fe,
1016 struct dtv_property *tvp)
1017{
1018 dprintk("%s(..)\n", __func__);
1019 return 0;
1020}
1021
1022static int ds3000_tune(struct dvb_frontend *fe,
1023 struct dvb_frontend_parameters *p)
1024{
1025 struct ds3000_state *state = fe->demodulator_priv;
1026 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
1027
1028 int ret = 0, retune, i;
1029 u8 status, mlpf, mlpf_new, mlpf_max, mlpf_min, nlpf;
1030 u16 value, ndiv;
1031 u32 f3db;
1032
1033 dprintk("%s() ", __func__);
1034
1035 /* Load the firmware if required */
1036 ret = ds3000_firmware_ondemand(fe);
1037 if (ret != 0) {
1038 printk(KERN_ERR "%s: Unable initialise the firmware\n",
1039 __func__);
1040 return ret;
1041 }
1042
1043 state->dnxt.delivery = c->modulation;
1044 state->dnxt.frequency = c->frequency;
1045 state->dnxt.rolloff = 2; /* fixme */
1046 state->dnxt.fec = c->fec_inner;
1047
1048 ret = ds3000_set_inversion(state, p->inversion);
1049 if (ret != 0)
1050 return ret;
1051
1052 ret = ds3000_set_symbolrate(state, c->symbol_rate);
1053 if (ret != 0)
1054 return ret;
1055
1056 /* discard the 'current' tuning parameters and prepare to tune */
1057 ds3000_clone_params(fe);
1058
1059 retune = 1; /* try 1 times */
1060 dprintk("%s: retune = %d\n", __func__, retune);
1061 dprintk("%s: frequency = %d\n", __func__, state->dcur.frequency);
1062 dprintk("%s: symbol_rate = %d\n", __func__, state->dcur.symbol_rate);
1063 dprintk("%s: FEC = %d \n", __func__,
1064 state->dcur.fec);
1065 dprintk("%s: Inversion = %d\n", __func__, state->dcur.inversion);
1066
1067 do {
1068 /* Reset status register */
1069 status = 0;
1070 /* Tune */
1071 /* TS2020 init */
1072 ds3000_tuner_writereg(state, 0x42, 0x73);
1073 ds3000_tuner_writereg(state, 0x05, 0x01);
1074 ds3000_tuner_writereg(state, 0x62, 0xf5);
1075 /* unknown */
1076 ds3000_tuner_writereg(state, 0x07, 0x02);
1077 ds3000_tuner_writereg(state, 0x10, 0x00);
1078 ds3000_tuner_writereg(state, 0x60, 0x79);
1079 ds3000_tuner_writereg(state, 0x08, 0x01);
1080 ds3000_tuner_writereg(state, 0x00, 0x01);
1081 /* calculate and set freq divider */
1082 if (state->dcur.frequency < 1146000) {
1083 ds3000_tuner_writereg(state, 0x10, 0x11);
1084 ndiv = ((state->dcur.frequency * (6 + 8) * 4) +
1085 (DS3000_XTAL_FREQ / 2)) /
1086 DS3000_XTAL_FREQ - 1024;
1087 } else {
1088 ds3000_tuner_writereg(state, 0x10, 0x01);
1089 ndiv = ((state->dcur.frequency * (6 + 8) * 2) +
1090 (DS3000_XTAL_FREQ / 2)) /
1091 DS3000_XTAL_FREQ - 1024;
1092 }
1093
1094 ds3000_tuner_writereg(state, 0x01, (ndiv & 0x0f00) >> 8);
1095 ds3000_tuner_writereg(state, 0x02, ndiv & 0x00ff);
1096
1097 /* set pll */
1098 ds3000_tuner_writereg(state, 0x03, 0x06);
1099 ds3000_tuner_writereg(state, 0x51, 0x0f);
1100 ds3000_tuner_writereg(state, 0x51, 0x1f);
1101 ds3000_tuner_writereg(state, 0x50, 0x10);
1102 ds3000_tuner_writereg(state, 0x50, 0x00);
1103 msleep(5);
1104
1105 /* unknown */
1106 ds3000_tuner_writereg(state, 0x51, 0x17);
1107 ds3000_tuner_writereg(state, 0x51, 0x1f);
1108 ds3000_tuner_writereg(state, 0x50, 0x08);
1109 ds3000_tuner_writereg(state, 0x50, 0x00);
1110 msleep(5);
1111
1112 value = ds3000_tuner_readreg(state, 0x3d);
1113 value &= 0x0f;
1114 if ((value > 4) && (value < 15)) {
1115 value -= 3;
1116 if (value < 4)
1117 value = 4;
1118 value = ((value << 3) | 0x01) & 0x79;
1119 }
1120
1121 ds3000_tuner_writereg(state, 0x60, value);
1122 ds3000_tuner_writereg(state, 0x51, 0x17);
1123 ds3000_tuner_writereg(state, 0x51, 0x1f);
1124 ds3000_tuner_writereg(state, 0x50, 0x08);
1125 ds3000_tuner_writereg(state, 0x50, 0x00);
1126
1127 /* set low-pass filter period */
1128 ds3000_tuner_writereg(state, 0x04, 0x2e);
1129 ds3000_tuner_writereg(state, 0x51, 0x1b);
1130 ds3000_tuner_writereg(state, 0x51, 0x1f);
1131 ds3000_tuner_writereg(state, 0x50, 0x04);
1132 ds3000_tuner_writereg(state, 0x50, 0x00);
1133 msleep(5);
1134
1135 f3db = ((state->dcur.symbol_rate / 1000) << 2) / 5 + 2000;
1136 if ((state->dcur.symbol_rate / 1000) < 5000)
1137 f3db += 3000;
1138 if (f3db < 7000)
1139 f3db = 7000;
1140 if (f3db > 40000)
1141 f3db = 40000;
1142
1143 /* set low-pass filter baseband */
1144 value = ds3000_tuner_readreg(state, 0x26);
1145 mlpf = 0x2e * 207 / ((value << 1) + 151);
1146 mlpf_max = mlpf * 135 / 100;
1147 mlpf_min = mlpf * 78 / 100;
1148 if (mlpf_max > 63)
1149 mlpf_max = 63;
1150
1151 /* rounded to the closest integer */
1152 nlpf = ((mlpf * f3db * 1000) + (2766 * DS3000_XTAL_FREQ / 2))
1153 / (2766 * DS3000_XTAL_FREQ);
1154 if (nlpf > 23)
1155 nlpf = 23;
1156 if (nlpf < 1)
1157 nlpf = 1;
1158
1159 /* rounded to the closest integer */
1160 mlpf_new = ((DS3000_XTAL_FREQ * nlpf * 2766) +
1161 (1000 * f3db / 2)) / (1000 * f3db);
1162
1163 if (mlpf_new < mlpf_min) {
1164 nlpf++;
1165 mlpf_new = ((DS3000_XTAL_FREQ * nlpf * 2766) +
1166 (1000 * f3db / 2)) / (1000 * f3db);
1167 }
1168
1169 if (mlpf_new > mlpf_max)
1170 mlpf_new = mlpf_max;
1171
1172 ds3000_tuner_writereg(state, 0x04, mlpf_new);
1173 ds3000_tuner_writereg(state, 0x06, nlpf);
1174 ds3000_tuner_writereg(state, 0x51, 0x1b);
1175 ds3000_tuner_writereg(state, 0x51, 0x1f);
1176 ds3000_tuner_writereg(state, 0x50, 0x04);
1177 ds3000_tuner_writereg(state, 0x50, 0x00);
1178 msleep(5);
1179
1180 /* unknown */
1181 ds3000_tuner_writereg(state, 0x51, 0x1e);
1182 ds3000_tuner_writereg(state, 0x51, 0x1f);
1183 ds3000_tuner_writereg(state, 0x50, 0x01);
1184 ds3000_tuner_writereg(state, 0x50, 0x00);
1185 msleep(60);
1186
1187 /* ds3000 global reset */
1188 ds3000_writereg(state, 0x07, 0x80);
1189 ds3000_writereg(state, 0x07, 0x00);
1190 /* ds3000 build-in uC reset */
1191 ds3000_writereg(state, 0xb2, 0x01);
1192 /* ds3000 software reset */
1193 ds3000_writereg(state, 0x00, 0x01);
1194
1195 switch (c->delivery_system) {
1196 case SYS_DVBS:
1197 /* initialise the demod in DVB-S mode */
1198 for (i = 0; i < sizeof(ds3000_dvbs_init_tab); i += 2)
1199 ds3000_writereg(state,
1200 ds3000_dvbs_init_tab[i],
1201 ds3000_dvbs_init_tab[i + 1]);
1202 value = ds3000_readreg(state, 0xfe);
1203 value &= 0xc0;
1204 value |= 0x1b;
1205 ds3000_writereg(state, 0xfe, value);
1206 break;
1207 case SYS_DVBS2:
1208 /* initialise the demod in DVB-S2 mode */
1209 for (i = 0; i < sizeof(ds3000_dvbs2_init_tab); i += 2)
1210 ds3000_writereg(state,
1211 ds3000_dvbs2_init_tab[i],
1212 ds3000_dvbs2_init_tab[i + 1]);
1213 ds3000_writereg(state, 0xfe, 0x54);
1214 break;
1215 default:
1216 return 1;
1217 }
1218
1219 /* enable 27MHz clock output */
1220 ds3000_writereg(state, 0x29, 0x80);
1221 /* enable ac coupling */
1222 ds3000_writereg(state, 0x25, 0x8a);
1223
1224 /* enhance symbol rate performance */
1225 if ((state->dcur.symbol_rate / 1000) <= 5000) {
1226 value = 29777 / (state->dcur.symbol_rate / 1000) + 1;
1227 if (value % 2 != 0)
1228 value++;
1229 ds3000_writereg(state, 0xc3, 0x0d);
1230 ds3000_writereg(state, 0xc8, value);
1231 ds3000_writereg(state, 0xc4, 0x10);
1232 ds3000_writereg(state, 0xc7, 0x0e);
1233 } else if ((state->dcur.symbol_rate / 1000) <= 10000) {
1234 value = 92166 / (state->dcur.symbol_rate / 1000) + 1;
1235 if (value % 2 != 0)
1236 value++;
1237 ds3000_writereg(state, 0xc3, 0x07);
1238 ds3000_writereg(state, 0xc8, value);
1239 ds3000_writereg(state, 0xc4, 0x09);
1240 ds3000_writereg(state, 0xc7, 0x12);
1241 } else if ((state->dcur.symbol_rate / 1000) <= 20000) {
1242 value = 64516 / (state->dcur.symbol_rate / 1000) + 1;
1243 ds3000_writereg(state, 0xc3, value);
1244 ds3000_writereg(state, 0xc8, 0x0e);
1245 ds3000_writereg(state, 0xc4, 0x07);
1246 ds3000_writereg(state, 0xc7, 0x18);
1247 } else {
1248 value = 129032 / (state->dcur.symbol_rate / 1000) + 1;
1249 ds3000_writereg(state, 0xc3, value);
1250 ds3000_writereg(state, 0xc8, 0x0a);
1251 ds3000_writereg(state, 0xc4, 0x05);
1252 ds3000_writereg(state, 0xc7, 0x24);
1253 }
1254
1255 /* normalized symbol rate rounded to the closest integer */
1256 value = (((state->dcur.symbol_rate / 1000) << 16) +
1257 (DS3000_SAMPLE_RATE / 2)) / DS3000_SAMPLE_RATE;
1258 ds3000_writereg(state, 0x61, value & 0x00ff);
1259 ds3000_writereg(state, 0x62, (value & 0xff00) >> 8);
1260
1261 /* co-channel interference cancellation disabled */
1262 ds3000_writereg(state, 0x56, 0x00);
1263
1264 /* equalizer disabled */
1265 ds3000_writereg(state, 0x76, 0x00);
1266
1267 /*ds3000_writereg(state, 0x08, 0x03);
1268 ds3000_writereg(state, 0xfd, 0x22);
1269 ds3000_writereg(state, 0x08, 0x07);
1270 ds3000_writereg(state, 0xfd, 0x42);
1271 ds3000_writereg(state, 0x08, 0x07);*/
1272
1273 /* ds3000 out of software reset */
1274 ds3000_writereg(state, 0x00, 0x00);
1275 /* start ds3000 build-in uC */
1276 ds3000_writereg(state, 0xb2, 0x00);
1277
1278 /* TODO: calculate and set carrier offset */
1279
1280 /* wait before retrying */
1281 for (i = 0; i < 30 ; i++) {
1282 if (ds3000_is_tuned(fe)) {
1283 dprintk("%s: Tuned\n", __func__);
1284 ds3000_dump_registers(fe);
1285 goto tuned;
1286 }
1287 msleep(1);
1288 }
1289
1290 dprintk("%s: Not tuned\n", __func__);
1291 ds3000_dump_registers(fe);
1292
1293 } while (--retune);
1294
1295tuned:
1296 return ret;
1297}
1298
1299static enum dvbfe_algo ds3000_get_algo(struct dvb_frontend *fe)
1300{
1301 dprintk("%s()\n", __func__);
1302 return DVBFE_ALGO_SW;
1303}
1304
1305/*
1306 * Initialise or wake up device
1307 *
1308 * Power config will reset and load initial firmware if required
1309 */
1310static int ds3000_initfe(struct dvb_frontend *fe)
1311{
1312 dprintk("%s()\n", __func__);
1313 return 0;
1314}
1315
1316/* Put device to sleep */
1317static int ds3000_sleep(struct dvb_frontend *fe)
1318{
1319 dprintk("%s()\n", __func__);
1320 return 0;
1321}
1322
1323static struct dvb_frontend_ops ds3000_ops = {
1324
1325 .info = {
1326 .name = "Montage Technology DS3000/TS2020",
1327 .type = FE_QPSK,
1328 .frequency_min = 950000,
1329 .frequency_max = 2150000,
1330 .frequency_stepsize = 1011, /* kHz for QPSK frontends */
1331 .frequency_tolerance = 5000,
1332 .symbol_rate_min = 1000000,
1333 .symbol_rate_max = 45000000,
1334 .caps = FE_CAN_INVERSION_AUTO |
1335 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
1336 FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 |
1337 FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
1338 FE_CAN_2G_MODULATION |
1339 FE_CAN_QPSK | FE_CAN_RECOVER
1340 },
1341
1342 .release = ds3000_release,
1343
1344 .init = ds3000_initfe,
1345 .sleep = ds3000_sleep,
1346 .read_status = ds3000_read_status,
1347 .read_ber = ds3000_read_ber,
1348 .read_signal_strength = ds3000_read_signal_strength,
1349 .read_snr = ds3000_read_snr,
1350 .read_ucblocks = ds3000_read_ucblocks,
1351 .set_tone = ds3000_set_tone,
1352 .diseqc_send_master_cmd = ds3000_send_diseqc_msg,
1353 .diseqc_send_burst = ds3000_diseqc_send_burst,
1354 .get_frontend_algo = ds3000_get_algo,
1355
1356 .set_property = ds3000_set_property,
1357 .get_property = ds3000_get_property,
1358 .set_frontend = ds3000_tune,
1359};
1360
1361module_param(debug, int, 0644);
1362MODULE_PARM_DESC(debug, "Activates frontend debugging (default:0)");
1363
1364MODULE_DESCRIPTION("DVB Frontend module for Montage Technology "
1365 "DS3000/TS2020 hardware");
1366MODULE_AUTHOR("Konstantin Dimitrov");
1367MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/ds3000.h b/drivers/media/dvb/frontends/ds3000.h
new file mode 100644
index 000000000000..67f67038740a
--- /dev/null
+++ b/drivers/media/dvb/frontends/ds3000.h
@@ -0,0 +1,45 @@
1/*
2 Montage Technology DS3000/TS2020 - DVBS/S2 Satellite demod/tuner driver
3 Copyright (C) 2009 Konstantin Dimitrov <kosio.dimitrov@gmail.com>
4
5 Copyright (C) 2009 TurboSight.com
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20*/
21
22#ifndef DS3000_H
23#define DS3000_H
24
25#include <linux/dvb/frontend.h>
26
27struct ds3000_config {
28 /* the demodulator's i2c address */
29 u8 demod_address;
30};
31
32#if defined(CONFIG_DVB_DS3000) || \
33 (defined(CONFIG_DVB_DS3000_MODULE) && defined(MODULE))
34extern struct dvb_frontend *ds3000_attach(const struct ds3000_config *config,
35 struct i2c_adapter *i2c);
36#else
37static inline
38struct dvb_frontend *ds3000_attach(const struct ds3000_config *config,
39 struct i2c_adapter *i2c)
40{
41 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
42 return NULL;
43}
44#endif /* CONFIG_DVB_DS3000 */
45#endif /* DS3000_H */
diff --git a/drivers/media/dvb/frontends/ec100.c b/drivers/media/dvb/frontends/ec100.c
new file mode 100644
index 000000000000..2414dc6ee5d9
--- /dev/null
+++ b/drivers/media/dvb/frontends/ec100.c
@@ -0,0 +1,335 @@
1/*
2 * E3C EC100 demodulator driver
3 *
4 * Copyright (C) 2009 Antti Palosaari <crope@iki.fi>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 *
20 */
21
22#include "dvb_frontend.h"
23#include "ec100_priv.h"
24#include "ec100.h"
25
26int ec100_debug;
27module_param_named(debug, ec100_debug, int, 0644);
28MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
29
30struct ec100_state {
31 struct i2c_adapter *i2c;
32 struct dvb_frontend frontend;
33 struct ec100_config config;
34
35 u16 ber;
36};
37
38/* write single register */
39static int ec100_write_reg(struct ec100_state *state, u8 reg, u8 val)
40{
41 u8 buf[2] = {reg, val};
42 struct i2c_msg msg = {
43 .addr = state->config.demod_address,
44 .flags = 0,
45 .len = 2,
46 .buf = buf};
47
48 if (i2c_transfer(state->i2c, &msg, 1) != 1) {
49 warn("I2C write failed reg:%02x", reg);
50 return -EREMOTEIO;
51 }
52 return 0;
53}
54
55/* read single register */
56static int ec100_read_reg(struct ec100_state *state, u8 reg, u8 *val)
57{
58 struct i2c_msg msg[2] = {
59 {
60 .addr = state->config.demod_address,
61 .flags = 0,
62 .len = 1,
63 .buf = &reg
64 }, {
65 .addr = state->config.demod_address,
66 .flags = I2C_M_RD,
67 .len = 1,
68 .buf = val
69 }
70 };
71
72 if (i2c_transfer(state->i2c, msg, 2) != 2) {
73 warn("I2C read failed reg:%02x", reg);
74 return -EREMOTEIO;
75 }
76 return 0;
77}
78
79static int ec100_set_frontend(struct dvb_frontend *fe,
80 struct dvb_frontend_parameters *params)
81{
82 struct ec100_state *state = fe->demodulator_priv;
83 int ret;
84 u8 tmp, tmp2;
85
86 deb_info("%s: freq:%d bw:%d\n", __func__, params->frequency,
87 params->u.ofdm.bandwidth);
88
89 /* program tuner */
90 if (fe->ops.tuner_ops.set_params)
91 fe->ops.tuner_ops.set_params(fe, params);
92
93 ret = ec100_write_reg(state, 0x04, 0x06);
94 if (ret)
95 goto error;
96 ret = ec100_write_reg(state, 0x67, 0x58);
97 if (ret)
98 goto error;
99 ret = ec100_write_reg(state, 0x05, 0x18);
100 if (ret)
101 goto error;
102
103 /* reg/bw | 6 | 7 | 8
104 -------+------+------+------
105 A 0x1b | 0xa1 | 0xe7 | 0x2c
106 A 0x1c | 0x55 | 0x63 | 0x72
107 -------+------+------+------
108 B 0x1b | 0xb7 | 0x00 | 0x49
109 B 0x1c | 0x55 | 0x64 | 0x72 */
110
111 switch (params->u.ofdm.bandwidth) {
112 case BANDWIDTH_6_MHZ:
113 tmp = 0xb7;
114 tmp2 = 0x55;
115 break;
116 case BANDWIDTH_7_MHZ:
117 tmp = 0x00;
118 tmp2 = 0x64;
119 break;
120 case BANDWIDTH_8_MHZ:
121 default:
122 tmp = 0x49;
123 tmp2 = 0x72;
124 }
125
126 ret = ec100_write_reg(state, 0x1b, tmp);
127 if (ret)
128 goto error;
129 ret = ec100_write_reg(state, 0x1c, tmp2);
130 if (ret)
131 goto error;
132
133 ret = ec100_write_reg(state, 0x0c, 0xbb); /* if freq */
134 if (ret)
135 goto error;
136 ret = ec100_write_reg(state, 0x0d, 0x31); /* if freq */
137 if (ret)
138 goto error;
139
140 ret = ec100_write_reg(state, 0x08, 0x24);
141 if (ret)
142 goto error;
143
144 ret = ec100_write_reg(state, 0x00, 0x00); /* go */
145 if (ret)
146 goto error;
147 ret = ec100_write_reg(state, 0x00, 0x20); /* go */
148 if (ret)
149 goto error;
150
151 return ret;
152error:
153 deb_info("%s: failed:%d\n", __func__, ret);
154 return ret;
155}
156
157static int ec100_get_tune_settings(struct dvb_frontend *fe,
158 struct dvb_frontend_tune_settings *fesettings)
159{
160 fesettings->min_delay_ms = 300;
161 fesettings->step_size = 0;
162 fesettings->max_drift = 0;
163
164 return 0;
165}
166
167static int ec100_read_status(struct dvb_frontend *fe, fe_status_t *status)
168{
169 struct ec100_state *state = fe->demodulator_priv;
170 int ret;
171 u8 tmp;
172 *status = 0;
173
174 ret = ec100_read_reg(state, 0x42, &tmp);
175 if (ret)
176 goto error;
177
178 if (tmp & 0x80) {
179 /* bit7 set - have lock */
180 *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI |
181 FE_HAS_SYNC | FE_HAS_LOCK;
182 } else {
183 ret = ec100_read_reg(state, 0x01, &tmp);
184 if (ret)
185 goto error;
186
187 if (tmp & 0x10) {
188 /* bit4 set - have signal */
189 *status |= FE_HAS_SIGNAL;
190 if (!(tmp & 0x01)) {
191 /* bit0 clear - have ~valid signal */
192 *status |= FE_HAS_CARRIER | FE_HAS_VITERBI;
193 }
194 }
195 }
196
197 return ret;
198error:
199 deb_info("%s: failed:%d\n", __func__, ret);
200 return ret;
201}
202
203static int ec100_read_ber(struct dvb_frontend *fe, u32 *ber)
204{
205 struct ec100_state *state = fe->demodulator_priv;
206 int ret;
207 u8 tmp, tmp2;
208 u16 ber2;
209
210 *ber = 0;
211
212 ret = ec100_read_reg(state, 0x65, &tmp);
213 if (ret)
214 goto error;
215 ret = ec100_read_reg(state, 0x66, &tmp2);
216 if (ret)
217 goto error;
218
219 ber2 = (tmp2 << 8) | tmp;
220
221 /* if counter overflow or clear */
222 if (ber2 < state->ber)
223 *ber = ber2;
224 else
225 *ber = ber2 - state->ber;
226
227 state->ber = ber2;
228
229 return ret;
230error:
231 deb_info("%s: failed:%d\n", __func__, ret);
232 return ret;
233}
234
235static int ec100_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
236{
237 struct ec100_state *state = fe->demodulator_priv;
238 int ret;
239 u8 tmp;
240
241 ret = ec100_read_reg(state, 0x24, &tmp);
242 if (ret) {
243 *strength = 0;
244 goto error;
245 }
246
247 *strength = ((tmp << 8) | tmp);
248
249 return ret;
250error:
251 deb_info("%s: failed:%d\n", __func__, ret);
252 return ret;
253}
254
255static int ec100_read_snr(struct dvb_frontend *fe, u16 *snr)
256{
257 *snr = 0;
258 return 0;
259}
260
261static int ec100_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
262{
263 *ucblocks = 0;
264 return 0;
265}
266
267static void ec100_release(struct dvb_frontend *fe)
268{
269 struct ec100_state *state = fe->demodulator_priv;
270 kfree(state);
271}
272
273static struct dvb_frontend_ops ec100_ops;
274
275struct dvb_frontend *ec100_attach(const struct ec100_config *config,
276 struct i2c_adapter *i2c)
277{
278 int ret;
279 struct ec100_state *state = NULL;
280 u8 tmp;
281
282 /* allocate memory for the internal state */
283 state = kzalloc(sizeof(struct ec100_state), GFP_KERNEL);
284 if (state == NULL)
285 goto error;
286
287 /* setup the state */
288 state->i2c = i2c;
289 memcpy(&state->config, config, sizeof(struct ec100_config));
290
291 /* check if the demod is there */
292 ret = ec100_read_reg(state, 0x33, &tmp);
293 if (ret || tmp != 0x0b)
294 goto error;
295
296 /* create dvb_frontend */
297 memcpy(&state->frontend.ops, &ec100_ops,
298 sizeof(struct dvb_frontend_ops));
299 state->frontend.demodulator_priv = state;
300
301 return &state->frontend;
302error:
303 kfree(state);
304 return NULL;
305}
306EXPORT_SYMBOL(ec100_attach);
307
308static struct dvb_frontend_ops ec100_ops = {
309 .info = {
310 .name = "E3C EC100 DVB-T",
311 .type = FE_OFDM,
312 .caps =
313 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
314 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
315 FE_CAN_QPSK | FE_CAN_QAM_16 |
316 FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
317 FE_CAN_TRANSMISSION_MODE_AUTO |
318 FE_CAN_GUARD_INTERVAL_AUTO |
319 FE_CAN_HIERARCHY_AUTO |
320 FE_CAN_MUTE_TS
321 },
322
323 .release = ec100_release,
324 .set_frontend = ec100_set_frontend,
325 .get_tune_settings = ec100_get_tune_settings,
326 .read_status = ec100_read_status,
327 .read_ber = ec100_read_ber,
328 .read_signal_strength = ec100_read_signal_strength,
329 .read_snr = ec100_read_snr,
330 .read_ucblocks = ec100_read_ucblocks,
331};
332
333MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
334MODULE_DESCRIPTION("E3C EC100 DVB-T demodulator driver");
335MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/ec100.h b/drivers/media/dvb/frontends/ec100.h
new file mode 100644
index 000000000000..ee8e52417958
--- /dev/null
+++ b/drivers/media/dvb/frontends/ec100.h
@@ -0,0 +1,46 @@
1/*
2 * E3C EC100 demodulator driver
3 *
4 * Copyright (C) 2009 Antti Palosaari <crope@iki.fi>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 *
20 */
21
22#ifndef EC100_H
23#define EC100_H
24
25#include <linux/dvb/frontend.h>
26
27struct ec100_config {
28 /* demodulator's I2C address */
29 u8 demod_address;
30};
31
32
33#if defined(CONFIG_DVB_EC100) || \
34 (defined(CONFIG_DVB_EC100_MODULE) && defined(MODULE))
35extern struct dvb_frontend *ec100_attach(const struct ec100_config *config,
36 struct i2c_adapter *i2c);
37#else
38static inline struct dvb_frontend *ec100_attach(
39 const struct ec100_config *config, struct i2c_adapter *i2c)
40{
41 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
42 return NULL;
43}
44#endif
45
46#endif /* EC100_H */
diff --git a/drivers/media/dvb/frontends/ec100_priv.h b/drivers/media/dvb/frontends/ec100_priv.h
new file mode 100644
index 000000000000..5c990144bc47
--- /dev/null
+++ b/drivers/media/dvb/frontends/ec100_priv.h
@@ -0,0 +1,39 @@
1/*
2 * E3C EC100 demodulator driver
3 *
4 * Copyright (C) 2009 Antti Palosaari <crope@iki.fi>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 *
20 */
21
22#ifndef EC100_PRIV
23#define EC100_PRIV
24
25#define LOG_PREFIX "ec100"
26
27#define dprintk(var, level, args...) \
28 do { if ((var & level)) printk(args); } while (0)
29
30#define deb_info(args...) dprintk(ec100_debug, 0x01, args)
31
32#undef err
33#define err(f, arg...) printk(KERN_ERR LOG_PREFIX": " f "\n" , ## arg)
34#undef info
35#define info(f, arg...) printk(KERN_INFO LOG_PREFIX": " f "\n" , ## arg)
36#undef warn
37#define warn(f, arg...) printk(KERN_WARNING LOG_PREFIX": " f "\n" , ## arg)
38
39#endif /* EC100_PRIV */
diff --git a/drivers/media/dvb/frontends/s5h1409.c b/drivers/media/dvb/frontends/s5h1409.c
index fb3011518427..0e2f61a8978f 100644
--- a/drivers/media/dvb/frontends/s5h1409.c
+++ b/drivers/media/dvb/frontends/s5h1409.c
@@ -44,7 +44,15 @@ struct s5h1409_state {
44 int if_freq; 44 int if_freq;
45 45
46 u32 is_qam_locked; 46 u32 is_qam_locked;
47 u32 qam_state; 47
48 /* QAM tuning state goes through the following state transitions */
49#define QAM_STATE_UNTUNED 0
50#define QAM_STATE_TUNING_STARTED 1
51#define QAM_STATE_INTERLEAVE_SET 2
52#define QAM_STATE_QAM_OPTIMIZED_L1 3
53#define QAM_STATE_QAM_OPTIMIZED_L2 4
54#define QAM_STATE_QAM_OPTIMIZED_L3 5
55 u8 qam_state;
48}; 56};
49 57
50static int debug; 58static int debug;
@@ -347,7 +355,7 @@ static int s5h1409_softreset(struct dvb_frontend *fe)
347 s5h1409_writereg(state, 0xf5, 0); 355 s5h1409_writereg(state, 0xf5, 0);
348 s5h1409_writereg(state, 0xf5, 1); 356 s5h1409_writereg(state, 0xf5, 1);
349 state->is_qam_locked = 0; 357 state->is_qam_locked = 0;
350 state->qam_state = 0; 358 state->qam_state = QAM_STATE_UNTUNED;
351 return 0; 359 return 0;
352} 360}
353 361
@@ -474,6 +482,59 @@ static void s5h1409_set_qam_amhum_mode(struct dvb_frontend *fe)
474 struct s5h1409_state *state = fe->demodulator_priv; 482 struct s5h1409_state *state = fe->demodulator_priv;
475 u16 reg; 483 u16 reg;
476 484
485 if (state->qam_state < QAM_STATE_INTERLEAVE_SET) {
486 /* We should not perform amhum optimization until
487 the interleave mode has been configured */
488 return;
489 }
490
491 if (state->qam_state == QAM_STATE_QAM_OPTIMIZED_L3) {
492 /* We've already reached the maximum optimization level, so
493 dont bother banging on the status registers */
494 return;
495 }
496
497 /* QAM EQ lock check */
498 reg = s5h1409_readreg(state, 0xf0);
499
500 if ((reg >> 13) & 0x1) {
501 reg &= 0xff;
502
503 s5h1409_writereg(state, 0x96, 0x000c);
504 if (reg < 0x68) {
505 if (state->qam_state < QAM_STATE_QAM_OPTIMIZED_L3) {
506 dprintk("%s() setting QAM state to OPT_L3\n",
507 __func__);
508 s5h1409_writereg(state, 0x93, 0x3130);
509 s5h1409_writereg(state, 0x9e, 0x2836);
510 state->qam_state = QAM_STATE_QAM_OPTIMIZED_L3;
511 }
512 } else {
513 if (state->qam_state < QAM_STATE_QAM_OPTIMIZED_L2) {
514 dprintk("%s() setting QAM state to OPT_L2\n",
515 __func__);
516 s5h1409_writereg(state, 0x93, 0x3332);
517 s5h1409_writereg(state, 0x9e, 0x2c37);
518 state->qam_state = QAM_STATE_QAM_OPTIMIZED_L2;
519 }
520 }
521
522 } else {
523 if (state->qam_state < QAM_STATE_QAM_OPTIMIZED_L1) {
524 dprintk("%s() setting QAM state to OPT_L1\n", __func__);
525 s5h1409_writereg(state, 0x96, 0x0008);
526 s5h1409_writereg(state, 0x93, 0x3332);
527 s5h1409_writereg(state, 0x9e, 0x2c37);
528 state->qam_state = QAM_STATE_QAM_OPTIMIZED_L1;
529 }
530 }
531}
532
533static void s5h1409_set_qam_amhum_mode_legacy(struct dvb_frontend *fe)
534{
535 struct s5h1409_state *state = fe->demodulator_priv;
536 u16 reg;
537
477 if (state->is_qam_locked) 538 if (state->is_qam_locked)
478 return; 539 return;
479 540
@@ -506,6 +567,44 @@ static void s5h1409_set_qam_interleave_mode(struct dvb_frontend *fe)
506 struct s5h1409_state *state = fe->demodulator_priv; 567 struct s5h1409_state *state = fe->demodulator_priv;
507 u16 reg, reg1, reg2; 568 u16 reg, reg1, reg2;
508 569
570 if (state->qam_state >= QAM_STATE_INTERLEAVE_SET) {
571 /* We've done the optimization already */
572 return;
573 }
574
575 reg = s5h1409_readreg(state, 0xf1);
576
577 /* Master lock */
578 if ((reg >> 15) & 0x1) {
579 if (state->qam_state == QAM_STATE_UNTUNED ||
580 state->qam_state == QAM_STATE_TUNING_STARTED) {
581 dprintk("%s() setting QAM state to INTERLEAVE_SET\n",
582 __func__);
583 reg1 = s5h1409_readreg(state, 0xb2);
584 reg2 = s5h1409_readreg(state, 0xad);
585
586 s5h1409_writereg(state, 0x96, 0x0020);
587 s5h1409_writereg(state, 0xad,
588 (((reg1 & 0xf000) >> 4) | (reg2 & 0xf0ff)));
589 state->qam_state = QAM_STATE_INTERLEAVE_SET;
590 }
591 } else {
592 if (state->qam_state == QAM_STATE_UNTUNED) {
593 dprintk("%s() setting QAM state to TUNING_STARTED\n",
594 __func__);
595 s5h1409_writereg(state, 0x96, 0x08);
596 s5h1409_writereg(state, 0xab,
597 s5h1409_readreg(state, 0xab) | 0x1001);
598 state->qam_state = QAM_STATE_TUNING_STARTED;
599 }
600 }
601}
602
603static void s5h1409_set_qam_interleave_mode_legacy(struct dvb_frontend *fe)
604{
605 struct s5h1409_state *state = fe->demodulator_priv;
606 u16 reg, reg1, reg2;
607
509 reg = s5h1409_readreg(state, 0xf1); 608 reg = s5h1409_readreg(state, 0xf1);
510 609
511 /* Master lock */ 610 /* Master lock */
@@ -553,16 +652,24 @@ static int s5h1409_set_frontend(struct dvb_frontend *fe,
553 fe->ops.i2c_gate_ctrl(fe, 0); 652 fe->ops.i2c_gate_ctrl(fe, 0);
554 } 653 }
555 654
556 /* Optimize the demod for QAM */
557 if (p->u.vsb.modulation != VSB_8) {
558 s5h1409_set_qam_amhum_mode(fe);
559 s5h1409_set_qam_interleave_mode(fe);
560 }
561
562 /* Issue a reset to the demod so it knows to resync against the 655 /* Issue a reset to the demod so it knows to resync against the
563 newly tuned frequency */ 656 newly tuned frequency */
564 s5h1409_softreset(fe); 657 s5h1409_softreset(fe);
565 658
659 /* Optimize the demod for QAM */
660 if (state->current_modulation != VSB_8) {
661 /* This almost certainly applies to all boards, but for now
662 only do it for the HVR-1600. Once the other boards are
663 tested, the "legacy" versions can just go away */
664 if (state->config->hvr1600_opt == S5H1409_HVR1600_OPTIMIZE) {
665 s5h1409_set_qam_interleave_mode(fe);
666 s5h1409_set_qam_amhum_mode(fe);
667 } else {
668 s5h1409_set_qam_amhum_mode_legacy(fe);
669 s5h1409_set_qam_interleave_mode_legacy(fe);
670 }
671 }
672
566 return 0; 673 return 0;
567} 674}
568 675
@@ -614,6 +721,21 @@ static int s5h1409_init(struct dvb_frontend *fe)
614 /* The datasheet says that after initialisation, VSB is default */ 721 /* The datasheet says that after initialisation, VSB is default */
615 state->current_modulation = VSB_8; 722 state->current_modulation = VSB_8;
616 723
724 /* Optimize for the HVR-1600 if appropriate. Note that some of these
725 may get folded into the generic case after testing with other
726 devices */
727 if (state->config->hvr1600_opt == S5H1409_HVR1600_OPTIMIZE) {
728 /* VSB AGC REF */
729 s5h1409_writereg(state, 0x09, 0x0050);
730
731 /* Unknown but Windows driver does it... */
732 s5h1409_writereg(state, 0x21, 0x0001);
733 s5h1409_writereg(state, 0x50, 0x030e);
734
735 /* QAM AGC REF */
736 s5h1409_writereg(state, 0x82, 0x0800);
737 }
738
617 if (state->config->output_mode == S5H1409_SERIAL_OUTPUT) 739 if (state->config->output_mode == S5H1409_SERIAL_OUTPUT)
618 s5h1409_writereg(state, 0xab, 740 s5h1409_writereg(state, 0xab,
619 s5h1409_readreg(state, 0xab) | 0x100); /* Serial */ 741 s5h1409_readreg(state, 0xab) | 0x100); /* Serial */
@@ -641,6 +763,17 @@ static int s5h1409_read_status(struct dvb_frontend *fe, fe_status_t *status)
641 763
642 *status = 0; 764 *status = 0;
643 765
766 /* Optimize the demod for QAM */
767 if (state->current_modulation != VSB_8) {
768 /* This almost certainly applies to all boards, but for now
769 only do it for the HVR-1600. Once the other boards are
770 tested, the "legacy" versions can just go away */
771 if (state->config->hvr1600_opt == S5H1409_HVR1600_OPTIMIZE) {
772 s5h1409_set_qam_interleave_mode(fe);
773 s5h1409_set_qam_amhum_mode(fe);
774 }
775 }
776
644 /* Get the demodulator status */ 777 /* Get the demodulator status */
645 reg = s5h1409_readreg(state, 0xf1); 778 reg = s5h1409_readreg(state, 0xf1);
646 if (reg & 0x1000) 779 if (reg & 0x1000)
diff --git a/drivers/media/dvb/frontends/s5h1409.h b/drivers/media/dvb/frontends/s5h1409.h
index 070d9743e330..91f2ebd1a534 100644
--- a/drivers/media/dvb/frontends/s5h1409.h
+++ b/drivers/media/dvb/frontends/s5h1409.h
@@ -57,6 +57,13 @@ struct s5h1409_config {
57#define S5H1409_MPEGTIMING_NONCONTINOUS_INVERTING_CLOCK 2 57#define S5H1409_MPEGTIMING_NONCONTINOUS_INVERTING_CLOCK 2
58#define S5H1409_MPEGTIMING_NONCONTINOUS_NONINVERTING_CLOCK 3 58#define S5H1409_MPEGTIMING_NONCONTINOUS_NONINVERTING_CLOCK 3
59 u16 mpeg_timing; 59 u16 mpeg_timing;
60
61 /* HVR-1600 optimizations (to better work with MXL5005s)
62 Note: some of these are likely to be folded into the generic driver
63 after being regression tested with other boards */
64#define S5H1409_HVR1600_NOOPTIMIZE 0
65#define S5H1409_HVR1600_OPTIMIZE 1
66 u8 hvr1600_opt;
60}; 67};
61 68
62#if defined(CONFIG_DVB_S5H1409) || (defined(CONFIG_DVB_S5H1409_MODULE) \ 69#if defined(CONFIG_DVB_S5H1409) || (defined(CONFIG_DVB_S5H1409_MODULE) \
diff --git a/drivers/media/dvb/frontends/stb6100_proc.h b/drivers/media/dvb/frontends/stb6100_proc.h
new file mode 100644
index 000000000000..112163a48622
--- /dev/null
+++ b/drivers/media/dvb/frontends/stb6100_proc.h
@@ -0,0 +1,138 @@
1/*
2 STB6100 Silicon Tuner wrapper
3 Copyright (C)2009 Igor M. Liplianin (liplianin@me.by)
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18*/
19
20static int stb6100_get_freq(struct dvb_frontend *fe, u32 *frequency)
21{
22 struct dvb_frontend_ops *frontend_ops = NULL;
23 struct dvb_tuner_ops *tuner_ops = NULL;
24 struct tuner_state state;
25 int err = 0;
26
27 if (&fe->ops)
28 frontend_ops = &fe->ops;
29 if (&frontend_ops->tuner_ops)
30 tuner_ops = &frontend_ops->tuner_ops;
31 if (tuner_ops->get_state) {
32 if (frontend_ops->i2c_gate_ctrl)
33 frontend_ops->i2c_gate_ctrl(fe, 1);
34
35 err = tuner_ops->get_state(fe, DVBFE_TUNER_FREQUENCY, &state);
36 if (err < 0) {
37 printk(KERN_ERR "%s: Invalid parameter\n", __func__);
38 return err;
39 }
40
41 if (frontend_ops->i2c_gate_ctrl)
42 frontend_ops->i2c_gate_ctrl(fe, 0);
43
44 *frequency = state.frequency;
45 }
46
47 return 0;
48}
49
50static int stb6100_set_freq(struct dvb_frontend *fe, u32 frequency)
51{
52 struct dvb_frontend_ops *frontend_ops = NULL;
53 struct dvb_tuner_ops *tuner_ops = NULL;
54 struct tuner_state state;
55 int err = 0;
56
57 state.frequency = frequency;
58 if (&fe->ops)
59 frontend_ops = &fe->ops;
60 if (&frontend_ops->tuner_ops)
61 tuner_ops = &frontend_ops->tuner_ops;
62 if (tuner_ops->set_state) {
63 if (frontend_ops->i2c_gate_ctrl)
64 frontend_ops->i2c_gate_ctrl(fe, 1);
65
66 err = tuner_ops->set_state(fe, DVBFE_TUNER_FREQUENCY, &state);
67 if (err < 0) {
68 printk(KERN_ERR "%s: Invalid parameter\n", __func__);
69 return err;
70 }
71
72 if (frontend_ops->i2c_gate_ctrl)
73 frontend_ops->i2c_gate_ctrl(fe, 0);
74
75 }
76
77 return 0;
78}
79
80static int stb6100_get_bandw(struct dvb_frontend *fe, u32 *bandwidth)
81{
82 struct dvb_frontend_ops *frontend_ops = NULL;
83 struct dvb_tuner_ops *tuner_ops = NULL;
84 struct tuner_state state;
85 int err = 0;
86
87 if (&fe->ops)
88 frontend_ops = &fe->ops;
89 if (&frontend_ops->tuner_ops)
90 tuner_ops = &frontend_ops->tuner_ops;
91 if (tuner_ops->get_state) {
92 if (frontend_ops->i2c_gate_ctrl)
93 frontend_ops->i2c_gate_ctrl(fe, 1);
94
95 err = tuner_ops->get_state(fe, DVBFE_TUNER_BANDWIDTH, &state);
96 if (err < 0) {
97 printk(KERN_ERR "%s: Invalid parameter\n", __func__);
98 return err;
99 }
100
101 if (frontend_ops->i2c_gate_ctrl)
102 frontend_ops->i2c_gate_ctrl(fe, 0);
103
104 *bandwidth = state.bandwidth;
105 }
106
107 return 0;
108}
109
110static int stb6100_set_bandw(struct dvb_frontend *fe, u32 bandwidth)
111{
112 struct dvb_frontend_ops *frontend_ops = NULL;
113 struct dvb_tuner_ops *tuner_ops = NULL;
114 struct tuner_state state;
115 int err = 0;
116
117 state.bandwidth = bandwidth;
118 if (&fe->ops)
119 frontend_ops = &fe->ops;
120 if (&frontend_ops->tuner_ops)
121 tuner_ops = &frontend_ops->tuner_ops;
122 if (tuner_ops->set_state) {
123 if (frontend_ops->i2c_gate_ctrl)
124 frontend_ops->i2c_gate_ctrl(fe, 1);
125
126 err = tuner_ops->set_state(fe, DVBFE_TUNER_BANDWIDTH, &state);
127 if (err < 0) {
128 printk(KERN_ERR "%s: Invalid parameter\n", __func__);
129 return err;
130 }
131
132 if (frontend_ops->i2c_gate_ctrl)
133 frontend_ops->i2c_gate_ctrl(fe, 0);
134
135 }
136
137 return 0;
138}
diff --git a/drivers/media/dvb/frontends/stv0900.h b/drivers/media/dvb/frontends/stv0900.h
index bf4e9b633044..29c3fa85c227 100644
--- a/drivers/media/dvb/frontends/stv0900.h
+++ b/drivers/media/dvb/frontends/stv0900.h
@@ -36,6 +36,7 @@ struct stv0900_reg {
36 36
37struct stv0900_config { 37struct stv0900_config {
38 u8 demod_address; 38 u8 demod_address;
39 u8 demod_mode;
39 u32 xtal; 40 u32 xtal;
40 u8 clkmode;/* 0 for CLKI, 2 for XTALI */ 41 u8 clkmode;/* 0 for CLKI, 2 for XTALI */
41 42
@@ -48,6 +49,8 @@ struct stv0900_config {
48 u8 tun2_maddress; 49 u8 tun2_maddress;
49 u8 tun1_adc;/* 1 for stv6110, 2 for stb6100 */ 50 u8 tun1_adc;/* 1 for stv6110, 2 for stb6100 */
50 u8 tun2_adc; 51 u8 tun2_adc;
52 /* Set device param to start dma */
53 int (*set_ts_params)(struct dvb_frontend *fe, int is_punctured);
51}; 54};
52 55
53#if defined(CONFIG_DVB_STV0900) || (defined(CONFIG_DVB_STV0900_MODULE) \ 56#if defined(CONFIG_DVB_STV0900) || (defined(CONFIG_DVB_STV0900_MODULE) \
diff --git a/drivers/media/dvb/frontends/stv0900_core.c b/drivers/media/dvb/frontends/stv0900_core.c
index 3bde3324a032..df49ea0983bc 100644
--- a/drivers/media/dvb/frontends/stv0900_core.c
+++ b/drivers/media/dvb/frontends/stv0900_core.c
@@ -34,7 +34,7 @@
34#include "stv0900_priv.h" 34#include "stv0900_priv.h"
35#include "stv0900_init.h" 35#include "stv0900_init.h"
36 36
37static int stvdebug = 1; 37int stvdebug = 1;
38module_param_named(debug, stvdebug, int, 0644); 38module_param_named(debug, stvdebug, int, 0644);
39 39
40/* internal params node */ 40/* internal params node */
@@ -105,7 +105,8 @@ static struct stv0900_inode *append_internal(struct stv0900_internal *internal)
105 while (new_node->next_inode != NULL) 105 while (new_node->next_inode != NULL)
106 new_node = new_node->next_inode; 106 new_node = new_node->next_inode;
107 107
108 new_node->next_inode = kmalloc(sizeof(struct stv0900_inode), GFP_KERNEL); 108 new_node->next_inode = kmalloc(sizeof(struct stv0900_inode),
109 GFP_KERNEL);
109 if (new_node->next_inode != NULL) 110 if (new_node->next_inode != NULL)
110 new_node = new_node->next_inode; 111 new_node = new_node->next_inode;
111 else 112 else
@@ -128,13 +129,13 @@ s32 ge2comp(s32 a, s32 width)
128 return (a >= (1 << (width - 1))) ? (a - (1 << width)) : a; 129 return (a >= (1 << (width - 1))) ? (a - (1 << width)) : a;
129} 130}
130 131
131void stv0900_write_reg(struct stv0900_internal *i_params, u16 reg_addr, 132void stv0900_write_reg(struct stv0900_internal *intp, u16 reg_addr,
132 u8 reg_data) 133 u8 reg_data)
133{ 134{
134 u8 data[3]; 135 u8 data[3];
135 int ret; 136 int ret;
136 struct i2c_msg i2cmsg = { 137 struct i2c_msg i2cmsg = {
137 .addr = i_params->i2c_addr, 138 .addr = intp->i2c_addr,
138 .flags = 0, 139 .flags = 0,
139 .len = 3, 140 .len = 3,
140 .buf = data, 141 .buf = data,
@@ -144,33 +145,33 @@ void stv0900_write_reg(struct stv0900_internal *i_params, u16 reg_addr,
144 data[1] = LSB(reg_addr); 145 data[1] = LSB(reg_addr);
145 data[2] = reg_data; 146 data[2] = reg_data;
146 147
147 ret = i2c_transfer(i_params->i2c_adap, &i2cmsg, 1); 148 ret = i2c_transfer(intp->i2c_adap, &i2cmsg, 1);
148 if (ret != 1) 149 if (ret != 1)
149 dprintk(KERN_ERR "%s: i2c error %d\n", __func__, ret); 150 dprintk("%s: i2c error %d\n", __func__, ret);
150} 151}
151 152
152u8 stv0900_read_reg(struct stv0900_internal *i_params, u16 reg) 153u8 stv0900_read_reg(struct stv0900_internal *intp, u16 reg)
153{ 154{
154 int ret; 155 int ret;
155 u8 b0[] = { MSB(reg), LSB(reg) }; 156 u8 b0[] = { MSB(reg), LSB(reg) };
156 u8 buf = 0; 157 u8 buf = 0;
157 struct i2c_msg msg[] = { 158 struct i2c_msg msg[] = {
158 { 159 {
159 .addr = i_params->i2c_addr, 160 .addr = intp->i2c_addr,
160 .flags = 0, 161 .flags = 0,
161 .buf = b0, 162 .buf = b0,
162 .len = 2, 163 .len = 2,
163 }, { 164 }, {
164 .addr = i_params->i2c_addr, 165 .addr = intp->i2c_addr,
165 .flags = I2C_M_RD, 166 .flags = I2C_M_RD,
166 .buf = &buf, 167 .buf = &buf,
167 .len = 1, 168 .len = 1,
168 }, 169 },
169 }; 170 };
170 171
171 ret = i2c_transfer(i_params->i2c_adap, msg, 2); 172 ret = i2c_transfer(intp->i2c_adap, msg, 2);
172 if (ret != 2) 173 if (ret != 2)
173 dprintk(KERN_ERR "%s: i2c error %d, reg[0x%02x]\n", 174 dprintk("%s: i2c error %d, reg[0x%02x]\n",
174 __func__, ret, reg); 175 __func__, ret, reg);
175 176
176 return buf; 177 return buf;
@@ -190,169 +191,165 @@ void extract_mask_pos(u32 label, u8 *mask, u8 *pos)
190 (*pos) = (i - 1); 191 (*pos) = (i - 1);
191} 192}
192 193
193void stv0900_write_bits(struct stv0900_internal *i_params, u32 label, u8 val) 194void stv0900_write_bits(struct stv0900_internal *intp, u32 label, u8 val)
194{ 195{
195 u8 reg, mask, pos; 196 u8 reg, mask, pos;
196 197
197 reg = stv0900_read_reg(i_params, (label >> 16) & 0xffff); 198 reg = stv0900_read_reg(intp, (label >> 16) & 0xffff);
198 extract_mask_pos(label, &mask, &pos); 199 extract_mask_pos(label, &mask, &pos);
199 200
200 val = mask & (val << pos); 201 val = mask & (val << pos);
201 202
202 reg = (reg & (~mask)) | val; 203 reg = (reg & (~mask)) | val;
203 stv0900_write_reg(i_params, (label >> 16) & 0xffff, reg); 204 stv0900_write_reg(intp, (label >> 16) & 0xffff, reg);
204 205
205} 206}
206 207
207u8 stv0900_get_bits(struct stv0900_internal *i_params, u32 label) 208u8 stv0900_get_bits(struct stv0900_internal *intp, u32 label)
208{ 209{
209 u8 val = 0xff; 210 u8 val = 0xff;
210 u8 mask, pos; 211 u8 mask, pos;
211 212
212 extract_mask_pos(label, &mask, &pos); 213 extract_mask_pos(label, &mask, &pos);
213 214
214 val = stv0900_read_reg(i_params, label >> 16); 215 val = stv0900_read_reg(intp, label >> 16);
215 val = (val & mask) >> pos; 216 val = (val & mask) >> pos;
216 217
217 return val; 218 return val;
218} 219}
219 220
220enum fe_stv0900_error stv0900_initialize(struct stv0900_internal *i_params) 221enum fe_stv0900_error stv0900_initialize(struct stv0900_internal *intp)
221{ 222{
222 s32 i; 223 s32 i;
223 enum fe_stv0900_error error;
224
225 if (i_params != NULL) {
226 i_params->chip_id = stv0900_read_reg(i_params, R0900_MID);
227 if (i_params->errs == STV0900_NO_ERROR) {
228 /*Startup sequence*/
229 stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x5c);
230 stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x5c);
231 stv0900_write_reg(i_params, R0900_P1_TNRCFG, 0x6c);
232 stv0900_write_reg(i_params, R0900_P2_TNRCFG, 0x6f);
233 stv0900_write_reg(i_params, R0900_P1_I2CRPT, 0x20);
234 stv0900_write_reg(i_params, R0900_P2_I2CRPT, 0x20);
235 stv0900_write_reg(i_params, R0900_NCOARSE, 0x13);
236 msleep(3);
237 stv0900_write_reg(i_params, R0900_I2CCFG, 0x08);
238
239 switch (i_params->clkmode) {
240 case 0:
241 case 2:
242 stv0900_write_reg(i_params, R0900_SYNTCTRL, 0x20
243 | i_params->clkmode);
244 break;
245 default:
246 /* preserve SELOSCI bit */
247 i = 0x02 & stv0900_read_reg(i_params, R0900_SYNTCTRL);
248 stv0900_write_reg(i_params, R0900_SYNTCTRL, 0x20 | i);
249 break;
250 }
251 224
252 msleep(3); 225 if (intp == NULL)
253 for (i = 0; i < 182; i++) 226 return STV0900_INVALID_HANDLE;
254 stv0900_write_reg(i_params, STV0900_InitVal[i][0], STV0900_InitVal[i][1]);
255 227
256 if (stv0900_read_reg(i_params, R0900_MID) >= 0x20) { 228 intp->chip_id = stv0900_read_reg(intp, R0900_MID);
257 stv0900_write_reg(i_params, R0900_TSGENERAL, 0x0c);
258 for (i = 0; i < 32; i++)
259 stv0900_write_reg(i_params, STV0900_Cut20_AddOnVal[i][0], STV0900_Cut20_AddOnVal[i][1]);
260 }
261 229
262 stv0900_write_reg(i_params, R0900_P1_FSPYCFG, 0x6c); 230 if (intp->errs != STV0900_NO_ERROR)
263 stv0900_write_reg(i_params, R0900_P2_FSPYCFG, 0x6c); 231 return intp->errs;
264 stv0900_write_reg(i_params, R0900_TSTRES0, 0x80);
265 stv0900_write_reg(i_params, R0900_TSTRES0, 0x00);
266 }
267 error = i_params->errs;
268 } else
269 error = STV0900_INVALID_HANDLE;
270 232
271 return error; 233 /*Startup sequence*/
234 stv0900_write_reg(intp, R0900_P1_DMDISTATE, 0x5c);
235 stv0900_write_reg(intp, R0900_P2_DMDISTATE, 0x5c);
236 msleep(3);
237 stv0900_write_reg(intp, R0900_P1_TNRCFG, 0x6c);
238 stv0900_write_reg(intp, R0900_P2_TNRCFG, 0x6f);
239 stv0900_write_reg(intp, R0900_P1_I2CRPT, 0x20);
240 stv0900_write_reg(intp, R0900_P2_I2CRPT, 0x20);
241 stv0900_write_reg(intp, R0900_NCOARSE, 0x13);
242 msleep(3);
243 stv0900_write_reg(intp, R0900_I2CCFG, 0x08);
272 244
245 switch (intp->clkmode) {
246 case 0:
247 case 2:
248 stv0900_write_reg(intp, R0900_SYNTCTRL, 0x20
249 | intp->clkmode);
250 break;
251 default:
252 /* preserve SELOSCI bit */
253 i = 0x02 & stv0900_read_reg(intp, R0900_SYNTCTRL);
254 stv0900_write_reg(intp, R0900_SYNTCTRL, 0x20 | i);
255 break;
256 }
257
258 msleep(3);
259 for (i = 0; i < 181; i++)
260 stv0900_write_reg(intp, STV0900_InitVal[i][0],
261 STV0900_InitVal[i][1]);
262
263 if (stv0900_read_reg(intp, R0900_MID) >= 0x20) {
264 stv0900_write_reg(intp, R0900_TSGENERAL, 0x0c);
265 for (i = 0; i < 32; i++)
266 stv0900_write_reg(intp, STV0900_Cut20_AddOnVal[i][0],
267 STV0900_Cut20_AddOnVal[i][1]);
268 }
269
270 stv0900_write_reg(intp, R0900_P1_FSPYCFG, 0x6c);
271 stv0900_write_reg(intp, R0900_P2_FSPYCFG, 0x6c);
272
273 stv0900_write_reg(intp, R0900_P1_PDELCTRL2, 0x01);
274 stv0900_write_reg(intp, R0900_P2_PDELCTRL2, 0x21);
275
276 stv0900_write_reg(intp, R0900_P1_PDELCTRL3, 0x20);
277 stv0900_write_reg(intp, R0900_P2_PDELCTRL3, 0x20);
278
279 stv0900_write_reg(intp, R0900_TSTRES0, 0x80);
280 stv0900_write_reg(intp, R0900_TSTRES0, 0x00);
281
282 return STV0900_NO_ERROR;
273} 283}
274 284
275u32 stv0900_get_mclk_freq(struct stv0900_internal *i_params, u32 ext_clk) 285u32 stv0900_get_mclk_freq(struct stv0900_internal *intp, u32 ext_clk)
276{ 286{
277 u32 mclk = 90000000, div = 0, ad_div = 0; 287 u32 mclk = 90000000, div = 0, ad_div = 0;
278 288
279 div = stv0900_get_bits(i_params, F0900_M_DIV); 289 div = stv0900_get_bits(intp, F0900_M_DIV);
280 ad_div = ((stv0900_get_bits(i_params, F0900_SELX1RATIO) == 1) ? 4 : 6); 290 ad_div = ((stv0900_get_bits(intp, F0900_SELX1RATIO) == 1) ? 4 : 6);
281 291
282 mclk = (div + 1) * ext_clk / ad_div; 292 mclk = (div + 1) * ext_clk / ad_div;
283 293
284 dprintk(KERN_INFO "%s: Calculated Mclk = %d\n", __func__, mclk); 294 dprintk("%s: Calculated Mclk = %d\n", __func__, mclk);
285 295
286 return mclk; 296 return mclk;
287} 297}
288 298
289enum fe_stv0900_error stv0900_set_mclk(struct stv0900_internal *i_params, u32 mclk) 299enum fe_stv0900_error stv0900_set_mclk(struct stv0900_internal *intp, u32 mclk)
290{ 300{
291 enum fe_stv0900_error error = STV0900_NO_ERROR;
292 u32 m_div, clk_sel; 301 u32 m_div, clk_sel;
293 302
294 dprintk(KERN_INFO "%s: Mclk set to %d, Quartz = %d\n", __func__, mclk, 303 dprintk("%s: Mclk set to %d, Quartz = %d\n", __func__, mclk,
295 i_params->quartz); 304 intp->quartz);
296 305
297 if (i_params == NULL) 306 if (intp == NULL)
298 error = STV0900_INVALID_HANDLE; 307 return STV0900_INVALID_HANDLE;
299 else {
300 if (i_params->errs)
301 error = STV0900_I2C_ERROR;
302 else {
303 clk_sel = ((stv0900_get_bits(i_params, F0900_SELX1RATIO) == 1) ? 4 : 6);
304 m_div = ((clk_sel * mclk) / i_params->quartz) - 1;
305 stv0900_write_bits(i_params, F0900_M_DIV, m_div);
306 i_params->mclk = stv0900_get_mclk_freq(i_params,
307 i_params->quartz);
308
309 /*Set the DiseqC frequency to 22KHz */
310 /*
311 Formula:
312 DiseqC_TX_Freq= MasterClock/(32*F22TX_Reg)
313 DiseqC_RX_Freq= MasterClock/(32*F22RX_Reg)
314 */
315 m_div = i_params->mclk / 704000;
316 stv0900_write_reg(i_params, R0900_P1_F22TX, m_div);
317 stv0900_write_reg(i_params, R0900_P1_F22RX, m_div);
318
319 stv0900_write_reg(i_params, R0900_P2_F22TX, m_div);
320 stv0900_write_reg(i_params, R0900_P2_F22RX, m_div);
321
322 if ((i_params->errs))
323 error = STV0900_I2C_ERROR;
324 }
325 }
326 308
327 return error; 309 if (intp->errs)
310 return STV0900_I2C_ERROR;
311
312 clk_sel = ((stv0900_get_bits(intp, F0900_SELX1RATIO) == 1) ? 4 : 6);
313 m_div = ((clk_sel * mclk) / intp->quartz) - 1;
314 stv0900_write_bits(intp, F0900_M_DIV, m_div);
315 intp->mclk = stv0900_get_mclk_freq(intp,
316 intp->quartz);
317
318 /*Set the DiseqC frequency to 22KHz */
319 /*
320 Formula:
321 DiseqC_TX_Freq= MasterClock/(32*F22TX_Reg)
322 DiseqC_RX_Freq= MasterClock/(32*F22RX_Reg)
323 */
324 m_div = intp->mclk / 704000;
325 stv0900_write_reg(intp, R0900_P1_F22TX, m_div);
326 stv0900_write_reg(intp, R0900_P1_F22RX, m_div);
327
328 stv0900_write_reg(intp, R0900_P2_F22TX, m_div);
329 stv0900_write_reg(intp, R0900_P2_F22RX, m_div);
330
331 if ((intp->errs))
332 return STV0900_I2C_ERROR;
333
334 return STV0900_NO_ERROR;
328} 335}
329 336
330u32 stv0900_get_err_count(struct stv0900_internal *i_params, int cntr, 337u32 stv0900_get_err_count(struct stv0900_internal *intp, int cntr,
331 enum fe_stv0900_demod_num demod) 338 enum fe_stv0900_demod_num demod)
332{ 339{
333 u32 lsb, msb, hsb, err_val; 340 u32 lsb, msb, hsb, err_val;
334 s32 err1field_hsb, err1field_msb, err1field_lsb;
335 s32 err2field_hsb, err2field_msb, err2field_lsb;
336
337 dmd_reg(err1field_hsb, F0900_P1_ERR_CNT12, F0900_P2_ERR_CNT12);
338 dmd_reg(err1field_msb, F0900_P1_ERR_CNT11, F0900_P2_ERR_CNT11);
339 dmd_reg(err1field_lsb, F0900_P1_ERR_CNT10, F0900_P2_ERR_CNT10);
340
341 dmd_reg(err2field_hsb, F0900_P1_ERR_CNT22, F0900_P2_ERR_CNT22);
342 dmd_reg(err2field_msb, F0900_P1_ERR_CNT21, F0900_P2_ERR_CNT21);
343 dmd_reg(err2field_lsb, F0900_P1_ERR_CNT20, F0900_P2_ERR_CNT20);
344 341
345 switch (cntr) { 342 switch (cntr) {
346 case 0: 343 case 0:
347 default: 344 default:
348 hsb = stv0900_get_bits(i_params, err1field_hsb); 345 hsb = stv0900_get_bits(intp, ERR_CNT12);
349 msb = stv0900_get_bits(i_params, err1field_msb); 346 msb = stv0900_get_bits(intp, ERR_CNT11);
350 lsb = stv0900_get_bits(i_params, err1field_lsb); 347 lsb = stv0900_get_bits(intp, ERR_CNT10);
351 break; 348 break;
352 case 1: 349 case 1:
353 hsb = stv0900_get_bits(i_params, err2field_hsb); 350 hsb = stv0900_get_bits(intp, ERR_CNT22);
354 msb = stv0900_get_bits(i_params, err2field_msb); 351 msb = stv0900_get_bits(intp, ERR_CNT21);
355 lsb = stv0900_get_bits(i_params, err2field_lsb); 352 lsb = stv0900_get_bits(intp, ERR_CNT20);
356 break; 353 break;
357 } 354 }
358 355
@@ -364,26 +361,22 @@ u32 stv0900_get_err_count(struct stv0900_internal *i_params, int cntr,
364static int stv0900_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) 361static int stv0900_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
365{ 362{
366 struct stv0900_state *state = fe->demodulator_priv; 363 struct stv0900_state *state = fe->demodulator_priv;
367 struct stv0900_internal *i_params = state->internal; 364 struct stv0900_internal *intp = state->internal;
368 enum fe_stv0900_demod_num demod = state->demod; 365 enum fe_stv0900_demod_num demod = state->demod;
369 366
370 u32 fi2c; 367 stv0900_write_bits(intp, I2CT_ON, enable);
371
372 dmd_reg(fi2c, F0900_P1_I2CT_ON, F0900_P2_I2CT_ON);
373
374 stv0900_write_bits(i_params, fi2c, enable);
375 368
376 return 0; 369 return 0;
377} 370}
378 371
379static void stv0900_set_ts_parallel_serial(struct stv0900_internal *i_params, 372static void stv0900_set_ts_parallel_serial(struct stv0900_internal *intp,
380 enum fe_stv0900_clock_type path1_ts, 373 enum fe_stv0900_clock_type path1_ts,
381 enum fe_stv0900_clock_type path2_ts) 374 enum fe_stv0900_clock_type path2_ts)
382{ 375{
383 376
384 dprintk(KERN_INFO "%s\n", __func__); 377 dprintk("%s\n", __func__);
385 378
386 if (i_params->chip_id >= 0x20) { 379 if (intp->chip_id >= 0x20) {
387 switch (path1_ts) { 380 switch (path1_ts) {
388 case STV0900_PARALLEL_PUNCT_CLOCK: 381 case STV0900_PARALLEL_PUNCT_CLOCK:
389 case STV0900_DVBCI_CLOCK: 382 case STV0900_DVBCI_CLOCK:
@@ -391,20 +384,20 @@ static void stv0900_set_ts_parallel_serial(struct stv0900_internal *i_params,
391 case STV0900_SERIAL_PUNCT_CLOCK: 384 case STV0900_SERIAL_PUNCT_CLOCK:
392 case STV0900_SERIAL_CONT_CLOCK: 385 case STV0900_SERIAL_CONT_CLOCK:
393 default: 386 default:
394 stv0900_write_reg(i_params, R0900_TSGENERAL, 387 stv0900_write_reg(intp, R0900_TSGENERAL,
395 0x00); 388 0x00);
396 break; 389 break;
397 case STV0900_PARALLEL_PUNCT_CLOCK: 390 case STV0900_PARALLEL_PUNCT_CLOCK:
398 case STV0900_DVBCI_CLOCK: 391 case STV0900_DVBCI_CLOCK:
399 stv0900_write_reg(i_params, R0900_TSGENERAL, 392 stv0900_write_reg(intp, R0900_TSGENERAL,
400 0x06); 393 0x06);
401 stv0900_write_bits(i_params, 394 stv0900_write_bits(intp,
402 F0900_P1_TSFIFO_MANSPEED, 3); 395 F0900_P1_TSFIFO_MANSPEED, 3);
403 stv0900_write_bits(i_params, 396 stv0900_write_bits(intp,
404 F0900_P2_TSFIFO_MANSPEED, 0); 397 F0900_P2_TSFIFO_MANSPEED, 0);
405 stv0900_write_reg(i_params, 398 stv0900_write_reg(intp,
406 R0900_P1_TSSPEED, 0x14); 399 R0900_P1_TSSPEED, 0x14);
407 stv0900_write_reg(i_params, 400 stv0900_write_reg(intp,
408 R0900_P2_TSSPEED, 0x28); 401 R0900_P2_TSSPEED, 0x28);
409 break; 402 break;
410 } 403 }
@@ -416,14 +409,14 @@ static void stv0900_set_ts_parallel_serial(struct stv0900_internal *i_params,
416 case STV0900_SERIAL_PUNCT_CLOCK: 409 case STV0900_SERIAL_PUNCT_CLOCK:
417 case STV0900_SERIAL_CONT_CLOCK: 410 case STV0900_SERIAL_CONT_CLOCK:
418 default: 411 default:
419 stv0900_write_reg(i_params, 412 stv0900_write_reg(intp,
420 R0900_TSGENERAL, 0x0C); 413 R0900_TSGENERAL, 0x0C);
421 break; 414 break;
422 case STV0900_PARALLEL_PUNCT_CLOCK: 415 case STV0900_PARALLEL_PUNCT_CLOCK:
423 case STV0900_DVBCI_CLOCK: 416 case STV0900_DVBCI_CLOCK:
424 stv0900_write_reg(i_params, 417 stv0900_write_reg(intp,
425 R0900_TSGENERAL, 0x0A); 418 R0900_TSGENERAL, 0x0A);
426 dprintk(KERN_INFO "%s: 0x0a\n", __func__); 419 dprintk("%s: 0x0a\n", __func__);
427 break; 420 break;
428 } 421 }
429 break; 422 break;
@@ -436,20 +429,20 @@ static void stv0900_set_ts_parallel_serial(struct stv0900_internal *i_params,
436 case STV0900_SERIAL_PUNCT_CLOCK: 429 case STV0900_SERIAL_PUNCT_CLOCK:
437 case STV0900_SERIAL_CONT_CLOCK: 430 case STV0900_SERIAL_CONT_CLOCK:
438 default: 431 default:
439 stv0900_write_reg(i_params, R0900_TSGENERAL1X, 432 stv0900_write_reg(intp, R0900_TSGENERAL1X,
440 0x10); 433 0x10);
441 break; 434 break;
442 case STV0900_PARALLEL_PUNCT_CLOCK: 435 case STV0900_PARALLEL_PUNCT_CLOCK:
443 case STV0900_DVBCI_CLOCK: 436 case STV0900_DVBCI_CLOCK:
444 stv0900_write_reg(i_params, R0900_TSGENERAL1X, 437 stv0900_write_reg(intp, R0900_TSGENERAL1X,
445 0x16); 438 0x16);
446 stv0900_write_bits(i_params, 439 stv0900_write_bits(intp,
447 F0900_P1_TSFIFO_MANSPEED, 3); 440 F0900_P1_TSFIFO_MANSPEED, 3);
448 stv0900_write_bits(i_params, 441 stv0900_write_bits(intp,
449 F0900_P2_TSFIFO_MANSPEED, 0); 442 F0900_P2_TSFIFO_MANSPEED, 0);
450 stv0900_write_reg(i_params, R0900_P1_TSSPEED, 443 stv0900_write_reg(intp, R0900_P1_TSSPEED,
451 0x14); 444 0x14);
452 stv0900_write_reg(i_params, R0900_P2_TSSPEED, 445 stv0900_write_reg(intp, R0900_P2_TSSPEED,
453 0x28); 446 0x28);
454 break; 447 break;
455 } 448 }
@@ -462,14 +455,14 @@ static void stv0900_set_ts_parallel_serial(struct stv0900_internal *i_params,
462 case STV0900_SERIAL_PUNCT_CLOCK: 455 case STV0900_SERIAL_PUNCT_CLOCK:
463 case STV0900_SERIAL_CONT_CLOCK: 456 case STV0900_SERIAL_CONT_CLOCK:
464 default: 457 default:
465 stv0900_write_reg(i_params, R0900_TSGENERAL1X, 458 stv0900_write_reg(intp, R0900_TSGENERAL1X,
466 0x14); 459 0x14);
467 break; 460 break;
468 case STV0900_PARALLEL_PUNCT_CLOCK: 461 case STV0900_PARALLEL_PUNCT_CLOCK:
469 case STV0900_DVBCI_CLOCK: 462 case STV0900_DVBCI_CLOCK:
470 stv0900_write_reg(i_params, R0900_TSGENERAL1X, 463 stv0900_write_reg(intp, R0900_TSGENERAL1X,
471 0x12); 464 0x12);
472 dprintk(KERN_INFO "%s: 0x12\n", __func__); 465 dprintk("%s: 0x12\n", __func__);
473 break; 466 break;
474 } 467 }
475 468
@@ -479,20 +472,20 @@ static void stv0900_set_ts_parallel_serial(struct stv0900_internal *i_params,
479 472
480 switch (path1_ts) { 473 switch (path1_ts) {
481 case STV0900_PARALLEL_PUNCT_CLOCK: 474 case STV0900_PARALLEL_PUNCT_CLOCK:
482 stv0900_write_bits(i_params, F0900_P1_TSFIFO_SERIAL, 0x00); 475 stv0900_write_bits(intp, F0900_P1_TSFIFO_SERIAL, 0x00);
483 stv0900_write_bits(i_params, F0900_P1_TSFIFO_DVBCI, 0x00); 476 stv0900_write_bits(intp, F0900_P1_TSFIFO_DVBCI, 0x00);
484 break; 477 break;
485 case STV0900_DVBCI_CLOCK: 478 case STV0900_DVBCI_CLOCK:
486 stv0900_write_bits(i_params, F0900_P1_TSFIFO_SERIAL, 0x00); 479 stv0900_write_bits(intp, F0900_P1_TSFIFO_SERIAL, 0x00);
487 stv0900_write_bits(i_params, F0900_P1_TSFIFO_DVBCI, 0x01); 480 stv0900_write_bits(intp, F0900_P1_TSFIFO_DVBCI, 0x01);
488 break; 481 break;
489 case STV0900_SERIAL_PUNCT_CLOCK: 482 case STV0900_SERIAL_PUNCT_CLOCK:
490 stv0900_write_bits(i_params, F0900_P1_TSFIFO_SERIAL, 0x01); 483 stv0900_write_bits(intp, F0900_P1_TSFIFO_SERIAL, 0x01);
491 stv0900_write_bits(i_params, F0900_P1_TSFIFO_DVBCI, 0x00); 484 stv0900_write_bits(intp, F0900_P1_TSFIFO_DVBCI, 0x00);
492 break; 485 break;
493 case STV0900_SERIAL_CONT_CLOCK: 486 case STV0900_SERIAL_CONT_CLOCK:
494 stv0900_write_bits(i_params, F0900_P1_TSFIFO_SERIAL, 0x01); 487 stv0900_write_bits(intp, F0900_P1_TSFIFO_SERIAL, 0x01);
495 stv0900_write_bits(i_params, F0900_P1_TSFIFO_DVBCI, 0x01); 488 stv0900_write_bits(intp, F0900_P1_TSFIFO_DVBCI, 0x01);
496 break; 489 break;
497 default: 490 default:
498 break; 491 break;
@@ -500,29 +493,29 @@ static void stv0900_set_ts_parallel_serial(struct stv0900_internal *i_params,
500 493
501 switch (path2_ts) { 494 switch (path2_ts) {
502 case STV0900_PARALLEL_PUNCT_CLOCK: 495 case STV0900_PARALLEL_PUNCT_CLOCK:
503 stv0900_write_bits(i_params, F0900_P2_TSFIFO_SERIAL, 0x00); 496 stv0900_write_bits(intp, F0900_P2_TSFIFO_SERIAL, 0x00);
504 stv0900_write_bits(i_params, F0900_P2_TSFIFO_DVBCI, 0x00); 497 stv0900_write_bits(intp, F0900_P2_TSFIFO_DVBCI, 0x00);
505 break; 498 break;
506 case STV0900_DVBCI_CLOCK: 499 case STV0900_DVBCI_CLOCK:
507 stv0900_write_bits(i_params, F0900_P2_TSFIFO_SERIAL, 0x00); 500 stv0900_write_bits(intp, F0900_P2_TSFIFO_SERIAL, 0x00);
508 stv0900_write_bits(i_params, F0900_P2_TSFIFO_DVBCI, 0x01); 501 stv0900_write_bits(intp, F0900_P2_TSFIFO_DVBCI, 0x01);
509 break; 502 break;
510 case STV0900_SERIAL_PUNCT_CLOCK: 503 case STV0900_SERIAL_PUNCT_CLOCK:
511 stv0900_write_bits(i_params, F0900_P2_TSFIFO_SERIAL, 0x01); 504 stv0900_write_bits(intp, F0900_P2_TSFIFO_SERIAL, 0x01);
512 stv0900_write_bits(i_params, F0900_P2_TSFIFO_DVBCI, 0x00); 505 stv0900_write_bits(intp, F0900_P2_TSFIFO_DVBCI, 0x00);
513 break; 506 break;
514 case STV0900_SERIAL_CONT_CLOCK: 507 case STV0900_SERIAL_CONT_CLOCK:
515 stv0900_write_bits(i_params, F0900_P2_TSFIFO_SERIAL, 0x01); 508 stv0900_write_bits(intp, F0900_P2_TSFIFO_SERIAL, 0x01);
516 stv0900_write_bits(i_params, F0900_P2_TSFIFO_DVBCI, 0x01); 509 stv0900_write_bits(intp, F0900_P2_TSFIFO_DVBCI, 0x01);
517 break; 510 break;
518 default: 511 default:
519 break; 512 break;
520 } 513 }
521 514
522 stv0900_write_bits(i_params, F0900_P2_RST_HWARE, 1); 515 stv0900_write_bits(intp, F0900_P2_RST_HWARE, 1);
523 stv0900_write_bits(i_params, F0900_P2_RST_HWARE, 0); 516 stv0900_write_bits(intp, F0900_P2_RST_HWARE, 0);
524 stv0900_write_bits(i_params, F0900_P1_RST_HWARE, 1); 517 stv0900_write_bits(intp, F0900_P1_RST_HWARE, 1);
525 stv0900_write_bits(i_params, F0900_P1_RST_HWARE, 0); 518 stv0900_write_bits(intp, F0900_P1_RST_HWARE, 0);
526} 519}
527 520
528void stv0900_set_tuner(struct dvb_frontend *fe, u32 frequency, 521void stv0900_set_tuner(struct dvb_frontend *fe, u32 frequency,
@@ -574,7 +567,7 @@ void stv0900_set_bandwidth(struct dvb_frontend *fe, u32 bandwidth)
574 } 567 }
575} 568}
576 569
577static s32 stv0900_get_rf_level(struct stv0900_internal *i_params, 570static s32 stv0900_get_rf_level(struct stv0900_internal *intp,
578 const struct stv0900_table *lookup, 571 const struct stv0900_table *lookup,
579 enum fe_stv0900_demod_num demod) 572 enum fe_stv0900_demod_num demod)
580{ 573{
@@ -584,45 +577,41 @@ static s32 stv0900_get_rf_level(struct stv0900_internal *i_params,
584 i, 577 i,
585 rf_lvl = 0; 578 rf_lvl = 0;
586 579
587 dprintk(KERN_INFO "%s\n", __func__); 580 dprintk("%s\n", __func__);
588 581
589 if ((lookup != NULL) && lookup->size) { 582 if ((lookup == NULL) || (lookup->size <= 0))
590 switch (demod) { 583 return 0;
591 case STV0900_DEMOD_1:
592 default:
593 agc_gain = MAKEWORD(stv0900_get_bits(i_params, F0900_P1_AGCIQ_VALUE1),
594 stv0900_get_bits(i_params, F0900_P1_AGCIQ_VALUE0));
595 break;
596 case STV0900_DEMOD_2:
597 agc_gain = MAKEWORD(stv0900_get_bits(i_params, F0900_P2_AGCIQ_VALUE1),
598 stv0900_get_bits(i_params, F0900_P2_AGCIQ_VALUE0));
599 break;
600 }
601 584
602 imin = 0; 585 agc_gain = MAKEWORD(stv0900_get_bits(intp, AGCIQ_VALUE1),
603 imax = lookup->size - 1; 586 stv0900_get_bits(intp, AGCIQ_VALUE0));
604 if (INRANGE(lookup->table[imin].regval, agc_gain, lookup->table[imax].regval)) {
605 while ((imax - imin) > 1) {
606 i = (imax + imin) >> 1;
607 587
608 if (INRANGE(lookup->table[imin].regval, agc_gain, lookup->table[i].regval)) 588 imin = 0;
609 imax = i; 589 imax = lookup->size - 1;
610 else 590 if (INRANGE(lookup->table[imin].regval, agc_gain,
611 imin = i; 591 lookup->table[imax].regval)) {
612 } 592 while ((imax - imin) > 1) {
593 i = (imax + imin) >> 1;
613 594
614 rf_lvl = (((s32)agc_gain - lookup->table[imin].regval) 595 if (INRANGE(lookup->table[imin].regval,
615 * (lookup->table[imax].realval - lookup->table[imin].realval) 596 agc_gain,
616 / (lookup->table[imax].regval - lookup->table[imin].regval)) 597 lookup->table[i].regval))
617 + lookup->table[imin].realval; 598 imax = i;
618 } else if (agc_gain > lookup->table[0].regval) 599 else
619 rf_lvl = 5; 600 imin = i;
620 else if (agc_gain < lookup->table[lookup->size-1].regval) 601 }
621 rf_lvl = -100;
622 602
623 } 603 rf_lvl = (s32)agc_gain - lookup->table[imin].regval;
604 rf_lvl *= (lookup->table[imax].realval -
605 lookup->table[imin].realval);
606 rf_lvl /= (lookup->table[imax].regval -
607 lookup->table[imin].regval);
608 rf_lvl += lookup->table[imin].realval;
609 } else if (agc_gain > lookup->table[0].regval)
610 rf_lvl = 5;
611 else if (agc_gain < lookup->table[lookup->size-1].regval)
612 rf_lvl = -100;
624 613
625 dprintk(KERN_INFO "%s: RFLevel = %d\n", __func__, rf_lvl); 614 dprintk("%s: RFLevel = %d\n", __func__, rf_lvl);
626 615
627 return rf_lvl; 616 return rf_lvl;
628} 617}
@@ -634,50 +623,51 @@ static int stv0900_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
634 s32 rflevel = stv0900_get_rf_level(internal, &stv0900_rf, 623 s32 rflevel = stv0900_get_rf_level(internal, &stv0900_rf,
635 state->demod); 624 state->demod);
636 625
637 *strength = (rflevel + 100) * (16383 / 105); 626 rflevel = (rflevel + 100) * (65535 / 70);
627 if (rflevel < 0)
628 rflevel = 0;
629
630 if (rflevel > 65535)
631 rflevel = 65535;
632
633 *strength = rflevel;
638 634
639 return 0; 635 return 0;
640} 636}
641 637
642
643static s32 stv0900_carr_get_quality(struct dvb_frontend *fe, 638static s32 stv0900_carr_get_quality(struct dvb_frontend *fe,
644 const struct stv0900_table *lookup) 639 const struct stv0900_table *lookup)
645{ 640{
646 struct stv0900_state *state = fe->demodulator_priv; 641 struct stv0900_state *state = fe->demodulator_priv;
647 struct stv0900_internal *i_params = state->internal; 642 struct stv0900_internal *intp = state->internal;
648 enum fe_stv0900_demod_num demod = state->demod; 643 enum fe_stv0900_demod_num demod = state->demod;
649 644
650 s32 c_n = -100, 645 s32 c_n = -100,
651 regval, imin, imax, 646 regval,
647 imin,
648 imax,
652 i, 649 i,
653 lock_flag_field,
654 noise_field1, 650 noise_field1,
655 noise_field0; 651 noise_field0;
656 652
657 dprintk(KERN_INFO "%s\n", __func__); 653 dprintk("%s\n", __func__);
658 654
659 dmd_reg(lock_flag_field, F0900_P1_LOCK_DEFINITIF,
660 F0900_P2_LOCK_DEFINITIF);
661 if (stv0900_get_standard(fe, demod) == STV0900_DVBS2_STANDARD) { 655 if (stv0900_get_standard(fe, demod) == STV0900_DVBS2_STANDARD) {
662 dmd_reg(noise_field1, F0900_P1_NOSPLHT_NORMED1, 656 noise_field1 = NOSPLHT_NORMED1;
663 F0900_P2_NOSPLHT_NORMED1); 657 noise_field0 = NOSPLHT_NORMED0;
664 dmd_reg(noise_field0, F0900_P1_NOSPLHT_NORMED0,
665 F0900_P2_NOSPLHT_NORMED0);
666 } else { 658 } else {
667 dmd_reg(noise_field1, F0900_P1_NOSDATAT_NORMED1, 659 noise_field1 = NOSDATAT_NORMED1;
668 F0900_P2_NOSDATAT_NORMED1); 660 noise_field0 = NOSDATAT_NORMED0;
669 dmd_reg(noise_field0, F0900_P1_NOSDATAT_NORMED0,
670 F0900_P2_NOSDATAT_NORMED0);
671 } 661 }
672 662
673 if (stv0900_get_bits(i_params, lock_flag_field)) { 663 if (stv0900_get_bits(intp, LOCK_DEFINITIF)) {
674 if ((lookup != NULL) && lookup->size) { 664 if ((lookup != NULL) && lookup->size) {
675 regval = 0; 665 regval = 0;
676 msleep(5); 666 msleep(5);
677 for (i = 0; i < 16; i++) { 667 for (i = 0; i < 16; i++) {
678 regval += MAKEWORD(stv0900_get_bits(i_params, 668 regval += MAKEWORD(stv0900_get_bits(intp,
679 noise_field1), 669 noise_field1),
680 stv0900_get_bits(i_params, 670 stv0900_get_bits(intp,
681 noise_field0)); 671 noise_field0));
682 msleep(1); 672 msleep(1);
683 } 673 }
@@ -715,10 +705,9 @@ static s32 stv0900_carr_get_quality(struct dvb_frontend *fe,
715static int stv0900_read_ucblocks(struct dvb_frontend *fe, u32 * ucblocks) 705static int stv0900_read_ucblocks(struct dvb_frontend *fe, u32 * ucblocks)
716{ 706{
717 struct stv0900_state *state = fe->demodulator_priv; 707 struct stv0900_state *state = fe->demodulator_priv;
718 struct stv0900_internal *i_params = state->internal; 708 struct stv0900_internal *intp = state->internal;
719 enum fe_stv0900_demod_num demod = state->demod; 709 enum fe_stv0900_demod_num demod = state->demod;
720 u8 err_val1, err_val0; 710 u8 err_val1, err_val0;
721 s32 err_field1, err_field0;
722 u32 header_err_val = 0; 711 u32 header_err_val = 0;
723 712
724 *ucblocks = 0x0; 713 *ucblocks = 0x0;
@@ -726,24 +715,14 @@ static int stv0900_read_ucblocks(struct dvb_frontend *fe, u32 * ucblocks)
726 /* DVB-S2 delineator errors count */ 715 /* DVB-S2 delineator errors count */
727 716
728 /* retreiving number for errnous headers */ 717 /* retreiving number for errnous headers */
729 dmd_reg(err_field0, R0900_P1_BBFCRCKO0, 718 err_val1 = stv0900_read_reg(intp, BBFCRCKO1);
730 R0900_P2_BBFCRCKO0); 719 err_val0 = stv0900_read_reg(intp, BBFCRCKO0);
731 dmd_reg(err_field1, R0900_P1_BBFCRCKO1, 720 header_err_val = (err_val1 << 8) | err_val0;
732 R0900_P2_BBFCRCKO1);
733
734 err_val1 = stv0900_read_reg(i_params, err_field1);
735 err_val0 = stv0900_read_reg(i_params, err_field0);
736 header_err_val = (err_val1<<8) | err_val0;
737 721
738 /* retreiving number for errnous packets */ 722 /* retreiving number for errnous packets */
739 dmd_reg(err_field0, R0900_P1_UPCRCKO0, 723 err_val1 = stv0900_read_reg(intp, UPCRCKO1);
740 R0900_P2_UPCRCKO0); 724 err_val0 = stv0900_read_reg(intp, UPCRCKO0);
741 dmd_reg(err_field1, R0900_P1_UPCRCKO1, 725 *ucblocks = (err_val1 << 8) | err_val0;
742 R0900_P2_UPCRCKO1);
743
744 err_val1 = stv0900_read_reg(i_params, err_field1);
745 err_val0 = stv0900_read_reg(i_params, err_field0);
746 *ucblocks = (err_val1<<8) | err_val0;
747 *ucblocks += header_err_val; 726 *ucblocks += header_err_val;
748 } 727 }
749 728
@@ -752,33 +731,27 @@ static int stv0900_read_ucblocks(struct dvb_frontend *fe, u32 * ucblocks)
752 731
753static int stv0900_read_snr(struct dvb_frontend *fe, u16 *snr) 732static int stv0900_read_snr(struct dvb_frontend *fe, u16 *snr)
754{ 733{
755 *snr = stv0900_carr_get_quality(fe, 734 s32 snrlcl = stv0900_carr_get_quality(fe,
756 (const struct stv0900_table *)&stv0900_s2_cn); 735 (const struct stv0900_table *)&stv0900_s2_cn);
757 *snr += 30; 736 snrlcl = (snrlcl + 30) * 384;
758 *snr *= (16383 / 1030); 737 if (snrlcl < 0)
738 snrlcl = 0;
739
740 if (snrlcl > 65535)
741 snrlcl = 65535;
742
743 *snr = snrlcl;
759 744
760 return 0; 745 return 0;
761} 746}
762 747
763static u32 stv0900_get_ber(struct stv0900_internal *i_params, 748static u32 stv0900_get_ber(struct stv0900_internal *intp,
764 enum fe_stv0900_demod_num demod) 749 enum fe_stv0900_demod_num demod)
765{ 750{
766 u32 ber = 10000000, i; 751 u32 ber = 10000000, i;
767 s32 dmd_state_reg;
768 s32 demod_state; 752 s32 demod_state;
769 s32 vstatus_reg;
770 s32 prvit_field;
771 s32 pdel_status_reg;
772 s32 pdel_lock_field;
773
774 dmd_reg(dmd_state_reg, F0900_P1_HEADER_MODE, F0900_P2_HEADER_MODE);
775 dmd_reg(vstatus_reg, R0900_P1_VSTATUSVIT, R0900_P2_VSTATUSVIT);
776 dmd_reg(prvit_field, F0900_P1_PRFVIT, F0900_P2_PRFVIT);
777 dmd_reg(pdel_status_reg, R0900_P1_PDELSTATUS1, R0900_P2_PDELSTATUS1);
778 dmd_reg(pdel_lock_field, F0900_P1_PKTDELIN_LOCK,
779 F0900_P2_PKTDELIN_LOCK);
780 753
781 demod_state = stv0900_get_bits(i_params, dmd_state_reg); 754 demod_state = stv0900_get_bits(intp, HEADER_MODE);
782 755
783 switch (demod_state) { 756 switch (demod_state) {
784 case STV0900_SEARCH: 757 case STV0900_SEARCH:
@@ -790,11 +763,11 @@ static u32 stv0900_get_ber(struct stv0900_internal *i_params,
790 ber = 0; 763 ber = 0;
791 for (i = 0; i < 5; i++) { 764 for (i = 0; i < 5; i++) {
792 msleep(5); 765 msleep(5);
793 ber += stv0900_get_err_count(i_params, 0, demod); 766 ber += stv0900_get_err_count(intp, 0, demod);
794 } 767 }
795 768
796 ber /= 5; 769 ber /= 5;
797 if (stv0900_get_bits(i_params, prvit_field)) { 770 if (stv0900_get_bits(intp, PRFVIT)) {
798 ber *= 9766; 771 ber *= 9766;
799 ber = ber >> 13; 772 ber = ber >> 13;
800 } 773 }
@@ -804,11 +777,11 @@ static u32 stv0900_get_ber(struct stv0900_internal *i_params,
804 ber = 0; 777 ber = 0;
805 for (i = 0; i < 5; i++) { 778 for (i = 0; i < 5; i++) {
806 msleep(5); 779 msleep(5);
807 ber += stv0900_get_err_count(i_params, 0, demod); 780 ber += stv0900_get_err_count(intp, 0, demod);
808 } 781 }
809 782
810 ber /= 5; 783 ber /= 5;
811 if (stv0900_get_bits(i_params, pdel_lock_field)) { 784 if (stv0900_get_bits(intp, PKTDELIN_LOCK)) {
812 ber *= 9766; 785 ber *= 9766;
813 ber = ber >> 13; 786 ber = ber >> 13;
814 } 787 }
@@ -829,20 +802,16 @@ static int stv0900_read_ber(struct dvb_frontend *fe, u32 *ber)
829 return 0; 802 return 0;
830} 803}
831 804
832int stv0900_get_demod_lock(struct stv0900_internal *i_params, 805int stv0900_get_demod_lock(struct stv0900_internal *intp,
833 enum fe_stv0900_demod_num demod, s32 time_out) 806 enum fe_stv0900_demod_num demod, s32 time_out)
834{ 807{
835 s32 timer = 0, 808 s32 timer = 0,
836 lock = 0, 809 lock = 0;
837 header_field,
838 lock_field;
839 810
840 enum fe_stv0900_search_state dmd_state; 811 enum fe_stv0900_search_state dmd_state;
841 812
842 dmd_reg(header_field, F0900_P1_HEADER_MODE, F0900_P2_HEADER_MODE);
843 dmd_reg(lock_field, F0900_P1_LOCK_DEFINITIF, F0900_P2_LOCK_DEFINITIF);
844 while ((timer < time_out) && (lock == 0)) { 813 while ((timer < time_out) && (lock == 0)) {
845 dmd_state = stv0900_get_bits(i_params, header_field); 814 dmd_state = stv0900_get_bits(intp, HEADER_MODE);
846 dprintk("Demod State = %d\n", dmd_state); 815 dprintk("Demod State = %d\n", dmd_state);
847 switch (dmd_state) { 816 switch (dmd_state) {
848 case STV0900_SEARCH: 817 case STV0900_SEARCH:
@@ -852,7 +821,7 @@ int stv0900_get_demod_lock(struct stv0900_internal *i_params,
852 break; 821 break;
853 case STV0900_DVBS2_FOUND: 822 case STV0900_DVBS2_FOUND:
854 case STV0900_DVBS_FOUND: 823 case STV0900_DVBS_FOUND:
855 lock = stv0900_get_bits(i_params, lock_field); 824 lock = stv0900_get_bits(intp, LOCK_DEFINITIF);
856 break; 825 break;
857 } 826 }
858 827
@@ -870,56 +839,40 @@ int stv0900_get_demod_lock(struct stv0900_internal *i_params,
870 return lock; 839 return lock;
871} 840}
872 841
873void stv0900_stop_all_s2_modcod(struct stv0900_internal *i_params, 842void stv0900_stop_all_s2_modcod(struct stv0900_internal *intp,
874 enum fe_stv0900_demod_num demod) 843 enum fe_stv0900_demod_num demod)
875{ 844{
876 s32 regflist, 845 s32 regflist,
877 i; 846 i;
878 847
879 dprintk(KERN_INFO "%s\n", __func__); 848 dprintk("%s\n", __func__);
880 849
881 dmd_reg(regflist, R0900_P1_MODCODLST0, R0900_P2_MODCODLST0); 850 regflist = MODCODLST0;
882 851
883 for (i = 0; i < 16; i++) 852 for (i = 0; i < 16; i++)
884 stv0900_write_reg(i_params, regflist + i, 0xff); 853 stv0900_write_reg(intp, regflist + i, 0xff);
885} 854}
886 855
887void stv0900_activate_s2_modcode(struct stv0900_internal *i_params, 856void stv0900_activate_s2_modcod(struct stv0900_internal *intp,
888 enum fe_stv0900_demod_num demod) 857 enum fe_stv0900_demod_num demod)
889{ 858{
890 u32 matype, 859 u32 matype,
891 mod_code, 860 mod_code,
892 fmod, 861 fmod,
893 reg_index, 862 reg_index,
894 field_index; 863 field_index;
895 864
896 dprintk(KERN_INFO "%s\n", __func__); 865 dprintk("%s\n", __func__);
897 866
898 if (i_params->chip_id <= 0x11) { 867 if (intp->chip_id <= 0x11) {
899 msleep(5); 868 msleep(5);
900 869
901 switch (demod) { 870 mod_code = stv0900_read_reg(intp, PLHMODCOD);
902 case STV0900_DEMOD_1: 871 matype = mod_code & 0x3;
903 default: 872 mod_code = (mod_code & 0x7f) >> 2;
904 mod_code = stv0900_read_reg(i_params,
905 R0900_P1_PLHMODCOD);
906 matype = mod_code & 0x3;
907 mod_code = (mod_code & 0x7f) >> 2;
908
909 reg_index = R0900_P1_MODCODLSTF - mod_code / 2;
910 field_index = mod_code % 2;
911 break;
912 case STV0900_DEMOD_2:
913 mod_code = stv0900_read_reg(i_params,
914 R0900_P2_PLHMODCOD);
915 matype = mod_code & 0x3;
916 mod_code = (mod_code & 0x7f) >> 2;
917
918 reg_index = R0900_P2_MODCODLSTF - mod_code / 2;
919 field_index = mod_code % 2;
920 break;
921 }
922 873
874 reg_index = MODCODLSTF - mod_code / 2;
875 field_index = mod_code % 2;
923 876
924 switch (matype) { 877 switch (matype) {
925 case 0: 878 case 0:
@@ -938,70 +891,41 @@ void stv0900_activate_s2_modcode(struct stv0900_internal *i_params,
938 } 891 }
939 892
940 if ((INRANGE(STV0900_QPSK_12, mod_code, STV0900_8PSK_910)) 893 if ((INRANGE(STV0900_QPSK_12, mod_code, STV0900_8PSK_910))
941 && (matype <= 1)) { 894 && (matype <= 1)) {
942 if (field_index == 0) 895 if (field_index == 0)
943 stv0900_write_reg(i_params, reg_index, 896 stv0900_write_reg(intp, reg_index,
944 0xf0 | fmod); 897 0xf0 | fmod);
945 else 898 else
946 stv0900_write_reg(i_params, reg_index, 899 stv0900_write_reg(intp, reg_index,
947 (fmod << 4) | 0xf); 900 (fmod << 4) | 0xf);
948 } 901 }
949 } else if (i_params->chip_id >= 0x12) {
950 switch (demod) {
951 case STV0900_DEMOD_1:
952 default:
953 for (reg_index = 0; reg_index < 7; reg_index++)
954 stv0900_write_reg(i_params, R0900_P1_MODCODLST0 + reg_index, 0xff);
955 902
956 stv0900_write_reg(i_params, R0900_P1_MODCODLSTE, 0xff); 903 } else if (intp->chip_id >= 0x12) {
957 stv0900_write_reg(i_params, R0900_P1_MODCODLSTF, 0xcf); 904 for (reg_index = 0; reg_index < 7; reg_index++)
958 for (reg_index = 0; reg_index < 8; reg_index++) 905 stv0900_write_reg(intp, MODCODLST0 + reg_index, 0xff);
959 stv0900_write_reg(i_params, R0900_P1_MODCODLST7 + reg_index, 0xcc);
960 906
961 break; 907 stv0900_write_reg(intp, MODCODLSTE, 0xff);
962 case STV0900_DEMOD_2: 908 stv0900_write_reg(intp, MODCODLSTF, 0xcf);
963 for (reg_index = 0; reg_index < 7; reg_index++) 909 for (reg_index = 0; reg_index < 8; reg_index++)
964 stv0900_write_reg(i_params, R0900_P2_MODCODLST0 + reg_index, 0xff); 910 stv0900_write_reg(intp, MODCODLST7 + reg_index, 0xcc);
965 911
966 stv0900_write_reg(i_params, R0900_P2_MODCODLSTE, 0xff);
967 stv0900_write_reg(i_params, R0900_P2_MODCODLSTF, 0xcf);
968 for (reg_index = 0; reg_index < 8; reg_index++)
969 stv0900_write_reg(i_params, R0900_P2_MODCODLST7 + reg_index, 0xcc);
970
971 break;
972 }
973 912
974 } 913 }
975} 914}
976 915
977void stv0900_activate_s2_modcode_single(struct stv0900_internal *i_params, 916void stv0900_activate_s2_modcod_single(struct stv0900_internal *intp,
978 enum fe_stv0900_demod_num demod) 917 enum fe_stv0900_demod_num demod)
979{ 918{
980 u32 reg_index; 919 u32 reg_index;
981 920
982 dprintk(KERN_INFO "%s\n", __func__); 921 dprintk("%s\n", __func__);
983
984 switch (demod) {
985 case STV0900_DEMOD_1:
986 default:
987 stv0900_write_reg(i_params, R0900_P1_MODCODLST0, 0xff);
988 stv0900_write_reg(i_params, R0900_P1_MODCODLST1, 0xf0);
989 stv0900_write_reg(i_params, R0900_P1_MODCODLSTF, 0x0f);
990 for (reg_index = 0; reg_index < 13; reg_index++)
991 stv0900_write_reg(i_params,
992 R0900_P1_MODCODLST2 + reg_index, 0);
993 922
994 break; 923 stv0900_write_reg(intp, MODCODLST0, 0xff);
995 case STV0900_DEMOD_2: 924 stv0900_write_reg(intp, MODCODLST1, 0xf0);
996 stv0900_write_reg(i_params, R0900_P2_MODCODLST0, 0xff); 925 stv0900_write_reg(intp, MODCODLSTF, 0x0f);
997 stv0900_write_reg(i_params, R0900_P2_MODCODLST1, 0xf0); 926 for (reg_index = 0; reg_index < 13; reg_index++)
998 stv0900_write_reg(i_params, R0900_P2_MODCODLSTF, 0x0f); 927 stv0900_write_reg(intp, MODCODLST2 + reg_index, 0);
999 for (reg_index = 0; reg_index < 13; reg_index++)
1000 stv0900_write_reg(i_params,
1001 R0900_P2_MODCODLST2 + reg_index, 0);
1002 928
1003 break;
1004 }
1005} 929}
1006 930
1007static enum dvbfe_algo stv0900_frontend_algo(struct dvb_frontend *fe) 931static enum dvbfe_algo stv0900_frontend_algo(struct dvb_frontend *fe)
@@ -1012,7 +936,7 @@ static enum dvbfe_algo stv0900_frontend_algo(struct dvb_frontend *fe)
1012static int stb0900_set_property(struct dvb_frontend *fe, 936static int stb0900_set_property(struct dvb_frontend *fe,
1013 struct dtv_property *tvp) 937 struct dtv_property *tvp)
1014{ 938{
1015 dprintk(KERN_INFO "%s(..)\n", __func__); 939 dprintk("%s(..)\n", __func__);
1016 940
1017 return 0; 941 return 0;
1018} 942}
@@ -1020,166 +944,123 @@ static int stb0900_set_property(struct dvb_frontend *fe,
1020static int stb0900_get_property(struct dvb_frontend *fe, 944static int stb0900_get_property(struct dvb_frontend *fe,
1021 struct dtv_property *tvp) 945 struct dtv_property *tvp)
1022{ 946{
1023 dprintk(KERN_INFO "%s(..)\n", __func__); 947 dprintk("%s(..)\n", __func__);
1024 948
1025 return 0; 949 return 0;
1026} 950}
1027 951
1028void stv0900_start_search(struct stv0900_internal *i_params, 952void stv0900_start_search(struct stv0900_internal *intp,
1029 enum fe_stv0900_demod_num demod) 953 enum fe_stv0900_demod_num demod)
1030{ 954{
1031 955 u32 freq;
1032 switch (demod) { 956 s16 freq_s16 ;
1033 case STV0900_DEMOD_1: 957
1034 default: 958 stv0900_write_bits(intp, DEMOD_MODE, 0x1f);
1035 stv0900_write_bits(i_params, F0900_P1_I2C_DEMOD_MODE, 0x1f); 959 if (intp->chip_id == 0x10)
1036 960 stv0900_write_reg(intp, CORRELEXP, 0xaa);
1037 if (i_params->chip_id == 0x10) 961
1038 stv0900_write_reg(i_params, R0900_P1_CORRELEXP, 0xaa); 962 if (intp->chip_id < 0x20)
1039 963 stv0900_write_reg(intp, CARHDR, 0x55);
1040 if (i_params->chip_id < 0x20) 964
1041 stv0900_write_reg(i_params, R0900_P1_CARHDR, 0x55); 965 if (intp->chip_id <= 0x20) {
1042 966 if (intp->symbol_rate[0] <= 5000000) {
1043 if (i_params->dmd1_symbol_rate <= 5000000) { 967 stv0900_write_reg(intp, CARCFG, 0x44);
1044 stv0900_write_reg(i_params, R0900_P1_CARCFG, 0x44); 968 stv0900_write_reg(intp, CFRUP1, 0x0f);
1045 stv0900_write_reg(i_params, R0900_P1_CFRUP1, 0x0f); 969 stv0900_write_reg(intp, CFRUP0, 0xff);
1046 stv0900_write_reg(i_params, R0900_P1_CFRUP0, 0xff); 970 stv0900_write_reg(intp, CFRLOW1, 0xf0);
1047 stv0900_write_reg(i_params, R0900_P1_CFRLOW1, 0xf0); 971 stv0900_write_reg(intp, CFRLOW0, 0x00);
1048 stv0900_write_reg(i_params, R0900_P1_CFRLOW0, 0x00); 972 stv0900_write_reg(intp, RTCS2, 0x68);
1049 stv0900_write_reg(i_params, R0900_P1_RTCS2, 0x68);
1050 } else { 973 } else {
1051 stv0900_write_reg(i_params, R0900_P1_CARCFG, 0xc4); 974 stv0900_write_reg(intp, CARCFG, 0xc4);
1052 stv0900_write_reg(i_params, R0900_P1_RTCS2, 0x44); 975 stv0900_write_reg(intp, RTCS2, 0x44);
1053 }
1054
1055 stv0900_write_reg(i_params, R0900_P1_CFRINIT1, 0);
1056 stv0900_write_reg(i_params, R0900_P1_CFRINIT0, 0);
1057
1058 if (i_params->chip_id >= 0x20) {
1059 stv0900_write_reg(i_params, R0900_P1_EQUALCFG, 0x41);
1060 stv0900_write_reg(i_params, R0900_P1_FFECFG, 0x41);
1061
1062 if ((i_params->dmd1_srch_standard == STV0900_SEARCH_DVBS1) || (i_params->dmd1_srch_standard == STV0900_SEARCH_DSS) || (i_params->dmd1_srch_standard == STV0900_AUTO_SEARCH)) {
1063 stv0900_write_reg(i_params, R0900_P1_VITSCALE, 0x82);
1064 stv0900_write_reg(i_params, R0900_P1_VAVSRVIT, 0x0);
1065 }
1066 } 976 }
1067 977
1068 stv0900_write_reg(i_params, R0900_P1_SFRSTEP, 0x00); 978 } else { /*cut 3.0 above*/
1069 stv0900_write_reg(i_params, R0900_P1_TMGTHRISE, 0xe0); 979 if (intp->symbol_rate[demod] <= 5000000)
1070 stv0900_write_reg(i_params, R0900_P1_TMGTHFALL, 0xc0); 980 stv0900_write_reg(intp, RTCS2, 0x68);
1071 stv0900_write_bits(i_params, F0900_P1_SCAN_ENABLE, 0); 981 else
1072 stv0900_write_bits(i_params, F0900_P1_CFR_AUTOSCAN, 0); 982 stv0900_write_reg(intp, RTCS2, 0x44);
1073 stv0900_write_bits(i_params, F0900_P1_S1S2_SEQUENTIAL, 0);
1074 stv0900_write_reg(i_params, R0900_P1_RTC, 0x88);
1075 if (i_params->chip_id >= 0x20) {
1076 if (i_params->dmd1_symbol_rate < 2000000) {
1077 stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0x39);
1078 stv0900_write_reg(i_params, R0900_P1_CARHDR, 0x40);
1079 }
1080
1081 if (i_params->dmd1_symbol_rate < 10000000) {
1082 stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0x4c);
1083 stv0900_write_reg(i_params, R0900_P1_CARHDR, 0x20);
1084 } else {
1085 stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0x4b);
1086 stv0900_write_reg(i_params, R0900_P1_CARHDR, 0x20);
1087 }
1088 983
984 stv0900_write_reg(intp, CARCFG, 0x46);
985 if (intp->srch_algo[demod] == STV0900_WARM_START) {
986 freq = 1000 << 16;
987 freq /= (intp->mclk / 1000);
988 freq_s16 = (s16)freq;
1089 } else { 989 } else {
1090 if (i_params->dmd1_symbol_rate < 10000000) 990 freq = (intp->srch_range[demod] / 2000);
1091 stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0xef); 991 if (intp->symbol_rate[demod] <= 5000000)
992 freq += 80;
1092 else 993 else
1093 stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0xed); 994 freq += 600;
1094 }
1095 995
1096 switch (i_params->dmd1_srch_algo) { 996 freq = freq << 16;
1097 case STV0900_WARM_START: 997 freq /= (intp->mclk / 1000);
1098 stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1f); 998 freq_s16 = (s16)freq;
1099 stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x18);
1100 break;
1101 case STV0900_COLD_START:
1102 stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1f);
1103 stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x15);
1104 break;
1105 default:
1106 break;
1107 }
1108
1109 break;
1110 case STV0900_DEMOD_2:
1111 stv0900_write_bits(i_params, F0900_P2_I2C_DEMOD_MODE, 0x1f);
1112 if (i_params->chip_id == 0x10)
1113 stv0900_write_reg(i_params, R0900_P2_CORRELEXP, 0xaa);
1114
1115 if (i_params->chip_id < 0x20)
1116 stv0900_write_reg(i_params, R0900_P2_CARHDR, 0x55);
1117
1118 if (i_params->dmd2_symbol_rate <= 5000000) {
1119 stv0900_write_reg(i_params, R0900_P2_CARCFG, 0x44);
1120 stv0900_write_reg(i_params, R0900_P2_CFRUP1, 0x0f);
1121 stv0900_write_reg(i_params, R0900_P2_CFRUP0, 0xff);
1122 stv0900_write_reg(i_params, R0900_P2_CFRLOW1, 0xf0);
1123 stv0900_write_reg(i_params, R0900_P2_CFRLOW0, 0x00);
1124 stv0900_write_reg(i_params, R0900_P2_RTCS2, 0x68);
1125 } else {
1126 stv0900_write_reg(i_params, R0900_P2_CARCFG, 0xc4);
1127 stv0900_write_reg(i_params, R0900_P2_RTCS2, 0x44);
1128 } 999 }
1129 1000
1130 stv0900_write_reg(i_params, R0900_P2_CFRINIT1, 0); 1001 stv0900_write_bits(intp, CFR_UP1, MSB(freq_s16));
1131 stv0900_write_reg(i_params, R0900_P2_CFRINIT0, 0); 1002 stv0900_write_bits(intp, CFR_UP0, LSB(freq_s16));
1003 freq_s16 *= (-1);
1004 stv0900_write_bits(intp, CFR_LOW1, MSB(freq_s16));
1005 stv0900_write_bits(intp, CFR_LOW0, LSB(freq_s16));
1006 }
1132 1007
1133 if (i_params->chip_id >= 0x20) { 1008 stv0900_write_reg(intp, CFRINIT1, 0);
1134 stv0900_write_reg(i_params, R0900_P2_EQUALCFG, 0x41); 1009 stv0900_write_reg(intp, CFRINIT0, 0);
1135 stv0900_write_reg(i_params, R0900_P2_FFECFG, 0x41);
1136 if ((i_params->dmd2_srch_stndrd == STV0900_SEARCH_DVBS1) || (i_params->dmd2_srch_stndrd == STV0900_SEARCH_DSS) || (i_params->dmd2_srch_stndrd == STV0900_AUTO_SEARCH)) {
1137 stv0900_write_reg(i_params, R0900_P2_VITSCALE, 0x82);
1138 stv0900_write_reg(i_params, R0900_P2_VAVSRVIT, 0x0);
1139 }
1140 }
1141 1010
1142 stv0900_write_reg(i_params, R0900_P2_SFRSTEP, 0x00); 1011 if (intp->chip_id >= 0x20) {
1143 stv0900_write_reg(i_params, R0900_P2_TMGTHRISE, 0xe0); 1012 stv0900_write_reg(intp, EQUALCFG, 0x41);
1144 stv0900_write_reg(i_params, R0900_P2_TMGTHFALL, 0xc0); 1013 stv0900_write_reg(intp, FFECFG, 0x41);
1145 stv0900_write_bits(i_params, F0900_P2_SCAN_ENABLE, 0);
1146 stv0900_write_bits(i_params, F0900_P2_CFR_AUTOSCAN, 0);
1147 stv0900_write_bits(i_params, F0900_P2_S1S2_SEQUENTIAL, 0);
1148 stv0900_write_reg(i_params, R0900_P2_RTC, 0x88);
1149 if (i_params->chip_id >= 0x20) {
1150 if (i_params->dmd2_symbol_rate < 2000000) {
1151 stv0900_write_reg(i_params, R0900_P2_CARFREQ, 0x39);
1152 stv0900_write_reg(i_params, R0900_P2_CARHDR, 0x40);
1153 }
1154 1014
1155 if (i_params->dmd2_symbol_rate < 10000000) { 1015 if ((intp->srch_standard[demod] == STV0900_SEARCH_DVBS1) ||
1156 stv0900_write_reg(i_params, R0900_P2_CARFREQ, 0x4c); 1016 (intp->srch_standard[demod] == STV0900_SEARCH_DSS) ||
1157 stv0900_write_reg(i_params, R0900_P2_CARHDR, 0x20); 1017 (intp->srch_standard[demod] == STV0900_AUTO_SEARCH)) {
1158 } else { 1018 stv0900_write_reg(intp, VITSCALE,
1159 stv0900_write_reg(i_params, R0900_P2_CARFREQ, 0x4b); 1019 0x82);
1160 stv0900_write_reg(i_params, R0900_P2_CARHDR, 0x20); 1020 stv0900_write_reg(intp, VAVSRVIT, 0x0);
1161 } 1021 }
1022 }
1162 1023
1024 stv0900_write_reg(intp, SFRSTEP, 0x00);
1025 stv0900_write_reg(intp, TMGTHRISE, 0xe0);
1026 stv0900_write_reg(intp, TMGTHFALL, 0xc0);
1027 stv0900_write_bits(intp, SCAN_ENABLE, 0);
1028 stv0900_write_bits(intp, CFR_AUTOSCAN, 0);
1029 stv0900_write_bits(intp, S1S2_SEQUENTIAL, 0);
1030 stv0900_write_reg(intp, RTC, 0x88);
1031 if (intp->chip_id >= 0x20) {
1032 if (intp->symbol_rate[demod] < 2000000) {
1033 if (intp->chip_id <= 0x20)
1034 stv0900_write_reg(intp, CARFREQ, 0x39);
1035 else /*cut 3.0*/
1036 stv0900_write_reg(intp, CARFREQ, 0x89);
1037
1038 stv0900_write_reg(intp, CARHDR, 0x40);
1039 } else if (intp->symbol_rate[demod] < 10000000) {
1040 stv0900_write_reg(intp, CARFREQ, 0x4c);
1041 stv0900_write_reg(intp, CARHDR, 0x20);
1163 } else { 1042 } else {
1164 if (i_params->dmd2_symbol_rate < 10000000) 1043 stv0900_write_reg(intp, CARFREQ, 0x4b);
1165 stv0900_write_reg(i_params, R0900_P2_CARFREQ, 0xef); 1044 stv0900_write_reg(intp, CARHDR, 0x20);
1166 else
1167 stv0900_write_reg(i_params, R0900_P2_CARFREQ, 0xed);
1168 } 1045 }
1169 1046
1170 switch (i_params->dmd2_srch_algo) { 1047 } else {
1171 case STV0900_WARM_START: 1048 if (intp->symbol_rate[demod] < 10000000)
1172 stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1f); 1049 stv0900_write_reg(intp, CARFREQ, 0xef);
1173 stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x18); 1050 else
1174 break; 1051 stv0900_write_reg(intp, CARFREQ, 0xed);
1175 case STV0900_COLD_START: 1052 }
1176 stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1f);
1177 stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x15);
1178 break;
1179 default:
1180 break;
1181 }
1182 1053
1054 switch (intp->srch_algo[demod]) {
1055 case STV0900_WARM_START:
1056 stv0900_write_reg(intp, DMDISTATE, 0x1f);
1057 stv0900_write_reg(intp, DMDISTATE, 0x18);
1058 break;
1059 case STV0900_COLD_START:
1060 stv0900_write_reg(intp, DMDISTATE, 0x1f);
1061 stv0900_write_reg(intp, DMDISTATE, 0x15);
1062 break;
1063 default:
1183 break; 1064 break;
1184 } 1065 }
1185} 1066}
@@ -1188,33 +1069,40 @@ u8 stv0900_get_optim_carr_loop(s32 srate, enum fe_stv0900_modcode modcode,
1188 s32 pilot, u8 chip_id) 1069 s32 pilot, u8 chip_id)
1189{ 1070{
1190 u8 aclc_value = 0x29; 1071 u8 aclc_value = 0x29;
1191 s32 i; 1072 s32 i;
1192 const struct stv0900_car_loop_optim *car_loop_s2; 1073 const struct stv0900_car_loop_optim *cls2, *cllqs2, *cllas2;
1193 1074
1194 dprintk(KERN_INFO "%s\n", __func__); 1075 dprintk("%s\n", __func__);
1195 1076
1196 if (chip_id <= 0x12) 1077 if (chip_id <= 0x12) {
1197 car_loop_s2 = FE_STV0900_S2CarLoop; 1078 cls2 = FE_STV0900_S2CarLoop;
1198 else if (chip_id == 0x20) 1079 cllqs2 = FE_STV0900_S2LowQPCarLoopCut30;
1199 car_loop_s2 = FE_STV0900_S2CarLoopCut20; 1080 cllas2 = FE_STV0900_S2APSKCarLoopCut30;
1200 else 1081 } else if (chip_id == 0x20) {
1201 car_loop_s2 = FE_STV0900_S2CarLoop; 1082 cls2 = FE_STV0900_S2CarLoopCut20;
1083 cllqs2 = FE_STV0900_S2LowQPCarLoopCut20;
1084 cllas2 = FE_STV0900_S2APSKCarLoopCut20;
1085 } else {
1086 cls2 = FE_STV0900_S2CarLoopCut30;
1087 cllqs2 = FE_STV0900_S2LowQPCarLoopCut30;
1088 cllas2 = FE_STV0900_S2APSKCarLoopCut30;
1089 }
1202 1090
1203 if (modcode < STV0900_QPSK_12) { 1091 if (modcode < STV0900_QPSK_12) {
1204 i = 0; 1092 i = 0;
1205 while ((i < 3) && (modcode != FE_STV0900_S2LowQPCarLoopCut20[i].modcode)) 1093 while ((i < 3) && (modcode != cllqs2[i].modcode))
1206 i++; 1094 i++;
1207 1095
1208 if (i >= 3) 1096 if (i >= 3)
1209 i = 2; 1097 i = 2;
1210 } else { 1098 } else {
1211 i = 0; 1099 i = 0;
1212 while ((i < 14) && (modcode != car_loop_s2[i].modcode)) 1100 while ((i < 14) && (modcode != cls2[i].modcode))
1213 i++; 1101 i++;
1214 1102
1215 if (i >= 14) { 1103 if (i >= 14) {
1216 i = 0; 1104 i = 0;
1217 while ((i < 11) && (modcode != FE_STV0900_S2APSKCarLoopCut20[i].modcode)) 1105 while ((i < 11) && (modcode != cllas2[i].modcode))
1218 i++; 1106 i++;
1219 1107
1220 if (i >= 11) 1108 if (i >= 11)
@@ -1225,76 +1113,82 @@ u8 stv0900_get_optim_carr_loop(s32 srate, enum fe_stv0900_modcode modcode,
1225 if (modcode <= STV0900_QPSK_25) { 1113 if (modcode <= STV0900_QPSK_25) {
1226 if (pilot) { 1114 if (pilot) {
1227 if (srate <= 3000000) 1115 if (srate <= 3000000)
1228 aclc_value = FE_STV0900_S2LowQPCarLoopCut20[i].car_loop_pilots_on_2; 1116 aclc_value = cllqs2[i].car_loop_pilots_on_2;
1229 else if (srate <= 7000000) 1117 else if (srate <= 7000000)
1230 aclc_value = FE_STV0900_S2LowQPCarLoopCut20[i].car_loop_pilots_on_5; 1118 aclc_value = cllqs2[i].car_loop_pilots_on_5;
1231 else if (srate <= 15000000) 1119 else if (srate <= 15000000)
1232 aclc_value = FE_STV0900_S2LowQPCarLoopCut20[i].car_loop_pilots_on_10; 1120 aclc_value = cllqs2[i].car_loop_pilots_on_10;
1233 else if (srate <= 25000000) 1121 else if (srate <= 25000000)
1234 aclc_value = FE_STV0900_S2LowQPCarLoopCut20[i].car_loop_pilots_on_20; 1122 aclc_value = cllqs2[i].car_loop_pilots_on_20;
1235 else 1123 else
1236 aclc_value = FE_STV0900_S2LowQPCarLoopCut20[i].car_loop_pilots_on_30; 1124 aclc_value = cllqs2[i].car_loop_pilots_on_30;
1237 } else { 1125 } else {
1238 if (srate <= 3000000) 1126 if (srate <= 3000000)
1239 aclc_value = FE_STV0900_S2LowQPCarLoopCut20[i].car_loop_pilots_off_2; 1127 aclc_value = cllqs2[i].car_loop_pilots_off_2;
1240 else if (srate <= 7000000) 1128 else if (srate <= 7000000)
1241 aclc_value = FE_STV0900_S2LowQPCarLoopCut20[i].car_loop_pilots_off_5; 1129 aclc_value = cllqs2[i].car_loop_pilots_off_5;
1242 else if (srate <= 15000000) 1130 else if (srate <= 15000000)
1243 aclc_value = FE_STV0900_S2LowQPCarLoopCut20[i].car_loop_pilots_off_10; 1131 aclc_value = cllqs2[i].car_loop_pilots_off_10;
1244 else if (srate <= 25000000) 1132 else if (srate <= 25000000)
1245 aclc_value = FE_STV0900_S2LowQPCarLoopCut20[i].car_loop_pilots_off_20; 1133 aclc_value = cllqs2[i].car_loop_pilots_off_20;
1246 else 1134 else
1247 aclc_value = FE_STV0900_S2LowQPCarLoopCut20[i].car_loop_pilots_off_30; 1135 aclc_value = cllqs2[i].car_loop_pilots_off_30;
1248 } 1136 }
1249 1137
1250 } else if (modcode <= STV0900_8PSK_910) { 1138 } else if (modcode <= STV0900_8PSK_910) {
1251 if (pilot) { 1139 if (pilot) {
1252 if (srate <= 3000000) 1140 if (srate <= 3000000)
1253 aclc_value = car_loop_s2[i].car_loop_pilots_on_2; 1141 aclc_value = cls2[i].car_loop_pilots_on_2;
1254 else if (srate <= 7000000) 1142 else if (srate <= 7000000)
1255 aclc_value = car_loop_s2[i].car_loop_pilots_on_5; 1143 aclc_value = cls2[i].car_loop_pilots_on_5;
1256 else if (srate <= 15000000) 1144 else if (srate <= 15000000)
1257 aclc_value = car_loop_s2[i].car_loop_pilots_on_10; 1145 aclc_value = cls2[i].car_loop_pilots_on_10;
1258 else if (srate <= 25000000) 1146 else if (srate <= 25000000)
1259 aclc_value = car_loop_s2[i].car_loop_pilots_on_20; 1147 aclc_value = cls2[i].car_loop_pilots_on_20;
1260 else 1148 else
1261 aclc_value = car_loop_s2[i].car_loop_pilots_on_30; 1149 aclc_value = cls2[i].car_loop_pilots_on_30;
1262 } else { 1150 } else {
1263 if (srate <= 3000000) 1151 if (srate <= 3000000)
1264 aclc_value = car_loop_s2[i].car_loop_pilots_off_2; 1152 aclc_value = cls2[i].car_loop_pilots_off_2;
1265 else if (srate <= 7000000) 1153 else if (srate <= 7000000)
1266 aclc_value = car_loop_s2[i].car_loop_pilots_off_5; 1154 aclc_value = cls2[i].car_loop_pilots_off_5;
1267 else if (srate <= 15000000) 1155 else if (srate <= 15000000)
1268 aclc_value = car_loop_s2[i].car_loop_pilots_off_10; 1156 aclc_value = cls2[i].car_loop_pilots_off_10;
1269 else if (srate <= 25000000) 1157 else if (srate <= 25000000)
1270 aclc_value = car_loop_s2[i].car_loop_pilots_off_20; 1158 aclc_value = cls2[i].car_loop_pilots_off_20;
1271 else 1159 else
1272 aclc_value = car_loop_s2[i].car_loop_pilots_off_30; 1160 aclc_value = cls2[i].car_loop_pilots_off_30;
1273 } 1161 }
1274 1162
1275 } else { 1163 } else {
1276 if (srate <= 3000000) 1164 if (srate <= 3000000)
1277 aclc_value = FE_STV0900_S2APSKCarLoopCut20[i].car_loop_pilots_on_2; 1165 aclc_value = cllas2[i].car_loop_pilots_on_2;
1278 else if (srate <= 7000000) 1166 else if (srate <= 7000000)
1279 aclc_value = FE_STV0900_S2APSKCarLoopCut20[i].car_loop_pilots_on_5; 1167 aclc_value = cllas2[i].car_loop_pilots_on_5;
1280 else if (srate <= 15000000) 1168 else if (srate <= 15000000)
1281 aclc_value = FE_STV0900_S2APSKCarLoopCut20[i].car_loop_pilots_on_10; 1169 aclc_value = cllas2[i].car_loop_pilots_on_10;
1282 else if (srate <= 25000000) 1170 else if (srate <= 25000000)
1283 aclc_value = FE_STV0900_S2APSKCarLoopCut20[i].car_loop_pilots_on_20; 1171 aclc_value = cllas2[i].car_loop_pilots_on_20;
1284 else 1172 else
1285 aclc_value = FE_STV0900_S2APSKCarLoopCut20[i].car_loop_pilots_on_30; 1173 aclc_value = cllas2[i].car_loop_pilots_on_30;
1286 } 1174 }
1287 1175
1288 return aclc_value; 1176 return aclc_value;
1289} 1177}
1290 1178
1291u8 stv0900_get_optim_short_carr_loop(s32 srate, enum fe_stv0900_modulation modulation, u8 chip_id) 1179u8 stv0900_get_optim_short_carr_loop(s32 srate,
1180 enum fe_stv0900_modulation modulation,
1181 u8 chip_id)
1292{ 1182{
1183 const struct stv0900_short_frames_car_loop_optim *s2scl;
1184 const struct stv0900_short_frames_car_loop_optim_vs_mod *s2sclc30;
1293 s32 mod_index = 0; 1185 s32 mod_index = 0;
1294
1295 u8 aclc_value = 0x0b; 1186 u8 aclc_value = 0x0b;
1296 1187
1297 dprintk(KERN_INFO "%s\n", __func__); 1188 dprintk("%s\n", __func__);
1189
1190 s2scl = FE_STV0900_S2ShortCarLoop;
1191 s2sclc30 = FE_STV0900_S2ShortCarLoopCut30;
1298 1192
1299 switch (modulation) { 1193 switch (modulation) {
1300 case STV0900_QPSK: 1194 case STV0900_QPSK:
@@ -1312,75 +1206,116 @@ u8 stv0900_get_optim_short_carr_loop(s32 srate, enum fe_stv0900_modulation modul
1312 break; 1206 break;
1313 } 1207 }
1314 1208
1315 switch (chip_id) { 1209 if (chip_id >= 0x30) {
1316 case 0x20:
1317 if (srate <= 3000000) 1210 if (srate <= 3000000)
1318 aclc_value = FE_STV0900_S2ShortCarLoop[mod_index].car_loop_cut20_2; 1211 aclc_value = s2sclc30[mod_index].car_loop_2;
1319 else if (srate <= 7000000) 1212 else if (srate <= 7000000)
1320 aclc_value = FE_STV0900_S2ShortCarLoop[mod_index].car_loop_cut20_5; 1213 aclc_value = s2sclc30[mod_index].car_loop_5;
1321 else if (srate <= 15000000) 1214 else if (srate <= 15000000)
1322 aclc_value = FE_STV0900_S2ShortCarLoop[mod_index].car_loop_cut20_10; 1215 aclc_value = s2sclc30[mod_index].car_loop_10;
1323 else if (srate <= 25000000) 1216 else if (srate <= 25000000)
1324 aclc_value = FE_STV0900_S2ShortCarLoop[mod_index].car_loop_cut20_20; 1217 aclc_value = s2sclc30[mod_index].car_loop_20;
1325 else 1218 else
1326 aclc_value = FE_STV0900_S2ShortCarLoop[mod_index].car_loop_cut20_30; 1219 aclc_value = s2sclc30[mod_index].car_loop_30;
1327 1220
1328 break; 1221 } else if (chip_id >= 0x20) {
1329 case 0x12:
1330 default:
1331 if (srate <= 3000000) 1222 if (srate <= 3000000)
1332 aclc_value = FE_STV0900_S2ShortCarLoop[mod_index].car_loop_cut12_2; 1223 aclc_value = s2scl[mod_index].car_loop_cut20_2;
1333 else if (srate <= 7000000) 1224 else if (srate <= 7000000)
1334 aclc_value = FE_STV0900_S2ShortCarLoop[mod_index].car_loop_cut12_5; 1225 aclc_value = s2scl[mod_index].car_loop_cut20_5;
1335 else if (srate <= 15000000) 1226 else if (srate <= 15000000)
1336 aclc_value = FE_STV0900_S2ShortCarLoop[mod_index].car_loop_cut12_10; 1227 aclc_value = s2scl[mod_index].car_loop_cut20_10;
1337 else if (srate <= 25000000) 1228 else if (srate <= 25000000)
1338 aclc_value = FE_STV0900_S2ShortCarLoop[mod_index].car_loop_cut12_20; 1229 aclc_value = s2scl[mod_index].car_loop_cut20_20;
1339 else 1230 else
1340 aclc_value = FE_STV0900_S2ShortCarLoop[mod_index].car_loop_cut12_30; 1231 aclc_value = s2scl[mod_index].car_loop_cut20_30;
1232
1233 } else {
1234 if (srate <= 3000000)
1235 aclc_value = s2scl[mod_index].car_loop_cut12_2;
1236 else if (srate <= 7000000)
1237 aclc_value = s2scl[mod_index].car_loop_cut12_5;
1238 else if (srate <= 15000000)
1239 aclc_value = s2scl[mod_index].car_loop_cut12_10;
1240 else if (srate <= 25000000)
1241 aclc_value = s2scl[mod_index].car_loop_cut12_20;
1242 else
1243 aclc_value = s2scl[mod_index].car_loop_cut12_30;
1341 1244
1342 break;
1343 } 1245 }
1344 1246
1345 return aclc_value; 1247 return aclc_value;
1346} 1248}
1347 1249
1348static enum fe_stv0900_error stv0900_st_dvbs2_single(struct stv0900_internal *i_params, 1250static
1251enum fe_stv0900_error stv0900_st_dvbs2_single(struct stv0900_internal *intp,
1349 enum fe_stv0900_demod_mode LDPC_Mode, 1252 enum fe_stv0900_demod_mode LDPC_Mode,
1350 enum fe_stv0900_demod_num demod) 1253 enum fe_stv0900_demod_num demod)
1351{ 1254{
1352 enum fe_stv0900_error error = STV0900_NO_ERROR; 1255 enum fe_stv0900_error error = STV0900_NO_ERROR;
1256 s32 reg_ind;
1353 1257
1354 dprintk(KERN_INFO "%s\n", __func__); 1258 dprintk("%s\n", __func__);
1355 1259
1356 switch (LDPC_Mode) { 1260 switch (LDPC_Mode) {
1357 case STV0900_DUAL: 1261 case STV0900_DUAL:
1358 default: 1262 default:
1359 if ((i_params->demod_mode != STV0900_DUAL) 1263 if ((intp->demod_mode != STV0900_DUAL)
1360 || (stv0900_get_bits(i_params, F0900_DDEMOD) != 1)) { 1264 || (stv0900_get_bits(intp, F0900_DDEMOD) != 1)) {
1361 stv0900_write_reg(i_params, R0900_GENCFG, 0x1d); 1265 stv0900_write_reg(intp, R0900_GENCFG, 0x1d);
1362 1266
1363 i_params->demod_mode = STV0900_DUAL; 1267 intp->demod_mode = STV0900_DUAL;
1364 1268
1365 stv0900_write_bits(i_params, F0900_FRESFEC, 1); 1269 stv0900_write_bits(intp, F0900_FRESFEC, 1);
1366 stv0900_write_bits(i_params, F0900_FRESFEC, 0); 1270 stv0900_write_bits(intp, F0900_FRESFEC, 0);
1271
1272 for (reg_ind = 0; reg_ind < 7; reg_ind++)
1273 stv0900_write_reg(intp,
1274 R0900_P1_MODCODLST0 + reg_ind,
1275 0xff);
1276 for (reg_ind = 0; reg_ind < 8; reg_ind++)
1277 stv0900_write_reg(intp,
1278 R0900_P1_MODCODLST7 + reg_ind,
1279 0xcc);
1280
1281 stv0900_write_reg(intp, R0900_P1_MODCODLSTE, 0xff);
1282 stv0900_write_reg(intp, R0900_P1_MODCODLSTF, 0xcf);
1283
1284 for (reg_ind = 0; reg_ind < 7; reg_ind++)
1285 stv0900_write_reg(intp,
1286 R0900_P2_MODCODLST0 + reg_ind,
1287 0xff);
1288 for (reg_ind = 0; reg_ind < 8; reg_ind++)
1289 stv0900_write_reg(intp,
1290 R0900_P2_MODCODLST7 + reg_ind,
1291 0xcc);
1292
1293 stv0900_write_reg(intp, R0900_P2_MODCODLSTE, 0xff);
1294 stv0900_write_reg(intp, R0900_P2_MODCODLSTF, 0xcf);
1367 } 1295 }
1368 1296
1369 break; 1297 break;
1370 case STV0900_SINGLE: 1298 case STV0900_SINGLE:
1371 if (demod == STV0900_DEMOD_2) 1299 if (demod == STV0900_DEMOD_2) {
1372 stv0900_write_reg(i_params, R0900_GENCFG, 0x06); 1300 stv0900_stop_all_s2_modcod(intp, STV0900_DEMOD_1);
1373 else 1301 stv0900_activate_s2_modcod_single(intp,
1374 stv0900_write_reg(i_params, R0900_GENCFG, 0x04); 1302 STV0900_DEMOD_2);
1303 stv0900_write_reg(intp, R0900_GENCFG, 0x06);
1304 } else {
1305 stv0900_stop_all_s2_modcod(intp, STV0900_DEMOD_2);
1306 stv0900_activate_s2_modcod_single(intp,
1307 STV0900_DEMOD_1);
1308 stv0900_write_reg(intp, R0900_GENCFG, 0x04);
1309 }
1375 1310
1376 i_params->demod_mode = STV0900_SINGLE; 1311 intp->demod_mode = STV0900_SINGLE;
1377 1312
1378 stv0900_write_bits(i_params, F0900_FRESFEC, 1); 1313 stv0900_write_bits(intp, F0900_FRESFEC, 1);
1379 stv0900_write_bits(i_params, F0900_FRESFEC, 0); 1314 stv0900_write_bits(intp, F0900_FRESFEC, 0);
1380 stv0900_write_bits(i_params, F0900_P1_ALGOSWRST, 1); 1315 stv0900_write_bits(intp, F0900_P1_ALGOSWRST, 1);
1381 stv0900_write_bits(i_params, F0900_P1_ALGOSWRST, 0); 1316 stv0900_write_bits(intp, F0900_P1_ALGOSWRST, 0);
1382 stv0900_write_bits(i_params, F0900_P2_ALGOSWRST, 1); 1317 stv0900_write_bits(intp, F0900_P2_ALGOSWRST, 1);
1383 stv0900_write_bits(i_params, F0900_P2_ALGOSWRST, 0); 1318 stv0900_write_bits(intp, F0900_P2_ALGOSWRST, 0);
1384 break; 1319 break;
1385 } 1320 }
1386 1321
@@ -1393,131 +1328,131 @@ static enum fe_stv0900_error stv0900_init_internal(struct dvb_frontend *fe,
1393 struct stv0900_state *state = fe->demodulator_priv; 1328 struct stv0900_state *state = fe->demodulator_priv;
1394 enum fe_stv0900_error error = STV0900_NO_ERROR; 1329 enum fe_stv0900_error error = STV0900_NO_ERROR;
1395 enum fe_stv0900_error demodError = STV0900_NO_ERROR; 1330 enum fe_stv0900_error demodError = STV0900_NO_ERROR;
1331 struct stv0900_internal *intp = NULL;
1332
1396 int selosci, i; 1333 int selosci, i;
1397 1334
1398 struct stv0900_inode *temp_int = find_inode(state->i2c_adap, 1335 struct stv0900_inode *temp_int = find_inode(state->i2c_adap,
1399 state->config->demod_address); 1336 state->config->demod_address);
1400 1337
1401 dprintk(KERN_INFO "%s\n", __func__); 1338 dprintk("%s\n", __func__);
1402 1339
1403 if (temp_int != NULL) { 1340 if ((temp_int != NULL) && (p_init->demod_mode == STV0900_DUAL)) {
1404 state->internal = temp_int->internal; 1341 state->internal = temp_int->internal;
1405 (state->internal->dmds_used)++; 1342 (state->internal->dmds_used)++;
1406 dprintk(KERN_INFO "%s: Find Internal Structure!\n", __func__); 1343 dprintk("%s: Find Internal Structure!\n", __func__);
1407 return STV0900_NO_ERROR; 1344 return STV0900_NO_ERROR;
1408 } else { 1345 } else {
1409 state->internal = kmalloc(sizeof(struct stv0900_internal), GFP_KERNEL); 1346 state->internal = kmalloc(sizeof(struct stv0900_internal),
1347 GFP_KERNEL);
1410 temp_int = append_internal(state->internal); 1348 temp_int = append_internal(state->internal);
1411 state->internal->dmds_used = 1; 1349 state->internal->dmds_used = 1;
1412 state->internal->i2c_adap = state->i2c_adap; 1350 state->internal->i2c_adap = state->i2c_adap;
1413 state->internal->i2c_addr = state->config->demod_address; 1351 state->internal->i2c_addr = state->config->demod_address;
1414 state->internal->clkmode = state->config->clkmode; 1352 state->internal->clkmode = state->config->clkmode;
1415 state->internal->errs = STV0900_NO_ERROR; 1353 state->internal->errs = STV0900_NO_ERROR;
1416 dprintk(KERN_INFO "%s: Create New Internal Structure!\n", __func__); 1354 dprintk("%s: Create New Internal Structure!\n", __func__);
1417 } 1355 }
1418 1356
1419 if (state->internal != NULL) { 1357 if (state->internal == NULL) {
1420 demodError = stv0900_initialize(state->internal); 1358 error = STV0900_INVALID_HANDLE;
1421 if (demodError == STV0900_NO_ERROR) { 1359 return error;
1422 error = STV0900_NO_ERROR; 1360 }
1423 } else {
1424 if (demodError == STV0900_INVALID_HANDLE)
1425 error = STV0900_INVALID_HANDLE;
1426 else
1427 error = STV0900_I2C_ERROR;
1428 }
1429 1361
1430 if (state->internal != NULL) { 1362 demodError = stv0900_initialize(state->internal);
1431 if (error == STV0900_NO_ERROR) { 1363 if (demodError == STV0900_NO_ERROR) {
1432 state->internal->demod_mode = p_init->demod_mode; 1364 error = STV0900_NO_ERROR;
1433 1365 } else {
1434 stv0900_st_dvbs2_single(state->internal, state->internal->demod_mode, STV0900_DEMOD_1); 1366 if (demodError == STV0900_INVALID_HANDLE)
1435 1367 error = STV0900_INVALID_HANDLE;
1436 state->internal->chip_id = stv0900_read_reg(state->internal, R0900_MID); 1368 else
1437 state->internal->rolloff = p_init->rolloff; 1369 error = STV0900_I2C_ERROR;
1438 state->internal->quartz = p_init->dmd_ref_clk;
1439
1440 stv0900_write_bits(state->internal, F0900_P1_ROLLOFF_CONTROL, p_init->rolloff);
1441 stv0900_write_bits(state->internal, F0900_P2_ROLLOFF_CONTROL, p_init->rolloff);
1442
1443 state->internal->ts_config = p_init->ts_config;
1444 if (state->internal->ts_config == NULL)
1445 stv0900_set_ts_parallel_serial(state->internal,
1446 p_init->path1_ts_clock,
1447 p_init->path2_ts_clock);
1448 else {
1449 for (i = 0; state->internal->ts_config[i].addr != 0xffff; i++)
1450 stv0900_write_reg(state->internal,
1451 state->internal->ts_config[i].addr,
1452 state->internal->ts_config[i].val);
1453
1454 stv0900_write_bits(state->internal, F0900_P2_RST_HWARE, 1);
1455 stv0900_write_bits(state->internal, F0900_P2_RST_HWARE, 0);
1456 stv0900_write_bits(state->internal, F0900_P1_RST_HWARE, 1);
1457 stv0900_write_bits(state->internal, F0900_P1_RST_HWARE, 0);
1458 }
1459 1370
1460 stv0900_write_bits(state->internal, F0900_P1_TUN_MADDRESS, p_init->tun1_maddress); 1371 return error;
1461 switch (p_init->tuner1_adc) { 1372 }
1462 case 1:
1463 stv0900_write_reg(state->internal, R0900_TSTTNR1, 0x26);
1464 break;
1465 default:
1466 break;
1467 }
1468 1373
1469 stv0900_write_bits(state->internal, F0900_P2_TUN_MADDRESS, p_init->tun2_maddress); 1374 if (state->internal == NULL) {
1470 switch (p_init->tuner2_adc) { 1375 error = STV0900_INVALID_HANDLE;
1471 case 1: 1376 return error;
1472 stv0900_write_reg(state->internal, R0900_TSTTNR3, 0x26); 1377 }
1473 break;
1474 default:
1475 break;
1476 }
1477 1378
1478 stv0900_write_bits(state->internal, F0900_P1_TUN_IQSWAP, p_init->tun1_iq_inversion); 1379 intp = state->internal;
1479 stv0900_write_bits(state->internal, F0900_P2_TUN_IQSWAP, p_init->tun2_iq_inversion);
1480 stv0900_set_mclk(state->internal, 135000000);
1481 msleep(3);
1482
1483 switch (state->internal->clkmode) {
1484 case 0:
1485 case 2:
1486 stv0900_write_reg(state->internal, R0900_SYNTCTRL, 0x20 | state->internal->clkmode);
1487 break;
1488 default:
1489 selosci = 0x02 & stv0900_read_reg(state->internal, R0900_SYNTCTRL);
1490 stv0900_write_reg(state->internal, R0900_SYNTCTRL, 0x20 | selosci);
1491 break;
1492 }
1493 msleep(3);
1494 1380
1495 state->internal->mclk = stv0900_get_mclk_freq(state->internal, state->internal->quartz); 1381 intp->demod_mode = p_init->demod_mode;
1496 if (state->internal->errs) 1382 stv0900_st_dvbs2_single(intp, intp->demod_mode, STV0900_DEMOD_1);
1497 error = STV0900_I2C_ERROR; 1383 intp->chip_id = stv0900_read_reg(intp, R0900_MID);
1498 } 1384 intp->rolloff = p_init->rolloff;
1499 } else { 1385 intp->quartz = p_init->dmd_ref_clk;
1500 error = STV0900_INVALID_HANDLE; 1386
1501 } 1387 stv0900_write_bits(intp, F0900_P1_ROLLOFF_CONTROL, p_init->rolloff);
1388 stv0900_write_bits(intp, F0900_P2_ROLLOFF_CONTROL, p_init->rolloff);
1389
1390 intp->ts_config = p_init->ts_config;
1391 if (intp->ts_config == NULL)
1392 stv0900_set_ts_parallel_serial(intp,
1393 p_init->path1_ts_clock,
1394 p_init->path2_ts_clock);
1395 else {
1396 for (i = 0; intp->ts_config[i].addr != 0xffff; i++)
1397 stv0900_write_reg(intp,
1398 intp->ts_config[i].addr,
1399 intp->ts_config[i].val);
1400
1401 stv0900_write_bits(intp, F0900_P2_RST_HWARE, 1);
1402 stv0900_write_bits(intp, F0900_P2_RST_HWARE, 0);
1403 stv0900_write_bits(intp, F0900_P1_RST_HWARE, 1);
1404 stv0900_write_bits(intp, F0900_P1_RST_HWARE, 0);
1405 }
1406
1407 stv0900_write_bits(intp, F0900_P1_TUN_MADDRESS, p_init->tun1_maddress);
1408 switch (p_init->tuner1_adc) {
1409 case 1:
1410 stv0900_write_reg(intp, R0900_TSTTNR1, 0x26);
1411 break;
1412 default:
1413 break;
1414 }
1415
1416 stv0900_write_bits(intp, F0900_P2_TUN_MADDRESS, p_init->tun2_maddress);
1417 switch (p_init->tuner2_adc) {
1418 case 1:
1419 stv0900_write_reg(intp, R0900_TSTTNR3, 0x26);
1420 break;
1421 default:
1422 break;
1423 }
1424
1425 stv0900_write_bits(intp, F0900_P1_TUN_IQSWAP, p_init->tun1_iq_inv);
1426 stv0900_write_bits(intp, F0900_P2_TUN_IQSWAP, p_init->tun2_iq_inv);
1427 stv0900_set_mclk(intp, 135000000);
1428 msleep(3);
1429
1430 switch (intp->clkmode) {
1431 case 0:
1432 case 2:
1433 stv0900_write_reg(intp, R0900_SYNTCTRL, 0x20 | intp->clkmode);
1434 break;
1435 default:
1436 selosci = 0x02 & stv0900_read_reg(intp, R0900_SYNTCTRL);
1437 stv0900_write_reg(intp, R0900_SYNTCTRL, 0x20 | selosci);
1438 break;
1502 } 1439 }
1440 msleep(3);
1441
1442 intp->mclk = stv0900_get_mclk_freq(intp, intp->quartz);
1443 if (intp->errs)
1444 error = STV0900_I2C_ERROR;
1503 1445
1504 return error; 1446 return error;
1505} 1447}
1506 1448
1507static int stv0900_status(struct stv0900_internal *i_params, 1449static int stv0900_status(struct stv0900_internal *intp,
1508 enum fe_stv0900_demod_num demod) 1450 enum fe_stv0900_demod_num demod)
1509{ 1451{
1510 enum fe_stv0900_search_state demod_state; 1452 enum fe_stv0900_search_state demod_state;
1511 s32 mode_field, delin_field, lock_field, fifo_field, lockedvit_field;
1512 int locked = FALSE; 1453 int locked = FALSE;
1513 1454
1514 dmd_reg(mode_field, F0900_P1_HEADER_MODE, F0900_P2_HEADER_MODE); 1455 demod_state = stv0900_get_bits(intp, HEADER_MODE);
1515 dmd_reg(lock_field, F0900_P1_LOCK_DEFINITIF, F0900_P2_LOCK_DEFINITIF);
1516 dmd_reg(delin_field, F0900_P1_PKTDELIN_LOCK, F0900_P2_PKTDELIN_LOCK);
1517 dmd_reg(fifo_field, F0900_P1_TSFIFO_LINEOK, F0900_P2_TSFIFO_LINEOK);
1518 dmd_reg(lockedvit_field, F0900_P1_LOCKEDVIT, F0900_P2_LOCKEDVIT);
1519
1520 demod_state = stv0900_get_bits(i_params, mode_field);
1521 switch (demod_state) { 1456 switch (demod_state) {
1522 case STV0900_SEARCH: 1457 case STV0900_SEARCH:
1523 case STV0900_PLH_DETECTED: 1458 case STV0900_PLH_DETECTED:
@@ -1525,17 +1460,19 @@ static int stv0900_status(struct stv0900_internal *i_params,
1525 locked = FALSE; 1460 locked = FALSE;
1526 break; 1461 break;
1527 case STV0900_DVBS2_FOUND: 1462 case STV0900_DVBS2_FOUND:
1528 locked = stv0900_get_bits(i_params, lock_field) && 1463 locked = stv0900_get_bits(intp, LOCK_DEFINITIF) &&
1529 stv0900_get_bits(i_params, delin_field) && 1464 stv0900_get_bits(intp, PKTDELIN_LOCK) &&
1530 stv0900_get_bits(i_params, fifo_field); 1465 stv0900_get_bits(intp, TSFIFO_LINEOK);
1531 break; 1466 break;
1532 case STV0900_DVBS_FOUND: 1467 case STV0900_DVBS_FOUND:
1533 locked = stv0900_get_bits(i_params, lock_field) && 1468 locked = stv0900_get_bits(intp, LOCK_DEFINITIF) &&
1534 stv0900_get_bits(i_params, lockedvit_field) && 1469 stv0900_get_bits(intp, LOCKEDVIT) &&
1535 stv0900_get_bits(i_params, fifo_field); 1470 stv0900_get_bits(intp, TSFIFO_LINEOK);
1536 break; 1471 break;
1537 } 1472 }
1538 1473
1474 dprintk("%s: locked = %d\n", __func__, locked);
1475
1539 return locked; 1476 return locked;
1540} 1477}
1541 1478
@@ -1543,7 +1480,8 @@ static enum dvbfe_search stv0900_search(struct dvb_frontend *fe,
1543 struct dvb_frontend_parameters *params) 1480 struct dvb_frontend_parameters *params)
1544{ 1481{
1545 struct stv0900_state *state = fe->demodulator_priv; 1482 struct stv0900_state *state = fe->demodulator_priv;
1546 struct stv0900_internal *i_params = state->internal; 1483 struct stv0900_internal *intp = state->internal;
1484 enum fe_stv0900_demod_num demod = state->demod;
1547 struct dtv_frontend_properties *c = &fe->dtv_property_cache; 1485 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
1548 1486
1549 struct stv0900_search_params p_search; 1487 struct stv0900_search_params p_search;
@@ -1551,10 +1489,16 @@ static enum dvbfe_search stv0900_search(struct dvb_frontend *fe,
1551 1489
1552 enum fe_stv0900_error error = STV0900_NO_ERROR; 1490 enum fe_stv0900_error error = STV0900_NO_ERROR;
1553 1491
1554 dprintk(KERN_INFO "%s: ", __func__); 1492 dprintk("%s: ", __func__);
1493
1494 if (!(INRANGE(100000, c->symbol_rate, 70000000)))
1495 return DVBFE_ALGO_SEARCH_FAILED;
1496
1497 if (state->config->set_ts_params)
1498 state->config->set_ts_params(fe, 0);
1555 1499
1556 p_result.locked = FALSE; 1500 p_result.locked = FALSE;
1557 p_search.path = state->demod; 1501 p_search.path = demod;
1558 p_search.frequency = c->frequency; 1502 p_search.frequency = c->frequency;
1559 p_search.symbol_rate = c->symbol_rate; 1503 p_search.symbol_rate = c->symbol_rate;
1560 p_search.search_range = 10000000; 1504 p_search.search_range = 10000000;
@@ -1563,103 +1507,47 @@ static enum dvbfe_search stv0900_search(struct dvb_frontend *fe,
1563 p_search.iq_inversion = STV0900_IQ_AUTO; 1507 p_search.iq_inversion = STV0900_IQ_AUTO;
1564 p_search.search_algo = STV0900_BLIND_SEARCH; 1508 p_search.search_algo = STV0900_BLIND_SEARCH;
1565 1509
1566 if ((INRANGE(100000, p_search.symbol_rate, 70000000)) && 1510 intp->srch_standard[demod] = p_search.standard;
1567 (INRANGE(100000, p_search.search_range, 50000000))) { 1511 intp->symbol_rate[demod] = p_search.symbol_rate;
1568 switch (p_search.path) { 1512 intp->srch_range[demod] = p_search.search_range;
1569 case STV0900_DEMOD_1: 1513 intp->freq[demod] = p_search.frequency;
1570 default: 1514 intp->srch_algo[demod] = p_search.search_algo;
1571 i_params->dmd1_srch_standard = p_search.standard; 1515 intp->srch_iq_inv[demod] = p_search.iq_inversion;
1572 i_params->dmd1_symbol_rate = p_search.symbol_rate; 1516 intp->fec[demod] = p_search.fec;
1573 i_params->dmd1_srch_range = p_search.search_range; 1517 if ((stv0900_algo(fe) == STV0900_RANGEOK) &&
1574 i_params->tuner1_freq = p_search.frequency; 1518 (intp->errs == STV0900_NO_ERROR)) {
1575 i_params->dmd1_srch_algo = p_search.search_algo; 1519 p_result.locked = intp->result[demod].locked;
1576 i_params->dmd1_srch_iq_inv = p_search.iq_inversion; 1520 p_result.standard = intp->result[demod].standard;
1577 i_params->dmd1_fec = p_search.fec; 1521 p_result.frequency = intp->result[demod].frequency;
1522 p_result.symbol_rate = intp->result[demod].symbol_rate;
1523 p_result.fec = intp->result[demod].fec;
1524 p_result.modcode = intp->result[demod].modcode;
1525 p_result.pilot = intp->result[demod].pilot;
1526 p_result.frame_len = intp->result[demod].frame_len;
1527 p_result.spectrum = intp->result[demod].spectrum;
1528 p_result.rolloff = intp->result[demod].rolloff;
1529 p_result.modulation = intp->result[demod].modulation;
1530 } else {
1531 p_result.locked = FALSE;
1532 switch (intp->err[demod]) {
1533 case STV0900_I2C_ERROR:
1534 error = STV0900_I2C_ERROR;
1578 break; 1535 break;
1579 1536 case STV0900_NO_ERROR:
1580 case STV0900_DEMOD_2: 1537 default:
1581 i_params->dmd2_srch_stndrd = p_search.standard; 1538 error = STV0900_SEARCH_FAILED;
1582 i_params->dmd2_symbol_rate = p_search.symbol_rate;
1583 i_params->dmd2_srch_range = p_search.search_range;
1584 i_params->tuner2_freq = p_search.frequency;
1585 i_params->dmd2_srch_algo = p_search.search_algo;
1586 i_params->dmd2_srch_iq_inv = p_search.iq_inversion;
1587 i_params->dmd2_fec = p_search.fec;
1588 break; 1539 break;
1589 } 1540 }
1590 1541 }
1591 if ((stv0900_algo(fe) == STV0900_RANGEOK) &&
1592 (i_params->errs == STV0900_NO_ERROR)) {
1593 switch (p_search.path) {
1594 case STV0900_DEMOD_1:
1595 default:
1596 p_result.locked = i_params->dmd1_rslts.locked;
1597 p_result.standard = i_params->dmd1_rslts.standard;
1598 p_result.frequency = i_params->dmd1_rslts.frequency;
1599 p_result.symbol_rate = i_params->dmd1_rslts.symbol_rate;
1600 p_result.fec = i_params->dmd1_rslts.fec;
1601 p_result.modcode = i_params->dmd1_rslts.modcode;
1602 p_result.pilot = i_params->dmd1_rslts.pilot;
1603 p_result.frame_length = i_params->dmd1_rslts.frame_length;
1604 p_result.spectrum = i_params->dmd1_rslts.spectrum;
1605 p_result.rolloff = i_params->dmd1_rslts.rolloff;
1606 p_result.modulation = i_params->dmd1_rslts.modulation;
1607 break;
1608 case STV0900_DEMOD_2:
1609 p_result.locked = i_params->dmd2_rslts.locked;
1610 p_result.standard = i_params->dmd2_rslts.standard;
1611 p_result.frequency = i_params->dmd2_rslts.frequency;
1612 p_result.symbol_rate = i_params->dmd2_rslts.symbol_rate;
1613 p_result.fec = i_params->dmd2_rslts.fec;
1614 p_result.modcode = i_params->dmd2_rslts.modcode;
1615 p_result.pilot = i_params->dmd2_rslts.pilot;
1616 p_result.frame_length = i_params->dmd2_rslts.frame_length;
1617 p_result.spectrum = i_params->dmd2_rslts.spectrum;
1618 p_result.rolloff = i_params->dmd2_rslts.rolloff;
1619 p_result.modulation = i_params->dmd2_rslts.modulation;
1620 break;
1621 }
1622
1623 } else {
1624 p_result.locked = FALSE;
1625 switch (p_search.path) {
1626 case STV0900_DEMOD_1:
1627 switch (i_params->dmd1_err) {
1628 case STV0900_I2C_ERROR:
1629 error = STV0900_I2C_ERROR;
1630 break;
1631 case STV0900_NO_ERROR:
1632 default:
1633 error = STV0900_SEARCH_FAILED;
1634 break;
1635 }
1636 break;
1637 case STV0900_DEMOD_2:
1638 switch (i_params->dmd2_err) {
1639 case STV0900_I2C_ERROR:
1640 error = STV0900_I2C_ERROR;
1641 break;
1642 case STV0900_NO_ERROR:
1643 default:
1644 error = STV0900_SEARCH_FAILED;
1645 break;
1646 }
1647 break;
1648 }
1649 }
1650
1651 } else
1652 error = STV0900_BAD_PARAMETER;
1653 1542
1654 if ((p_result.locked == TRUE) && (error == STV0900_NO_ERROR)) { 1543 if ((p_result.locked == TRUE) && (error == STV0900_NO_ERROR)) {
1655 dprintk(KERN_INFO "Search Success\n"); 1544 dprintk("Search Success\n");
1656 return DVBFE_ALGO_SEARCH_SUCCESS; 1545 return DVBFE_ALGO_SEARCH_SUCCESS;
1657 } else { 1546 } else {
1658 dprintk(KERN_INFO "Search Fail\n"); 1547 dprintk("Search Fail\n");
1659 return DVBFE_ALGO_SEARCH_FAILED; 1548 return DVBFE_ALGO_SEARCH_FAILED;
1660 } 1549 }
1661 1550
1662 return DVBFE_ALGO_SEARCH_ERROR;
1663} 1551}
1664 1552
1665static int stv0900_read_status(struct dvb_frontend *fe, enum fe_status *status) 1553static int stv0900_read_status(struct dvb_frontend *fe, enum fe_status *status)
@@ -1690,16 +1578,13 @@ static int stv0900_stop_ts(struct dvb_frontend *fe, int stop_ts)
1690{ 1578{
1691 1579
1692 struct stv0900_state *state = fe->demodulator_priv; 1580 struct stv0900_state *state = fe->demodulator_priv;
1693 struct stv0900_internal *i_params = state->internal; 1581 struct stv0900_internal *intp = state->internal;
1694 enum fe_stv0900_demod_num demod = state->demod; 1582 enum fe_stv0900_demod_num demod = state->demod;
1695 s32 rst_field;
1696
1697 dmd_reg(rst_field, F0900_P1_RST_HWARE, F0900_P2_RST_HWARE);
1698 1583
1699 if (stop_ts == TRUE) 1584 if (stop_ts == TRUE)
1700 stv0900_write_bits(i_params, rst_field, 1); 1585 stv0900_write_bits(intp, RST_HWARE, 1);
1701 else 1586 else
1702 stv0900_write_bits(i_params, rst_field, 0); 1587 stv0900_write_bits(intp, RST_HWARE, 0);
1703 1588
1704 return 0; 1589 return 0;
1705} 1590}
@@ -1707,23 +1592,19 @@ static int stv0900_stop_ts(struct dvb_frontend *fe, int stop_ts)
1707static int stv0900_diseqc_init(struct dvb_frontend *fe) 1592static int stv0900_diseqc_init(struct dvb_frontend *fe)
1708{ 1593{
1709 struct stv0900_state *state = fe->demodulator_priv; 1594 struct stv0900_state *state = fe->demodulator_priv;
1710 struct stv0900_internal *i_params = state->internal; 1595 struct stv0900_internal *intp = state->internal;
1711 enum fe_stv0900_demod_num demod = state->demod; 1596 enum fe_stv0900_demod_num demod = state->demod;
1712 s32 mode_field, reset_field;
1713 1597
1714 dmd_reg(mode_field, F0900_P1_DISTX_MODE, F0900_P2_DISTX_MODE); 1598 stv0900_write_bits(intp, DISTX_MODE, state->config->diseqc_mode);
1715 dmd_reg(reset_field, F0900_P1_DISEQC_RESET, F0900_P2_DISEQC_RESET); 1599 stv0900_write_bits(intp, DISEQC_RESET, 1);
1716 1600 stv0900_write_bits(intp, DISEQC_RESET, 0);
1717 stv0900_write_bits(i_params, mode_field, state->config->diseqc_mode);
1718 stv0900_write_bits(i_params, reset_field, 1);
1719 stv0900_write_bits(i_params, reset_field, 0);
1720 1601
1721 return 0; 1602 return 0;
1722} 1603}
1723 1604
1724static int stv0900_init(struct dvb_frontend *fe) 1605static int stv0900_init(struct dvb_frontend *fe)
1725{ 1606{
1726 dprintk(KERN_INFO "%s\n", __func__); 1607 dprintk("%s\n", __func__);
1727 1608
1728 stv0900_stop_ts(fe, 1); 1609 stv0900_stop_ts(fe, 1);
1729 stv0900_diseqc_init(fe); 1610 stv0900_diseqc_init(fe);
@@ -1731,48 +1612,24 @@ static int stv0900_init(struct dvb_frontend *fe)
1731 return 0; 1612 return 0;
1732} 1613}
1733 1614
1734static int stv0900_diseqc_send(struct stv0900_internal *i_params , u8 *Data, 1615static int stv0900_diseqc_send(struct stv0900_internal *intp , u8 *data,
1735 u32 NbData, enum fe_stv0900_demod_num demod) 1616 u32 NbData, enum fe_stv0900_demod_num demod)
1736{ 1617{
1737 s32 i = 0; 1618 s32 i = 0;
1738 1619
1739 switch (demod) { 1620 stv0900_write_bits(intp, DIS_PRECHARGE, 1);
1740 case STV0900_DEMOD_1: 1621 while (i < NbData) {
1741 default: 1622 while (stv0900_get_bits(intp, FIFO_FULL))
1742 stv0900_write_bits(i_params, F0900_P1_DIS_PRECHARGE, 1); 1623 ;/* checkpatch complains */
1743 while (i < NbData) { 1624 stv0900_write_reg(intp, DISTXDATA, data[i]);
1744 while (stv0900_get_bits(i_params, F0900_P1_FIFO_FULL)) 1625 i++;
1745 ;/* checkpatch complains */ 1626 }
1746 stv0900_write_reg(i_params, R0900_P1_DISTXDATA, Data[i]);
1747 i++;
1748 }
1749
1750 stv0900_write_bits(i_params, F0900_P1_DIS_PRECHARGE, 0);
1751 i = 0;
1752 while ((stv0900_get_bits(i_params, F0900_P1_TX_IDLE) != 1) && (i < 10)) {
1753 msleep(10);
1754 i++;
1755 }
1756
1757 break;
1758 case STV0900_DEMOD_2:
1759 stv0900_write_bits(i_params, F0900_P2_DIS_PRECHARGE, 1);
1760
1761 while (i < NbData) {
1762 while (stv0900_get_bits(i_params, F0900_P2_FIFO_FULL))
1763 ;/* checkpatch complains */
1764 stv0900_write_reg(i_params, R0900_P2_DISTXDATA, Data[i]);
1765 i++;
1766 }
1767
1768 stv0900_write_bits(i_params, F0900_P2_DIS_PRECHARGE, 0);
1769 i = 0;
1770 while ((stv0900_get_bits(i_params, F0900_P2_TX_IDLE) != 1) && (i < 10)) {
1771 msleep(10);
1772 i++;
1773 }
1774 1627
1775 break; 1628 stv0900_write_bits(intp, DIS_PRECHARGE, 0);
1629 i = 0;
1630 while ((stv0900_get_bits(intp, TX_IDLE) != 1) && (i < 10)) {
1631 msleep(10);
1632 i++;
1776 } 1633 }
1777 1634
1778 return 0; 1635 return 0;
@@ -1792,22 +1649,21 @@ static int stv0900_send_master_cmd(struct dvb_frontend *fe,
1792static int stv0900_send_burst(struct dvb_frontend *fe, fe_sec_mini_cmd_t burst) 1649static int stv0900_send_burst(struct dvb_frontend *fe, fe_sec_mini_cmd_t burst)
1793{ 1650{
1794 struct stv0900_state *state = fe->demodulator_priv; 1651 struct stv0900_state *state = fe->demodulator_priv;
1795 struct stv0900_internal *i_params = state->internal; 1652 struct stv0900_internal *intp = state->internal;
1796 enum fe_stv0900_demod_num demod = state->demod; 1653 enum fe_stv0900_demod_num demod = state->demod;
1797 s32 mode_field; 1654 u8 data;
1798 u32 diseqc_fifo;
1799 1655
1800 dmd_reg(mode_field, F0900_P1_DISTX_MODE, F0900_P2_DISTX_MODE);
1801 dmd_reg(diseqc_fifo, R0900_P1_DISTXDATA, R0900_P2_DISTXDATA);
1802 1656
1803 switch (burst) { 1657 switch (burst) {
1804 case SEC_MINI_A: 1658 case SEC_MINI_A:
1805 stv0900_write_bits(i_params, mode_field, 3);/* Unmodulated */ 1659 stv0900_write_bits(intp, DISTX_MODE, 3);/* Unmodulated */
1806 stv0900_write_reg(i_params, diseqc_fifo, 0x00); 1660 data = 0x00;
1661 stv0900_diseqc_send(intp, &data, 1, state->demod);
1807 break; 1662 break;
1808 case SEC_MINI_B: 1663 case SEC_MINI_B:
1809 stv0900_write_bits(i_params, mode_field, 2);/* Modulated */ 1664 stv0900_write_bits(intp, DISTX_MODE, 2);/* Modulated */
1810 stv0900_write_reg(i_params, diseqc_fifo, 0xff); 1665 data = 0xff;
1666 stv0900_diseqc_send(intp, &data, 1, state->demod);
1811 break; 1667 break;
1812 } 1668 }
1813 1669
@@ -1818,68 +1674,54 @@ static int stv0900_recv_slave_reply(struct dvb_frontend *fe,
1818 struct dvb_diseqc_slave_reply *reply) 1674 struct dvb_diseqc_slave_reply *reply)
1819{ 1675{
1820 struct stv0900_state *state = fe->demodulator_priv; 1676 struct stv0900_state *state = fe->demodulator_priv;
1821 struct stv0900_internal *i_params = state->internal; 1677 struct stv0900_internal *intp = state->internal;
1678 enum fe_stv0900_demod_num demod = state->demod;
1822 s32 i = 0; 1679 s32 i = 0;
1823 1680
1824 switch (state->demod) { 1681 reply->msg_len = 0;
1825 case STV0900_DEMOD_1:
1826 default:
1827 reply->msg_len = 0;
1828
1829 while ((stv0900_get_bits(i_params, F0900_P1_RX_END) != 1) && (i < 10)) {
1830 msleep(10);
1831 i++;
1832 }
1833
1834 if (stv0900_get_bits(i_params, F0900_P1_RX_END)) {
1835 reply->msg_len = stv0900_get_bits(i_params, F0900_P1_FIFO_BYTENBR);
1836
1837 for (i = 0; i < reply->msg_len; i++)
1838 reply->msg[i] = stv0900_read_reg(i_params, R0900_P1_DISRXDATA);
1839 }
1840 break;
1841 case STV0900_DEMOD_2:
1842 reply->msg_len = 0;
1843 1682
1844 while ((stv0900_get_bits(i_params, F0900_P2_RX_END) != 1) && (i < 10)) { 1683 while ((stv0900_get_bits(intp, RX_END) != 1) && (i < 10)) {
1845 msleep(10); 1684 msleep(10);
1846 i++; 1685 i++;
1847 } 1686 }
1848 1687
1849 if (stv0900_get_bits(i_params, F0900_P2_RX_END)) { 1688 if (stv0900_get_bits(intp, RX_END)) {
1850 reply->msg_len = stv0900_get_bits(i_params, F0900_P2_FIFO_BYTENBR); 1689 reply->msg_len = stv0900_get_bits(intp, FIFO_BYTENBR);
1851 1690
1852 for (i = 0; i < reply->msg_len; i++) 1691 for (i = 0; i < reply->msg_len; i++)
1853 reply->msg[i] = stv0900_read_reg(i_params, R0900_P2_DISRXDATA); 1692 reply->msg[i] = stv0900_read_reg(intp, DISRXDATA);
1854 }
1855 break;
1856 } 1693 }
1857 1694
1858 return 0; 1695 return 0;
1859} 1696}
1860 1697
1861static int stv0900_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone) 1698static int stv0900_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t toneoff)
1862{ 1699{
1863 struct stv0900_state *state = fe->demodulator_priv; 1700 struct stv0900_state *state = fe->demodulator_priv;
1864 struct stv0900_internal *i_params = state->internal; 1701 struct stv0900_internal *intp = state->internal;
1865 enum fe_stv0900_demod_num demod = state->demod; 1702 enum fe_stv0900_demod_num demod = state->demod;
1866 s32 mode_field, reset_field;
1867
1868 dprintk(KERN_INFO "%s: %s\n", __func__, ((tone == 0) ? "Off" : "On"));
1869 1703
1870 dmd_reg(mode_field, F0900_P1_DISTX_MODE, F0900_P2_DISTX_MODE); 1704 dprintk("%s: %s\n", __func__, ((toneoff == 0) ? "On" : "Off"));
1871 dmd_reg(reset_field, F0900_P1_DISEQC_RESET, F0900_P2_DISEQC_RESET);
1872 1705
1873 if (tone) { 1706 switch (toneoff) {
1874 /*Set the DiseqC mode to 22Khz continues tone*/ 1707 case SEC_TONE_ON:
1875 stv0900_write_bits(i_params, mode_field, 0); 1708 /*Set the DiseqC mode to 22Khz _continues_ tone*/
1876 stv0900_write_bits(i_params, reset_field, 1); 1709 stv0900_write_bits(intp, DISTX_MODE, 0);
1710 stv0900_write_bits(intp, DISEQC_RESET, 1);
1877 /*release DiseqC reset to enable the 22KHz tone*/ 1711 /*release DiseqC reset to enable the 22KHz tone*/
1878 stv0900_write_bits(i_params, reset_field, 0); 1712 stv0900_write_bits(intp, DISEQC_RESET, 0);
1879 } else { 1713 break;
1880 stv0900_write_bits(i_params, mode_field, 0); 1714 case SEC_TONE_OFF:
1715 /*return diseqc mode to config->diseqc_mode.
1716 Usually it's without _continues_ tone */
1717 stv0900_write_bits(intp, DISTX_MODE,
1718 state->config->diseqc_mode);
1881 /*maintain the DiseqC reset to disable the 22KHz tone*/ 1719 /*maintain the DiseqC reset to disable the 22KHz tone*/
1882 stv0900_write_bits(i_params, reset_field, 1); 1720 stv0900_write_bits(intp, DISEQC_RESET, 1);
1721 stv0900_write_bits(intp, DISEQC_RESET, 0);
1722 break;
1723 default:
1724 return -EINVAL;
1883 } 1725 }
1884 1726
1885 return 0; 1727 return 0;
@@ -1889,11 +1731,11 @@ static void stv0900_release(struct dvb_frontend *fe)
1889{ 1731{
1890 struct stv0900_state *state = fe->demodulator_priv; 1732 struct stv0900_state *state = fe->demodulator_priv;
1891 1733
1892 dprintk(KERN_INFO "%s\n", __func__); 1734 dprintk("%s\n", __func__);
1893 1735
1894 if ((--(state->internal->dmds_used)) <= 0) { 1736 if ((--(state->internal->dmds_used)) <= 0) {
1895 1737
1896 dprintk(KERN_INFO "%s: Actually removing\n", __func__); 1738 dprintk("%s: Actually removing\n", __func__);
1897 1739
1898 remove_inode(state->internal); 1740 remove_inode(state->internal);
1899 kfree(state->internal); 1741 kfree(state->internal);
@@ -1963,17 +1805,17 @@ struct dvb_frontend *stv0900_attach(const struct stv0900_config *config,
1963 case 0: 1805 case 0:
1964 case 1: 1806 case 1:
1965 init_params.dmd_ref_clk = config->xtal; 1807 init_params.dmd_ref_clk = config->xtal;
1966 init_params.demod_mode = STV0900_DUAL; 1808 init_params.demod_mode = config->demod_mode;
1967 init_params.rolloff = STV0900_35; 1809 init_params.rolloff = STV0900_35;
1968 init_params.path1_ts_clock = config->path1_mode; 1810 init_params.path1_ts_clock = config->path1_mode;
1969 init_params.tun1_maddress = config->tun1_maddress; 1811 init_params.tun1_maddress = config->tun1_maddress;
1970 init_params.tun1_iq_inversion = STV0900_IQ_NORMAL; 1812 init_params.tun1_iq_inv = STV0900_IQ_NORMAL;
1971 init_params.tuner1_adc = config->tun1_adc; 1813 init_params.tuner1_adc = config->tun1_adc;
1972 init_params.path2_ts_clock = config->path2_mode; 1814 init_params.path2_ts_clock = config->path2_mode;
1973 init_params.ts_config = config->ts_config_regs; 1815 init_params.ts_config = config->ts_config_regs;
1974 init_params.tun2_maddress = config->tun2_maddress; 1816 init_params.tun2_maddress = config->tun2_maddress;
1975 init_params.tuner2_adc = config->tun2_adc; 1817 init_params.tuner2_adc = config->tun2_adc;
1976 init_params.tun2_iq_inversion = STV0900_IQ_SWAPPED; 1818 init_params.tun2_iq_inv = STV0900_IQ_SWAPPED;
1977 1819
1978 err_stv0900 = stv0900_init_internal(&state->frontend, 1820 err_stv0900 = stv0900_init_internal(&state->frontend,
1979 &init_params); 1821 &init_params);
diff --git a/drivers/media/dvb/frontends/stv0900_init.h b/drivers/media/dvb/frontends/stv0900_init.h
index ff388b47a4e3..b684df9995d8 100644
--- a/drivers/media/dvb/frontends/stv0900_init.h
+++ b/drivers/media/dvb/frontends/stv0900_init.h
@@ -141,85 +141,228 @@ struct stv0900_short_frames_car_loop_optim {
141 141
142}; 142};
143 143
144struct stv0900_short_frames_car_loop_optim_vs_mod {
145 enum fe_stv0900_modulation modulation;
146 u8 car_loop_2; /* SR<3msps */
147 u8 car_loop_5; /* 3<SR<=7msps */
148 u8 car_loop_10; /* 7<SR<=15msps */
149 u8 car_loop_20; /* 10<SR<=25msps */
150 u8 car_loop_30; /* 10<SR<=45msps */
151};
152
144/* Cut 1.x Tracking carrier loop carrier QPSK 1/2 to 8PSK 9/10 long Frame */ 153/* Cut 1.x Tracking carrier loop carrier QPSK 1/2 to 8PSK 9/10 long Frame */
145static const struct stv0900_car_loop_optim FE_STV0900_S2CarLoop[14] = { 154static const struct stv0900_car_loop_optim FE_STV0900_S2CarLoop[14] = {
146 /*Modcod 2MPon 2MPoff 5MPon 5MPoff 10MPon 10MPoff 20MPon 20MPoff 30MPon 30MPoff */ 155 /*Modcod 2MPon 2MPoff 5MPon 5MPoff 10MPon
147 { STV0900_QPSK_12, 0x1C, 0x0D, 0x1B, 0x2C, 0x3A, 0x1C, 0x2A, 0x3B, 0x2A, 0x1B }, 156 10MPoff 20MPon 20MPoff 30MPon 30MPoff */
148 { STV0900_QPSK_35, 0x2C, 0x0D, 0x2B, 0x2C, 0x3A, 0x0C, 0x3A, 0x2B, 0x2A, 0x0B }, 157 { STV0900_QPSK_12, 0x1C, 0x0D, 0x1B, 0x2C, 0x3A,
149 { STV0900_QPSK_23, 0x2C, 0x0D, 0x2B, 0x2C, 0x0B, 0x0C, 0x3A, 0x1B, 0x2A, 0x3A }, 158 0x1C, 0x2A, 0x3B, 0x2A, 0x1B },
150 { STV0900_QPSK_34, 0x3C, 0x0D, 0x3B, 0x1C, 0x0B, 0x3B, 0x3A, 0x0B, 0x2A, 0x3A }, 159 { STV0900_QPSK_35, 0x2C, 0x0D, 0x2B, 0x2C, 0x3A,
151 { STV0900_QPSK_45, 0x3C, 0x0D, 0x3B, 0x1C, 0x0B, 0x3B, 0x3A, 0x0B, 0x2A, 0x3A }, 160 0x0C, 0x3A, 0x2B, 0x2A, 0x0B },
152 { STV0900_QPSK_56, 0x0D, 0x0D, 0x3B, 0x1C, 0x0B, 0x3B, 0x3A, 0x0B, 0x2A, 0x3A }, 161 { STV0900_QPSK_23, 0x2C, 0x0D, 0x2B, 0x2C, 0x0B,
153 { STV0900_QPSK_89, 0x0D, 0x0D, 0x3B, 0x1C, 0x1B, 0x3B, 0x3A, 0x0B, 0x2A, 0x3A }, 162 0x0C, 0x3A, 0x1B, 0x2A, 0x3A },
154 { STV0900_QPSK_910, 0x1D, 0x0D, 0x3B, 0x1C, 0x1B, 0x3B, 0x3A, 0x0B, 0x2A, 0x3A }, 163 { STV0900_QPSK_34, 0x3C, 0x0D, 0x3B, 0x1C, 0x0B,
155 { STV0900_8PSK_35, 0x29, 0x3B, 0x09, 0x2B, 0x38, 0x0B, 0x18, 0x1A, 0x08, 0x0A }, 164 0x3B, 0x3A, 0x0B, 0x2A, 0x3A },
156 { STV0900_8PSK_23, 0x0A, 0x3B, 0x29, 0x2B, 0x19, 0x0B, 0x38, 0x1A, 0x18, 0x0A }, 165 { STV0900_QPSK_45, 0x3C, 0x0D, 0x3B, 0x1C, 0x0B,
157 { STV0900_8PSK_34, 0x3A, 0x3B, 0x2A, 0x2B, 0x39, 0x0B, 0x19, 0x1A, 0x38, 0x0A }, 166 0x3B, 0x3A, 0x0B, 0x2A, 0x3A },
158 { STV0900_8PSK_56, 0x1B, 0x3B, 0x0B, 0x2B, 0x1A, 0x0B, 0x39, 0x1A, 0x19, 0x0A }, 167 { STV0900_QPSK_56, 0x0D, 0x0D, 0x3B, 0x1C, 0x0B,
159 { STV0900_8PSK_89, 0x3B, 0x3B, 0x0B, 0x2B, 0x2A, 0x0B, 0x39, 0x1A, 0x29, 0x39 }, 168 0x3B, 0x3A, 0x0B, 0x2A, 0x3A },
160 { STV0900_8PSK_910, 0x3B, 0x3B, 0x0B, 0x2B, 0x2A, 0x0B, 0x39, 0x1A, 0x29, 0x39 } 169 { STV0900_QPSK_89, 0x0D, 0x0D, 0x3B, 0x1C, 0x1B,
170 0x3B, 0x3A, 0x0B, 0x2A, 0x3A },
171 { STV0900_QPSK_910, 0x1D, 0x0D, 0x3B, 0x1C, 0x1B,
172 0x3B, 0x3A, 0x0B, 0x2A, 0x3A },
173 { STV0900_8PSK_35, 0x29, 0x3B, 0x09, 0x2B, 0x38,
174 0x0B, 0x18, 0x1A, 0x08, 0x0A },
175 { STV0900_8PSK_23, 0x0A, 0x3B, 0x29, 0x2B, 0x19,
176 0x0B, 0x38, 0x1A, 0x18, 0x0A },
177 { STV0900_8PSK_34, 0x3A, 0x3B, 0x2A, 0x2B, 0x39,
178 0x0B, 0x19, 0x1A, 0x38, 0x0A },
179 { STV0900_8PSK_56, 0x1B, 0x3B, 0x0B, 0x2B, 0x1A,
180 0x0B, 0x39, 0x1A, 0x19, 0x0A },
181 { STV0900_8PSK_89, 0x3B, 0x3B, 0x0B, 0x2B, 0x2A,
182 0x0B, 0x39, 0x1A, 0x29, 0x39 },
183 { STV0900_8PSK_910, 0x3B, 0x3B, 0x0B, 0x2B, 0x2A,
184 0x0B, 0x39, 0x1A, 0x29, 0x39 }
161}; 185};
162 186
163 187
164/* Cut 2.0 Tracking carrier loop carrier QPSK 1/2 to 8PSK 9/10 long Frame */ 188/* Cut 2.0 Tracking carrier loop carrier QPSK 1/2 to 8PSK 9/10 long Frame */
165static const struct stv0900_car_loop_optim FE_STV0900_S2CarLoopCut20[14] = { 189static const struct stv0900_car_loop_optim FE_STV0900_S2CarLoopCut20[14] = {
166 /* Modcod 2MPon 2MPoff 5MPon 5MPoff 10MPon 10MPoff 20MPon 20MPoff 30MPon 30MPoff */ 190 /* Modcod 2MPon 2MPoff 5MPon 5MPoff 10MPon
167 { STV0900_QPSK_12, 0x1F, 0x3F, 0x1E, 0x3F, 0x3D, 0x1F, 0x3D, 0x3E, 0x3D, 0x1E }, 191 10MPoff 20MPon 20MPoff 30MPon 30MPoff */
168 { STV0900_QPSK_35, 0x2F, 0x3F, 0x2E, 0x2F, 0x3D, 0x0F, 0x0E, 0x2E, 0x3D, 0x0E }, 192 { STV0900_QPSK_12, 0x1F, 0x3F, 0x1E, 0x3F, 0x3D,
169 { STV0900_QPSK_23, 0x2F, 0x3F, 0x2E, 0x2F, 0x0E, 0x0F, 0x0E, 0x1E, 0x3D, 0x3D }, 193 0x1F, 0x3D, 0x3E, 0x3D, 0x1E },
170 { STV0900_QPSK_34, 0x3F, 0x3F, 0x3E, 0x1F, 0x0E, 0x3E, 0x0E, 0x1E, 0x3D, 0x3D }, 194 { STV0900_QPSK_35, 0x2F, 0x3F, 0x2E, 0x2F, 0x3D,
171 { STV0900_QPSK_45, 0x3F, 0x3F, 0x3E, 0x1F, 0x0E, 0x3E, 0x0E, 0x1E, 0x3D, 0x3D }, 195 0x0F, 0x0E, 0x2E, 0x3D, 0x0E },
172 { STV0900_QPSK_56, 0x3F, 0x3F, 0x3E, 0x1F, 0x0E, 0x3E, 0x0E, 0x1E, 0x3D, 0x3D }, 196 { STV0900_QPSK_23, 0x2F, 0x3F, 0x2E, 0x2F, 0x0E,
173 { STV0900_QPSK_89, 0x3F, 0x3F, 0x3E, 0x1F, 0x1E, 0x3E, 0x0E, 0x1E, 0x3D, 0x3D }, 197 0x0F, 0x0E, 0x1E, 0x3D, 0x3D },
174 { STV0900_QPSK_910, 0x3F, 0x3F, 0x3E, 0x1F, 0x1E, 0x3E, 0x0E, 0x1E, 0x3D, 0x3D }, 198 { STV0900_QPSK_34, 0x3F, 0x3F, 0x3E, 0x1F, 0x0E,
175 { STV0900_8PSK_35, 0x3c, 0x0c, 0x1c, 0x3b, 0x0c, 0x3b, 0x2b, 0x2b, 0x1b, 0x2b }, 199 0x3E, 0x0E, 0x1E, 0x3D, 0x3D },
176 { STV0900_8PSK_23, 0x1d, 0x0c, 0x3c, 0x0c, 0x2c, 0x3b, 0x0c, 0x2b, 0x2b, 0x2b }, 200 { STV0900_QPSK_45, 0x3F, 0x3F, 0x3E, 0x1F, 0x0E,
177 { STV0900_8PSK_34, 0x0e, 0x1c, 0x3d, 0x0c, 0x0d, 0x3b, 0x2c, 0x3b, 0x0c, 0x2b }, 201 0x3E, 0x0E, 0x1E, 0x3D, 0x3D },
178 { STV0900_8PSK_56, 0x2e, 0x3e, 0x1e, 0x2e, 0x2d, 0x1e, 0x3c, 0x2d, 0x2c, 0x1d }, 202 { STV0900_QPSK_56, 0x3F, 0x3F, 0x3E, 0x1F, 0x0E,
179 { STV0900_8PSK_89, 0x3e, 0x3e, 0x1e, 0x2e, 0x3d, 0x1e, 0x0d, 0x2d, 0x3c, 0x1d }, 203 0x3E, 0x0E, 0x1E, 0x3D, 0x3D },
180 { STV0900_8PSK_910, 0x3e, 0x3e, 0x1e, 0x2e, 0x3d, 0x1e, 0x1d, 0x2d, 0x0d, 0x1d } 204 { STV0900_QPSK_89, 0x3F, 0x3F, 0x3E, 0x1F, 0x1E,
205 0x3E, 0x0E, 0x1E, 0x3D, 0x3D },
206 { STV0900_QPSK_910, 0x3F, 0x3F, 0x3E, 0x1F, 0x1E,
207 0x3E, 0x0E, 0x1E, 0x3D, 0x3D },
208 { STV0900_8PSK_35, 0x3c, 0x0c, 0x1c, 0x3b, 0x0c,
209 0x3b, 0x2b, 0x2b, 0x1b, 0x2b },
210 { STV0900_8PSK_23, 0x1d, 0x0c, 0x3c, 0x0c, 0x2c,
211 0x3b, 0x0c, 0x2b, 0x2b, 0x2b },
212 { STV0900_8PSK_34, 0x0e, 0x1c, 0x3d, 0x0c, 0x0d,
213 0x3b, 0x2c, 0x3b, 0x0c, 0x2b },
214 { STV0900_8PSK_56, 0x2e, 0x3e, 0x1e, 0x2e, 0x2d,
215 0x1e, 0x3c, 0x2d, 0x2c, 0x1d },
216 { STV0900_8PSK_89, 0x3e, 0x3e, 0x1e, 0x2e, 0x3d,
217 0x1e, 0x0d, 0x2d, 0x3c, 0x1d },
218 { STV0900_8PSK_910, 0x3e, 0x3e, 0x1e, 0x2e, 0x3d,
219 0x1e, 0x1d, 0x2d, 0x0d, 0x1d },
181}; 220};
182 221
183 222
184 223
185/* Cut 2.0 Tracking carrier loop carrier 16APSK 2/3 to 32APSK 9/10 long Frame */ 224/* Cut 2.0 Tracking carrier loop carrier 16APSK 2/3 to 32APSK 9/10 long Frame */
186static const struct stv0900_car_loop_optim FE_STV0900_S2APSKCarLoopCut20[11] = { 225static const struct stv0900_car_loop_optim FE_STV0900_S2APSKCarLoopCut20[11] = {
187 /* Modcod 2MPon 2MPoff 5MPon 5MPoff 10MPon 10MPoff 20MPon 20MPoff 30MPon 30MPoff */ 226 /* Modcod 2MPon 2MPoff 5MPon 5MPoff 10MPon
188 { STV0900_16APSK_23, 0x0C, 0x0C, 0x0C, 0x0C, 0x1D, 0x0C, 0x3C, 0x0C, 0x2C, 0x0C }, 227 10MPoff 20MPon 20MPoff 30MPon 30MPoff */
189 { STV0900_16APSK_34, 0x0C, 0x0C, 0x0C, 0x0C, 0x0E, 0x0C, 0x2D, 0x0C, 0x1D, 0x0C }, 228 { STV0900_16APSK_23, 0x0C, 0x0C, 0x0C, 0x0C, 0x1D,
190 { STV0900_16APSK_45, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x0C, 0x3D, 0x0C, 0x2D, 0x0C }, 229 0x0C, 0x3C, 0x0C, 0x2C, 0x0C },
191 { STV0900_16APSK_56, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x0C, 0x3D, 0x0C, 0x2D, 0x0C }, 230 { STV0900_16APSK_34, 0x0C, 0x0C, 0x0C, 0x0C, 0x0E,
192 { STV0900_16APSK_89, 0x0C, 0x0C, 0x0C, 0x0C, 0x2E, 0x0C, 0x0E, 0x0C, 0x3D, 0x0C }, 231 0x0C, 0x2D, 0x0C, 0x1D, 0x0C },
193 { STV0900_16APSK_910, 0x0C, 0x0C, 0x0C, 0x0C, 0x2E, 0x0C, 0x0E, 0x0C, 0x3D, 0x0C }, 232 { STV0900_16APSK_45, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E,
194 { STV0900_32APSK_34, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C }, 233 0x0C, 0x3D, 0x0C, 0x2D, 0x0C },
195 { STV0900_32APSK_45, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C }, 234 { STV0900_16APSK_56, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E,
196 { STV0900_32APSK_56, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C }, 235 0x0C, 0x3D, 0x0C, 0x2D, 0x0C },
197 { STV0900_32APSK_89, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C }, 236 { STV0900_16APSK_89, 0x0C, 0x0C, 0x0C, 0x0C, 0x2E,
198 { STV0900_32APSK_910, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C } 237 0x0C, 0x0E, 0x0C, 0x3D, 0x0C },
238 { STV0900_16APSK_910, 0x0C, 0x0C, 0x0C, 0x0C, 0x2E,
239 0x0C, 0x0E, 0x0C, 0x3D, 0x0C },
240 { STV0900_32APSK_34, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
241 0x0C, 0x0C, 0x0C, 0x0C, 0x0C },
242 { STV0900_32APSK_45, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
243 0x0C, 0x0C, 0x0C, 0x0C, 0x0C },
244 { STV0900_32APSK_56, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
245 0x0C, 0x0C, 0x0C, 0x0C, 0x0C },
246 { STV0900_32APSK_89, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
247 0x0C, 0x0C, 0x0C, 0x0C, 0x0C },
248 { STV0900_32APSK_910, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
249 0x0C, 0x0C, 0x0C, 0x0C, 0x0C },
199}; 250};
200 251
201 252
202/* Cut 2.0 Tracking carrier loop carrier QPSK 1/4 to QPSK 2/5 long Frame */ 253/* Cut 2.0 Tracking carrier loop carrier QPSK 1/4 to QPSK 2/5 long Frame */
203static const struct stv0900_car_loop_optim FE_STV0900_S2LowQPCarLoopCut20[3] = { 254static const struct stv0900_car_loop_optim FE_STV0900_S2LowQPCarLoopCut20[3] = {
204 /* Modcod 2MPon 2MPoff 5MPon 5MPoff 10MPon 10MPoff 20MPon 20MPoff 30MPon 30MPoff */ 255 /* Modcod 2MPon 2MPoff 5MPon 5MPoff 10MPon
205 { STV0900_QPSK_14, 0x0F, 0x3F, 0x0E, 0x3F, 0x2D, 0x2F, 0x2D, 0x1F, 0x3D, 0x3E }, 256 10MPoff 20MPon 20MPoff 30MPon 30MPoff */
206 { STV0900_QPSK_13, 0x0F, 0x3F, 0x0E, 0x3F, 0x2D, 0x2F, 0x3D, 0x0F, 0x3D, 0x2E }, 257 { STV0900_QPSK_14, 0x0F, 0x3F, 0x0E, 0x3F, 0x2D,
207 { STV0900_QPSK_25, 0x1F, 0x3F, 0x1E, 0x3F, 0x3D, 0x1F, 0x3D, 0x3E, 0x3D, 0x2E } 258 0x2F, 0x2D, 0x1F, 0x3D, 0x3E },
259 { STV0900_QPSK_13, 0x0F, 0x3F, 0x0E, 0x3F, 0x2D,
260 0x2F, 0x3D, 0x0F, 0x3D, 0x2E },
261 { STV0900_QPSK_25, 0x1F, 0x3F, 0x1E, 0x3F, 0x3D,
262 0x1F, 0x3D, 0x3E, 0x3D, 0x2E }
208}; 263};
209 264
210 265
211/* Cut 2.0 Tracking carrier loop carrier short Frame, cut 1.2 and 2.0 */ 266/* Cut 2.0 Tracking carrier loop carrier short Frame, cut 1.2 and 2.0 */
212static const struct stv0900_short_frames_car_loop_optim FE_STV0900_S2ShortCarLoop[4] = { 267static const
213 /*Mod 2M_cut1.2 2M_cut2.0 5M_cut1.2 5M_cut2.0 10M_cut1.2 10M_cut2.0 20M_cut1.2 20M_cut2.0 30M_cut1.2 30M_cut2.0 */ 268struct stv0900_short_frames_car_loop_optim FE_STV0900_S2ShortCarLoop[4] = {
214 { STV0900_QPSK, 0x3C, 0x2F, 0x2B, 0x2E, 0x0B, 0x0E, 0x3A, 0x0E, 0x2A, 0x3D }, 269 /*Mod 2Mcut1.2 2Mcut2.0 5Mcut1.2 5Mcut2.0 10Mcut1.2
215 { STV0900_8PSK, 0x0B, 0x3E, 0x2A, 0x0E, 0x0A, 0x2D, 0x19, 0x0D, 0x09, 0x3C }, 270 10Mcut2.0 20Mcut1.2 20M_cut2.0 30Mcut1.2 30Mcut2.0*/
216 { STV0900_16APSK, 0x1B, 0x1E, 0x1B, 0x1E, 0x1B, 0x1E, 0x3A, 0x3D, 0x2A, 0x2D }, 271 { STV0900_QPSK, 0x3C, 0x2F, 0x2B, 0x2E, 0x0B,
217 { STV0900_32APSK, 0x1B, 0x1E, 0x1B, 0x1E, 0x1B, 0x1E, 0x3A, 0x3D, 0x2A, 0x2D } 272 0x0E, 0x3A, 0x0E, 0x2A, 0x3D },
273 { STV0900_8PSK, 0x0B, 0x3E, 0x2A, 0x0E, 0x0A,
274 0x2D, 0x19, 0x0D, 0x09, 0x3C },
275 { STV0900_16APSK, 0x1B, 0x1E, 0x1B, 0x1E, 0x1B,
276 0x1E, 0x3A, 0x3D, 0x2A, 0x2D },
277 { STV0900_32APSK, 0x1B, 0x1E, 0x1B, 0x1E, 0x1B,
278 0x1E, 0x3A, 0x3D, 0x2A, 0x2D }
279};
280
281static const struct stv0900_car_loop_optim FE_STV0900_S2CarLoopCut30[14] = {
282 /*Modcod 2MPon 2MPoff 5MPon 5MPoff 10MPon
283 10MPoff 20MPon 20MPoff 30MPon 30MPoff */
284 { STV0900_QPSK_12, 0x3C, 0x2C, 0x0C, 0x2C, 0x1B,
285 0x2C, 0x1B, 0x1C, 0x0B, 0x3B },
286 { STV0900_QPSK_35, 0x0D, 0x0D, 0x0C, 0x0D, 0x1B,
287 0x3C, 0x1B, 0x1C, 0x0B, 0x3B },
288 { STV0900_QPSK_23, 0x1D, 0x0D, 0x0C, 0x1D, 0x2B,
289 0x3C, 0x1B, 0x1C, 0x0B, 0x3B },
290 { STV0900_QPSK_34, 0x1D, 0x1D, 0x0C, 0x1D, 0x2B,
291 0x3C, 0x1B, 0x1C, 0x0B, 0x3B },
292 { STV0900_QPSK_45, 0x2D, 0x1D, 0x1C, 0x1D, 0x2B,
293 0x3C, 0x2B, 0x0C, 0x1B, 0x3B },
294 { STV0900_QPSK_56, 0x2D, 0x1D, 0x1C, 0x1D, 0x2B,
295 0x3C, 0x2B, 0x0C, 0x1B, 0x3B },
296 { STV0900_QPSK_89, 0x3D, 0x2D, 0x1C, 0x1D, 0x3B,
297 0x3C, 0x2B, 0x0C, 0x1B, 0x3B },
298 { STV0900_QPSK_910, 0x3D, 0x2D, 0x1C, 0x1D, 0x3B,
299 0x3C, 0x2B, 0x0C, 0x1B, 0x3B },
300 { STV0900_8PSK_35, 0x39, 0x19, 0x39, 0x19, 0x19,
301 0x19, 0x19, 0x19, 0x09, 0x19 },
302 { STV0900_8PSK_23, 0x2A, 0x39, 0x1A, 0x0A, 0x39,
303 0x0A, 0x29, 0x39, 0x29, 0x0A },
304 { STV0900_8PSK_34, 0x0B, 0x3A, 0x0B, 0x0B, 0x3A,
305 0x1B, 0x1A, 0x0B, 0x1A, 0x3A },
306 { STV0900_8PSK_56, 0x0C, 0x1B, 0x3B, 0x2B, 0x1B,
307 0x3B, 0x3A, 0x3B, 0x3A, 0x1B },
308 { STV0900_8PSK_89, 0x2C, 0x2C, 0x2C, 0x1C, 0x2B,
309 0x0C, 0x0B, 0x3B, 0x0B, 0x1B },
310 { STV0900_8PSK_910, 0x2C, 0x3C, 0x2C, 0x1C, 0x3B,
311 0x1C, 0x0B, 0x3B, 0x0B, 0x1B }
312};
313
314static const
315struct stv0900_car_loop_optim FE_STV0900_S2APSKCarLoopCut30[11] = {
316 /*Modcod 2MPon 2MPoff 5MPon 5MPoff 10MPon
317 10MPoff 20MPon 20MPoff 30MPon 30MPoff */
318 { STV0900_16APSK_23, 0x0A, 0x0A, 0x0A, 0x0A, 0x1A,
319 0x0A, 0x3A, 0x0A, 0x2A, 0x0A },
320 { STV0900_16APSK_34, 0x0A, 0x0A, 0x0A, 0x0A, 0x0B,
321 0x0A, 0x3B, 0x0A, 0x1B, 0x0A },
322 { STV0900_16APSK_45, 0x0A, 0x0A, 0x0A, 0x0A, 0x1B,
323 0x0A, 0x3B, 0x0A, 0x2B, 0x0A },
324 { STV0900_16APSK_56, 0x0A, 0x0A, 0x0A, 0x0A, 0x1B,
325 0x0A, 0x3B, 0x0A, 0x2B, 0x0A },
326 { STV0900_16APSK_89, 0x0A, 0x0A, 0x0A, 0x0A, 0x2B,
327 0x0A, 0x0C, 0x0A, 0x3B, 0x0A },
328 { STV0900_16APSK_910, 0x0A, 0x0A, 0x0A, 0x0A, 0x2B,
329 0x0A, 0x0C, 0x0A, 0x3B, 0x0A },
330 { STV0900_32APSK_34, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A,
331 0x0A, 0x0A, 0x0A, 0x0A, 0x0A },
332 { STV0900_32APSK_45, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A,
333 0x0A, 0x0A, 0x0A, 0x0A, 0x0A },
334 { STV0900_32APSK_56, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A,
335 0x0A, 0x0A, 0x0A, 0x0A, 0x0A },
336 { STV0900_32APSK_89, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A,
337 0x0A, 0x0A, 0x0A, 0x0A, 0x0A },
338 { STV0900_32APSK_910, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A,
339 0x0A, 0x0A, 0x0A, 0x0A, 0x0A }
340};
341
342static const
343struct stv0900_car_loop_optim FE_STV0900_S2LowQPCarLoopCut30[3] = {
344 /*Modcod 2MPon 2MPoff 5MPon 5MPoff 10MPon
345 10MPoff 20MPon 20MPoff 30MPon 30MPoff*/
346 { STV0900_QPSK_14, 0x0C, 0x3C, 0x0B, 0x3C, 0x2A,
347 0x2C, 0x2A, 0x1C, 0x3A, 0x3B },
348 { STV0900_QPSK_13, 0x0C, 0x3C, 0x0B, 0x3C, 0x2A,
349 0x2C, 0x3A, 0x0C, 0x3A, 0x2B },
350 { STV0900_QPSK_25, 0x1C, 0x3C, 0x1B, 0x3C, 0x3A,
351 0x1C, 0x3A, 0x3B, 0x3A, 0x2B }
352};
353
354static const struct stv0900_short_frames_car_loop_optim_vs_mod
355FE_STV0900_S2ShortCarLoopCut30[4] = {
356 /*Mod 2Mcut3.0 5Mcut3.0 10Mcut3.0 20Mcut3.0 30Mcut3.0*/
357 { STV0900_QPSK, 0x2C, 0x2B, 0x0B, 0x0B, 0x3A },
358 { STV0900_8PSK, 0x3B, 0x0B, 0x2A, 0x0A, 0x39 },
359 { STV0900_16APSK, 0x1B, 0x1B, 0x1B, 0x3A, 0x2A },
360 { STV0900_32APSK, 0x1B, 0x1B, 0x1B, 0x3A, 0x2A },
361
218}; 362};
219 363
220static const u16 STV0900_InitVal[182][2] = { 364static const u16 STV0900_InitVal[181][2] = {
221 { R0900_OUTCFG , 0x00 }, 365 { R0900_OUTCFG , 0x00 },
222 { R0900_MODECFG , 0xff },
223 { R0900_AGCRF1CFG , 0x11 }, 366 { R0900_AGCRF1CFG , 0x11 },
224 { R0900_AGCRF2CFG , 0x13 }, 367 { R0900_AGCRF2CFG , 0x13 },
225 { R0900_TSGENERAL1X , 0x14 }, 368 { R0900_TSGENERAL1X , 0x14 },
@@ -381,7 +524,7 @@ static const u16 STV0900_InitVal[182][2] = {
381 { R0900_GAINLLR_NF15 , 0x1A }, 524 { R0900_GAINLLR_NF15 , 0x1A },
382 { R0900_GAINLLR_NF16 , 0x1F }, 525 { R0900_GAINLLR_NF16 , 0x1F },
383 { R0900_GAINLLR_NF17 , 0x21 }, 526 { R0900_GAINLLR_NF17 , 0x21 },
384 { R0900_RCCFGH , 0x20 }, 527 { R0900_RCCFG2 , 0x20 },
385 { R0900_P1_FECM , 0x01 }, /*disable DSS modes*/ 528 { R0900_P1_FECM , 0x01 }, /*disable DSS modes*/
386 { R0900_P2_FECM , 0x01 }, /*disable DSS modes*/ 529 { R0900_P2_FECM , 0x01 }, /*disable DSS modes*/
387 { R0900_P1_PRVIT , 0x2F }, /*disable puncture rate 6/7*/ 530 { R0900_P1_PRVIT , 0x2F }, /*disable puncture rate 6/7*/
diff --git a/drivers/media/dvb/frontends/stv0900_priv.h b/drivers/media/dvb/frontends/stv0900_priv.h
index 5ed7a145c7d3..d8ba8a984abe 100644
--- a/drivers/media/dvb/frontends/stv0900_priv.h
+++ b/drivers/media/dvb/frontends/stv0900_priv.h
@@ -46,22 +46,6 @@
46#define FALSE (!TRUE) 46#define FALSE (!TRUE)
47#endif 47#endif
48 48
49#define dmd_reg(a, b, c) \
50 do { \
51 a = 0; \
52 switch (demod) { \
53 case STV0900_DEMOD_1: \
54 default: \
55 a = b; \
56 break; \
57 case STV0900_DEMOD_2: \
58 a = c; \
59 break; \
60 } \
61 } while (0)
62
63static int stvdebug;
64
65#define dprintk(args...) \ 49#define dprintk(args...) \
66 do { \ 50 do { \
67 if (stvdebug) \ 51 if (stvdebug) \
@@ -70,6 +54,8 @@ static int stvdebug;
70 54
71#define STV0900_MAXLOOKUPSIZE 500 55#define STV0900_MAXLOOKUPSIZE 500
72#define STV0900_BLIND_SEARCH_AGC2_TH 700 56#define STV0900_BLIND_SEARCH_AGC2_TH 700
57#define STV0900_BLIND_SEARCH_AGC2_TH_CUT30 1400
58#define IQPOWER_THRESHOLD 30
73 59
74/* One point of the lookup table */ 60/* One point of the lookup table */
75struct stv000_lookpoint { 61struct stv000_lookpoint {
@@ -263,14 +249,14 @@ struct stv0900_init_params{
263 int tuner1_adc; 249 int tuner1_adc;
264 250
265 /* IQ from the tuner1 to the demod */ 251 /* IQ from the tuner1 to the demod */
266 enum stv0900_iq_inversion tun1_iq_inversion; 252 enum stv0900_iq_inversion tun1_iq_inv;
267 enum fe_stv0900_clock_type path2_ts_clock; 253 enum fe_stv0900_clock_type path2_ts_clock;
268 254
269 u8 tun2_maddress; 255 u8 tun2_maddress;
270 int tuner2_adc; 256 int tuner2_adc;
271 257
272 /* IQ from the tuner2 to the demod */ 258 /* IQ from the tuner2 to the demod */
273 enum stv0900_iq_inversion tun2_iq_inversion; 259 enum stv0900_iq_inversion tun2_iq_inv;
274 struct stv0900_reg *ts_config; 260 struct stv0900_reg *ts_config;
275}; 261};
276 262
@@ -300,7 +286,7 @@ struct stv0900_signal_info {
300 enum fe_stv0900_modcode modcode; 286 enum fe_stv0900_modcode modcode;
301 enum fe_stv0900_modulation modulation; 287 enum fe_stv0900_modulation modulation;
302 enum fe_stv0900_pilot pilot; 288 enum fe_stv0900_pilot pilot;
303 enum fe_stv0900_frame_length frame_length; 289 enum fe_stv0900_frame_length frame_len;
304 enum stv0900_iq_inversion spectrum; 290 enum stv0900_iq_inversion spectrum;
305 enum fe_stv0900_rolloff rolloff; 291 enum fe_stv0900_rolloff rolloff;
306 292
@@ -318,47 +304,25 @@ struct stv0900_internal{
318 /* Demodulator use for single demod or for dual demod) */ 304 /* Demodulator use for single demod or for dual demod) */
319 enum fe_stv0900_demod_mode demod_mode; 305 enum fe_stv0900_demod_mode demod_mode;
320 306
321 /*Demod 1*/ 307 /*Demods */
322 s32 tuner1_freq; 308 s32 freq[2];
323 s32 tuner1_bw; 309 s32 bw[2];
324 s32 dmd1_symbol_rate; 310 s32 symbol_rate[2];
325 s32 dmd1_srch_range; 311 s32 srch_range[2];
326 312
327 /* algorithm for search Blind, Cold or Warm*/ 313 /* algorithm for search Blind, Cold or Warm*/
328 enum fe_stv0900_search_algo dmd1_srch_algo; 314 enum fe_stv0900_search_algo srch_algo[2];
329 /* search standard: Auto, DVBS1/DSS only or DVBS2 only*/ 315 /* search standard: Auto, DVBS1/DSS only or DVBS2 only*/
330 enum fe_stv0900_search_standard dmd1_srch_standard; 316 enum fe_stv0900_search_standard srch_standard[2];
331 /* inversion search : auto, auto norma first, normal or inverted */ 317 /* inversion search : auto, auto norma first, normal or inverted */
332 enum fe_stv0900_search_iq dmd1_srch_iq_inv; 318 enum fe_stv0900_search_iq srch_iq_inv[2];
333 enum fe_stv0900_modcode dmd1_modcode; 319 enum fe_stv0900_modcode modcode[2];
334 enum fe_stv0900_modulation dmd1_modulation; 320 enum fe_stv0900_modulation modulation[2];
335 enum fe_stv0900_fec dmd1_fec; 321 enum fe_stv0900_fec fec[2];
336
337 struct stv0900_signal_info dmd1_rslts;
338 enum fe_stv0900_signal_type dmd1_state;
339 322
340 enum fe_stv0900_error dmd1_err; 323 struct stv0900_signal_info result[2];
324 enum fe_stv0900_error err[2];
341 325
342 /*Demod 2*/
343 s32 tuner2_freq;
344 s32 tuner2_bw;
345 s32 dmd2_symbol_rate;
346 s32 dmd2_srch_range;
347
348 enum fe_stv0900_search_algo dmd2_srch_algo;
349 enum fe_stv0900_search_standard dmd2_srch_stndrd;
350 /* inversion search : auto, auto normal first, normal or inverted */
351 enum fe_stv0900_search_iq dmd2_srch_iq_inv;
352 enum fe_stv0900_modcode dmd2_modcode;
353 enum fe_stv0900_modulation dmd2_modulation;
354 enum fe_stv0900_fec dmd2_fec;
355
356 /* results of the search*/
357 struct stv0900_signal_info dmd2_rslts;
358 /* current state of the search algorithm */
359 enum fe_stv0900_signal_type dmd2_state;
360
361 enum fe_stv0900_error dmd2_err;
362 326
363 struct i2c_adapter *i2c_adap; 327 struct i2c_adapter *i2c_adap;
364 u8 i2c_addr; 328 u8 i2c_addr;
@@ -379,6 +343,8 @@ struct stv0900_state {
379 int demod; 343 int demod;
380}; 344};
381 345
346extern int stvdebug;
347
382extern s32 ge2comp(s32 a, s32 width); 348extern s32 ge2comp(s32 a, s32 width);
383 349
384extern void stv0900_write_reg(struct stv0900_internal *i_params, 350extern void stv0900_write_reg(struct stv0900_internal *i_params,
@@ -418,13 +384,14 @@ extern u8 stv0900_get_optim_short_carr_loop(s32 srate,
418extern void stv0900_stop_all_s2_modcod(struct stv0900_internal *i_params, 384extern void stv0900_stop_all_s2_modcod(struct stv0900_internal *i_params,
419 enum fe_stv0900_demod_num demod); 385 enum fe_stv0900_demod_num demod);
420 386
421extern void stv0900_activate_s2_modcode(struct stv0900_internal *i_params, 387extern void stv0900_activate_s2_modcod(struct stv0900_internal *i_params,
422 enum fe_stv0900_demod_num demod); 388 enum fe_stv0900_demod_num demod);
423 389
424extern void stv0900_activate_s2_modcode_single(struct stv0900_internal *i_params, 390extern void stv0900_activate_s2_modcod_single(struct stv0900_internal *i_params,
425 enum fe_stv0900_demod_num demod); 391 enum fe_stv0900_demod_num demod);
426 392
427extern enum fe_stv0900_tracking_standard stv0900_get_standard(struct dvb_frontend *fe, 393extern enum
394fe_stv0900_tracking_standard stv0900_get_standard(struct dvb_frontend *fe,
428 enum fe_stv0900_demod_num demod); 395 enum fe_stv0900_demod_num demod);
429 396
430#endif 397#endif
diff --git a/drivers/media/dvb/frontends/stv0900_reg.h b/drivers/media/dvb/frontends/stv0900_reg.h
index 264f9cf9a17e..7b8edf192e97 100644
--- a/drivers/media/dvb/frontends/stv0900_reg.h
+++ b/drivers/media/dvb/frontends/stv0900_reg.h
@@ -14,7 +14,7 @@
14 * 14 *
15 * This program is distributed in the hope that it will be useful, 15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * 18 *
19 * GNU General Public License for more details. 19 * GNU General Public License for more details.
20 * 20 *
@@ -26,3762 +26,3950 @@
26#ifndef STV0900_REG_H 26#ifndef STV0900_REG_H
27#define STV0900_REG_H 27#define STV0900_REG_H
28 28
29extern s32 shiftx(s32 x, int demod, s32 shift);
30
31#define REGx(x) shiftx(x, demod, 0x200)
32#define FLDx(x) shiftx(x, demod, 0x2000000)
33
29/*MID*/ 34/*MID*/
30#define R0900_MID 0xf100 35#define R0900_MID 0xf100
31#define F0900_MCHIP_IDENT 0xf10000f0 36#define F0900_MCHIP_IDENT 0xf10000f0
32#define F0900_MRELEASE 0xf100000f 37#define F0900_MRELEASE 0xf100000f
33 38
34/*DACR1*/ 39/*DACR1*/
35#define R0900_DACR1 0xf113 40#define R0900_DACR1 0xf113
36#define F0900_DAC_MODE 0xf11300e0 41#define F0900_DAC_MODE 0xf11300e0
37#define F0900_DAC_VALUE1 0xf113000f 42#define F0900_DAC_VALUE1 0xf113000f
38 43
39/*DACR2*/ 44/*DACR2*/
40#define R0900_DACR2 0xf114 45#define R0900_DACR2 0xf114
41#define F0900_DAC_VALUE0 0xf11400ff 46#define F0900_DAC_VALUE0 0xf11400ff
42 47
43/*OUTCFG*/ 48/*OUTCFG*/
44#define R0900_OUTCFG 0xf11c 49#define R0900_OUTCFG 0xf11c
45#define F0900_INV_DATA6 0xf11c0080 50#define F0900_OUTSERRS1_HZ 0xf11c0040
46#define F0900_OUTSERRS1_HZ 0xf11c0040 51#define F0900_OUTSERRS2_HZ 0xf11c0020
47#define F0900_OUTSERRS2_HZ 0xf11c0020 52#define F0900_OUTSERRS3_HZ 0xf11c0010
48#define F0900_OUTSERRS3_HZ 0xf11c0010 53#define F0900_OUTPARRS3_HZ 0xf11c0008
49#define F0900_OUTPARRS3_HZ 0xf11c0008
50#define F0900_OUTHZ3_CONTROL 0xf11c0007
51
52/*MODECFG*/
53#define R0900_MODECFG 0xf11d
54#define F0900_FECSPY_SEL_2 0xf11d0020
55#define F0900_HWARE_SEL_2 0xf11d0010
56#define F0900_PKTDEL_SEL_2 0xf11d0008
57#define F0900_DISEQC_SEL_2 0xf11d0004
58#define F0900_VIT_SEL_2 0xf11d0002
59#define F0900_DEMOD_SEL_2 0xf11d0001
60 54
61/*IRQSTATUS3*/ 55/*IRQSTATUS3*/
62#define R0900_IRQSTATUS3 0xf120 56#define R0900_IRQSTATUS3 0xf120
63#define F0900_SPLL_LOCK 0xf1200020 57#define F0900_SPLL_LOCK 0xf1200020
64#define F0900_SSTREAM_LCK_3 0xf1200010 58#define F0900_SSTREAM_LCK_3 0xf1200010
65#define F0900_SSTREAM_LCK_2 0xf1200008 59#define F0900_SSTREAM_LCK_2 0xf1200008
66#define F0900_SSTREAM_LCK_1 0xf1200004 60#define F0900_SSTREAM_LCK_1 0xf1200004
67#define F0900_SDVBS1_PRF_2 0xf1200002 61#define F0900_SDVBS1_PRF_2 0xf1200002
68#define F0900_SDVBS1_PRF_1 0xf1200001 62#define F0900_SDVBS1_PRF_1 0xf1200001
69 63
70/*IRQSTATUS2*/ 64/*IRQSTATUS2*/
71#define R0900_IRQSTATUS2 0xf121 65#define R0900_IRQSTATUS2 0xf121
72#define F0900_SSPY_ENDSIM_3 0xf1210080 66#define F0900_SSPY_ENDSIM_3 0xf1210080
73#define F0900_SSPY_ENDSIM_2 0xf1210040 67#define F0900_SSPY_ENDSIM_2 0xf1210040
74#define F0900_SSPY_ENDSIM_1 0xf1210020 68#define F0900_SSPY_ENDSIM_1 0xf1210020
75#define F0900_SPKTDEL_ERROR_2 0xf1210010 69#define F0900_SPKTDEL_ERROR_2 0xf1210010
76#define F0900_SPKTDEL_LOCKB_2 0xf1210008 70#define F0900_SPKTDEL_LOCKB_2 0xf1210008
77#define F0900_SPKTDEL_LOCK_2 0xf1210004 71#define F0900_SPKTDEL_LOCK_2 0xf1210004
78#define F0900_SPKTDEL_ERROR_1 0xf1210002 72#define F0900_SPKTDEL_ERROR_1 0xf1210002
79#define F0900_SPKTDEL_LOCKB_1 0xf1210001 73#define F0900_SPKTDEL_LOCKB_1 0xf1210001
80 74
81/*IRQSTATUS1*/ 75/*IRQSTATUS1*/
82#define R0900_IRQSTATUS1 0xf122 76#define R0900_IRQSTATUS1 0xf122
83#define F0900_SPKTDEL_LOCK_1 0xf1220080 77#define F0900_SPKTDEL_LOCK_1 0xf1220080
84#define F0900_SEXTPINB2 0xf1220040 78#define F0900_SDEMOD_LOCKB_2 0xf1220004
85#define F0900_SEXTPIN2 0xf1220020 79#define F0900_SDEMOD_LOCK_2 0xf1220002
86#define F0900_SEXTPINB1 0xf1220010 80#define F0900_SDEMOD_IRQ_2 0xf1220001
87#define F0900_SEXTPIN1 0xf1220008
88#define F0900_SDEMOD_LOCKB_2 0xf1220004
89#define F0900_SDEMOD_LOCK_2 0xf1220002
90#define F0900_SDEMOD_IRQ_2 0xf1220001
91 81
92/*IRQSTATUS0*/ 82/*IRQSTATUS0*/
93#define R0900_IRQSTATUS0 0xf123 83#define R0900_IRQSTATUS0 0xf123
94#define F0900_SDEMOD_LOCKB_1 0xf1230080 84#define F0900_SDEMOD_LOCKB_1 0xf1230080
95#define F0900_SDEMOD_LOCK_1 0xf1230040 85#define F0900_SDEMOD_LOCK_1 0xf1230040
96#define F0900_SDEMOD_IRQ_1 0xf1230020 86#define F0900_SDEMOD_IRQ_1 0xf1230020
97#define F0900_SBCH_ERRFLAG 0xf1230010 87#define F0900_SBCH_ERRFLAG 0xf1230010
98#define F0900_SDISEQC2RX_IRQ 0xf1230008 88#define F0900_SDISEQC2RX_IRQ 0xf1230008
99#define F0900_SDISEQC2TX_IRQ 0xf1230004 89#define F0900_SDISEQC2TX_IRQ 0xf1230004
100#define F0900_SDISEQC1RX_IRQ 0xf1230002 90#define F0900_SDISEQC1RX_IRQ 0xf1230002
101#define F0900_SDISEQC1TX_IRQ 0xf1230001 91#define F0900_SDISEQC1TX_IRQ 0xf1230001
102 92
103/*IRQMASK3*/ 93/*IRQMASK3*/
104#define R0900_IRQMASK3 0xf124 94#define R0900_IRQMASK3 0xf124
105#define F0900_MPLL_LOCK 0xf1240020 95#define F0900_MPLL_LOCK 0xf1240020
106#define F0900_MSTREAM_LCK_3 0xf1240010 96#define F0900_MSTREAM_LCK_3 0xf1240010
107#define F0900_MSTREAM_LCK_2 0xf1240008 97#define F0900_MSTREAM_LCK_2 0xf1240008
108#define F0900_MSTREAM_LCK_1 0xf1240004 98#define F0900_MSTREAM_LCK_1 0xf1240004
109#define F0900_MDVBS1_PRF_2 0xf1240002 99#define F0900_MDVBS1_PRF_2 0xf1240002
110#define F0900_MDVBS1_PRF_1 0xf1240001 100#define F0900_MDVBS1_PRF_1 0xf1240001
111 101
112/*IRQMASK2*/ 102/*IRQMASK2*/
113#define R0900_IRQMASK2 0xf125 103#define R0900_IRQMASK2 0xf125
114#define F0900_MSPY_ENDSIM_3 0xf1250080 104#define F0900_MSPY_ENDSIM_3 0xf1250080
115#define F0900_MSPY_ENDSIM_2 0xf1250040 105#define F0900_MSPY_ENDSIM_2 0xf1250040
116#define F0900_MSPY_ENDSIM_1 0xf1250020 106#define F0900_MSPY_ENDSIM_1 0xf1250020
117#define F0900_MPKTDEL_ERROR_2 0xf1250010 107#define F0900_MPKTDEL_ERROR_2 0xf1250010
118#define F0900_MPKTDEL_LOCKB_2 0xf1250008 108#define F0900_MPKTDEL_LOCKB_2 0xf1250008
119#define F0900_MPKTDEL_LOCK_2 0xf1250004 109#define F0900_MPKTDEL_LOCK_2 0xf1250004
120#define F0900_MPKTDEL_ERROR_1 0xf1250002 110#define F0900_MPKTDEL_ERROR_1 0xf1250002
121#define F0900_MPKTDEL_LOCKB_1 0xf1250001 111#define F0900_MPKTDEL_LOCKB_1 0xf1250001
122 112
123/*IRQMASK1*/ 113/*IRQMASK1*/
124#define R0900_IRQMASK1 0xf126 114#define R0900_IRQMASK1 0xf126
125#define F0900_MPKTDEL_LOCK_1 0xf1260080 115#define F0900_MPKTDEL_LOCK_1 0xf1260080
126#define F0900_MEXTPINB2 0xf1260040 116#define F0900_MEXTPINB2 0xf1260040
127#define F0900_MEXTPIN2 0xf1260020 117#define F0900_MEXTPIN2 0xf1260020
128#define F0900_MEXTPINB1 0xf1260010 118#define F0900_MEXTPINB1 0xf1260010
129#define F0900_MEXTPIN1 0xf1260008 119#define F0900_MEXTPIN1 0xf1260008
130#define F0900_MDEMOD_LOCKB_2 0xf1260004 120#define F0900_MDEMOD_LOCKB_2 0xf1260004
131#define F0900_MDEMOD_LOCK_2 0xf1260002 121#define F0900_MDEMOD_LOCK_2 0xf1260002
132#define F0900_MDEMOD_IRQ_2 0xf1260001 122#define F0900_MDEMOD_IRQ_2 0xf1260001
133 123
134/*IRQMASK0*/ 124/*IRQMASK0*/
135#define R0900_IRQMASK0 0xf127 125#define R0900_IRQMASK0 0xf127
136#define F0900_MDEMOD_LOCKB_1 0xf1270080 126#define F0900_MDEMOD_LOCKB_1 0xf1270080
137#define F0900_MDEMOD_LOCK_1 0xf1270040 127#define F0900_MDEMOD_LOCK_1 0xf1270040
138#define F0900_MDEMOD_IRQ_1 0xf1270020 128#define F0900_MDEMOD_IRQ_1 0xf1270020
139#define F0900_MBCH_ERRFLAG 0xf1270010 129#define F0900_MBCH_ERRFLAG 0xf1270010
140#define F0900_MDISEQC2RX_IRQ 0xf1270008 130#define F0900_MDISEQC2RX_IRQ 0xf1270008
141#define F0900_MDISEQC2TX_IRQ 0xf1270004 131#define F0900_MDISEQC2TX_IRQ 0xf1270004
142#define F0900_MDISEQC1RX_IRQ 0xf1270002 132#define F0900_MDISEQC1RX_IRQ 0xf1270002
143#define F0900_MDISEQC1TX_IRQ 0xf1270001 133#define F0900_MDISEQC1TX_IRQ 0xf1270001
144 134
145/*I2CCFG*/ 135/*I2CCFG*/
146#define R0900_I2CCFG 0xf129 136#define R0900_I2CCFG 0xf129
147#define F0900_I2C2_FASTMODE 0xf1290080 137#define F0900_I2C_FASTMODE 0xf1290008
148#define F0900_STATUS_WR2 0xf1290040 138#define F0900_I2CADDR_INC 0xf1290003
149#define F0900_I2C2ADDR_INC 0xf1290030
150#define F0900_I2C_FASTMODE 0xf1290008
151#define F0900_STATUS_WR 0xf1290004
152#define F0900_I2CADDR_INC 0xf1290003
153 139
154/*P1_I2CRPT*/ 140/*P1_I2CRPT*/
155#define R0900_P1_I2CRPT 0xf12a 141#define R0900_P1_I2CRPT 0xf12a
156#define F0900_P1_I2CT_ON 0xf12a0080 142#define I2CRPT shiftx(R0900_P1_I2CRPT, demod, -1)
157#define F0900_P1_ENARPT_LEVEL 0xf12a0070 143#define F0900_P1_I2CT_ON 0xf12a0080
158#define F0900_P1_SCLT_DELAY 0xf12a0008 144#define I2CT_ON shiftx(F0900_P1_I2CT_ON, demod, -0x10000)
159#define F0900_P1_STOP_ENABLE 0xf12a0004 145#define F0900_P1_ENARPT_LEVEL 0xf12a0070
160#define F0900_P1_STOP_SDAT2SDA 0xf12a0002 146#define F0900_P1_SCLT_DELAY 0xf12a0008
147#define F0900_P1_STOP_ENABLE 0xf12a0004
148#define F0900_P1_STOP_SDAT2SDA 0xf12a0002
161 149
162/*P2_I2CRPT*/ 150/*P2_I2CRPT*/
163#define R0900_P2_I2CRPT 0xf12b 151#define R0900_P2_I2CRPT 0xf12b
164#define F0900_P2_I2CT_ON 0xf12b0080 152#define F0900_P2_I2CT_ON 0xf12b0080
165#define F0900_P2_ENARPT_LEVEL 0xf12b0070 153#define F0900_P2_ENARPT_LEVEL 0xf12b0070
166#define F0900_P2_SCLT_DELAY 0xf12b0008 154#define F0900_P2_SCLT_DELAY 0xf12b0008
167#define F0900_P2_STOP_ENABLE 0xf12b0004 155#define F0900_P2_STOP_ENABLE 0xf12b0004
168#define F0900_P2_STOP_SDAT2SDA 0xf12b0002 156#define F0900_P2_STOP_SDAT2SDA 0xf12b0002
157
158/*IOPVALUE6*/
159#define R0900_IOPVALUE6 0xf138
160#define F0900_VSCL 0xf1380004
161#define F0900_VSDA 0xf1380002
162#define F0900_VDATA3_0 0xf1380001
163
164/*IOPVALUE5*/
165#define R0900_IOPVALUE5 0xf139
166#define F0900_VDATA3_1 0xf1390080
167#define F0900_VDATA3_2 0xf1390040
168#define F0900_VDATA3_3 0xf1390020
169#define F0900_VDATA3_4 0xf1390010
170#define F0900_VDATA3_5 0xf1390008
171#define F0900_VDATA3_6 0xf1390004
172#define F0900_VDATA3_7 0xf1390002
173#define F0900_VCLKOUT3 0xf1390001
174
175/*IOPVALUE4*/
176#define R0900_IOPVALUE4 0xf13a
177#define F0900_VSTROUT3 0xf13a0080
178#define F0900_VDPN3 0xf13a0040
179#define F0900_VERROR3 0xf13a0020
180#define F0900_VDATA2_7 0xf13a0010
181#define F0900_VCLKOUT2 0xf13a0008
182#define F0900_VSTROUT2 0xf13a0004
183#define F0900_VDPN2 0xf13a0002
184#define F0900_VERROR2 0xf13a0001
185
186/*IOPVALUE3*/
187#define R0900_IOPVALUE3 0xf13b
188#define F0900_VDATA1_7 0xf13b0080
189#define F0900_VCLKOUT1 0xf13b0040
190#define F0900_VSTROUT1 0xf13b0020
191#define F0900_VDPN1 0xf13b0010
192#define F0900_VERROR1 0xf13b0008
193#define F0900_VCLKOUT27 0xf13b0004
194#define F0900_VDISEQCOUT2 0xf13b0002
195#define F0900_VSCLT2 0xf13b0001
196
197/*IOPVALUE2*/
198#define R0900_IOPVALUE2 0xf13c
199#define F0900_VSDAT2 0xf13c0080
200#define F0900_VAGCRF2 0xf13c0040
201#define F0900_VDISEQCOUT1 0xf13c0020
202#define F0900_VSCLT1 0xf13c0010
203#define F0900_VSDAT1 0xf13c0008
204#define F0900_VAGCRF1 0xf13c0004
205#define F0900_VDIRCLK 0xf13c0002
206#define F0900_VSTDBY 0xf13c0001
207
208/*IOPVALUE1*/
209#define R0900_IOPVALUE1 0xf13d
210#define F0900_VCS1 0xf13d0080
211#define F0900_VCS0 0xf13d0040
212#define F0900_VGPIO13 0xf13d0020
213#define F0900_VGPIO12 0xf13d0010
214#define F0900_VGPIO11 0xf13d0008
215#define F0900_VGPIO10 0xf13d0004
216#define F0900_VGPIO9 0xf13d0002
217#define F0900_VGPIO8 0xf13d0001
218
219/*IOPVALUE0*/
220#define R0900_IOPVALUE0 0xf13e
221#define F0900_VGPIO7 0xf13e0080
222#define F0900_VGPIO6 0xf13e0040
223#define F0900_VGPIO5 0xf13e0020
224#define F0900_VGPIO4 0xf13e0010
225#define F0900_VGPIO3 0xf13e0008
226#define F0900_VGPIO2 0xf13e0004
227#define F0900_VGPIO1 0xf13e0002
228#define F0900_VCLKI2 0xf13e0001
169 229
170/*CLKI2CFG*/ 230/*CLKI2CFG*/
171#define R0900_CLKI2CFG 0xf140 231#define R0900_CLKI2CFG 0xf140
172#define F0900_CLKI2_OPD 0xf1400080 232#define F0900_CLKI2_OPD 0xf1400080
173#define F0900_CLKI2_CONFIG 0xf140007e 233#define F0900_CLKI2_CONFIG 0xf140007e
174#define F0900_CLKI2_XOR 0xf1400001 234#define F0900_CLKI2_XOR 0xf1400001
175 235
176/*GPIO1CFG*/ 236/*GPIO1CFG*/
177#define R0900_GPIO1CFG 0xf141 237#define R0900_GPIO1CFG 0xf141
178#define F0900_GPIO1_OPD 0xf1410080 238#define F0900_GPIO1_OPD 0xf1410080
179#define F0900_GPIO1_CONFIG 0xf141007e 239#define F0900_GPIO1_CONFIG 0xf141007e
180#define F0900_GPIO1_XOR 0xf1410001 240#define F0900_GPIO1_XOR 0xf1410001
181 241
182/*GPIO2CFG*/ 242/*GPIO2CFG*/
183#define R0900_GPIO2CFG 0xf142 243#define R0900_GPIO2CFG 0xf142
184#define F0900_GPIO2_OPD 0xf1420080 244#define F0900_GPIO2_OPD 0xf1420080
185#define F0900_GPIO2_CONFIG 0xf142007e 245#define F0900_GPIO2_CONFIG 0xf142007e
186#define F0900_GPIO2_XOR 0xf1420001 246#define F0900_GPIO2_XOR 0xf1420001
187 247
188/*GPIO3CFG*/ 248/*GPIO3CFG*/
189#define R0900_GPIO3CFG 0xf143 249#define R0900_GPIO3CFG 0xf143
190#define F0900_GPIO3_OPD 0xf1430080 250#define F0900_GPIO3_OPD 0xf1430080
191#define F0900_GPIO3_CONFIG 0xf143007e 251#define F0900_GPIO3_CONFIG 0xf143007e
192#define F0900_GPIO3_XOR 0xf1430001 252#define F0900_GPIO3_XOR 0xf1430001
193 253
194/*GPIO4CFG*/ 254/*GPIO4CFG*/
195#define R0900_GPIO4CFG 0xf144 255#define R0900_GPIO4CFG 0xf144
196#define F0900_GPIO4_OPD 0xf1440080 256#define F0900_GPIO4_OPD 0xf1440080
197#define F0900_GPIO4_CONFIG 0xf144007e 257#define F0900_GPIO4_CONFIG 0xf144007e
198#define F0900_GPIO4_XOR 0xf1440001 258#define F0900_GPIO4_XOR 0xf1440001
199 259
200/*GPIO5CFG*/ 260/*GPIO5CFG*/
201#define R0900_GPIO5CFG 0xf145 261#define R0900_GPIO5CFG 0xf145
202#define F0900_GPIO5_OPD 0xf1450080 262#define F0900_GPIO5_OPD 0xf1450080
203#define F0900_GPIO5_CONFIG 0xf145007e 263#define F0900_GPIO5_CONFIG 0xf145007e
204#define F0900_GPIO5_XOR 0xf1450001 264#define F0900_GPIO5_XOR 0xf1450001
205 265
206/*GPIO6CFG*/ 266/*GPIO6CFG*/
207#define R0900_GPIO6CFG 0xf146 267#define R0900_GPIO6CFG 0xf146
208#define F0900_GPIO6_OPD 0xf1460080 268#define F0900_GPIO6_OPD 0xf1460080
209#define F0900_GPIO6_CONFIG 0xf146007e 269#define F0900_GPIO6_CONFIG 0xf146007e
210#define F0900_GPIO6_XOR 0xf1460001 270#define F0900_GPIO6_XOR 0xf1460001
211 271
212/*GPIO7CFG*/ 272/*GPIO7CFG*/
213#define R0900_GPIO7CFG 0xf147 273#define R0900_GPIO7CFG 0xf147
214#define F0900_GPIO7_OPD 0xf1470080 274#define F0900_GPIO7_OPD 0xf1470080
215#define F0900_GPIO7_CONFIG 0xf147007e 275#define F0900_GPIO7_CONFIG 0xf147007e
216#define F0900_GPIO7_XOR 0xf1470001 276#define F0900_GPIO7_XOR 0xf1470001
217 277
218/*GPIO8CFG*/ 278/*GPIO8CFG*/
219#define R0900_GPIO8CFG 0xf148 279#define R0900_GPIO8CFG 0xf148
220#define F0900_GPIO8_OPD 0xf1480080 280#define F0900_GPIO8_OPD 0xf1480080
221#define F0900_GPIO8_CONFIG 0xf148007e 281#define F0900_GPIO8_CONFIG 0xf148007e
222#define F0900_GPIO8_XOR 0xf1480001 282#define F0900_GPIO8_XOR 0xf1480001
223 283
224/*GPIO9CFG*/ 284/*GPIO9CFG*/
225#define R0900_GPIO9CFG 0xf149 285#define R0900_GPIO9CFG 0xf149
226#define F0900_GPIO9_OPD 0xf1490080 286#define F0900_GPIO9_OPD 0xf1490080
227#define F0900_GPIO9_CONFIG 0xf149007e 287#define F0900_GPIO9_CONFIG 0xf149007e
228#define F0900_GPIO9_XOR 0xf1490001 288#define F0900_GPIO9_XOR 0xf1490001
229 289
230/*GPIO10CFG*/ 290/*GPIO10CFG*/
231#define R0900_GPIO10CFG 0xf14a 291#define R0900_GPIO10CFG 0xf14a
232#define F0900_GPIO10_OPD 0xf14a0080 292#define F0900_GPIO10_OPD 0xf14a0080
233#define F0900_GPIO10_CONFIG 0xf14a007e 293#define F0900_GPIO10_CONFIG 0xf14a007e
234#define F0900_GPIO10_XOR 0xf14a0001 294#define F0900_GPIO10_XOR 0xf14a0001
235 295
236/*GPIO11CFG*/ 296/*GPIO11CFG*/
237#define R0900_GPIO11CFG 0xf14b 297#define R0900_GPIO11CFG 0xf14b
238#define F0900_GPIO11_OPD 0xf14b0080 298#define F0900_GPIO11_OPD 0xf14b0080
239#define F0900_GPIO11_CONFIG 0xf14b007e 299#define F0900_GPIO11_CONFIG 0xf14b007e
240#define F0900_GPIO11_XOR 0xf14b0001 300#define F0900_GPIO11_XOR 0xf14b0001
241 301
242/*GPIO12CFG*/ 302/*GPIO12CFG*/
243#define R0900_GPIO12CFG 0xf14c 303#define R0900_GPIO12CFG 0xf14c
244#define F0900_GPIO12_OPD 0xf14c0080 304#define F0900_GPIO12_OPD 0xf14c0080
245#define F0900_GPIO12_CONFIG 0xf14c007e 305#define F0900_GPIO12_CONFIG 0xf14c007e
246#define F0900_GPIO12_XOR 0xf14c0001 306#define F0900_GPIO12_XOR 0xf14c0001
247 307
248/*GPIO13CFG*/ 308/*GPIO13CFG*/
249#define R0900_GPIO13CFG 0xf14d 309#define R0900_GPIO13CFG 0xf14d
250#define F0900_GPIO13_OPD 0xf14d0080 310#define F0900_GPIO13_OPD 0xf14d0080
251#define F0900_GPIO13_CONFIG 0xf14d007e 311#define F0900_GPIO13_CONFIG 0xf14d007e
252#define F0900_GPIO13_XOR 0xf14d0001 312#define F0900_GPIO13_XOR 0xf14d0001
253 313
254/*CS0CFG*/ 314/*CS0CFG*/
255#define R0900_CS0CFG 0xf14e 315#define R0900_CS0CFG 0xf14e
256#define F0900_CS0_OPD 0xf14e0080 316#define F0900_CS0_OPD 0xf14e0080
257#define F0900_CS0_CONFIG 0xf14e007e 317#define F0900_CS0_CONFIG 0xf14e007e
258#define F0900_CS0_XOR 0xf14e0001 318#define F0900_CS0_XOR 0xf14e0001
259 319
260/*CS1CFG*/ 320/*CS1CFG*/
261#define R0900_CS1CFG 0xf14f 321#define R0900_CS1CFG 0xf14f
262#define F0900_CS1_OPD 0xf14f0080 322#define F0900_CS1_OPD 0xf14f0080
263#define F0900_CS1_CONFIG 0xf14f007e 323#define F0900_CS1_CONFIG 0xf14f007e
264#define F0900_CS1_XOR 0xf14f0001 324#define F0900_CS1_XOR 0xf14f0001
265 325
266/*STDBYCFG*/ 326/*STDBYCFG*/
267#define R0900_STDBYCFG 0xf150 327#define R0900_STDBYCFG 0xf150
268#define F0900_STDBY_OPD 0xf1500080 328#define F0900_STDBY_OPD 0xf1500080
269#define F0900_STDBY_CONFIG 0xf150007e 329#define F0900_STDBY_CONFIG 0xf150007e
270#define F0900_STBDY_XOR 0xf1500001 330#define F0900_STBDY_XOR 0xf1500001
271 331
272/*DIRCLKCFG*/ 332/*DIRCLKCFG*/
273#define R0900_DIRCLKCFG 0xf151 333#define R0900_DIRCLKCFG 0xf151
274#define F0900_DIRCLK_OPD 0xf1510080 334#define F0900_DIRCLK_OPD 0xf1510080
275#define F0900_DIRCLK_CONFIG 0xf151007e 335#define F0900_DIRCLK_CONFIG 0xf151007e
276#define F0900_DIRCLK_XOR 0xf1510001 336#define F0900_DIRCLK_XOR 0xf1510001
277 337
278/*AGCRF1CFG*/ 338/*AGCRF1CFG*/
279#define R0900_AGCRF1CFG 0xf152 339#define R0900_AGCRF1CFG 0xf152
280#define F0900_AGCRF1_OPD 0xf1520080 340#define F0900_AGCRF1_OPD 0xf1520080
281#define F0900_AGCRF1_CONFIG 0xf152007e 341#define F0900_AGCRF1_CONFIG 0xf152007e
282#define F0900_AGCRF1_XOR 0xf1520001 342#define F0900_AGCRF1_XOR 0xf1520001
283 343
284/*SDAT1CFG*/ 344/*SDAT1CFG*/
285#define R0900_SDAT1CFG 0xf153 345#define R0900_SDAT1CFG 0xf153
286#define F0900_SDAT1_OPD 0xf1530080 346#define F0900_SDAT1_OPD 0xf1530080
287#define F0900_SDAT1_CONFIG 0xf153007e 347#define F0900_SDAT1_CONFIG 0xf153007e
288#define F0900_SDAT1_XOR 0xf1530001 348#define F0900_SDAT1_XOR 0xf1530001
289 349
290/*SCLT1CFG*/ 350/*SCLT1CFG*/
291#define R0900_SCLT1CFG 0xf154 351#define R0900_SCLT1CFG 0xf154
292#define F0900_SCLT1_OPD 0xf1540080 352#define F0900_SCLT1_OPD 0xf1540080
293#define F0900_SCLT1_CONFIG 0xf154007e 353#define F0900_SCLT1_CONFIG 0xf154007e
294#define F0900_SCLT1_XOR 0xf1540001 354#define F0900_SCLT1_XOR 0xf1540001
295 355
296/*DISEQCO1CFG*/ 356/*DISEQCO1CFG*/
297#define R0900_DISEQCO1CFG 0xf155 357#define R0900_DISEQCO1CFG 0xf155
298#define F0900_DISEQCO1_OPD 0xf1550080 358#define F0900_DISEQCO1_OPD 0xf1550080
299#define F0900_DISEQCO1_CONFIG 0xf155007e 359#define F0900_DISEQCO1_CONFIG 0xf155007e
300#define F0900_DISEQC1_XOR 0xf1550001 360#define F0900_DISEQC1_XOR 0xf1550001
301 361
302/*AGCRF2CFG*/ 362/*AGCRF2CFG*/
303#define R0900_AGCRF2CFG 0xf156 363#define R0900_AGCRF2CFG 0xf156
304#define F0900_AGCRF2_OPD 0xf1560080 364#define F0900_AGCRF2_OPD 0xf1560080
305#define F0900_AGCRF2_CONFIG 0xf156007e 365#define F0900_AGCRF2_CONFIG 0xf156007e
306#define F0900_AGCRF2_XOR 0xf1560001 366#define F0900_AGCRF2_XOR 0xf1560001
307 367
308/*SDAT2CFG*/ 368/*SDAT2CFG*/
309#define R0900_SDAT2CFG 0xf157 369#define R0900_SDAT2CFG 0xf157
310#define F0900_SDAT2_OPD 0xf1570080 370#define F0900_SDAT2_OPD 0xf1570080
311#define F0900_SDAT2_CONFIG 0xf157007e 371#define F0900_SDAT2_CONFIG 0xf157007e
312#define F0900_SDAT2_XOR 0xf1570001 372#define F0900_SDAT2_XOR 0xf1570001
313 373
314/*SCLT2CFG*/ 374/*SCLT2CFG*/
315#define R0900_SCLT2CFG 0xf158 375#define R0900_SCLT2CFG 0xf158
316#define F0900_SCLT2_OPD 0xf1580080 376#define F0900_SCLT2_OPD 0xf1580080
317#define F0900_SCLT2_CONFIG 0xf158007e 377#define F0900_SCLT2_CONFIG 0xf158007e
318#define F0900_SCLT2_XOR 0xf1580001 378#define F0900_SCLT2_XOR 0xf1580001
319 379
320/*DISEQCO2CFG*/ 380/*DISEQCO2CFG*/
321#define R0900_DISEQCO2CFG 0xf159 381#define R0900_DISEQCO2CFG 0xf159
322#define F0900_DISEQCO2_OPD 0xf1590080 382#define F0900_DISEQCO2_OPD 0xf1590080
323#define F0900_DISEQCO2_CONFIG 0xf159007e 383#define F0900_DISEQCO2_CONFIG 0xf159007e
324#define F0900_DISEQC2_XOR 0xf1590001 384#define F0900_DISEQC2_XOR 0xf1590001
325 385
326/*CLKOUT27CFG*/ 386/*CLKOUT27CFG*/
327#define R0900_CLKOUT27CFG 0xf15a 387#define R0900_CLKOUT27CFG 0xf15a
328#define F0900_CLKOUT27_OPD 0xf15a0080 388#define F0900_CLKOUT27_OPD 0xf15a0080
329#define F0900_CLKOUT27_CONFIG 0xf15a007e 389#define F0900_CLKOUT27_CONFIG 0xf15a007e
330#define F0900_CLKOUT27_XOR 0xf15a0001 390#define F0900_CLKOUT27_XOR 0xf15a0001
331 391
332/*ERROR1CFG*/ 392/*ERROR1CFG*/
333#define R0900_ERROR1CFG 0xf15b 393#define R0900_ERROR1CFG 0xf15b
334#define F0900_ERROR1_OPD 0xf15b0080 394#define F0900_ERROR1_OPD 0xf15b0080
335#define F0900_ERROR1_CONFIG 0xf15b007e 395#define F0900_ERROR1_CONFIG 0xf15b007e
336#define F0900_ERROR1_XOR 0xf15b0001 396#define F0900_ERROR1_XOR 0xf15b0001
337 397
338/*DPN1CFG*/ 398/*DPN1CFG*/
339#define R0900_DPN1CFG 0xf15c 399#define R0900_DPN1CFG 0xf15c
340#define F0900_DPN1_OPD 0xf15c0080 400#define F0900_DPN1_OPD 0xf15c0080
341#define F0900_DPN1_CONFIG 0xf15c007e 401#define F0900_DPN1_CONFIG 0xf15c007e
342#define F0900_DPN1_XOR 0xf15c0001 402#define F0900_DPN1_XOR 0xf15c0001
343 403
344/*STROUT1CFG*/ 404/*STROUT1CFG*/
345#define R0900_STROUT1CFG 0xf15d 405#define R0900_STROUT1CFG 0xf15d
346#define F0900_STROUT1_OPD 0xf15d0080 406#define F0900_STROUT1_OPD 0xf15d0080
347#define F0900_STROUT1_CONFIG 0xf15d007e 407#define F0900_STROUT1_CONFIG 0xf15d007e
348#define F0900_STROUT1_XOR 0xf15d0001 408#define F0900_STROUT1_XOR 0xf15d0001
349 409
350/*CLKOUT1CFG*/ 410/*CLKOUT1CFG*/
351#define R0900_CLKOUT1CFG 0xf15e 411#define R0900_CLKOUT1CFG 0xf15e
352#define F0900_CLKOUT1_OPD 0xf15e0080 412#define F0900_CLKOUT1_OPD 0xf15e0080
353#define F0900_CLKOUT1_CONFIG 0xf15e007e 413#define F0900_CLKOUT1_CONFIG 0xf15e007e
354#define F0900_CLKOUT1_XOR 0xf15e0001 414#define F0900_CLKOUT1_XOR 0xf15e0001
355 415
356/*DATA71CFG*/ 416/*DATA71CFG*/
357#define R0900_DATA71CFG 0xf15f 417#define R0900_DATA71CFG 0xf15f
358#define F0900_DATA71_OPD 0xf15f0080 418#define F0900_DATA71_OPD 0xf15f0080
359#define F0900_DATA71_CONFIG 0xf15f007e 419#define F0900_DATA71_CONFIG 0xf15f007e
360#define F0900_DATA71_XOR 0xf15f0001 420#define F0900_DATA71_XOR 0xf15f0001
361 421
362/*ERROR2CFG*/ 422/*ERROR2CFG*/
363#define R0900_ERROR2CFG 0xf160 423#define R0900_ERROR2CFG 0xf160
364#define F0900_ERROR2_OPD 0xf1600080 424#define F0900_ERROR2_OPD 0xf1600080
365#define F0900_ERROR2_CONFIG 0xf160007e 425#define F0900_ERROR2_CONFIG 0xf160007e
366#define F0900_ERROR2_XOR 0xf1600001 426#define F0900_ERROR2_XOR 0xf1600001
367 427
368/*DPN2CFG*/ 428/*DPN2CFG*/
369#define R0900_DPN2CFG 0xf161 429#define R0900_DPN2CFG 0xf161
370#define F0900_DPN2_OPD 0xf1610080 430#define F0900_DPN2_OPD 0xf1610080
371#define F0900_DPN2_CONFIG 0xf161007e 431#define F0900_DPN2_CONFIG 0xf161007e
372#define F0900_DPN2_XOR 0xf1610001 432#define F0900_DPN2_XOR 0xf1610001
373 433
374/*STROUT2CFG*/ 434/*STROUT2CFG*/
375#define R0900_STROUT2CFG 0xf162 435#define R0900_STROUT2CFG 0xf162
376#define F0900_STROUT2_OPD 0xf1620080 436#define F0900_STROUT2_OPD 0xf1620080
377#define F0900_STROUT2_CONFIG 0xf162007e 437#define F0900_STROUT2_CONFIG 0xf162007e
378#define F0900_STROUT2_XOR 0xf1620001 438#define F0900_STROUT2_XOR 0xf1620001
379 439
380/*CLKOUT2CFG*/ 440/*CLKOUT2CFG*/
381#define R0900_CLKOUT2CFG 0xf163 441#define R0900_CLKOUT2CFG 0xf163
382#define F0900_CLKOUT2_OPD 0xf1630080 442#define F0900_CLKOUT2_OPD 0xf1630080
383#define F0900_CLKOUT2_CONFIG 0xf163007e 443#define F0900_CLKOUT2_CONFIG 0xf163007e
384#define F0900_CLKOUT2_XOR 0xf1630001 444#define F0900_CLKOUT2_XOR 0xf1630001
385 445
386/*DATA72CFG*/ 446/*DATA72CFG*/
387#define R0900_DATA72CFG 0xf164 447#define R0900_DATA72CFG 0xf164
388#define F0900_DATA72_OPD 0xf1640080 448#define F0900_DATA72_OPD 0xf1640080
389#define F0900_DATA72_CONFIG 0xf164007e 449#define F0900_DATA72_CONFIG 0xf164007e
390#define F0900_DATA72_XOR 0xf1640001 450#define F0900_DATA72_XOR 0xf1640001
391 451
392/*ERROR3CFG*/ 452/*ERROR3CFG*/
393#define R0900_ERROR3CFG 0xf165 453#define R0900_ERROR3CFG 0xf165
394#define F0900_ERROR3_OPD 0xf1650080 454#define F0900_ERROR3_OPD 0xf1650080
395#define F0900_ERROR3_CONFIG 0xf165007e 455#define F0900_ERROR3_CONFIG 0xf165007e
396#define F0900_ERROR3_XOR 0xf1650001 456#define F0900_ERROR3_XOR 0xf1650001
397 457
398/*DPN3CFG*/ 458/*DPN3CFG*/
399#define R0900_DPN3CFG 0xf166 459#define R0900_DPN3CFG 0xf166
400#define F0900_DPN3_OPD 0xf1660080 460#define F0900_DPN3_OPD 0xf1660080
401#define F0900_DPN3_CONFIG 0xf166007e 461#define F0900_DPN3_CONFIG 0xf166007e
402#define F0900_DPN3_XOR 0xf1660001 462#define F0900_DPN3_XOR 0xf1660001
403 463
404/*STROUT3CFG*/ 464/*STROUT3CFG*/
405#define R0900_STROUT3CFG 0xf167 465#define R0900_STROUT3CFG 0xf167
406#define F0900_STROUT3_OPD 0xf1670080 466#define F0900_STROUT3_OPD 0xf1670080
407#define F0900_STROUT3_CONFIG 0xf167007e 467#define F0900_STROUT3_CONFIG 0xf167007e
408#define F0900_STROUT3_XOR 0xf1670001 468#define F0900_STROUT3_XOR 0xf1670001
409 469
410/*CLKOUT3CFG*/ 470/*CLKOUT3CFG*/
411#define R0900_CLKOUT3CFG 0xf168 471#define R0900_CLKOUT3CFG 0xf168
412#define F0900_CLKOUT3_OPD 0xf1680080 472#define F0900_CLKOUT3_OPD 0xf1680080
413#define F0900_CLKOUT3_CONFIG 0xf168007e 473#define F0900_CLKOUT3_CONFIG 0xf168007e
414#define F0900_CLKOUT3_XOR 0xf1680001 474#define F0900_CLKOUT3_XOR 0xf1680001
415 475
416/*DATA73CFG*/ 476/*DATA73CFG*/
417#define R0900_DATA73CFG 0xf169 477#define R0900_DATA73CFG 0xf169
418#define F0900_DATA73_OPD 0xf1690080 478#define F0900_DATA73_OPD 0xf1690080
419#define F0900_DATA73_CONFIG 0xf169007e 479#define F0900_DATA73_CONFIG 0xf169007e
420#define F0900_DATA73_XOR 0xf1690001 480#define F0900_DATA73_XOR 0xf1690001
481
482/*STRSTATUS1*/
483#define R0900_STRSTATUS1 0xf16a
484#define F0900_STRSTATUS_SEL2 0xf16a00f0
485#define F0900_STRSTATUS_SEL1 0xf16a000f
486
487/*STRSTATUS2*/
488#define R0900_STRSTATUS2 0xf16b
489#define F0900_STRSTATUS_SEL4 0xf16b00f0
490#define F0900_STRSTATUS_SEL3 0xf16b000f
491
492/*STRSTATUS3*/
493#define R0900_STRSTATUS3 0xf16c
494#define F0900_STRSTATUS_SEL6 0xf16c00f0
495#define F0900_STRSTATUS_SEL5 0xf16c000f
421 496
422/*FSKTFC2*/ 497/*FSKTFC2*/
423#define R0900_FSKTFC2 0xf170 498#define R0900_FSKTFC2 0xf170
424#define F0900_FSKT_KMOD 0xf17000fc 499#define F0900_FSKT_KMOD 0xf17000fc
425#define F0900_FSKT_CAR2 0xf1700003 500#define F0900_FSKT_CAR2 0xf1700003
426 501
427/*FSKTFC1*/ 502/*FSKTFC1*/
428#define R0900_FSKTFC1 0xf171 503#define R0900_FSKTFC1 0xf171
429#define F0900_FSKT_CAR1 0xf17100ff 504#define F0900_FSKT_CAR1 0xf17100ff
430 505
431/*FSKTFC0*/ 506/*FSKTFC0*/
432#define R0900_FSKTFC0 0xf172 507#define R0900_FSKTFC0 0xf172
433#define F0900_FSKT_CAR0 0xf17200ff 508#define F0900_FSKT_CAR0 0xf17200ff
434 509
435/*FSKTDELTAF1*/ 510/*FSKTDELTAF1*/
436#define R0900_FSKTDELTAF1 0xf173 511#define R0900_FSKTDELTAF1 0xf173
437#define F0900_FSKT_DELTAF1 0xf173000f 512#define F0900_FSKT_DELTAF1 0xf173000f
438 513
439/*FSKTDELTAF0*/ 514/*FSKTDELTAF0*/
440#define R0900_FSKTDELTAF0 0xf174 515#define R0900_FSKTDELTAF0 0xf174
441#define F0900_FSKT_DELTAF0 0xf17400ff 516#define F0900_FSKT_DELTAF0 0xf17400ff
442 517
443/*FSKTCTRL*/ 518/*FSKTCTRL*/
444#define R0900_FSKTCTRL 0xf175 519#define R0900_FSKTCTRL 0xf175
445#define F0900_FSKT_EN_SGN 0xf1750040 520#define F0900_FSKT_EN_SGN 0xf1750040
446#define F0900_FSKT_MOD_SGN 0xf1750020 521#define F0900_FSKT_MOD_SGN 0xf1750020
447#define F0900_FSKT_MOD_EN 0xf175001c 522#define F0900_FSKT_MOD_EN 0xf175001c
448#define F0900_FSKT_DACMODE 0xf1750003 523#define F0900_FSKT_DACMODE 0xf1750003
449 524
450/*FSKRFC2*/ 525/*FSKRFC2*/
451#define R0900_FSKRFC2 0xf176 526#define R0900_FSKRFC2 0xf176
452#define F0900_FSKR_DETSGN 0xf1760040 527#define F0900_FSKR_DETSGN 0xf1760040
453#define F0900_FSKR_OUTSGN 0xf1760020 528#define F0900_FSKR_OUTSGN 0xf1760020
454#define F0900_FSKR_KAGC 0xf176001c 529#define F0900_FSKR_KAGC 0xf176001c
455#define F0900_FSKR_CAR2 0xf1760003 530#define F0900_FSKR_CAR2 0xf1760003
456 531
457/*FSKRFC1*/ 532/*FSKRFC1*/
458#define R0900_FSKRFC1 0xf177 533#define R0900_FSKRFC1 0xf177
459#define F0900_FSKR_CAR1 0xf17700ff 534#define F0900_FSKR_CAR1 0xf17700ff
460 535
461/*FSKRFC0*/ 536/*FSKRFC0*/
462#define R0900_FSKRFC0 0xf178 537#define R0900_FSKRFC0 0xf178
463#define F0900_FSKR_CAR0 0xf17800ff 538#define F0900_FSKR_CAR0 0xf17800ff
464 539
465/*FSKRK1*/ 540/*FSKRK1*/
466#define R0900_FSKRK1 0xf179 541#define R0900_FSKRK1 0xf179
467#define F0900_FSKR_K1_EXP 0xf17900e0 542#define F0900_FSKR_K1_EXP 0xf17900e0
468#define F0900_FSKR_K1_MANT 0xf179001f 543#define F0900_FSKR_K1_MANT 0xf179001f
469 544
470/*FSKRK2*/ 545/*FSKRK2*/
471#define R0900_FSKRK2 0xf17a 546#define R0900_FSKRK2 0xf17a
472#define F0900_FSKR_K2_EXP 0xf17a00e0 547#define F0900_FSKR_K2_EXP 0xf17a00e0
473#define F0900_FSKR_K2_MANT 0xf17a001f 548#define F0900_FSKR_K2_MANT 0xf17a001f
474 549
475/*FSKRAGCR*/ 550/*FSKRAGCR*/
476#define R0900_FSKRAGCR 0xf17b 551#define R0900_FSKRAGCR 0xf17b
477#define F0900_FSKR_OUTCTL 0xf17b00c0 552#define F0900_FSKR_OUTCTL 0xf17b00c0
478#define F0900_FSKR_AGC_REF 0xf17b003f 553#define F0900_FSKR_AGC_REF 0xf17b003f
479 554
480/*FSKRAGC*/ 555/*FSKRAGC*/
481#define R0900_FSKRAGC 0xf17c 556#define R0900_FSKRAGC 0xf17c
482#define F0900_FSKR_AGC_ACCU 0xf17c00ff 557#define F0900_FSKR_AGC_ACCU 0xf17c00ff
483 558
484/*FSKRALPHA*/ 559/*FSKRALPHA*/
485#define R0900_FSKRALPHA 0xf17d 560#define R0900_FSKRALPHA 0xf17d
486#define F0900_FSKR_ALPHA_EXP 0xf17d001c 561#define F0900_FSKR_ALPHA_EXP 0xf17d001c
487#define F0900_FSKR_ALPHA_M 0xf17d0003 562#define F0900_FSKR_ALPHA_M 0xf17d0003
488 563
489/*FSKRPLTH1*/ 564/*FSKRPLTH1*/
490#define R0900_FSKRPLTH1 0xf17e 565#define R0900_FSKRPLTH1 0xf17e
491#define F0900_FSKR_BETA 0xf17e00f0 566#define F0900_FSKR_BETA 0xf17e00f0
492#define F0900_FSKR_PLL_TRESH1 0xf17e000f 567#define F0900_FSKR_PLL_TRESH1 0xf17e000f
493 568
494/*FSKRPLTH0*/ 569/*FSKRPLTH0*/
495#define R0900_FSKRPLTH0 0xf17f 570#define R0900_FSKRPLTH0 0xf17f
496#define F0900_FSKR_PLL_TRESH0 0xf17f00ff 571#define F0900_FSKR_PLL_TRESH0 0xf17f00ff
497 572
498/*FSKRDF1*/ 573/*FSKRDF1*/
499#define R0900_FSKRDF1 0xf180 574#define R0900_FSKRDF1 0xf180
500#define F0900_FSKR_OUT 0xf1800080 575#define F0900_FSKR_OUT 0xf1800080
501#define F0900_FSKR_DELTAF1 0xf180001f 576#define F0900_FSKR_DELTAF1 0xf180001f
502 577
503/*FSKRDF0*/ 578/*FSKRDF0*/
504#define R0900_FSKRDF0 0xf181 579#define R0900_FSKRDF0 0xf181
505#define F0900_FSKR_DELTAF0 0xf18100ff 580#define F0900_FSKR_DELTAF0 0xf18100ff
506 581
507/*FSKRSTEPP*/ 582/*FSKRSTEPP*/
508#define R0900_FSKRSTEPP 0xf182 583#define R0900_FSKRSTEPP 0xf182
509#define F0900_FSKR_STEP_PLUS 0xf18200ff 584#define F0900_FSKR_STEP_PLUS 0xf18200ff
510 585
511/*FSKRSTEPM*/ 586/*FSKRSTEPM*/
512#define R0900_FSKRSTEPM 0xf183 587#define R0900_FSKRSTEPM 0xf183
513#define F0900_FSKR_STEP_MINUS 0xf18300ff 588#define F0900_FSKR_STEP_MINUS 0xf18300ff
514 589
515/*FSKRDET1*/ 590/*FSKRDET1*/
516#define R0900_FSKRDET1 0xf184 591#define R0900_FSKRDET1 0xf184
517#define F0900_FSKR_DETECT 0xf1840080 592#define F0900_FSKR_DETECT 0xf1840080
518#define F0900_FSKR_CARDET_ACCU1 0xf184000f 593#define F0900_FSKR_CARDET_ACCU1 0xf184000f
519 594
520/*FSKRDET0*/ 595/*FSKRDET0*/
521#define R0900_FSKRDET0 0xf185 596#define R0900_FSKRDET0 0xf185
522#define F0900_FSKR_CARDET_ACCU0 0xf18500ff 597#define F0900_FSKR_CARDET_ACCU0 0xf18500ff
523 598
524/*FSKRDTH1*/ 599/*FSKRDTH1*/
525#define R0900_FSKRDTH1 0xf186 600#define R0900_FSKRDTH1 0xf186
526#define F0900_FSKR_CARLOSS_THRESH1 0xf18600f0 601#define F0900_FSKR_CARLOSS_THRESH1 0xf18600f0
527#define F0900_FSKR_CARDET_THRESH1 0xf186000f 602#define F0900_FSKR_CARDET_THRESH1 0xf186000f
528 603
529/*FSKRDTH0*/ 604/*FSKRDTH0*/
530#define R0900_FSKRDTH0 0xf187 605#define R0900_FSKRDTH0 0xf187
531#define F0900_FSKR_CARDET_THRESH0 0xf18700ff 606#define F0900_FSKR_CARDET_THRESH0 0xf18700ff
532 607
533/*FSKRLOSS*/ 608/*FSKRLOSS*/
534#define R0900_FSKRLOSS 0xf188 609#define R0900_FSKRLOSS 0xf188
535#define F0900_FSKR_CARLOSS_THRESH0 0xf18800ff 610#define F0900_FSKR_CARLOSS_THRESH0 0xf18800ff
536 611
537/*P2_DISTXCTL*/ 612/*P2_DISTXCTL*/
538#define R0900_P2_DISTXCTL 0xf190 613#define R0900_P2_DISTXCTL 0xf190
539#define F0900_P2_TIM_OFF 0xf1900080 614#define F0900_P2_TIM_OFF 0xf1900080
540#define F0900_P2_DISEQC_RESET 0xf1900040 615#define F0900_P2_DISEQC_RESET 0xf1900040
541#define F0900_P2_TIM_CMD 0xf1900030 616#define F0900_P2_TIM_CMD 0xf1900030
542#define F0900_P2_DIS_PRECHARGE 0xf1900008 617#define F0900_P2_DIS_PRECHARGE 0xf1900008
543#define F0900_P2_DISTX_MODE 0xf1900007 618#define F0900_P2_DISTX_MODE 0xf1900007
544 619
545/*P2_DISRXCTL*/ 620/*P2_DISRXCTL*/
546#define R0900_P2_DISRXCTL 0xf191 621#define R0900_P2_DISRXCTL 0xf191
547#define F0900_P2_RECEIVER_ON 0xf1910080 622#define F0900_P2_RECEIVER_ON 0xf1910080
548#define F0900_P2_IGNO_SHORT22K 0xf1910040 623#define F0900_P2_IGNO_SHORT22K 0xf1910040
549#define F0900_P2_ONECHIP_TRX 0xf1910020 624#define F0900_P2_ONECHIP_TRX 0xf1910020
550#define F0900_P2_EXT_ENVELOP 0xf1910010 625#define F0900_P2_EXT_ENVELOP 0xf1910010
551#define F0900_P2_PIN_SELECT 0xf191000c 626#define F0900_P2_PIN_SELECT0 0xf191000c
552#define F0900_P2_IRQ_RXEND 0xf1910002 627#define F0900_P2_IRQ_RXEND 0xf1910002
553#define F0900_P2_IRQ_4NBYTES 0xf1910001 628#define F0900_P2_IRQ_4NBYTES 0xf1910001
554 629
555/*P2_DISRX_ST0*/ 630/*P2_DISRX_ST0*/
556#define R0900_P2_DISRX_ST0 0xf194 631#define R0900_P2_DISRX_ST0 0xf194
557#define F0900_P2_RX_END 0xf1940080 632#define F0900_P2_RX_END 0xf1940080
558#define F0900_P2_RX_ACTIVE 0xf1940040 633#define F0900_P2_RX_ACTIVE 0xf1940040
559#define F0900_P2_SHORT_22KHZ 0xf1940020 634#define F0900_P2_SHORT_22KHZ 0xf1940020
560#define F0900_P2_CONT_TONE 0xf1940010 635#define F0900_P2_CONT_TONE 0xf1940010
561#define F0900_P2_FIFO_4BREADY 0xf1940008 636#define F0900_P2_FIFO_4BREADY 0xf1940008
562#define F0900_P2_FIFO_EMPTY 0xf1940004 637#define F0900_P2_FIFO_EMPTY 0xf1940004
563#define F0900_P2_ABORT_DISRX 0xf1940001 638#define F0900_P2_ABORT_DISRX 0xf1940001
564 639
565/*P2_DISRX_ST1*/ 640/*P2_DISRX_ST1*/
566#define R0900_P2_DISRX_ST1 0xf195 641#define R0900_P2_DISRX_ST1 0xf195
567#define F0900_P2_RX_FAIL 0xf1950080 642#define F0900_P2_RX_FAIL 0xf1950080
568#define F0900_P2_FIFO_PARITYFAIL 0xf1950040 643#define F0900_P2_FIFO_PARITYFAIL 0xf1950040
569#define F0900_P2_RX_NONBYTE 0xf1950020 644#define F0900_P2_RX_NONBYTE 0xf1950020
570#define F0900_P2_FIFO_OVERFLOW 0xf1950010 645#define F0900_P2_FIFO_OVERFLOW 0xf1950010
571#define F0900_P2_FIFO_BYTENBR 0xf195000f 646#define F0900_P2_FIFO_BYTENBR 0xf195000f
572 647
573/*P2_DISRXDATA*/ 648/*P2_DISRXDATA*/
574#define R0900_P2_DISRXDATA 0xf196 649#define R0900_P2_DISRXDATA 0xf196
575#define F0900_P2_DISRX_DATA 0xf19600ff 650#define F0900_P2_DISRX_DATA 0xf19600ff
576 651
577/*P2_DISTXDATA*/ 652/*P2_DISTXDATA*/
578#define R0900_P2_DISTXDATA 0xf197 653#define R0900_P2_DISTXDATA 0xf197
579#define F0900_P2_DISEQC_FIFO 0xf19700ff 654#define F0900_P2_DISEQC_FIFO 0xf19700ff
580 655
581/*P2_DISTXSTATUS*/ 656/*P2_DISTXSTATUS*/
582#define R0900_P2_DISTXSTATUS 0xf198 657#define R0900_P2_DISTXSTATUS 0xf198
583#define F0900_P2_TX_FAIL 0xf1980080 658#define F0900_P2_TX_FAIL 0xf1980080
584#define F0900_P2_FIFO_FULL 0xf1980040 659#define F0900_P2_FIFO_FULL 0xf1980040
585#define F0900_P2_TX_IDLE 0xf1980020 660#define F0900_P2_TX_IDLE 0xf1980020
586#define F0900_P2_GAP_BURST 0xf1980010 661#define F0900_P2_GAP_BURST 0xf1980010
587#define F0900_P2_TXFIFO_BYTES 0xf198000f 662#define F0900_P2_TXFIFO_BYTES 0xf198000f
588 663
589/*P2_F22TX*/ 664/*P2_F22TX*/
590#define R0900_P2_F22TX 0xf199 665#define R0900_P2_F22TX 0xf199
591#define F0900_P2_F22_REG 0xf19900ff 666#define F0900_P2_F22_REG 0xf19900ff
592 667
593/*P2_F22RX*/ 668/*P2_F22RX*/
594#define R0900_P2_F22RX 0xf19a 669#define R0900_P2_F22RX 0xf19a
595#define F0900_P2_F22RX_REG 0xf19a00ff 670#define F0900_P2_F22RX_REG 0xf19a00ff
596 671
597/*P2_ACRPRESC*/ 672/*P2_ACRPRESC*/
598#define R0900_P2_ACRPRESC 0xf19c 673#define R0900_P2_ACRPRESC 0xf19c
599#define F0900_P2_ACR_CODFRDY 0xf19c0008 674#define F0900_P2_ACR_PRESC 0xf19c0007
600#define F0900_P2_ACR_PRESC 0xf19c0007
601 675
602/*P2_ACRDIV*/ 676/*P2_ACRDIV*/
603#define R0900_P2_ACRDIV 0xf19d 677#define R0900_P2_ACRDIV 0xf19d
604#define F0900_P2_ACR_DIV 0xf19d00ff 678#define F0900_P2_ACR_DIV 0xf19d00ff
605 679
606/*P1_DISTXCTL*/ 680/*P1_DISTXCTL*/
607#define R0900_P1_DISTXCTL 0xf1a0 681#define R0900_P1_DISTXCTL 0xf1a0
608#define F0900_P1_TIM_OFF 0xf1a00080 682#define DISTXCTL shiftx(R0900_P1_DISTXCTL, demod, 0x10)
609#define F0900_P1_DISEQC_RESET 0xf1a00040 683#define F0900_P1_TIM_OFF 0xf1a00080
610#define F0900_P1_TIM_CMD 0xf1a00030 684#define F0900_P1_DISEQC_RESET 0xf1a00040
611#define F0900_P1_DIS_PRECHARGE 0xf1a00008 685#define DISEQC_RESET shiftx(F0900_P1_DISEQC_RESET, demod, 0x100000)
612#define F0900_P1_DISTX_MODE 0xf1a00007 686#define F0900_P1_TIM_CMD 0xf1a00030
687#define F0900_P1_DIS_PRECHARGE 0xf1a00008
688#define DIS_PRECHARGE shiftx(F0900_P1_DIS_PRECHARGE, demod, 0x100000)
689#define F0900_P1_DISTX_MODE 0xf1a00007
690#define DISTX_MODE shiftx(F0900_P1_DISTX_MODE, demod, 0x100000)
613 691
614/*P1_DISRXCTL*/ 692/*P1_DISRXCTL*/
615#define R0900_P1_DISRXCTL 0xf1a1 693#define R0900_P1_DISRXCTL 0xf1a1
616#define F0900_P1_RECEIVER_ON 0xf1a10080 694#define DISRXCTL shiftx(R0900_P1_DISRXCTL, demod, 0x10)
617#define F0900_P1_IGNO_SHORT22K 0xf1a10040 695#define F0900_P1_RECEIVER_ON 0xf1a10080
618#define F0900_P1_ONECHIP_TRX 0xf1a10020 696#define F0900_P1_IGNO_SHORT22K 0xf1a10040
619#define F0900_P1_EXT_ENVELOP 0xf1a10010 697#define F0900_P1_ONECHIP_TRX 0xf1a10020
620#define F0900_P1_PIN_SELECT 0xf1a1000c 698#define F0900_P1_EXT_ENVELOP 0xf1a10010
621#define F0900_P1_IRQ_RXEND 0xf1a10002 699#define F0900_P1_PIN_SELECT0 0xf1a1000c
622#define F0900_P1_IRQ_4NBYTES 0xf1a10001 700#define F0900_P1_IRQ_RXEND 0xf1a10002
701#define F0900_P1_IRQ_4NBYTES 0xf1a10001
623 702
624/*P1_DISRX_ST0*/ 703/*P1_DISRX_ST0*/
625#define R0900_P1_DISRX_ST0 0xf1a4 704#define R0900_P1_DISRX_ST0 0xf1a4
626#define F0900_P1_RX_END 0xf1a40080 705#define DISRX_ST0 shiftx(R0900_P1_DISRX_ST0, demod, 0x10)
627#define F0900_P1_RX_ACTIVE 0xf1a40040 706#define F0900_P1_RX_END 0xf1a40080
628#define F0900_P1_SHORT_22KHZ 0xf1a40020 707#define RX_END shiftx(F0900_P1_RX_END, demod, 0x100000)
629#define F0900_P1_CONT_TONE 0xf1a40010 708#define F0900_P1_RX_ACTIVE 0xf1a40040
630#define F0900_P1_FIFO_4BREADY 0xf1a40008 709#define F0900_P1_SHORT_22KHZ 0xf1a40020
631#define F0900_P1_FIFO_EMPTY 0xf1a40004 710#define F0900_P1_CONT_TONE 0xf1a40010
632#define F0900_P1_ABORT_DISRX 0xf1a40001 711#define F0900_P1_FIFO_4BREADY 0xf1a40008
712#define F0900_P1_FIFO_EMPTY 0xf1a40004
713#define F0900_P1_ABORT_DISRX 0xf1a40001
633 714
634/*P1_DISRX_ST1*/ 715/*P1_DISRX_ST1*/
635#define R0900_P1_DISRX_ST1 0xf1a5 716#define R0900_P1_DISRX_ST1 0xf1a5
636#define F0900_P1_RX_FAIL 0xf1a50080 717#define DISRX_ST1 shiftx(R0900_P1_DISRX_ST1, demod, 0x10)
637#define F0900_P1_FIFO_PARITYFAIL 0xf1a50040 718#define F0900_P1_RX_FAIL 0xf1a50080
638#define F0900_P1_RX_NONBYTE 0xf1a50020 719#define F0900_P1_FIFO_PARITYFAIL 0xf1a50040
639#define F0900_P1_FIFO_OVERFLOW 0xf1a50010 720#define F0900_P1_RX_NONBYTE 0xf1a50020
640#define F0900_P1_FIFO_BYTENBR 0xf1a5000f 721#define F0900_P1_FIFO_OVERFLOW 0xf1a50010
722#define F0900_P1_FIFO_BYTENBR 0xf1a5000f
723#define FIFO_BYTENBR shiftx(F0900_P1_FIFO_BYTENBR, demod, 0x100000)
641 724
642/*P1_DISRXDATA*/ 725/*P1_DISRXDATA*/
643#define R0900_P1_DISRXDATA 0xf1a6 726#define R0900_P1_DISRXDATA 0xf1a6
644#define F0900_P1_DISRX_DATA 0xf1a600ff 727#define DISRXDATA shiftx(R0900_P1_DISRXDATA, demod, 0x10)
728#define F0900_P1_DISRX_DATA 0xf1a600ff
645 729
646/*P1_DISTXDATA*/ 730/*P1_DISTXDATA*/
647#define R0900_P1_DISTXDATA 0xf1a7 731#define R0900_P1_DISTXDATA 0xf1a7
648#define F0900_P1_DISEQC_FIFO 0xf1a700ff 732#define DISTXDATA shiftx(R0900_P1_DISTXDATA, demod, 0x10)
733#define F0900_P1_DISEQC_FIFO 0xf1a700ff
649 734
650/*P1_DISTXSTATUS*/ 735/*P1_DISTXSTATUS*/
651#define R0900_P1_DISTXSTATUS 0xf1a8 736#define R0900_P1_DISTXSTATUS 0xf1a8
652#define F0900_P1_TX_FAIL 0xf1a80080 737#define F0900_P1_TX_FAIL 0xf1a80080
653#define F0900_P1_FIFO_FULL 0xf1a80040 738#define F0900_P1_FIFO_FULL 0xf1a80040
654#define F0900_P1_TX_IDLE 0xf1a80020 739#define FIFO_FULL shiftx(F0900_P1_FIFO_FULL, demod, 0x100000)
655#define F0900_P1_GAP_BURST 0xf1a80010 740#define F0900_P1_TX_IDLE 0xf1a80020
656#define F0900_P1_TXFIFO_BYTES 0xf1a8000f 741#define TX_IDLE shiftx(F0900_P1_TX_IDLE, demod, 0x100000)
742#define F0900_P1_GAP_BURST 0xf1a80010
743#define F0900_P1_TXFIFO_BYTES 0xf1a8000f
657 744
658/*P1_F22TX*/ 745/*P1_F22TX*/
659#define R0900_P1_F22TX 0xf1a9 746#define R0900_P1_F22TX 0xf1a9
660#define F0900_P1_F22_REG 0xf1a900ff 747#define F22TX shiftx(R0900_P1_F22TX, demod, 0x10)
748#define F0900_P1_F22_REG 0xf1a900ff
661 749
662/*P1_F22RX*/ 750/*P1_F22RX*/
663#define R0900_P1_F22RX 0xf1aa 751#define R0900_P1_F22RX 0xf1aa
664#define F0900_P1_F22RX_REG 0xf1aa00ff 752#define F22RX shiftx(R0900_P1_F22RX, demod, 0x10)
753#define F0900_P1_F22RX_REG 0xf1aa00ff
665 754
666/*P1_ACRPRESC*/ 755/*P1_ACRPRESC*/
667#define R0900_P1_ACRPRESC 0xf1ac 756#define R0900_P1_ACRPRESC 0xf1ac
668#define F0900_P1_ACR_CODFRDY 0xf1ac0008 757#define ACRPRESC shiftx(R0900_P1_ACRPRESC, demod, 0x10)
669#define F0900_P1_ACR_PRESC 0xf1ac0007 758#define F0900_P1_ACR_PRESC 0xf1ac0007
670 759
671/*P1_ACRDIV*/ 760/*P1_ACRDIV*/
672#define R0900_P1_ACRDIV 0xf1ad 761#define R0900_P1_ACRDIV 0xf1ad
673#define F0900_P1_ACR_DIV 0xf1ad00ff 762#define ACRDIV shiftx(R0900_P1_ACRDIV, demod, 0x10)
763#define F0900_P1_ACR_DIV 0xf1ad00ff
674 764
675/*NCOARSE*/ 765/*NCOARSE*/
676#define R0900_NCOARSE 0xf1b3 766#define R0900_NCOARSE 0xf1b3
677#define F0900_M_DIV 0xf1b300ff 767#define F0900_M_DIV 0xf1b300ff
678 768
679/*SYNTCTRL*/ 769/*SYNTCTRL*/
680#define R0900_SYNTCTRL 0xf1b6 770#define R0900_SYNTCTRL 0xf1b6
681#define F0900_STANDBY 0xf1b60080 771#define F0900_STANDBY 0xf1b60080
682#define F0900_BYPASSPLLCORE 0xf1b60040 772#define F0900_BYPASSPLLCORE 0xf1b60040
683#define F0900_SELX1RATIO 0xf1b60020 773#define F0900_SELX1RATIO 0xf1b60020
684#define F0900_I2C_TUD 0xf1b60010 774#define F0900_STOP_PLL 0xf1b60008
685#define F0900_STOP_PLL 0xf1b60008 775#define F0900_BYPASSPLLFSK 0xf1b60004
686#define F0900_BYPASSPLLFSK 0xf1b60004 776#define F0900_SELOSCI 0xf1b60002
687#define F0900_SELOSCI 0xf1b60002 777#define F0900_BYPASSPLLADC 0xf1b60001
688#define F0900_BYPASSPLLADC 0xf1b60001
689 778
690/*FILTCTRL*/ 779/*FILTCTRL*/
691#define R0900_FILTCTRL 0xf1b7 780#define R0900_FILTCTRL 0xf1b7
692#define F0900_INV_CLK135 0xf1b70080 781#define F0900_INV_CLK135 0xf1b70080
693#define F0900_PERM_BYPDIS 0xf1b70040 782#define F0900_SEL_FSKCKDIV 0xf1b70004
694#define F0900_SEL_FSKCKDIV 0xf1b70004 783#define F0900_INV_CLKFSK 0xf1b70002
695#define F0900_INV_CLKFSK 0xf1b70002 784#define F0900_BYPASS_APPLI 0xf1b70001
696#define F0900_BYPASS_APPLI 0xf1b70001
697 785
698/*PLLSTAT*/ 786/*PLLSTAT*/
699#define R0900_PLLSTAT 0xf1b8 787#define R0900_PLLSTAT 0xf1b8
700#define F0900_ACM_SEL 0xf1b80080 788#define F0900_PLLLOCK 0xf1b80001
701#define F0900_DTV_SEL 0xf1b80040
702#define F0900_PLLLOCK 0xf1b80001
703 789
704/*STOPCLK1*/ 790/*STOPCLK1*/
705#define R0900_STOPCLK1 0xf1c2 791#define R0900_STOPCLK1 0xf1c2
706#define F0900_STOP_CLKPKDT2 0xf1c20040 792#define F0900_STOP_CLKPKDT2 0xf1c20040
707#define F0900_STOP_CLKPKDT1 0xf1c20020 793#define F0900_STOP_CLKPKDT1 0xf1c20020
708#define F0900_STOP_CLKFEC 0xf1c20010 794#define F0900_STOP_CLKFEC 0xf1c20010
709#define F0900_STOP_CLKADCI2 0xf1c20008 795#define F0900_STOP_CLKADCI2 0xf1c20008
710#define F0900_INV_CLKADCI2 0xf1c20004 796#define F0900_INV_CLKADCI2 0xf1c20004
711#define F0900_STOP_CLKADCI1 0xf1c20002 797#define F0900_STOP_CLKADCI1 0xf1c20002
712#define F0900_INV_CLKADCI1 0xf1c20001 798#define F0900_INV_CLKADCI1 0xf1c20001
713 799
714/*STOPCLK2*/ 800/*STOPCLK2*/
715#define R0900_STOPCLK2 0xf1c3 801#define R0900_STOPCLK2 0xf1c3
716#define F0900_STOP_CLKSAMP2 0xf1c30010 802#define F0900_STOP_CLKSAMP2 0xf1c30010
717#define F0900_STOP_CLKSAMP1 0xf1c30008 803#define F0900_STOP_CLKSAMP1 0xf1c30008
718#define F0900_STOP_CLKVIT2 0xf1c30004 804#define F0900_STOP_CLKVIT2 0xf1c30004
719#define F0900_STOP_CLKVIT1 0xf1c30002 805#define F0900_STOP_CLKVIT1 0xf1c30002
720#define F0900_STOP_CLKTS 0xf1c30001 806#define STOP_CLKVIT shiftx(F0900_STOP_CLKVIT1, demod, -2)
807#define F0900_STOP_CLKTS 0xf1c30001
721 808
722/*TSTTNR0*/ 809/*TSTTNR0*/
723#define R0900_TSTTNR0 0xf1df 810#define R0900_TSTTNR0 0xf1df
724#define F0900_SEL_FSK 0xf1df0080 811#define F0900_SEL_FSK 0xf1df0080
725#define F0900_FSK_PON 0xf1df0004 812#define F0900_FSK_PON 0xf1df0004
726#define F0900_FSK_OPENLOOP 0xf1df0002
727 813
728/*TSTTNR1*/ 814/*TSTTNR1*/
729#define R0900_TSTTNR1 0xf1e0 815#define R0900_TSTTNR1 0xf1e0
730#define F0900_BYPASS_ADC1 0xf1e00080 816#define F0900_ADC1_PON 0xf1e00002
731#define F0900_INVADC1_CKOUT 0xf1e00040 817#define F0900_ADC1_INMODE 0xf1e00001
732#define F0900_SELIQSRC1 0xf1e00030
733#define F0900_ADC1_PON 0xf1e00002
734#define F0900_ADC1_INMODE 0xf1e00001
735 818
736/*TSTTNR2*/ 819/*TSTTNR2*/
737#define R0900_TSTTNR2 0xf1e1 820#define R0900_TSTTNR2 0xf1e1
738#define F0900_DISEQC1_PON 0xf1e10020 821#define F0900_DISEQC1_PON 0xf1e10020
739#define F0900_DISEQC1_TEST 0xf1e1001f
740 822
741/*TSTTNR3*/ 823/*TSTTNR3*/
742#define R0900_TSTTNR3 0xf1e2 824#define R0900_TSTTNR3 0xf1e2
743#define F0900_BYPASS_ADC2 0xf1e20080 825#define F0900_ADC2_PON 0xf1e20002
744#define F0900_INVADC2_CKOUT 0xf1e20040 826#define F0900_ADC2_INMODE 0xf1e20001
745#define F0900_SELIQSRC2 0xf1e20030
746#define F0900_ADC2_PON 0xf1e20002
747#define F0900_ADC2_INMODE 0xf1e20001
748 827
749/*TSTTNR4*/ 828/*TSTTNR4*/
750#define R0900_TSTTNR4 0xf1e3 829#define R0900_TSTTNR4 0xf1e3
751#define F0900_DISEQC2_PON 0xf1e30020 830#define F0900_DISEQC2_PON 0xf1e30020
752#define F0900_DISEQC2_TEST 0xf1e3001f
753 831
754/*P2_IQCONST*/ 832/*P2_IQCONST*/
755#define R0900_P2_IQCONST 0xf200 833#define R0900_P2_IQCONST 0xf200
756#define F0900_P2_CONSTEL_SELECT 0xf2000060 834#define F0900_P2_CONSTEL_SELECT 0xf2000060
757#define F0900_P2_IQSYMB_SEL 0xf200001f 835#define F0900_P2_IQSYMB_SEL 0xf200001f
758 836
759/*P2_NOSCFG*/ 837/*P2_NOSCFG*/
760#define R0900_P2_NOSCFG 0xf201 838#define R0900_P2_NOSCFG 0xf201
761#define F0900_P2_DUMMYPL_NOSDATA 0xf2010020 839#define F0900_P2_DUMMYPL_NOSDATA 0xf2010020
762#define F0900_P2_NOSPLH_BETA 0xf2010018 840#define F0900_P2_NOSPLH_BETA 0xf2010018
763#define F0900_P2_NOSDATA_BETA 0xf2010007 841#define F0900_P2_NOSDATA_BETA 0xf2010007
764 842
765/*P2_ISYMB*/ 843/*P2_ISYMB*/
766#define R0900_P2_ISYMB 0xf202 844#define R0900_P2_ISYMB 0xf202
767#define F0900_P2_I_SYMBOL 0xf20201ff 845#define F0900_P2_I_SYMBOL 0xf20201ff
768 846
769/*P2_QSYMB*/ 847/*P2_QSYMB*/
770#define R0900_P2_QSYMB 0xf203 848#define R0900_P2_QSYMB 0xf203
771#define F0900_P2_Q_SYMBOL 0xf20301ff 849#define F0900_P2_Q_SYMBOL 0xf20301ff
772 850
773/*P2_AGC1CFG*/ 851/*P2_AGC1CFG*/
774#define R0900_P2_AGC1CFG 0xf204 852#define R0900_P2_AGC1CFG 0xf204
775#define F0900_P2_DC_FROZEN 0xf2040080 853#define F0900_P2_DC_FROZEN 0xf2040080
776#define F0900_P2_DC_CORRECT 0xf2040040 854#define F0900_P2_DC_CORRECT 0xf2040040
777#define F0900_P2_AMM_FROZEN 0xf2040020 855#define F0900_P2_AMM_FROZEN 0xf2040020
778#define F0900_P2_AMM_CORRECT 0xf2040010 856#define F0900_P2_AMM_CORRECT 0xf2040010
779#define F0900_P2_QUAD_FROZEN 0xf2040008 857#define F0900_P2_QUAD_FROZEN 0xf2040008
780#define F0900_P2_QUAD_CORRECT 0xf2040004 858#define F0900_P2_QUAD_CORRECT 0xf2040004
781#define F0900_P2_DCCOMP_SLOW 0xf2040002
782#define F0900_P2_IQMISM_SLOW 0xf2040001
783 859
784/*P2_AGC1CN*/ 860/*P2_AGC1CN*/
785#define R0900_P2_AGC1CN 0xf206 861#define R0900_P2_AGC1CN 0xf206
786#define F0900_P2_AGC1_LOCKED 0xf2060080 862#define F0900_P2_AGC1_LOCKED 0xf2060080
787#define F0900_P2_AGC1_OVERFLOW 0xf2060040 863#define F0900_P2_AGC1_MINPOWER 0xf2060010
788#define F0900_P2_AGC1_NOSLOWLK 0xf2060020 864#define F0900_P2_AGCOUT_FAST 0xf2060008
789#define F0900_P2_AGC1_MINPOWER 0xf2060010 865#define F0900_P2_AGCIQ_BETA 0xf2060007
790#define F0900_P2_AGCOUT_FAST 0xf2060008
791#define F0900_P2_AGCIQ_BETA 0xf2060007
792 866
793/*P2_AGC1REF*/ 867/*P2_AGC1REF*/
794#define R0900_P2_AGC1REF 0xf207 868#define R0900_P2_AGC1REF 0xf207
795#define F0900_P2_AGCIQ_REF 0xf20700ff 869#define F0900_P2_AGCIQ_REF 0xf20700ff
796 870
797/*P2_IDCCOMP*/ 871/*P2_IDCCOMP*/
798#define R0900_P2_IDCCOMP 0xf208 872#define R0900_P2_IDCCOMP 0xf208
799#define F0900_P2_IAVERAGE_ADJ 0xf20801ff 873#define F0900_P2_IAVERAGE_ADJ 0xf20801ff
800 874
801/*P2_QDCCOMP*/ 875/*P2_QDCCOMP*/
802#define R0900_P2_QDCCOMP 0xf209 876#define R0900_P2_QDCCOMP 0xf209
803#define F0900_P2_QAVERAGE_ADJ 0xf20901ff 877#define F0900_P2_QAVERAGE_ADJ 0xf20901ff
804 878
805/*P2_POWERI*/ 879/*P2_POWERI*/
806#define R0900_P2_POWERI 0xf20a 880#define R0900_P2_POWERI 0xf20a
807#define F0900_P2_POWER_I 0xf20a00ff 881#define F0900_P2_POWER_I 0xf20a00ff
808 882
809/*P2_POWERQ*/ 883/*P2_POWERQ*/
810#define R0900_P2_POWERQ 0xf20b 884#define R0900_P2_POWERQ 0xf20b
811#define F0900_P2_POWER_Q 0xf20b00ff 885#define F0900_P2_POWER_Q 0xf20b00ff
812 886
813/*P2_AGC1AMM*/ 887/*P2_AGC1AMM*/
814#define R0900_P2_AGC1AMM 0xf20c 888#define R0900_P2_AGC1AMM 0xf20c
815#define F0900_P2_AMM_VALUE 0xf20c00ff 889#define F0900_P2_AMM_VALUE 0xf20c00ff
816 890
817/*P2_AGC1QUAD*/ 891/*P2_AGC1QUAD*/
818#define R0900_P2_AGC1QUAD 0xf20d 892#define R0900_P2_AGC1QUAD 0xf20d
819#define F0900_P2_QUAD_VALUE 0xf20d01ff 893#define F0900_P2_QUAD_VALUE 0xf20d01ff
820 894
821/*P2_AGCIQIN1*/ 895/*P2_AGCIQIN1*/
822#define R0900_P2_AGCIQIN1 0xf20e 896#define R0900_P2_AGCIQIN1 0xf20e
823#define F0900_P2_AGCIQ_VALUE1 0xf20e00ff 897#define F0900_P2_AGCIQ_VALUE1 0xf20e00ff
824 898
825/*P2_AGCIQIN0*/ 899/*P2_AGCIQIN0*/
826#define R0900_P2_AGCIQIN0 0xf20f 900#define R0900_P2_AGCIQIN0 0xf20f
827#define F0900_P2_AGCIQ_VALUE0 0xf20f00ff 901#define F0900_P2_AGCIQ_VALUE0 0xf20f00ff
828 902
829/*P2_DEMOD*/ 903/*P2_DEMOD*/
830#define R0900_P2_DEMOD 0xf210 904#define R0900_P2_DEMOD 0xf210
831#define F0900_P2_DEMOD_STOP 0xf2100040 905#define F0900_P2_MANUALS2_ROLLOFF 0xf2100080
832#define F0900_P2_SPECINV_CONTROL 0xf2100030 906#define F0900_P2_SPECINV_CONTROL 0xf2100030
833#define F0900_P2_FORCE_ENASAMP 0xf2100008 907#define F0900_P2_FORCE_ENASAMP 0xf2100008
834#define F0900_P2_MANUAL_ROLLOFF 0xf2100004 908#define F0900_P2_MANUALSX_ROLLOFF 0xf2100004
835#define F0900_P2_ROLLOFF_CONTROL 0xf2100003 909#define F0900_P2_ROLLOFF_CONTROL 0xf2100003
836 910
837/*P2_DMDMODCOD*/ 911/*P2_DMDMODCOD*/
838#define R0900_P2_DMDMODCOD 0xf211 912#define R0900_P2_DMDMODCOD 0xf211
839#define F0900_P2_MANUAL_MODCOD 0xf2110080 913#define F0900_P2_MANUAL_MODCOD 0xf2110080
840#define F0900_P2_DEMOD_MODCOD 0xf211007c 914#define F0900_P2_DEMOD_MODCOD 0xf211007c
841#define F0900_P2_DEMOD_TYPE 0xf2110003 915#define F0900_P2_DEMOD_TYPE 0xf2110003
842 916
843/*P2_DSTATUS*/ 917/*P2_DSTATUS*/
844#define R0900_P2_DSTATUS 0xf212 918#define R0900_P2_DSTATUS 0xf212
845#define F0900_P2_CAR_LOCK 0xf2120080 919#define F0900_P2_CAR_LOCK 0xf2120080
846#define F0900_P2_TMGLOCK_QUALITY 0xf2120060 920#define F0900_P2_TMGLOCK_QUALITY 0xf2120060
847#define F0900_P2_SDVBS1_ENABLE 0xf2120010 921#define F0900_P2_LOCK_DEFINITIF 0xf2120008
848#define F0900_P2_LOCK_DEFINITIF 0xf2120008 922#define F0900_P2_OVADC_DETECT 0xf2120001
849#define F0900_P2_TIMING_IS_LOCKED 0xf2120004
850#define F0900_P2_COARSE_TMGLOCK 0xf2120002
851#define F0900_P2_COARSE_CARLOCK 0xf2120001
852 923
853/*P2_DSTATUS2*/ 924/*P2_DSTATUS2*/
854#define R0900_P2_DSTATUS2 0xf213 925#define R0900_P2_DSTATUS2 0xf213
855#define F0900_P2_DEMOD_DELOCK 0xf2130080 926#define F0900_P2_DEMOD_DELOCK 0xf2130080
856#define F0900_P2_DEMOD_TIMEOUT 0xf2130040 927#define F0900_P2_AGC1_NOSIGNALACK 0xf2130008
857#define F0900_P2_MODCODRQ_SYNCTAG 0xf2130020 928#define F0900_P2_AGC2_OVERFLOW 0xf2130004
858#define F0900_P2_POLYPH_SATEVENT 0xf2130010 929#define F0900_P2_CFR_OVERFLOW 0xf2130002
859#define F0900_P2_AGC1_NOSIGNALACK 0xf2130008 930#define F0900_P2_GAMMA_OVERUNDER 0xf2130001
860#define F0900_P2_AGC2_OVERFLOW 0xf2130004
861#define F0900_P2_CFR_OVERFLOW 0xf2130002
862#define F0900_P2_GAMMA_OVERUNDER 0xf2130001
863 931
864/*P2_DMDCFGMD*/ 932/*P2_DMDCFGMD*/
865#define R0900_P2_DMDCFGMD 0xf214 933#define R0900_P2_DMDCFGMD 0xf214
866#define F0900_P2_DVBS2_ENABLE 0xf2140080 934#define F0900_P2_DVBS2_ENABLE 0xf2140080
867#define F0900_P2_DVBS1_ENABLE 0xf2140040 935#define F0900_P2_DVBS1_ENABLE 0xf2140040
868#define F0900_P2_CFR_AUTOSCAN 0xf2140020 936#define F0900_P2_SCAN_ENABLE 0xf2140010
869#define F0900_P2_SCAN_ENABLE 0xf2140010 937#define F0900_P2_CFR_AUTOSCAN 0xf2140008
870#define F0900_P2_TUN_AUTOSCAN 0xf2140008 938#define F0900_P2_TUN_RNG 0xf2140003
871#define F0900_P2_NOFORCE_RELOCK 0xf2140004
872#define F0900_P2_TUN_RNG 0xf2140003
873 939
874/*P2_DMDCFG2*/ 940/*P2_DMDCFG2*/
875#define R0900_P2_DMDCFG2 0xf215 941#define R0900_P2_DMDCFG2 0xf215
876#define F0900_P2_AGC1_WAITLOCK 0xf2150080 942#define F0900_P2_S1S2_SEQUENTIAL 0xf2150040
877#define F0900_P2_S1S2_SEQUENTIAL 0xf2150040 943#define F0900_P2_INFINITE_RELOCK 0xf2150010
878#define F0900_P2_OVERFLOW_TIMEOUT 0xf2150020
879#define F0900_P2_SCANFAIL_TIMEOUT 0xf2150010
880#define F0900_P2_DMDTOUT_BACK 0xf2150008
881#define F0900_P2_CARLOCK_S1ENABLE 0xf2150004
882#define F0900_P2_COARSE_LK3MODE 0xf2150002
883#define F0900_P2_COARSE_LK2MODE 0xf2150001
884 944
885/*P2_DMDISTATE*/ 945/*P2_DMDISTATE*/
886#define R0900_P2_DMDISTATE 0xf216 946#define R0900_P2_DMDISTATE 0xf216
887#define F0900_P2_I2C_NORESETDMODE 0xf2160080 947#define F0900_P2_I2C_DEMOD_MODE 0xf216001f
888#define F0900_P2_FORCE_ETAPED 0xf2160040
889#define F0900_P2_SDMDRST_DIRCLK 0xf2160020
890#define F0900_P2_I2C_DEMOD_MODE 0xf216001f
891 948
892/*P2_DMDT0M*/ 949/*P2_DMDT0M*/
893#define R0900_P2_DMDT0M 0xf217 950#define R0900_P2_DMDT0M 0xf217
894#define F0900_P2_DMDT0_MIN 0xf21700ff 951#define F0900_P2_DMDT0_MIN 0xf21700ff
895 952
896/*P2_DMDSTATE*/ 953/*P2_DMDSTATE*/
897#define R0900_P2_DMDSTATE 0xf21b 954#define R0900_P2_DMDSTATE 0xf21b
898#define F0900_P2_DEMOD_LOCKED 0xf21b0080 955#define F0900_P2_HEADER_MODE 0xf21b0060
899#define F0900_P2_HEADER_MODE 0xf21b0060
900#define F0900_P2_DEMOD_MODE 0xf21b001f
901 956
902/*P2_DMDFLYW*/ 957/*P2_DMDFLYW*/
903#define R0900_P2_DMDFLYW 0xf21c 958#define R0900_P2_DMDFLYW 0xf21c
904#define F0900_P2_I2C_IRQVAL 0xf21c00f0 959#define F0900_P2_I2C_IRQVAL 0xf21c00f0
905#define F0900_P2_FLYWHEEL_CPT 0xf21c000f 960#define F0900_P2_FLYWHEEL_CPT 0xf21c000f
906 961
907/*P2_DSTATUS3*/ 962/*P2_DSTATUS3*/
908#define R0900_P2_DSTATUS3 0xf21d 963#define R0900_P2_DSTATUS3 0xf21d
909#define F0900_P2_CFR_ZIGZAG 0xf21d0080 964#define F0900_P2_DEMOD_CFGMODE 0xf21d0060
910#define F0900_P2_DEMOD_CFGMODE 0xf21d0060
911#define F0900_P2_GAMMA_LOWBAUDRATE 0xf21d0010
912#define F0900_P2_RELOCK_MODE 0xf21d0008
913#define F0900_P2_DEMOD_FAIL 0xf21d0004
914#define F0900_P2_ETAPE1A_DVBXMEM 0xf21d0003
915 965
916/*P2_DMDCFG3*/ 966/*P2_DMDCFG3*/
917#define R0900_P2_DMDCFG3 0xf21e 967#define R0900_P2_DMDCFG3 0xf21e
918#define F0900_P2_DVBS1_TMGWAIT 0xf21e0080 968#define F0900_P2_NOSTOP_FIFOFULL 0xf21e0008
919#define F0900_P2_NO_BWCENTERING 0xf21e0040
920#define F0900_P2_INV_SEQSRCH 0xf21e0020
921#define F0900_P2_DIS_SFRUPLOW_TRK 0xf21e0010
922#define F0900_P2_NOSTOP_FIFOFULL 0xf21e0008
923#define F0900_P2_LOCKTIME_MODE 0xf21e0007
924 969
925/*P2_DMDCFG4*/ 970/*P2_DMDCFG4*/
926#define R0900_P2_DMDCFG4 0xf21f 971#define R0900_P2_DMDCFG4 0xf21f
927#define F0900_P2_TUNER_NRELAUNCH 0xf21f0008 972#define F0900_P2_TUNER_NRELAUNCH 0xf21f0008
928#define F0900_P2_DIS_CLKENABLE 0xf21f0004
929#define F0900_P2_DIS_HDRDIVLOCK 0xf21f0002
930#define F0900_P2_NO_TNRWBINIT 0xf21f0001
931 973
932/*P2_CORRELMANT*/ 974/*P2_CORRELMANT*/
933#define R0900_P2_CORRELMANT 0xf220 975#define R0900_P2_CORRELMANT 0xf220
934#define F0900_P2_CORREL_MANT 0xf22000ff 976#define F0900_P2_CORREL_MANT 0xf22000ff
935 977
936/*P2_CORRELABS*/ 978/*P2_CORRELABS*/
937#define R0900_P2_CORRELABS 0xf221 979#define R0900_P2_CORRELABS 0xf221
938#define F0900_P2_CORREL_ABS 0xf22100ff 980#define F0900_P2_CORREL_ABS 0xf22100ff
939 981
940/*P2_CORRELEXP*/ 982/*P2_CORRELEXP*/
941#define R0900_P2_CORRELEXP 0xf222 983#define R0900_P2_CORRELEXP 0xf222
942#define F0900_P2_CORREL_ABSEXP 0xf22200f0 984#define F0900_P2_CORREL_ABSEXP 0xf22200f0
943#define F0900_P2_CORREL_EXP 0xf222000f 985#define F0900_P2_CORREL_EXP 0xf222000f
944 986
945/*P2_PLHMODCOD*/ 987/*P2_PLHMODCOD*/
946#define R0900_P2_PLHMODCOD 0xf224 988#define R0900_P2_PLHMODCOD 0xf224
947#define F0900_P2_SPECINV_DEMOD 0xf2240080 989#define F0900_P2_SPECINV_DEMOD 0xf2240080
948#define F0900_P2_PLH_MODCOD 0xf224007c 990#define F0900_P2_PLH_MODCOD 0xf224007c
949#define F0900_P2_PLH_TYPE 0xf2240003 991#define F0900_P2_PLH_TYPE 0xf2240003
950 992
951/*P2_AGCK32*/ 993/*P2_DMDREG*/
952#define R0900_P2_AGCK32 0xf22b 994#define R0900_P2_DMDREG 0xf225
953#define F0900_P2_R3ADJOFF_32APSK 0xf22b0080 995#define F0900_P2_DECIM_PLFRAMES 0xf2250001
954#define F0900_P2_R2ADJOFF_32APSK 0xf22b0040
955#define F0900_P2_R1ADJOFF_32APSK 0xf22b0020
956#define F0900_P2_RADJ_32APSK 0xf22b001f
957 996
958/*P2_AGC2O*/ 997/*P2_AGC2O*/
959#define R0900_P2_AGC2O 0xf22c 998#define R0900_P2_AGC2O 0xf22c
960#define F0900_P2_AGC2REF_ADJUSTING 0xf22c0080 999#define F0900_P2_AGC2_COEF 0xf22c0007
961#define F0900_P2_AGC2_COARSEFAST 0xf22c0040
962#define F0900_P2_AGC2_LKSQRT 0xf22c0020
963#define F0900_P2_AGC2_LKMODE 0xf22c0010
964#define F0900_P2_AGC2_LKEQUA 0xf22c0008
965#define F0900_P2_AGC2_COEF 0xf22c0007
966 1000
967/*P2_AGC2REF*/ 1001/*P2_AGC2REF*/
968#define R0900_P2_AGC2REF 0xf22d 1002#define R0900_P2_AGC2REF 0xf22d
969#define F0900_P2_AGC2_REF 0xf22d00ff 1003#define F0900_P2_AGC2_REF 0xf22d00ff
970 1004
971/*P2_AGC1ADJ*/ 1005/*P2_AGC1ADJ*/
972#define R0900_P2_AGC1ADJ 0xf22e 1006#define R0900_P2_AGC1ADJ 0xf22e
973#define F0900_P2_AGC1ADJ_MANUAL 0xf22e0080 1007#define F0900_P2_AGC1_ADJUSTED 0xf22e007f
974#define F0900_P2_AGC1_ADJUSTED 0xf22e017f
975 1008
976/*P2_AGC2I1*/ 1009/*P2_AGC2I1*/
977#define R0900_P2_AGC2I1 0xf236 1010#define R0900_P2_AGC2I1 0xf236
978#define F0900_P2_AGC2_INTEGRATOR1 0xf23600ff 1011#define F0900_P2_AGC2_INTEGRATOR1 0xf23600ff
979 1012
980/*P2_AGC2I0*/ 1013/*P2_AGC2I0*/
981#define R0900_P2_AGC2I0 0xf237 1014#define R0900_P2_AGC2I0 0xf237
982#define F0900_P2_AGC2_INTEGRATOR0 0xf23700ff 1015#define F0900_P2_AGC2_INTEGRATOR0 0xf23700ff
983 1016
984/*P2_CARCFG*/ 1017/*P2_CARCFG*/
985#define R0900_P2_CARCFG 0xf238 1018#define R0900_P2_CARCFG 0xf238
986#define F0900_P2_CFRUPLOW_AUTO 0xf2380080 1019#define F0900_P2_CFRUPLOW_AUTO 0xf2380080
987#define F0900_P2_CFRUPLOW_TEST 0xf2380040 1020#define F0900_P2_CFRUPLOW_TEST 0xf2380040
988#define F0900_P2_EN_CAR2CENTER 0xf2380020 1021#define F0900_P2_ROTAON 0xf2380004
989#define F0900_P2_CARHDR_NODIV8 0xf2380010 1022#define F0900_P2_PH_DET_ALGO 0xf2380003
990#define F0900_P2_I2C_ROTA 0xf2380008
991#define F0900_P2_ROTAON 0xf2380004
992#define F0900_P2_PH_DET_ALGO 0xf2380003
993 1023
994/*P2_ACLC*/ 1024/*P2_ACLC*/
995#define R0900_P2_ACLC 0xf239 1025#define R0900_P2_ACLC 0xf239
996#define F0900_P2_STOP_S2ALPHA 0xf23900c0 1026#define F0900_P2_CAR_ALPHA_MANT 0xf2390030
997#define F0900_P2_CAR_ALPHA_MANT 0xf2390030 1027#define F0900_P2_CAR_ALPHA_EXP 0xf239000f
998#define F0900_P2_CAR_ALPHA_EXP 0xf239000f
999 1028
1000/*P2_BCLC*/ 1029/*P2_BCLC*/
1001#define R0900_P2_BCLC 0xf23a 1030#define R0900_P2_BCLC 0xf23a
1002#define F0900_P2_STOP_S2BETA 0xf23a00c0 1031#define F0900_P2_CAR_BETA_MANT 0xf23a0030
1003#define F0900_P2_CAR_BETA_MANT 0xf23a0030 1032#define F0900_P2_CAR_BETA_EXP 0xf23a000f
1004#define F0900_P2_CAR_BETA_EXP 0xf23a000f
1005 1033
1006/*P2_CARFREQ*/ 1034/*P2_CARFREQ*/
1007#define R0900_P2_CARFREQ 0xf23d 1035#define R0900_P2_CARFREQ 0xf23d
1008#define F0900_P2_KC_COARSE_EXP 0xf23d00f0 1036#define F0900_P2_KC_COARSE_EXP 0xf23d00f0
1009#define F0900_P2_BETA_FREQ 0xf23d000f 1037#define F0900_P2_BETA_FREQ 0xf23d000f
1010 1038
1011/*P2_CARHDR*/ 1039/*P2_CARHDR*/
1012#define R0900_P2_CARHDR 0xf23e 1040#define R0900_P2_CARHDR 0xf23e
1013#define F0900_P2_K_FREQ_HDR 0xf23e00ff 1041#define F0900_P2_K_FREQ_HDR 0xf23e00ff
1014 1042
1015/*P2_LDT*/ 1043/*P2_LDT*/
1016#define R0900_P2_LDT 0xf23f 1044#define R0900_P2_LDT 0xf23f
1017#define F0900_P2_CARLOCK_THRES 0xf23f01ff 1045#define F0900_P2_CARLOCK_THRES 0xf23f01ff
1018 1046
1019/*P2_LDT2*/ 1047/*P2_LDT2*/
1020#define R0900_P2_LDT2 0xf240 1048#define R0900_P2_LDT2 0xf240
1021#define F0900_P2_CARLOCK_THRES2 0xf24001ff 1049#define F0900_P2_CARLOCK_THRES2 0xf24001ff
1022 1050
1023/*P2_CFRICFG*/ 1051/*P2_CFRICFG*/
1024#define R0900_P2_CFRICFG 0xf241 1052#define R0900_P2_CFRICFG 0xf241
1025#define F0900_P2_CFRINIT_UNVALRNG 0xf2410080 1053#define F0900_P2_NEG_CFRSTEP 0xf2410001
1026#define F0900_P2_CFRINIT_LUNVALCPT 0xf2410040
1027#define F0900_P2_CFRINIT_ABORTDBL 0xf2410020
1028#define F0900_P2_CFRINIT_ABORTPRED 0xf2410010
1029#define F0900_P2_CFRINIT_UNVALSKIP 0xf2410008
1030#define F0900_P2_CFRINIT_CSTINC 0xf2410004
1031#define F0900_P2_NEG_CFRSTEP 0xf2410001
1032 1054
1033/*P2_CFRUP1*/ 1055/*P2_CFRUP1*/
1034#define R0900_P2_CFRUP1 0xf242 1056#define R0900_P2_CFRUP1 0xf242
1035#define F0900_P2_CFR_UP1 0xf24201ff 1057#define F0900_P2_CFR_UP1 0xf24201ff
1036 1058
1037/*P2_CFRUP0*/ 1059/*P2_CFRUP0*/
1038#define R0900_P2_CFRUP0 0xf243 1060#define R0900_P2_CFRUP0 0xf243
1039#define F0900_P2_CFR_UP0 0xf24300ff 1061#define F0900_P2_CFR_UP0 0xf24300ff
1040 1062
1041/*P2_CFRLOW1*/ 1063/*P2_CFRLOW1*/
1042#define R0900_P2_CFRLOW1 0xf246 1064#define R0900_P2_CFRLOW1 0xf246
1043#define F0900_P2_CFR_LOW1 0xf24601ff 1065#define F0900_P2_CFR_LOW1 0xf24601ff
1044 1066
1045/*P2_CFRLOW0*/ 1067/*P2_CFRLOW0*/
1046#define R0900_P2_CFRLOW0 0xf247 1068#define R0900_P2_CFRLOW0 0xf247
1047#define F0900_P2_CFR_LOW0 0xf24700ff 1069#define F0900_P2_CFR_LOW0 0xf24700ff
1048 1070
1049/*P2_CFRINIT1*/ 1071/*P2_CFRINIT1*/
1050#define R0900_P2_CFRINIT1 0xf248 1072#define R0900_P2_CFRINIT1 0xf248
1051#define F0900_P2_CFR_INIT1 0xf24801ff 1073#define F0900_P2_CFR_INIT1 0xf24801ff
1052 1074
1053/*P2_CFRINIT0*/ 1075/*P2_CFRINIT0*/
1054#define R0900_P2_CFRINIT0 0xf249 1076#define R0900_P2_CFRINIT0 0xf249
1055#define F0900_P2_CFR_INIT0 0xf24900ff 1077#define F0900_P2_CFR_INIT0 0xf24900ff
1056 1078
1057/*P2_CFRINC1*/ 1079/*P2_CFRINC1*/
1058#define R0900_P2_CFRINC1 0xf24a 1080#define R0900_P2_CFRINC1 0xf24a
1059#define F0900_P2_MANUAL_CFRINC 0xf24a0080 1081#define F0900_P2_MANUAL_CFRINC 0xf24a0080
1060#define F0900_P2_CFR_INC1 0xf24a017f 1082#define F0900_P2_CFR_INC1 0xf24a003f
1061 1083
1062/*P2_CFRINC0*/ 1084/*P2_CFRINC0*/
1063#define R0900_P2_CFRINC0 0xf24b 1085#define R0900_P2_CFRINC0 0xf24b
1064#define F0900_P2_CFR_INC0 0xf24b00f0 1086#define F0900_P2_CFR_INC0 0xf24b00f8
1065 1087
1066/*P2_CFR2*/ 1088/*P2_CFR2*/
1067#define R0900_P2_CFR2 0xf24c 1089#define R0900_P2_CFR2 0xf24c
1068#define F0900_P2_CAR_FREQ2 0xf24c01ff 1090#define F0900_P2_CAR_FREQ2 0xf24c01ff
1069 1091
1070/*P2_CFR1*/ 1092/*P2_CFR1*/
1071#define R0900_P2_CFR1 0xf24d 1093#define R0900_P2_CFR1 0xf24d
1072#define F0900_P2_CAR_FREQ1 0xf24d00ff 1094#define F0900_P2_CAR_FREQ1 0xf24d00ff
1073 1095
1074/*P2_CFR0*/ 1096/*P2_CFR0*/
1075#define R0900_P2_CFR0 0xf24e 1097#define R0900_P2_CFR0 0xf24e
1076#define F0900_P2_CAR_FREQ0 0xf24e00ff 1098#define F0900_P2_CAR_FREQ0 0xf24e00ff
1077 1099
1078/*P2_LDI*/ 1100/*P2_LDI*/
1079#define R0900_P2_LDI 0xf24f 1101#define R0900_P2_LDI 0xf24f
1080#define F0900_P2_LOCK_DET_INTEGR 0xf24f01ff 1102#define F0900_P2_LOCK_DET_INTEGR 0xf24f01ff
1081 1103
1082/*P2_TMGCFG*/ 1104/*P2_TMGCFG*/
1083#define R0900_P2_TMGCFG 0xf250 1105#define R0900_P2_TMGCFG 0xf250
1084#define F0900_P2_TMGLOCK_BETA 0xf25000c0 1106#define F0900_P2_TMGLOCK_BETA 0xf25000c0
1085#define F0900_P2_NOTMG_GROUPDELAY 0xf2500020 1107#define F0900_P2_DO_TIMING_CORR 0xf2500010
1086#define F0900_P2_DO_TIMING_CORR 0xf2500010 1108#define F0900_P2_TMG_MINFREQ 0xf2500003
1087#define F0900_P2_MANUAL_SCAN 0xf250000c
1088#define F0900_P2_TMG_MINFREQ 0xf2500003
1089 1109
1090/*P2_RTC*/ 1110/*P2_RTC*/
1091#define R0900_P2_RTC 0xf251 1111#define R0900_P2_RTC 0xf251
1092#define F0900_P2_TMGALPHA_EXP 0xf25100f0 1112#define F0900_P2_TMGALPHA_EXP 0xf25100f0
1093#define F0900_P2_TMGBETA_EXP 0xf251000f 1113#define F0900_P2_TMGBETA_EXP 0xf251000f
1094 1114
1095/*P2_RTCS2*/ 1115/*P2_RTCS2*/
1096#define R0900_P2_RTCS2 0xf252 1116#define R0900_P2_RTCS2 0xf252
1097#define F0900_P2_TMGALPHAS2_EXP 0xf25200f0 1117#define F0900_P2_TMGALPHAS2_EXP 0xf25200f0
1098#define F0900_P2_TMGBETAS2_EXP 0xf252000f 1118#define F0900_P2_TMGBETAS2_EXP 0xf252000f
1099 1119
1100/*P2_TMGTHRISE*/ 1120/*P2_TMGTHRISE*/
1101#define R0900_P2_TMGTHRISE 0xf253 1121#define R0900_P2_TMGTHRISE 0xf253
1102#define F0900_P2_TMGLOCK_THRISE 0xf25300ff 1122#define F0900_P2_TMGLOCK_THRISE 0xf25300ff
1103 1123
1104/*P2_TMGTHFALL*/ 1124/*P2_TMGTHFALL*/
1105#define R0900_P2_TMGTHFALL 0xf254 1125#define R0900_P2_TMGTHFALL 0xf254
1106#define F0900_P2_TMGLOCK_THFALL 0xf25400ff 1126#define F0900_P2_TMGLOCK_THFALL 0xf25400ff
1107 1127
1108/*P2_SFRUPRATIO*/ 1128/*P2_SFRUPRATIO*/
1109#define R0900_P2_SFRUPRATIO 0xf255 1129#define R0900_P2_SFRUPRATIO 0xf255
1110#define F0900_P2_SFR_UPRATIO 0xf25500ff 1130#define F0900_P2_SFR_UPRATIO 0xf25500ff
1111 1131
1112/*P2_SFRLOWRATIO*/ 1132/*P2_SFRLOWRATIO*/
1113#define R0900_P2_SFRLOWRATIO 0xf256 1133#define R0900_P2_SFRLOWRATIO 0xf256
1114#define F0900_P2_SFR_LOWRATIO 0xf25600ff 1134#define F0900_P2_SFR_LOWRATIO 0xf25600ff
1115 1135
1116/*P2_KREFTMG*/ 1136/*P2_KREFTMG*/
1117#define R0900_P2_KREFTMG 0xf258 1137#define R0900_P2_KREFTMG 0xf258
1118#define F0900_P2_KREF_TMG 0xf25800ff 1138#define F0900_P2_KREF_TMG 0xf25800ff
1119 1139
1120/*P2_SFRSTEP*/ 1140/*P2_SFRSTEP*/
1121#define R0900_P2_SFRSTEP 0xf259 1141#define R0900_P2_SFRSTEP 0xf259
1122#define F0900_P2_SFR_SCANSTEP 0xf25900f0 1142#define F0900_P2_SFR_SCANSTEP 0xf25900f0
1123#define F0900_P2_SFR_CENTERSTEP 0xf259000f 1143#define F0900_P2_SFR_CENTERSTEP 0xf259000f
1124 1144
1125/*P2_TMGCFG2*/ 1145/*P2_TMGCFG2*/
1126#define R0900_P2_TMGCFG2 0xf25a 1146#define R0900_P2_TMGCFG2 0xf25a
1127#define F0900_P2_DIS_AUTOSAMP 0xf25a0008 1147#define F0900_P2_SFRRATIO_FINE 0xf25a0001
1128#define F0900_P2_SCANINIT_QUART 0xf25a0004 1148
1129#define F0900_P2_NOTMG_DVBS1DERAT 0xf25a0002 1149/*P2_KREFTMG2*/
1130#define F0900_P2_SFRRATIO_FINE 0xf25a0001 1150#define R0900_P2_KREFTMG2 0xf25b
1151#define F0900_P2_KREF_TMG2 0xf25b00ff
1131 1152
1132/*P2_SFRINIT1*/ 1153/*P2_SFRINIT1*/
1133#define R0900_P2_SFRINIT1 0xf25e 1154#define R0900_P2_SFRINIT1 0xf25e
1134#define F0900_P2_SFR_INIT1 0xf25e00ff 1155#define F0900_P2_SFR_INIT1 0xf25e007f
1135 1156
1136/*P2_SFRINIT0*/ 1157/*P2_SFRINIT0*/
1137#define R0900_P2_SFRINIT0 0xf25f 1158#define R0900_P2_SFRINIT0 0xf25f
1138#define F0900_P2_SFR_INIT0 0xf25f00ff 1159#define F0900_P2_SFR_INIT0 0xf25f00ff
1139 1160
1140/*P2_SFRUP1*/ 1161/*P2_SFRUP1*/
1141#define R0900_P2_SFRUP1 0xf260 1162#define R0900_P2_SFRUP1 0xf260
1142#define F0900_P2_AUTO_GUP 0xf2600080 1163#define F0900_P2_AUTO_GUP 0xf2600080
1143#define F0900_P2_SYMB_FREQ_UP1 0xf260007f 1164#define F0900_P2_SYMB_FREQ_UP1 0xf260007f
1144 1165
1145/*P2_SFRUP0*/ 1166/*P2_SFRUP0*/
1146#define R0900_P2_SFRUP0 0xf261 1167#define R0900_P2_SFRUP0 0xf261
1147#define F0900_P2_SYMB_FREQ_UP0 0xf26100ff 1168#define F0900_P2_SYMB_FREQ_UP0 0xf26100ff
1148 1169
1149/*P2_SFRLOW1*/ 1170/*P2_SFRLOW1*/
1150#define R0900_P2_SFRLOW1 0xf262 1171#define R0900_P2_SFRLOW1 0xf262
1151#define F0900_P2_AUTO_GLOW 0xf2620080 1172#define F0900_P2_AUTO_GLOW 0xf2620080
1152#define F0900_P2_SYMB_FREQ_LOW1 0xf262007f 1173#define F0900_P2_SYMB_FREQ_LOW1 0xf262007f
1153 1174
1154/*P2_SFRLOW0*/ 1175/*P2_SFRLOW0*/
1155#define R0900_P2_SFRLOW0 0xf263 1176#define R0900_P2_SFRLOW0 0xf263
1156#define F0900_P2_SYMB_FREQ_LOW0 0xf26300ff 1177#define F0900_P2_SYMB_FREQ_LOW0 0xf26300ff
1157 1178
1158/*P2_SFR3*/ 1179/*P2_SFR3*/
1159#define R0900_P2_SFR3 0xf264 1180#define R0900_P2_SFR3 0xf264
1160#define F0900_P2_SYMB_FREQ3 0xf26400ff 1181#define F0900_P2_SYMB_FREQ3 0xf26400ff
1161 1182
1162/*P2_SFR2*/ 1183/*P2_SFR2*/
1163#define R0900_P2_SFR2 0xf265 1184#define R0900_P2_SFR2 0xf265
1164#define F0900_P2_SYMB_FREQ2 0xf26500ff 1185#define F0900_P2_SYMB_FREQ2 0xf26500ff
1165 1186
1166/*P2_SFR1*/ 1187/*P2_SFR1*/
1167#define R0900_P2_SFR1 0xf266 1188#define R0900_P2_SFR1 0xf266
1168#define F0900_P2_SYMB_FREQ1 0xf26600ff 1189#define F0900_P2_SYMB_FREQ1 0xf26600ff
1169 1190
1170/*P2_SFR0*/ 1191/*P2_SFR0*/
1171#define R0900_P2_SFR0 0xf267 1192#define R0900_P2_SFR0 0xf267
1172#define F0900_P2_SYMB_FREQ0 0xf26700ff 1193#define F0900_P2_SYMB_FREQ0 0xf26700ff
1173 1194
1174/*P2_TMGREG2*/ 1195/*P2_TMGREG2*/
1175#define R0900_P2_TMGREG2 0xf268 1196#define R0900_P2_TMGREG2 0xf268
1176#define F0900_P2_TMGREG2 0xf26800ff 1197#define F0900_P2_TMGREG2 0xf26800ff
1177 1198
1178/*P2_TMGREG1*/ 1199/*P2_TMGREG1*/
1179#define R0900_P2_TMGREG1 0xf269 1200#define R0900_P2_TMGREG1 0xf269
1180#define F0900_P2_TMGREG1 0xf26900ff 1201#define F0900_P2_TMGREG1 0xf26900ff
1181 1202
1182/*P2_TMGREG0*/ 1203/*P2_TMGREG0*/
1183#define R0900_P2_TMGREG0 0xf26a 1204#define R0900_P2_TMGREG0 0xf26a
1184#define F0900_P2_TMGREG0 0xf26a00ff 1205#define F0900_P2_TMGREG0 0xf26a00ff
1185 1206
1186/*P2_TMGLOCK1*/ 1207/*P2_TMGLOCK1*/
1187#define R0900_P2_TMGLOCK1 0xf26b 1208#define R0900_P2_TMGLOCK1 0xf26b
1188#define F0900_P2_TMGLOCK_LEVEL1 0xf26b01ff 1209#define F0900_P2_TMGLOCK_LEVEL1 0xf26b01ff
1189 1210
1190/*P2_TMGLOCK0*/ 1211/*P2_TMGLOCK0*/
1191#define R0900_P2_TMGLOCK0 0xf26c 1212#define R0900_P2_TMGLOCK0 0xf26c
1192#define F0900_P2_TMGLOCK_LEVEL0 0xf26c00ff 1213#define F0900_P2_TMGLOCK_LEVEL0 0xf26c00ff
1193 1214
1194/*P2_TMGOBS*/ 1215/*P2_TMGOBS*/
1195#define R0900_P2_TMGOBS 0xf26d 1216#define R0900_P2_TMGOBS 0xf26d
1196#define F0900_P2_ROLLOFF_STATUS 0xf26d00c0 1217#define F0900_P2_ROLLOFF_STATUS 0xf26d00c0
1197#define F0900_P2_SCAN_SIGN 0xf26d0030
1198#define F0900_P2_TMG_SCANNING 0xf26d0008
1199#define F0900_P2_CHCENTERING_MODE 0xf26d0004
1200#define F0900_P2_TMG_SCANFAIL 0xf26d0002
1201 1218
1202/*P2_EQUALCFG*/ 1219/*P2_EQUALCFG*/
1203#define R0900_P2_EQUALCFG 0xf26f 1220#define R0900_P2_EQUALCFG 0xf26f
1204#define F0900_P2_NOTMG_NEGALWAIT 0xf26f0080 1221#define F0900_P2_EQUAL_ON 0xf26f0040
1205#define F0900_P2_EQUAL_ON 0xf26f0040 1222#define F0900_P2_MU_EQUALDFE 0xf26f0007
1206#define F0900_P2_SEL_EQUALCOR 0xf26f0038
1207#define F0900_P2_MU_EQUALDFE 0xf26f0007
1208 1223
1209/*P2_EQUAI1*/ 1224/*P2_EQUAI1*/
1210#define R0900_P2_EQUAI1 0xf270 1225#define R0900_P2_EQUAI1 0xf270
1211#define F0900_P2_EQUA_ACCI1 0xf27001ff 1226#define F0900_P2_EQUA_ACCI1 0xf27001ff
1212 1227
1213/*P2_EQUAQ1*/ 1228/*P2_EQUAQ1*/
1214#define R0900_P2_EQUAQ1 0xf271 1229#define R0900_P2_EQUAQ1 0xf271
1215#define F0900_P2_EQUA_ACCQ1 0xf27101ff 1230#define F0900_P2_EQUA_ACCQ1 0xf27101ff
1216 1231
1217/*P2_EQUAI2*/ 1232/*P2_EQUAI2*/
1218#define R0900_P2_EQUAI2 0xf272 1233#define R0900_P2_EQUAI2 0xf272
1219#define F0900_P2_EQUA_ACCI2 0xf27201ff 1234#define F0900_P2_EQUA_ACCI2 0xf27201ff
1220 1235
1221/*P2_EQUAQ2*/ 1236/*P2_EQUAQ2*/
1222#define R0900_P2_EQUAQ2 0xf273 1237#define R0900_P2_EQUAQ2 0xf273
1223#define F0900_P2_EQUA_ACCQ2 0xf27301ff 1238#define F0900_P2_EQUA_ACCQ2 0xf27301ff
1224 1239
1225/*P2_EQUAI3*/ 1240/*P2_EQUAI3*/
1226#define R0900_P2_EQUAI3 0xf274 1241#define R0900_P2_EQUAI3 0xf274
1227#define F0900_P2_EQUA_ACCI3 0xf27401ff 1242#define F0900_P2_EQUA_ACCI3 0xf27401ff
1228 1243
1229/*P2_EQUAQ3*/ 1244/*P2_EQUAQ3*/
1230#define R0900_P2_EQUAQ3 0xf275 1245#define R0900_P2_EQUAQ3 0xf275
1231#define F0900_P2_EQUA_ACCQ3 0xf27501ff 1246#define F0900_P2_EQUA_ACCQ3 0xf27501ff
1232 1247
1233/*P2_EQUAI4*/ 1248/*P2_EQUAI4*/
1234#define R0900_P2_EQUAI4 0xf276 1249#define R0900_P2_EQUAI4 0xf276
1235#define F0900_P2_EQUA_ACCI4 0xf27601ff 1250#define F0900_P2_EQUA_ACCI4 0xf27601ff
1236 1251
1237/*P2_EQUAQ4*/ 1252/*P2_EQUAQ4*/
1238#define R0900_P2_EQUAQ4 0xf277 1253#define R0900_P2_EQUAQ4 0xf277
1239#define F0900_P2_EQUA_ACCQ4 0xf27701ff 1254#define F0900_P2_EQUA_ACCQ4 0xf27701ff
1240 1255
1241/*P2_EQUAI5*/ 1256/*P2_EQUAI5*/
1242#define R0900_P2_EQUAI5 0xf278 1257#define R0900_P2_EQUAI5 0xf278
1243#define F0900_P2_EQUA_ACCI5 0xf27801ff 1258#define F0900_P2_EQUA_ACCI5 0xf27801ff
1244 1259
1245/*P2_EQUAQ5*/ 1260/*P2_EQUAQ5*/
1246#define R0900_P2_EQUAQ5 0xf279 1261#define R0900_P2_EQUAQ5 0xf279
1247#define F0900_P2_EQUA_ACCQ5 0xf27901ff 1262#define F0900_P2_EQUA_ACCQ5 0xf27901ff
1248 1263
1249/*P2_EQUAI6*/ 1264/*P2_EQUAI6*/
1250#define R0900_P2_EQUAI6 0xf27a 1265#define R0900_P2_EQUAI6 0xf27a
1251#define F0900_P2_EQUA_ACCI6 0xf27a01ff 1266#define F0900_P2_EQUA_ACCI6 0xf27a01ff
1252 1267
1253/*P2_EQUAQ6*/ 1268/*P2_EQUAQ6*/
1254#define R0900_P2_EQUAQ6 0xf27b 1269#define R0900_P2_EQUAQ6 0xf27b
1255#define F0900_P2_EQUA_ACCQ6 0xf27b01ff 1270#define F0900_P2_EQUA_ACCQ6 0xf27b01ff
1256 1271
1257/*P2_EQUAI7*/ 1272/*P2_EQUAI7*/
1258#define R0900_P2_EQUAI7 0xf27c 1273#define R0900_P2_EQUAI7 0xf27c
1259#define F0900_P2_EQUA_ACCI7 0xf27c01ff 1274#define F0900_P2_EQUA_ACCI7 0xf27c01ff
1260 1275
1261/*P2_EQUAQ7*/ 1276/*P2_EQUAQ7*/
1262#define R0900_P2_EQUAQ7 0xf27d 1277#define R0900_P2_EQUAQ7 0xf27d
1263#define F0900_P2_EQUA_ACCQ7 0xf27d01ff 1278#define F0900_P2_EQUA_ACCQ7 0xf27d01ff
1264 1279
1265/*P2_EQUAI8*/ 1280/*P2_EQUAI8*/
1266#define R0900_P2_EQUAI8 0xf27e 1281#define R0900_P2_EQUAI8 0xf27e
1267#define F0900_P2_EQUA_ACCI8 0xf27e01ff 1282#define F0900_P2_EQUA_ACCI8 0xf27e01ff
1268 1283
1269/*P2_EQUAQ8*/ 1284/*P2_EQUAQ8*/
1270#define R0900_P2_EQUAQ8 0xf27f 1285#define R0900_P2_EQUAQ8 0xf27f
1271#define F0900_P2_EQUA_ACCQ8 0xf27f01ff 1286#define F0900_P2_EQUA_ACCQ8 0xf27f01ff
1272 1287
1273/*P2_NNOSDATAT1*/ 1288/*P2_NNOSDATAT1*/
1274#define R0900_P2_NNOSDATAT1 0xf280 1289#define R0900_P2_NNOSDATAT1 0xf280
1275#define F0900_P2_NOSDATAT_NORMED1 0xf28000ff 1290#define F0900_P2_NOSDATAT_NORMED1 0xf28000ff
1276 1291
1277/*P2_NNOSDATAT0*/ 1292/*P2_NNOSDATAT0*/
1278#define R0900_P2_NNOSDATAT0 0xf281 1293#define R0900_P2_NNOSDATAT0 0xf281
1279#define F0900_P2_NOSDATAT_NORMED0 0xf28100ff 1294#define F0900_P2_NOSDATAT_NORMED0 0xf28100ff
1280 1295
1281/*P2_NNOSDATA1*/ 1296/*P2_NNOSDATA1*/
1282#define R0900_P2_NNOSDATA1 0xf282 1297#define R0900_P2_NNOSDATA1 0xf282
1283#define F0900_P2_NOSDATA_NORMED1 0xf28200ff 1298#define F0900_P2_NOSDATA_NORMED1 0xf28200ff
1284 1299
1285/*P2_NNOSDATA0*/ 1300/*P2_NNOSDATA0*/
1286#define R0900_P2_NNOSDATA0 0xf283 1301#define R0900_P2_NNOSDATA0 0xf283
1287#define F0900_P2_NOSDATA_NORMED0 0xf28300ff 1302#define F0900_P2_NOSDATA_NORMED0 0xf28300ff
1288 1303
1289/*P2_NNOSPLHT1*/ 1304/*P2_NNOSPLHT1*/
1290#define R0900_P2_NNOSPLHT1 0xf284 1305#define R0900_P2_NNOSPLHT1 0xf284
1291#define F0900_P2_NOSPLHT_NORMED1 0xf28400ff 1306#define F0900_P2_NOSPLHT_NORMED1 0xf28400ff
1292 1307
1293/*P2_NNOSPLHT0*/ 1308/*P2_NNOSPLHT0*/
1294#define R0900_P2_NNOSPLHT0 0xf285 1309#define R0900_P2_NNOSPLHT0 0xf285
1295#define F0900_P2_NOSPLHT_NORMED0 0xf28500ff 1310#define F0900_P2_NOSPLHT_NORMED0 0xf28500ff
1296 1311
1297/*P2_NNOSPLH1*/ 1312/*P2_NNOSPLH1*/
1298#define R0900_P2_NNOSPLH1 0xf286 1313#define R0900_P2_NNOSPLH1 0xf286
1299#define F0900_P2_NOSPLH_NORMED1 0xf28600ff 1314#define F0900_P2_NOSPLH_NORMED1 0xf28600ff
1300 1315
1301/*P2_NNOSPLH0*/ 1316/*P2_NNOSPLH0*/
1302#define R0900_P2_NNOSPLH0 0xf287 1317#define R0900_P2_NNOSPLH0 0xf287
1303#define F0900_P2_NOSPLH_NORMED0 0xf28700ff 1318#define F0900_P2_NOSPLH_NORMED0 0xf28700ff
1304 1319
1305/*P2_NOSDATAT1*/ 1320/*P2_NOSDATAT1*/
1306#define R0900_P2_NOSDATAT1 0xf288 1321#define R0900_P2_NOSDATAT1 0xf288
1307#define F0900_P2_NOSDATAT_UNNORMED1 0xf28800ff 1322#define F0900_P2_NOSDATAT_UNNORMED1 0xf28800ff
1308 1323
1309/*P2_NOSDATAT0*/ 1324/*P2_NOSDATAT0*/
1310#define R0900_P2_NOSDATAT0 0xf289 1325#define R0900_P2_NOSDATAT0 0xf289
1311#define F0900_P2_NOSDATAT_UNNORMED0 0xf28900ff 1326#define F0900_P2_NOSDATAT_UNNORMED0 0xf28900ff
1312 1327
1313/*P2_NOSDATA1*/ 1328/*P2_NOSDATA1*/
1314#define R0900_P2_NOSDATA1 0xf28a 1329#define R0900_P2_NOSDATA1 0xf28a
1315#define F0900_P2_NOSDATA_UNNORMED1 0xf28a00ff 1330#define F0900_P2_NOSDATA_UNNORMED1 0xf28a00ff
1316 1331
1317/*P2_NOSDATA0*/ 1332/*P2_NOSDATA0*/
1318#define R0900_P2_NOSDATA0 0xf28b 1333#define R0900_P2_NOSDATA0 0xf28b
1319#define F0900_P2_NOSDATA_UNNORMED0 0xf28b00ff 1334#define F0900_P2_NOSDATA_UNNORMED0 0xf28b00ff
1320 1335
1321/*P2_NOSPLHT1*/ 1336/*P2_NOSPLHT1*/
1322#define R0900_P2_NOSPLHT1 0xf28c 1337#define R0900_P2_NOSPLHT1 0xf28c
1323#define F0900_P2_NOSPLHT_UNNORMED1 0xf28c00ff 1338#define F0900_P2_NOSPLHT_UNNORMED1 0xf28c00ff
1324 1339
1325/*P2_NOSPLHT0*/ 1340/*P2_NOSPLHT0*/
1326#define R0900_P2_NOSPLHT0 0xf28d 1341#define R0900_P2_NOSPLHT0 0xf28d
1327#define F0900_P2_NOSPLHT_UNNORMED0 0xf28d00ff 1342#define F0900_P2_NOSPLHT_UNNORMED0 0xf28d00ff
1328 1343
1329/*P2_NOSPLH1*/ 1344/*P2_NOSPLH1*/
1330#define R0900_P2_NOSPLH1 0xf28e 1345#define R0900_P2_NOSPLH1 0xf28e
1331#define F0900_P2_NOSPLH_UNNORMED1 0xf28e00ff 1346#define F0900_P2_NOSPLH_UNNORMED1 0xf28e00ff
1332 1347
1333/*P2_NOSPLH0*/ 1348/*P2_NOSPLH0*/
1334#define R0900_P2_NOSPLH0 0xf28f 1349#define R0900_P2_NOSPLH0 0xf28f
1335#define F0900_P2_NOSPLH_UNNORMED0 0xf28f00ff 1350#define F0900_P2_NOSPLH_UNNORMED0 0xf28f00ff
1336 1351
1337/*P2_CAR2CFG*/ 1352/*P2_CAR2CFG*/
1338#define R0900_P2_CAR2CFG 0xf290 1353#define R0900_P2_CAR2CFG 0xf290
1339#define F0900_P2_DESCRAMB_OFF 0xf2900080 1354#define F0900_P2_CARRIER3_DISABLE 0xf2900040
1340#define F0900_P2_PN4_SELECT 0xf2900040 1355#define F0900_P2_ROTA2ON 0xf2900004
1341#define F0900_P2_CFR2_STOPDVBS1 0xf2900020 1356#define F0900_P2_PH_DET_ALGO2 0xf2900003
1342#define F0900_P2_STOP_CFR2UPDATE 0xf2900010 1357
1343#define F0900_P2_STOP_NCO2UPDATE 0xf2900008 1358/*P2_CFR2CFR1*/
1344#define F0900_P2_ROTA2ON 0xf2900004 1359#define R0900_P2_CFR2CFR1 0xf291
1345#define F0900_P2_PH_DET_ALGO2 0xf2900003 1360#define F0900_P2_CFR2TOCFR1_DVBS1 0xf29100c0
1346 1361#define F0900_P2_EN_S2CAR2CENTER 0xf2910020
1347/*P2_ACLC2*/ 1362#define F0900_P2_DIS_BCHERRCFR2 0xf2910010
1348#define R0900_P2_ACLC2 0xf291 1363#define F0900_P2_CFR2TOCFR1_BETA 0xf2910007
1349#define F0900_P2_CAR2_PUNCT_ADERAT 0xf2910040
1350#define F0900_P2_CAR2_ALPHA_MANT 0xf2910030
1351#define F0900_P2_CAR2_ALPHA_EXP 0xf291000f
1352
1353/*P2_BCLC2*/
1354#define R0900_P2_BCLC2 0xf292
1355#define F0900_P2_DVBS2_NIP 0xf2920080
1356#define F0900_P2_CAR2_PUNCT_BDERAT 0xf2920040
1357#define F0900_P2_CAR2_BETA_MANT 0xf2920030
1358#define F0900_P2_CAR2_BETA_EXP 0xf292000f
1359 1364
1360/*P2_CFR22*/ 1365/*P2_CFR22*/
1361#define R0900_P2_CFR22 0xf293 1366#define R0900_P2_CFR22 0xf293
1362#define F0900_P2_CAR2_FREQ2 0xf29301ff 1367#define F0900_P2_CAR2_FREQ2 0xf29301ff
1363 1368
1364/*P2_CFR21*/ 1369/*P2_CFR21*/
1365#define R0900_P2_CFR21 0xf294 1370#define R0900_P2_CFR21 0xf294
1366#define F0900_P2_CAR2_FREQ1 0xf29400ff 1371#define F0900_P2_CAR2_FREQ1 0xf29400ff
1367 1372
1368/*P2_CFR20*/ 1373/*P2_CFR20*/
1369#define R0900_P2_CFR20 0xf295 1374#define R0900_P2_CFR20 0xf295
1370#define F0900_P2_CAR2_FREQ0 0xf29500ff 1375#define F0900_P2_CAR2_FREQ0 0xf29500ff
1371 1376
1372/*P2_ACLC2S2Q*/ 1377/*P2_ACLC2S2Q*/
1373#define R0900_P2_ACLC2S2Q 0xf297 1378#define R0900_P2_ACLC2S2Q 0xf297
1374#define F0900_P2_ENAB_SPSKSYMB 0xf2970080 1379#define F0900_P2_ENAB_SPSKSYMB 0xf2970080
1375#define F0900_P2_CAR2S2_QADERAT 0xf2970040 1380#define F0900_P2_CAR2S2_Q_ALPH_M 0xf2970030
1376#define F0900_P2_CAR2S2_Q_ALPH_M 0xf2970030 1381#define F0900_P2_CAR2S2_Q_ALPH_E 0xf297000f
1377#define F0900_P2_CAR2S2_Q_ALPH_E 0xf297000f
1378 1382
1379/*P2_ACLC2S28*/ 1383/*P2_ACLC2S28*/
1380#define R0900_P2_ACLC2S28 0xf298 1384#define R0900_P2_ACLC2S28 0xf298
1381#define F0900_P2_OLDI3Q_MODE 0xf2980080 1385#define F0900_P2_OLDI3Q_MODE 0xf2980080
1382#define F0900_P2_CAR2S2_8ADERAT 0xf2980040 1386#define F0900_P2_CAR2S2_8_ALPH_M 0xf2980030
1383#define F0900_P2_CAR2S2_8_ALPH_M 0xf2980030 1387#define F0900_P2_CAR2S2_8_ALPH_E 0xf298000f
1384#define F0900_P2_CAR2S2_8_ALPH_E 0xf298000f
1385 1388
1386/*P2_ACLC2S216A*/ 1389/*P2_ACLC2S216A*/
1387#define R0900_P2_ACLC2S216A 0xf299 1390#define R0900_P2_ACLC2S216A 0xf299
1388#define F0900_P2_CAR2S2_16ADERAT 0xf2990040 1391#define F0900_P2_DIS_C3STOPA2 0xf2990080
1389#define F0900_P2_CAR2S2_16A_ALPH_M 0xf2990030 1392#define F0900_P2_CAR2S2_16ADERAT 0xf2990040
1390#define F0900_P2_CAR2S2_16A_ALPH_E 0xf299000f 1393#define F0900_P2_CAR2S2_16A_ALPH_M 0xf2990030
1394#define F0900_P2_CAR2S2_16A_ALPH_E 0xf299000f
1391 1395
1392/*P2_ACLC2S232A*/ 1396/*P2_ACLC2S232A*/
1393#define R0900_P2_ACLC2S232A 0xf29a 1397#define R0900_P2_ACLC2S232A 0xf29a
1394#define F0900_P2_CAR2S2_32ADERAT 0xf29a0040 1398#define F0900_P2_CAR2S2_32ADERAT 0xf29a0040
1395#define F0900_P2_CAR2S2_32A_ALPH_M 0xf29a0030 1399#define F0900_P2_CAR2S2_32A_ALPH_M 0xf29a0030
1396#define F0900_P2_CAR2S2_32A_ALPH_E 0xf29a000f 1400#define F0900_P2_CAR2S2_32A_ALPH_E 0xf29a000f
1397 1401
1398/*P2_BCLC2S2Q*/ 1402/*P2_BCLC2S2Q*/
1399#define R0900_P2_BCLC2S2Q 0xf29c 1403#define R0900_P2_BCLC2S2Q 0xf29c
1400#define F0900_P2_DVBS2S2Q_NIP 0xf29c0080 1404#define F0900_P2_CAR2S2_Q_BETA_M 0xf29c0030
1401#define F0900_P2_CAR2S2_QBDERAT 0xf29c0040 1405#define F0900_P2_CAR2S2_Q_BETA_E 0xf29c000f
1402#define F0900_P2_CAR2S2_Q_BETA_M 0xf29c0030
1403#define F0900_P2_CAR2S2_Q_BETA_E 0xf29c000f
1404 1406
1405/*P2_BCLC2S28*/ 1407/*P2_BCLC2S28*/
1406#define R0900_P2_BCLC2S28 0xf29d 1408#define R0900_P2_BCLC2S28 0xf29d
1407#define F0900_P2_DVBS2S28_NIP 0xf29d0080 1409#define F0900_P2_CAR2S2_8_BETA_M 0xf29d0030
1408#define F0900_P2_CAR2S2_8BDERAT 0xf29d0040 1410#define F0900_P2_CAR2S2_8_BETA_E 0xf29d000f
1409#define F0900_P2_CAR2S2_8_BETA_M 0xf29d0030
1410#define F0900_P2_CAR2S2_8_BETA_E 0xf29d000f
1411 1411
1412/*P2_BCLC2S216A*/ 1412/*P2_BCLC2S216A*/
1413#define R0900_P2_BCLC2S216A 0xf29e 1413#define R0900_P2_BCLC2S216A 0xf29e
1414#define F0900_P2_DVBS2S216A_NIP 0xf29e0080
1415#define F0900_P2_CAR2S2_16BDERAT 0xf29e0040
1416#define F0900_P2_CAR2S2_16A_BETA_M 0xf29e0030
1417#define F0900_P2_CAR2S2_16A_BETA_E 0xf29e000f
1418 1414
1419/*P2_BCLC2S232A*/ 1415/*P2_BCLC2S232A*/
1420#define R0900_P2_BCLC2S232A 0xf29f 1416#define R0900_P2_BCLC2S232A 0xf29f
1421#define F0900_P2_DVBS2S232A_NIP 0xf29f0080
1422#define F0900_P2_CAR2S2_32BDERAT 0xf29f0040
1423#define F0900_P2_CAR2S2_32A_BETA_M 0xf29f0030
1424#define F0900_P2_CAR2S2_32A_BETA_E 0xf29f000f
1425 1417
1426/*P2_PLROOT2*/ 1418/*P2_PLROOT2*/
1427#define R0900_P2_PLROOT2 0xf2ac 1419#define R0900_P2_PLROOT2 0xf2ac
1428#define F0900_P2_SHORTFR_DISABLE 0xf2ac0080 1420#define F0900_P2_PLSCRAMB_MODE 0xf2ac000c
1429#define F0900_P2_LONGFR_DISABLE 0xf2ac0040 1421#define F0900_P2_PLSCRAMB_ROOT2 0xf2ac0003
1430#define F0900_P2_DUMMYPL_DISABLE 0xf2ac0020
1431#define F0900_P2_SHORTFR_AVOID 0xf2ac0010
1432#define F0900_P2_PLSCRAMB_MODE 0xf2ac000c
1433#define F0900_P2_PLSCRAMB_ROOT2 0xf2ac0003
1434 1422
1435/*P2_PLROOT1*/ 1423/*P2_PLROOT1*/
1436#define R0900_P2_PLROOT1 0xf2ad 1424#define R0900_P2_PLROOT1 0xf2ad
1437#define F0900_P2_PLSCRAMB_ROOT1 0xf2ad00ff 1425#define F0900_P2_PLSCRAMB_ROOT1 0xf2ad00ff
1438 1426
1439/*P2_PLROOT0*/ 1427/*P2_PLROOT0*/
1440#define R0900_P2_PLROOT0 0xf2ae 1428#define R0900_P2_PLROOT0 0xf2ae
1441#define F0900_P2_PLSCRAMB_ROOT0 0xf2ae00ff 1429#define F0900_P2_PLSCRAMB_ROOT0 0xf2ae00ff
1442 1430
1443/*P2_MODCODLST0*/ 1431/*P2_MODCODLST0*/
1444#define R0900_P2_MODCODLST0 0xf2b0 1432#define R0900_P2_MODCODLST0 0xf2b0
1445#define F0900_P2_EN_TOKEN31 0xf2b00080
1446#define F0900_P2_SYNCTAG_SELECT 0xf2b00040
1447#define F0900_P2_MODCODRQ_MODE 0xf2b00030
1448 1433
1449/*P2_MODCODLST1*/ 1434/*P2_MODCODLST1*/
1450#define R0900_P2_MODCODLST1 0xf2b1 1435#define R0900_P2_MODCODLST1 0xf2b1
1451#define F0900_P2_DIS_MODCOD29 0xf2b100f0 1436#define F0900_P2_DIS_MODCOD29 0xf2b100f0
1452#define F0900_P2_DIS_32PSK_9_10 0xf2b1000f 1437#define F0900_P2_DIS_32PSK_9_10 0xf2b1000f
1453 1438
1454/*P2_MODCODLST2*/ 1439/*P2_MODCODLST2*/
1455#define R0900_P2_MODCODLST2 0xf2b2 1440#define R0900_P2_MODCODLST2 0xf2b2
1456#define F0900_P2_DIS_32PSK_8_9 0xf2b200f0 1441#define F0900_P2_DIS_32PSK_8_9 0xf2b200f0
1457#define F0900_P2_DIS_32PSK_5_6 0xf2b2000f 1442#define F0900_P2_DIS_32PSK_5_6 0xf2b2000f
1458 1443
1459/*P2_MODCODLST3*/ 1444/*P2_MODCODLST3*/
1460#define R0900_P2_MODCODLST3 0xf2b3 1445#define R0900_P2_MODCODLST3 0xf2b3
1461#define F0900_P2_DIS_32PSK_4_5 0xf2b300f0 1446#define F0900_P2_DIS_32PSK_4_5 0xf2b300f0
1462#define F0900_P2_DIS_32PSK_3_4 0xf2b3000f 1447#define F0900_P2_DIS_32PSK_3_4 0xf2b3000f
1463 1448
1464/*P2_MODCODLST4*/ 1449/*P2_MODCODLST4*/
1465#define R0900_P2_MODCODLST4 0xf2b4 1450#define R0900_P2_MODCODLST4 0xf2b4
1466#define F0900_P2_DIS_16PSK_9_10 0xf2b400f0 1451#define F0900_P2_DIS_16PSK_9_10 0xf2b400f0
1467#define F0900_P2_DIS_16PSK_8_9 0xf2b4000f 1452#define F0900_P2_DIS_16PSK_8_9 0xf2b4000f
1468 1453
1469/*P2_MODCODLST5*/ 1454/*P2_MODCODLST5*/
1470#define R0900_P2_MODCODLST5 0xf2b5 1455#define R0900_P2_MODCODLST5 0xf2b5
1471#define F0900_P2_DIS_16PSK_5_6 0xf2b500f0 1456#define F0900_P2_DIS_16PSK_5_6 0xf2b500f0
1472#define F0900_P2_DIS_16PSK_4_5 0xf2b5000f 1457#define F0900_P2_DIS_16PSK_4_5 0xf2b5000f
1473 1458
1474/*P2_MODCODLST6*/ 1459/*P2_MODCODLST6*/
1475#define R0900_P2_MODCODLST6 0xf2b6 1460#define R0900_P2_MODCODLST6 0xf2b6
1476#define F0900_P2_DIS_16PSK_3_4 0xf2b600f0 1461#define F0900_P2_DIS_16PSK_3_4 0xf2b600f0
1477#define F0900_P2_DIS_16PSK_2_3 0xf2b6000f 1462#define F0900_P2_DIS_16PSK_2_3 0xf2b6000f
1478 1463
1479/*P2_MODCODLST7*/ 1464/*P2_MODCODLST7*/
1480#define R0900_P2_MODCODLST7 0xf2b7 1465#define R0900_P2_MODCODLST7 0xf2b7
1481#define F0900_P2_DIS_8P_9_10 0xf2b700f0 1466#define F0900_P2_DIS_8P_9_10 0xf2b700f0
1482#define F0900_P2_DIS_8P_8_9 0xf2b7000f 1467#define F0900_P2_DIS_8P_8_9 0xf2b7000f
1483 1468
1484/*P2_MODCODLST8*/ 1469/*P2_MODCODLST8*/
1485#define R0900_P2_MODCODLST8 0xf2b8 1470#define R0900_P2_MODCODLST8 0xf2b8
1486#define F0900_P2_DIS_8P_5_6 0xf2b800f0 1471#define F0900_P2_DIS_8P_5_6 0xf2b800f0
1487#define F0900_P2_DIS_8P_3_4 0xf2b8000f 1472#define F0900_P2_DIS_8P_3_4 0xf2b8000f
1488 1473
1489/*P2_MODCODLST9*/ 1474/*P2_MODCODLST9*/
1490#define R0900_P2_MODCODLST9 0xf2b9 1475#define R0900_P2_MODCODLST9 0xf2b9
1491#define F0900_P2_DIS_8P_2_3 0xf2b900f0 1476#define F0900_P2_DIS_8P_2_3 0xf2b900f0
1492#define F0900_P2_DIS_8P_3_5 0xf2b9000f 1477#define F0900_P2_DIS_8P_3_5 0xf2b9000f
1493 1478
1494/*P2_MODCODLSTA*/ 1479/*P2_MODCODLSTA*/
1495#define R0900_P2_MODCODLSTA 0xf2ba 1480#define R0900_P2_MODCODLSTA 0xf2ba
1496#define F0900_P2_DIS_QP_9_10 0xf2ba00f0 1481#define F0900_P2_DIS_QP_9_10 0xf2ba00f0
1497#define F0900_P2_DIS_QP_8_9 0xf2ba000f 1482#define F0900_P2_DIS_QP_8_9 0xf2ba000f
1498 1483
1499/*P2_MODCODLSTB*/ 1484/*P2_MODCODLSTB*/
1500#define R0900_P2_MODCODLSTB 0xf2bb 1485#define R0900_P2_MODCODLSTB 0xf2bb
1501#define F0900_P2_DIS_QP_5_6 0xf2bb00f0 1486#define F0900_P2_DIS_QP_5_6 0xf2bb00f0
1502#define F0900_P2_DIS_QP_4_5 0xf2bb000f 1487#define F0900_P2_DIS_QP_4_5 0xf2bb000f
1503 1488
1504/*P2_MODCODLSTC*/ 1489/*P2_MODCODLSTC*/
1505#define R0900_P2_MODCODLSTC 0xf2bc 1490#define R0900_P2_MODCODLSTC 0xf2bc
1506#define F0900_P2_DIS_QP_3_4 0xf2bc00f0 1491#define F0900_P2_DIS_QP_3_4 0xf2bc00f0
1507#define F0900_P2_DIS_QP_2_3 0xf2bc000f 1492#define F0900_P2_DIS_QP_2_3 0xf2bc000f
1508 1493
1509/*P2_MODCODLSTD*/ 1494/*P2_MODCODLSTD*/
1510#define R0900_P2_MODCODLSTD 0xf2bd 1495#define R0900_P2_MODCODLSTD 0xf2bd
1511#define F0900_P2_DIS_QP_3_5 0xf2bd00f0 1496#define F0900_P2_DIS_QP_3_5 0xf2bd00f0
1512#define F0900_P2_DIS_QP_1_2 0xf2bd000f 1497#define F0900_P2_DIS_QP_1_2 0xf2bd000f
1513 1498
1514/*P2_MODCODLSTE*/ 1499/*P2_MODCODLSTE*/
1515#define R0900_P2_MODCODLSTE 0xf2be 1500#define R0900_P2_MODCODLSTE 0xf2be
1516#define F0900_P2_DIS_QP_2_5 0xf2be00f0 1501#define F0900_P2_DIS_QP_2_5 0xf2be00f0
1517#define F0900_P2_DIS_QP_1_3 0xf2be000f 1502#define F0900_P2_DIS_QP_1_3 0xf2be000f
1518 1503
1519/*P2_MODCODLSTF*/ 1504/*P2_MODCODLSTF*/
1520#define R0900_P2_MODCODLSTF 0xf2bf 1505#define R0900_P2_MODCODLSTF 0xf2bf
1521#define F0900_P2_DIS_QP_1_4 0xf2bf00f0 1506#define F0900_P2_DIS_QP_1_4 0xf2bf00f0
1522#define F0900_P2_DDEMOD_SET 0xf2bf0002 1507
1523#define F0900_P2_DDEMOD_MASK 0xf2bf0001 1508/*P2_GAUSSR0*/
1509#define R0900_P2_GAUSSR0 0xf2c0
1510#define F0900_P2_EN_CCIMODE 0xf2c00080
1511#define F0900_P2_R0_GAUSSIEN 0xf2c0007f
1512
1513/*P2_CCIR0*/
1514#define R0900_P2_CCIR0 0xf2c1
1515#define F0900_P2_CCIDETECT_PLHONLY 0xf2c10080
1516#define F0900_P2_R0_CCI 0xf2c1007f
1517
1518/*P2_CCIQUANT*/
1519#define R0900_P2_CCIQUANT 0xf2c2
1520#define F0900_P2_CCI_BETA 0xf2c200e0
1521#define F0900_P2_CCI_QUANT 0xf2c2001f
1522
1523/*P2_CCITHRES*/
1524#define R0900_P2_CCITHRES 0xf2c3
1525#define F0900_P2_CCI_THRESHOLD 0xf2c300ff
1526
1527/*P2_CCIACC*/
1528#define R0900_P2_CCIACC 0xf2c4
1529#define F0900_P2_CCI_VALUE 0xf2c400ff
1524 1530
1525/*P2_DMDRESCFG*/ 1531/*P2_DMDRESCFG*/
1526#define R0900_P2_DMDRESCFG 0xf2c6 1532#define R0900_P2_DMDRESCFG 0xf2c6
1527#define F0900_P2_DMDRES_RESET 0xf2c60080 1533#define F0900_P2_DMDRES_RESET 0xf2c60080
1528#define F0900_P2_DMDRES_NOISESQR 0xf2c60010 1534#define F0900_P2_DMDRES_STRALL 0xf2c60008
1529#define F0900_P2_DMDRES_STRALL 0xf2c60008 1535#define F0900_P2_DMDRES_NEWONLY 0xf2c60004
1530#define F0900_P2_DMDRES_NEWONLY 0xf2c60004 1536#define F0900_P2_DMDRES_NOSTORE 0xf2c60002
1531#define F0900_P2_DMDRES_NOSTORE 0xf2c60002
1532#define F0900_P2_DMDRES_AGC2MEM 0xf2c60001
1533 1537
1534/*P2_DMDRESADR*/ 1538/*P2_DMDRESADR*/
1535#define R0900_P2_DMDRESADR 0xf2c7 1539#define R0900_P2_DMDRESADR 0xf2c7
1536#define F0900_P2_SUSP_PREDCANAL 0xf2c70080 1540#define F0900_P2_DMDRES_VALIDCFR 0xf2c70040
1537#define F0900_P2_DMDRES_VALIDCFR 0xf2c70040 1541#define F0900_P2_DMDRES_MEMFULL 0xf2c70030
1538#define F0900_P2_DMDRES_MEMFULL 0xf2c70030 1542#define F0900_P2_DMDRES_RESNBR 0xf2c7000f
1539#define F0900_P2_DMDRES_RESNBR 0xf2c7000f
1540 1543
1541/*P2_DMDRESDATA7*/ 1544/*P2_DMDRESDATA7*/
1542#define R0900_P2_DMDRESDATA7 0xf2c8 1545#define R0900_P2_DMDRESDATA7 0xf2c8
1543#define F0900_P2_DMDRES_DATA7 0xf2c800ff 1546#define F0900_P2_DMDRES_DATA7 0xf2c800ff
1544 1547
1545/*P2_DMDRESDATA6*/ 1548/*P2_DMDRESDATA6*/
1546#define R0900_P2_DMDRESDATA6 0xf2c9 1549#define R0900_P2_DMDRESDATA6 0xf2c9
1547#define F0900_P2_DMDRES_DATA6 0xf2c900ff 1550#define F0900_P2_DMDRES_DATA6 0xf2c900ff
1548 1551
1549/*P2_DMDRESDATA5*/ 1552/*P2_DMDRESDATA5*/
1550#define R0900_P2_DMDRESDATA5 0xf2ca 1553#define R0900_P2_DMDRESDATA5 0xf2ca
1551#define F0900_P2_DMDRES_DATA5 0xf2ca00ff 1554#define F0900_P2_DMDRES_DATA5 0xf2ca00ff
1552 1555
1553/*P2_DMDRESDATA4*/ 1556/*P2_DMDRESDATA4*/
1554#define R0900_P2_DMDRESDATA4 0xf2cb 1557#define R0900_P2_DMDRESDATA4 0xf2cb
1555#define F0900_P2_DMDRES_DATA4 0xf2cb00ff 1558#define F0900_P2_DMDRES_DATA4 0xf2cb00ff
1556 1559
1557/*P2_DMDRESDATA3*/ 1560/*P2_DMDRESDATA3*/
1558#define R0900_P2_DMDRESDATA3 0xf2cc 1561#define R0900_P2_DMDRESDATA3 0xf2cc
1559#define F0900_P2_DMDRES_DATA3 0xf2cc00ff 1562#define F0900_P2_DMDRES_DATA3 0xf2cc00ff
1560 1563
1561/*P2_DMDRESDATA2*/ 1564/*P2_DMDRESDATA2*/
1562#define R0900_P2_DMDRESDATA2 0xf2cd 1565#define R0900_P2_DMDRESDATA2 0xf2cd
1563#define F0900_P2_DMDRES_DATA2 0xf2cd00ff 1566#define F0900_P2_DMDRES_DATA2 0xf2cd00ff
1564 1567
1565/*P2_DMDRESDATA1*/ 1568/*P2_DMDRESDATA1*/
1566#define R0900_P2_DMDRESDATA1 0xf2ce 1569#define R0900_P2_DMDRESDATA1 0xf2ce
1567#define F0900_P2_DMDRES_DATA1 0xf2ce00ff 1570#define F0900_P2_DMDRES_DATA1 0xf2ce00ff
1568 1571
1569/*P2_DMDRESDATA0*/ 1572/*P2_DMDRESDATA0*/
1570#define R0900_P2_DMDRESDATA0 0xf2cf 1573#define R0900_P2_DMDRESDATA0 0xf2cf
1571#define F0900_P2_DMDRES_DATA0 0xf2cf00ff 1574#define F0900_P2_DMDRES_DATA0 0xf2cf00ff
1572 1575
1573/*P2_FFEI1*/ 1576/*P2_FFEI1*/
1574#define R0900_P2_FFEI1 0xf2d0 1577#define R0900_P2_FFEI1 0xf2d0
1575#define F0900_P2_FFE_ACCI1 0xf2d001ff 1578#define F0900_P2_FFE_ACCI1 0xf2d001ff
1576 1579
1577/*P2_FFEQ1*/ 1580/*P2_FFEQ1*/
1578#define R0900_P2_FFEQ1 0xf2d1 1581#define R0900_P2_FFEQ1 0xf2d1
1579#define F0900_P2_FFE_ACCQ1 0xf2d101ff 1582#define F0900_P2_FFE_ACCQ1 0xf2d101ff
1580 1583
1581/*P2_FFEI2*/ 1584/*P2_FFEI2*/
1582#define R0900_P2_FFEI2 0xf2d2 1585#define R0900_P2_FFEI2 0xf2d2
1583#define F0900_P2_FFE_ACCI2 0xf2d201ff 1586#define F0900_P2_FFE_ACCI2 0xf2d201ff
1584 1587
1585/*P2_FFEQ2*/ 1588/*P2_FFEQ2*/
1586#define R0900_P2_FFEQ2 0xf2d3 1589#define R0900_P2_FFEQ2 0xf2d3
1587#define F0900_P2_FFE_ACCQ2 0xf2d301ff 1590#define F0900_P2_FFE_ACCQ2 0xf2d301ff
1588 1591
1589/*P2_FFEI3*/ 1592/*P2_FFEI3*/
1590#define R0900_P2_FFEI3 0xf2d4 1593#define R0900_P2_FFEI3 0xf2d4
1591#define F0900_P2_FFE_ACCI3 0xf2d401ff 1594#define F0900_P2_FFE_ACCI3 0xf2d401ff
1592 1595
1593/*P2_FFEQ3*/ 1596/*P2_FFEQ3*/
1594#define R0900_P2_FFEQ3 0xf2d5 1597#define R0900_P2_FFEQ3 0xf2d5
1595#define F0900_P2_FFE_ACCQ3 0xf2d501ff 1598#define F0900_P2_FFE_ACCQ3 0xf2d501ff
1596 1599
1597/*P2_FFEI4*/ 1600/*P2_FFEI4*/
1598#define R0900_P2_FFEI4 0xf2d6 1601#define R0900_P2_FFEI4 0xf2d6
1599#define F0900_P2_FFE_ACCI4 0xf2d601ff 1602#define F0900_P2_FFE_ACCI4 0xf2d601ff
1600 1603
1601/*P2_FFEQ4*/ 1604/*P2_FFEQ4*/
1602#define R0900_P2_FFEQ4 0xf2d7 1605#define R0900_P2_FFEQ4 0xf2d7
1603#define F0900_P2_FFE_ACCQ4 0xf2d701ff 1606#define F0900_P2_FFE_ACCQ4 0xf2d701ff
1604 1607
1605/*P2_FFECFG*/ 1608/*P2_FFECFG*/
1606#define R0900_P2_FFECFG 0xf2d8 1609#define R0900_P2_FFECFG 0xf2d8
1607#define F0900_P2_EQUALFFE_ON 0xf2d80040 1610#define F0900_P2_EQUALFFE_ON 0xf2d80040
1608#define F0900_P2_EQUAL_USEDSYMB 0xf2d80030 1611#define F0900_P2_MU_EQUALFFE 0xf2d80007
1609#define F0900_P2_MU_EQUALFFE 0xf2d80007
1610 1612
1611/*P2_TNRCFG*/ 1613/*P2_TNRCFG*/
1612#define R0900_P2_TNRCFG 0xf2e0 1614#define R0900_P2_TNRCFG 0xf2e0
1613#define F0900_P2_TUN_ACKFAIL 0xf2e00080 1615#define F0900_P2_TUN_ACKFAIL 0xf2e00080
1614#define F0900_P2_TUN_TYPE 0xf2e00070 1616#define F0900_P2_TUN_TYPE 0xf2e00070
1615#define F0900_P2_TUN_SECSTOP 0xf2e00008 1617#define F0900_P2_TUN_SECSTOP 0xf2e00008
1616#define F0900_P2_TUN_VCOSRCH 0xf2e00004 1618#define F0900_P2_TUN_VCOSRCH 0xf2e00004
1617#define F0900_P2_TUN_MADDRESS 0xf2e00003 1619#define F0900_P2_TUN_MADDRESS 0xf2e00003
1618 1620
1619/*P2_TNRCFG2*/ 1621/*P2_TNRCFG2*/
1620#define R0900_P2_TNRCFG2 0xf2e1 1622#define R0900_P2_TNRCFG2 0xf2e1
1621#define F0900_P2_TUN_IQSWAP 0xf2e10080 1623#define F0900_P2_TUN_IQSWAP 0xf2e10080
1622#define F0900_P2_STB6110_STEP2MHZ 0xf2e10040 1624#define F0900_P2_DIS_BWCALC 0xf2e10004
1623#define F0900_P2_STB6120_DBLI2C 0xf2e10020 1625#define F0900_P2_SHORT_WAITSTATES 0xf2e10002
1624#define F0900_P2_DIS_FCCK 0xf2e10010
1625#define F0900_P2_DIS_LPEN 0xf2e10008
1626#define F0900_P2_DIS_BWCALC 0xf2e10004
1627#define F0900_P2_SHORT_WAITSTATES 0xf2e10002
1628#define F0900_P2_DIS_2BWAGC1 0xf2e10001
1629 1626
1630/*P2_TNRXTAL*/ 1627/*P2_TNRXTAL*/
1631#define R0900_P2_TNRXTAL 0xf2e4 1628#define R0900_P2_TNRXTAL 0xf2e4
1632#define F0900_P2_TUN_MCLKDECIMAL 0xf2e400e0 1629#define F0900_P2_TUN_XTALFREQ 0xf2e4001f
1633#define F0900_P2_TUN_XTALFREQ 0xf2e4001f
1634 1630
1635/*P2_TNRSTEPS*/ 1631/*P2_TNRSTEPS*/
1636#define R0900_P2_TNRSTEPS 0xf2e7 1632#define R0900_P2_TNRSTEPS 0xf2e7
1637#define F0900_P2_TUNER_BW1P6 0xf2e70080 1633#define F0900_P2_TUNER_BW0P125 0xf2e70080
1638#define F0900_P2_BWINC_OFFSET 0xf2e70070 1634#define F0900_P2_BWINC_OFFSET 0xf2e70170
1639#define F0900_P2_SOFTSTEP_RNG 0xf2e70008 1635#define F0900_P2_SOFTSTEP_RNG 0xf2e70008
1640#define F0900_P2_TUN_BWOFFSET 0xf2e70107 1636#define F0900_P2_TUN_BWOFFSET 0xf2e70007
1641 1637
1642/*P2_TNRGAIN*/ 1638/*P2_TNRGAIN*/
1643#define R0900_P2_TNRGAIN 0xf2e8 1639#define R0900_P2_TNRGAIN 0xf2e8
1644#define F0900_P2_TUN_KDIVEN 0xf2e800c0 1640#define F0900_P2_TUN_KDIVEN 0xf2e800c0
1645#define F0900_P2_STB6X00_OCK 0xf2e80030 1641#define F0900_P2_STB6X00_OCK 0xf2e80030
1646#define F0900_P2_TUN_GAIN 0xf2e8000f 1642#define F0900_P2_TUN_GAIN 0xf2e8000f
1647 1643
1648/*P2_TNRRF1*/ 1644/*P2_TNRRF1*/
1649#define R0900_P2_TNRRF1 0xf2e9 1645#define R0900_P2_TNRRF1 0xf2e9
1650#define F0900_P2_TUN_RFFREQ2 0xf2e900ff 1646#define F0900_P2_TUN_RFFREQ2 0xf2e900ff
1651 1647
1652/*P2_TNRRF0*/ 1648/*P2_TNRRF0*/
1653#define R0900_P2_TNRRF0 0xf2ea 1649#define R0900_P2_TNRRF0 0xf2ea
1654#define F0900_P2_TUN_RFFREQ1 0xf2ea00ff 1650#define F0900_P2_TUN_RFFREQ1 0xf2ea00ff
1655 1651
1656/*P2_TNRBW*/ 1652/*P2_TNRBW*/
1657#define R0900_P2_TNRBW 0xf2eb 1653#define R0900_P2_TNRBW 0xf2eb
1658#define F0900_P2_TUN_RFFREQ0 0xf2eb00c0 1654#define F0900_P2_TUN_RFFREQ0 0xf2eb00c0
1659#define F0900_P2_TUN_BW 0xf2eb003f 1655#define F0900_P2_TUN_BW 0xf2eb003f
1660 1656
1661/*P2_TNRADJ*/ 1657/*P2_TNRADJ*/
1662#define R0900_P2_TNRADJ 0xf2ec 1658#define R0900_P2_TNRADJ 0xf2ec
1663#define F0900_P2_STB61X0_RCLK 0xf2ec0080 1659#define F0900_P2_STB61X0_CALTIME 0xf2ec0040
1664#define F0900_P2_STB61X0_CALTIME 0xf2ec0040
1665#define F0900_P2_STB6X00_DLB 0xf2ec0038
1666#define F0900_P2_STB6000_FCL 0xf2ec0007
1667 1660
1668/*P2_TNRCTL2*/ 1661/*P2_TNRCTL2*/
1669#define R0900_P2_TNRCTL2 0xf2ed 1662#define R0900_P2_TNRCTL2 0xf2ed
1670#define F0900_P2_STB61X0_LCP1_RCCKOFF 0xf2ed0080 1663#define F0900_P2_STB61X0_RCCKOFF 0xf2ed0080
1671#define F0900_P2_STB61X0_LCP0 0xf2ed0040 1664#define F0900_P2_STB61X0_ICP_SDOFF 0xf2ed0040
1672#define F0900_P2_STB61X0_XTOUT_RFOUTS 0xf2ed0020 1665#define F0900_P2_STB61X0_DCLOOPOFF 0xf2ed0020
1673#define F0900_P2_STB61X0_XTON_MCKDV 0xf2ed0010 1666#define F0900_P2_STB61X0_REFOUTSEL 0xf2ed0010
1674#define F0900_P2_STB61X0_CALOFF_DCOFF 0xf2ed0008 1667#define F0900_P2_STB61X0_CALOFF 0xf2ed0008
1675#define F0900_P2_STB6110_LPT 0xf2ed0004 1668#define F0900_P2_STB6XX0_LPT_BEN 0xf2ed0004
1676#define F0900_P2_STB6110_RX 0xf2ed0002 1669#define F0900_P2_STB6XX0_RX_OSCP 0xf2ed0002
1677#define F0900_P2_STB6110_SYN 0xf2ed0001 1670#define F0900_P2_STB6XX0_SYN 0xf2ed0001
1678 1671
1679/*P2_TNRCFG3*/ 1672/*P2_TNRCFG3*/
1680#define R0900_P2_TNRCFG3 0xf2ee 1673#define R0900_P2_TNRCFG3 0xf2ee
1681#define F0900_P2_STB6120_DISCTRL1 0xf2ee0080 1674#define F0900_P2_TUN_PLLFREQ 0xf2ee001c
1682#define F0900_P2_STB6120_INVORDER 0xf2ee0040 1675#define F0900_P2_TUN_I2CFREQ_MODE 0xf2ee0003
1683#define F0900_P2_STB6120_ENCTRL6 0xf2ee0020
1684#define F0900_P2_TUN_PLLFREQ 0xf2ee001c
1685#define F0900_P2_TUN_I2CFREQ_MODE 0xf2ee0003
1686 1676
1687/*P2_TNRLAUNCH*/ 1677/*P2_TNRLAUNCH*/
1688#define R0900_P2_TNRLAUNCH 0xf2f0 1678#define R0900_P2_TNRLAUNCH 0xf2f0
1689 1679
1690/*P2_TNRLD*/ 1680/*P2_TNRLD*/
1691#define R0900_P2_TNRLD 0xf2f0 1681#define R0900_P2_TNRLD 0xf2f0
1692#define F0900_P2_TUNLD_VCOING 0xf2f00080 1682#define F0900_P2_TUNLD_VCOING 0xf2f00080
1693#define F0900_P2_TUN_REG1FAIL 0xf2f00040 1683#define F0900_P2_TUN_REG1FAIL 0xf2f00040
1694#define F0900_P2_TUN_REG2FAIL 0xf2f00020 1684#define F0900_P2_TUN_REG2FAIL 0xf2f00020
1695#define F0900_P2_TUN_REG3FAIL 0xf2f00010 1685#define F0900_P2_TUN_REG3FAIL 0xf2f00010
1696#define F0900_P2_TUN_REG4FAIL 0xf2f00008 1686#define F0900_P2_TUN_REG4FAIL 0xf2f00008
1697#define F0900_P2_TUN_REG5FAIL 0xf2f00004 1687#define F0900_P2_TUN_REG5FAIL 0xf2f00004
1698#define F0900_P2_TUN_BWING 0xf2f00002 1688#define F0900_P2_TUN_BWING 0xf2f00002
1699#define F0900_P2_TUN_LOCKED 0xf2f00001 1689#define F0900_P2_TUN_LOCKED 0xf2f00001
1700 1690
1701/*P2_TNROBSL*/ 1691/*P2_TNROBSL*/
1702#define R0900_P2_TNROBSL 0xf2f6 1692#define R0900_P2_TNROBSL 0xf2f6
1703#define F0900_P2_TUN_I2CABORTED 0xf2f60080 1693#define F0900_P2_TUN_I2CABORTED 0xf2f60080
1704#define F0900_P2_TUN_LPEN 0xf2f60040 1694#define F0900_P2_TUN_LPEN 0xf2f60040
1705#define F0900_P2_TUN_FCCK 0xf2f60020 1695#define F0900_P2_TUN_FCCK 0xf2f60020
1706#define F0900_P2_TUN_I2CLOCKED 0xf2f60010 1696#define F0900_P2_TUN_I2CLOCKED 0xf2f60010
1707#define F0900_P2_TUN_PROGDONE 0xf2f6000c 1697#define F0900_P2_TUN_PROGDONE 0xf2f6000c
1708#define F0900_P2_TUN_RFRESTE1 0xf2f60003 1698#define F0900_P2_TUN_RFRESTE1 0xf2f60003
1709 1699
1710/*P2_TNRRESTE*/ 1700/*P2_TNRRESTE*/
1711#define R0900_P2_TNRRESTE 0xf2f7 1701#define R0900_P2_TNRRESTE 0xf2f7
1712#define F0900_P2_TUN_RFRESTE0 0xf2f700ff 1702#define F0900_P2_TUN_RFRESTE0 0xf2f700ff
1713 1703
1714/*P2_SMAPCOEF7*/ 1704/*P2_SMAPCOEF7*/
1715#define R0900_P2_SMAPCOEF7 0xf300 1705#define R0900_P2_SMAPCOEF7 0xf300
1716#define F0900_P2_DIS_QSCALE 0xf3000080 1706#define F0900_P2_DIS_QSCALE 0xf3000080
1717#define F0900_P2_SMAPCOEF_Q_LLR12 0xf300017f 1707#define F0900_P2_SMAPCOEF_Q_LLR12 0xf300017f
1718 1708
1719/*P2_SMAPCOEF6*/ 1709/*P2_SMAPCOEF6*/
1720#define R0900_P2_SMAPCOEF6 0xf301 1710#define R0900_P2_SMAPCOEF6 0xf301
1721#define F0900_P2_DIS_NEWSCALE 0xf3010008 1711#define F0900_P2_ADJ_8PSKLLR1 0xf3010004
1722#define F0900_P2_ADJ_8PSKLLR1 0xf3010004 1712#define F0900_P2_OLD_8PSKLLR1 0xf3010002
1723#define F0900_P2_OLD_8PSKLLR1 0xf3010002 1713#define F0900_P2_DIS_AB8PSK 0xf3010001
1724#define F0900_P2_DIS_AB8PSK 0xf3010001
1725 1714
1726/*P2_SMAPCOEF5*/ 1715/*P2_SMAPCOEF5*/
1727#define R0900_P2_SMAPCOEF5 0xf302 1716#define R0900_P2_SMAPCOEF5 0xf302
1728#define F0900_P2_DIS_8SCALE 0xf3020080 1717#define F0900_P2_DIS_8SCALE 0xf3020080
1729#define F0900_P2_SMAPCOEF_8P_LLR23 0xf302017f 1718#define F0900_P2_SMAPCOEF_8P_LLR23 0xf302017f
1719
1720/*P2_NCO2MAX1*/
1721#define R0900_P2_NCO2MAX1 0xf314
1722#define F0900_P2_TETA2_MAXVABS1 0xf31400ff
1723
1724/*P2_NCO2MAX0*/
1725#define R0900_P2_NCO2MAX0 0xf315
1726#define F0900_P2_TETA2_MAXVABS0 0xf31500ff
1727
1728/*P2_NCO2FR1*/
1729#define R0900_P2_NCO2FR1 0xf316
1730#define F0900_P2_NCO2FINAL_ANGLE1 0xf31600ff
1731
1732/*P2_NCO2FR0*/
1733#define R0900_P2_NCO2FR0 0xf317
1734#define F0900_P2_NCO2FINAL_ANGLE0 0xf31700ff
1735
1736/*P2_CFR2AVRGE1*/
1737#define R0900_P2_CFR2AVRGE1 0xf318
1738#define F0900_P2_I2C_CFR2AVERAGE1 0xf31800ff
1739
1740/*P2_CFR2AVRGE0*/
1741#define R0900_P2_CFR2AVRGE0 0xf319
1742#define F0900_P2_I2C_CFR2AVERAGE0 0xf31900ff
1730 1743
1731/*P2_DMDPLHSTAT*/ 1744/*P2_DMDPLHSTAT*/
1732#define R0900_P2_DMDPLHSTAT 0xf320 1745#define R0900_P2_DMDPLHSTAT 0xf320
1733#define F0900_P2_PLH_STATISTIC 0xf32000ff 1746#define F0900_P2_PLH_STATISTIC 0xf32000ff
1734 1747
1735/*P2_LOCKTIME3*/ 1748/*P2_LOCKTIME3*/
1736#define R0900_P2_LOCKTIME3 0xf322 1749#define R0900_P2_LOCKTIME3 0xf322
1737#define F0900_P2_DEMOD_LOCKTIME3 0xf32200ff 1750#define F0900_P2_DEMOD_LOCKTIME3 0xf32200ff
1738 1751
1739/*P2_LOCKTIME2*/ 1752/*P2_LOCKTIME2*/
1740#define R0900_P2_LOCKTIME2 0xf323 1753#define R0900_P2_LOCKTIME2 0xf323
1741#define F0900_P2_DEMOD_LOCKTIME2 0xf32300ff 1754#define F0900_P2_DEMOD_LOCKTIME2 0xf32300ff
1742 1755
1743/*P2_LOCKTIME1*/ 1756/*P2_LOCKTIME1*/
1744#define R0900_P2_LOCKTIME1 0xf324 1757#define R0900_P2_LOCKTIME1 0xf324
1745#define F0900_P2_DEMOD_LOCKTIME1 0xf32400ff 1758#define F0900_P2_DEMOD_LOCKTIME1 0xf32400ff
1746 1759
1747/*P2_LOCKTIME0*/ 1760/*P2_LOCKTIME0*/
1748#define R0900_P2_LOCKTIME0 0xf325 1761#define R0900_P2_LOCKTIME0 0xf325
1749#define F0900_P2_DEMOD_LOCKTIME0 0xf32500ff 1762#define F0900_P2_DEMOD_LOCKTIME0 0xf32500ff
1750 1763
1751/*P2_VITSCALE*/ 1764/*P2_VITSCALE*/
1752#define R0900_P2_VITSCALE 0xf332 1765#define R0900_P2_VITSCALE 0xf332
1753#define F0900_P2_NVTH_NOSRANGE 0xf3320080 1766#define F0900_P2_NVTH_NOSRANGE 0xf3320080
1754#define F0900_P2_VERROR_MAXMODE 0xf3320040 1767#define F0900_P2_VERROR_MAXMODE 0xf3320040
1755#define F0900_P2_KDIV_MODE 0xf3320030 1768#define F0900_P2_NSLOWSN_LOCKED 0xf3320008
1756#define F0900_P2_NSLOWSN_LOCKED 0xf3320008 1769#define F0900_P2_DIS_RSFLOCK 0xf3320002
1757#define F0900_P2_DELOCK_PRFLOSS 0xf3320004
1758#define F0900_P2_DIS_RSFLOCK 0xf3320002
1759 1770
1760/*P2_FECM*/ 1771/*P2_FECM*/
1761#define R0900_P2_FECM 0xf333 1772#define R0900_P2_FECM 0xf333
1762#define F0900_P2_DSS_DVB 0xf3330080 1773#define F0900_P2_DSS_DVB 0xf3330080
1763#define F0900_P2_DEMOD_BYPASS 0xf3330040 1774#define F0900_P2_DSS_SRCH 0xf3330010
1764#define F0900_P2_CMP_SLOWMODE 0xf3330020 1775#define F0900_P2_SYNCVIT 0xf3330002
1765#define F0900_P2_DSS_SRCH 0xf3330010 1776#define F0900_P2_IQINV 0xf3330001
1766#define F0900_P2_DIFF_MODEVIT 0xf3330004
1767#define F0900_P2_SYNCVIT 0xf3330002
1768#define F0900_P2_IQINV 0xf3330001
1769 1777
1770/*P2_VTH12*/ 1778/*P2_VTH12*/
1771#define R0900_P2_VTH12 0xf334 1779#define R0900_P2_VTH12 0xf334
1772#define F0900_P2_VTH12 0xf33400ff 1780#define F0900_P2_VTH12 0xf33400ff
1773 1781
1774/*P2_VTH23*/ 1782/*P2_VTH23*/
1775#define R0900_P2_VTH23 0xf335 1783#define R0900_P2_VTH23 0xf335
1776#define F0900_P2_VTH23 0xf33500ff 1784#define F0900_P2_VTH23 0xf33500ff
1777 1785
1778/*P2_VTH34*/ 1786/*P2_VTH34*/
1779#define R0900_P2_VTH34 0xf336 1787#define R0900_P2_VTH34 0xf336
1780#define F0900_P2_VTH34 0xf33600ff 1788#define F0900_P2_VTH34 0xf33600ff
1781 1789
1782/*P2_VTH56*/ 1790/*P2_VTH56*/
1783#define R0900_P2_VTH56 0xf337 1791#define R0900_P2_VTH56 0xf337
1784#define F0900_P2_VTH56 0xf33700ff 1792#define F0900_P2_VTH56 0xf33700ff
1785 1793
1786/*P2_VTH67*/ 1794/*P2_VTH67*/
1787#define R0900_P2_VTH67 0xf338 1795#define R0900_P2_VTH67 0xf338
1788#define F0900_P2_VTH67 0xf33800ff 1796#define F0900_P2_VTH67 0xf33800ff
1789 1797
1790/*P2_VTH78*/ 1798/*P2_VTH78*/
1791#define R0900_P2_VTH78 0xf339 1799#define R0900_P2_VTH78 0xf339
1792#define F0900_P2_VTH78 0xf33900ff 1800#define F0900_P2_VTH78 0xf33900ff
1793 1801
1794/*P2_VITCURPUN*/ 1802/*P2_VITCURPUN*/
1795#define R0900_P2_VITCURPUN 0xf33a 1803#define R0900_P2_VITCURPUN 0xf33a
1796#define F0900_P2_VIT_MAPPING 0xf33a00e0 1804#define F0900_P2_VIT_CURPUN 0xf33a001f
1797#define F0900_P2_VIT_CURPUN 0xf33a001f
1798 1805
1799/*P2_VERROR*/ 1806/*P2_VERROR*/
1800#define R0900_P2_VERROR 0xf33b 1807#define R0900_P2_VERROR 0xf33b
1801#define F0900_P2_REGERR_VIT 0xf33b00ff 1808#define F0900_P2_REGERR_VIT 0xf33b00ff
1802 1809
1803/*P2_PRVIT*/ 1810/*P2_PRVIT*/
1804#define R0900_P2_PRVIT 0xf33c 1811#define R0900_P2_PRVIT 0xf33c
1805#define F0900_P2_DIS_VTHLOCK 0xf33c0040 1812#define F0900_P2_DIS_VTHLOCK 0xf33c0040
1806#define F0900_P2_E7_8VIT 0xf33c0020 1813#define F0900_P2_E7_8VIT 0xf33c0020
1807#define F0900_P2_E6_7VIT 0xf33c0010 1814#define F0900_P2_E6_7VIT 0xf33c0010
1808#define F0900_P2_E5_6VIT 0xf33c0008 1815#define F0900_P2_E5_6VIT 0xf33c0008
1809#define F0900_P2_E3_4VIT 0xf33c0004 1816#define F0900_P2_E3_4VIT 0xf33c0004
1810#define F0900_P2_E2_3VIT 0xf33c0002 1817#define F0900_P2_E2_3VIT 0xf33c0002
1811#define F0900_P2_E1_2VIT 0xf33c0001 1818#define F0900_P2_E1_2VIT 0xf33c0001
1812 1819
1813/*P2_VAVSRVIT*/ 1820/*P2_VAVSRVIT*/
1814#define R0900_P2_VAVSRVIT 0xf33d 1821#define R0900_P2_VAVSRVIT 0xf33d
1815#define F0900_P2_AMVIT 0xf33d0080 1822#define F0900_P2_AMVIT 0xf33d0080
1816#define F0900_P2_FROZENVIT 0xf33d0040 1823#define F0900_P2_FROZENVIT 0xf33d0040
1817#define F0900_P2_SNVIT 0xf33d0030 1824#define F0900_P2_SNVIT 0xf33d0030
1818#define F0900_P2_TOVVIT 0xf33d000c 1825#define F0900_P2_TOVVIT 0xf33d000c
1819#define F0900_P2_HYPVIT 0xf33d0003 1826#define F0900_P2_HYPVIT 0xf33d0003
1820 1827
1821/*P2_VSTATUSVIT*/ 1828/*P2_VSTATUSVIT*/
1822#define R0900_P2_VSTATUSVIT 0xf33e 1829#define R0900_P2_VSTATUSVIT 0xf33e
1823#define F0900_P2_VITERBI_ON 0xf33e0080 1830#define F0900_P2_PRFVIT 0xf33e0010
1824#define F0900_P2_END_LOOPVIT 0xf33e0040 1831#define F0900_P2_LOCKEDVIT 0xf33e0008
1825#define F0900_P2_VITERBI_DEPRF 0xf33e0020
1826#define F0900_P2_PRFVIT 0xf33e0010
1827#define F0900_P2_LOCKEDVIT 0xf33e0008
1828#define F0900_P2_VITERBI_DELOCK 0xf33e0004
1829#define F0900_P2_VIT_DEMODSEL 0xf33e0002
1830#define F0900_P2_VITERBI_COMPOUT 0xf33e0001
1831 1832
1832/*P2_VTHINUSE*/ 1833/*P2_VTHINUSE*/
1833#define R0900_P2_VTHINUSE 0xf33f 1834#define R0900_P2_VTHINUSE 0xf33f
1834#define F0900_P2_VIT_INUSE 0xf33f00ff 1835#define F0900_P2_VIT_INUSE 0xf33f00ff
1835 1836
1836/*P2_KDIV12*/ 1837/*P2_KDIV12*/
1837#define R0900_P2_KDIV12 0xf340 1838#define R0900_P2_KDIV12 0xf340
1838#define F0900_P2_KDIV12_MANUAL 0xf3400080 1839#define F0900_P2_K_DIVIDER_12 0xf340007f
1839#define F0900_P2_K_DIVIDER_12 0xf340007f
1840 1840
1841/*P2_KDIV23*/ 1841/*P2_KDIV23*/
1842#define R0900_P2_KDIV23 0xf341 1842#define R0900_P2_KDIV23 0xf341
1843#define F0900_P2_KDIV23_MANUAL 0xf3410080 1843#define F0900_P2_K_DIVIDER_23 0xf341007f
1844#define F0900_P2_K_DIVIDER_23 0xf341007f
1845 1844
1846/*P2_KDIV34*/ 1845/*P2_KDIV34*/
1847#define R0900_P2_KDIV34 0xf342 1846#define R0900_P2_KDIV34 0xf342
1848#define F0900_P2_KDIV34_MANUAL 0xf3420080 1847#define F0900_P2_K_DIVIDER_34 0xf342007f
1849#define F0900_P2_K_DIVIDER_34 0xf342007f
1850 1848
1851/*P2_KDIV56*/ 1849/*P2_KDIV56*/
1852#define R0900_P2_KDIV56 0xf343 1850#define R0900_P2_KDIV56 0xf343
1853#define F0900_P2_KDIV56_MANUAL 0xf3430080 1851#define F0900_P2_K_DIVIDER_56 0xf343007f
1854#define F0900_P2_K_DIVIDER_56 0xf343007f
1855 1852
1856/*P2_KDIV67*/ 1853/*P2_KDIV67*/
1857#define R0900_P2_KDIV67 0xf344 1854#define R0900_P2_KDIV67 0xf344
1858#define F0900_P2_KDIV67_MANUAL 0xf3440080 1855#define F0900_P2_K_DIVIDER_67 0xf344007f
1859#define F0900_P2_K_DIVIDER_67 0xf344007f
1860 1856
1861/*P2_KDIV78*/ 1857/*P2_KDIV78*/
1862#define R0900_P2_KDIV78 0xf345 1858#define R0900_P2_KDIV78 0xf345
1863#define F0900_P2_KDIV78_MANUAL 0xf3450080 1859#define F0900_P2_K_DIVIDER_78 0xf345007f
1864#define F0900_P2_K_DIVIDER_78 0xf345007f
1865 1860
1866/*P2_PDELCTRL1*/ 1861/*P2_PDELCTRL1*/
1867#define R0900_P2_PDELCTRL1 0xf350 1862#define R0900_P2_PDELCTRL1 0xf350
1868#define F0900_P2_INV_MISMASK 0xf3500080 1863#define F0900_P2_INV_MISMASK 0xf3500080
1869#define F0900_P2_FORCE_ACCEPTED 0xf3500040 1864#define F0900_P2_FILTER_EN 0xf3500020
1870#define F0900_P2_FILTER_EN 0xf3500020 1865#define F0900_P2_EN_MIS00 0xf3500002
1871#define F0900_P2_FORCE_PKTDELINUSE 0xf3500010 1866#define F0900_P2_ALGOSWRST 0xf3500001
1872#define F0900_P2_HYSTEN 0xf3500008
1873#define F0900_P2_HYSTSWRST 0xf3500004
1874#define F0900_P2_EN_MIS00 0xf3500002
1875#define F0900_P2_ALGOSWRST 0xf3500001
1876 1867
1877/*P2_PDELCTRL2*/ 1868/*P2_PDELCTRL2*/
1878#define R0900_P2_PDELCTRL2 0xf351 1869#define R0900_P2_PDELCTRL2 0xf351
1879#define F0900_P2_FORCE_CONTINUOUS 0xf3510080 1870#define F0900_P2_RESET_UPKO_COUNT 0xf3510040
1880#define F0900_P2_RESET_UPKO_COUNT 0xf3510040 1871#define F0900_P2_FRAME_MODE 0xf3510002
1881#define F0900_P2_USER_PKTDELIN_NB 0xf3510020 1872#define F0900_P2_NOBCHERRFLG_USE 0xf3510001
1882#define F0900_P2_FORCE_LOCKED 0xf3510010
1883#define F0900_P2_DATA_UNBBSCRAM 0xf3510008
1884#define F0900_P2_FORCE_LONGPKT 0xf3510004
1885#define F0900_P2_FRAME_MODE 0xf3510002
1886 1873
1887/*P2_HYSTTHRESH*/ 1874/*P2_HYSTTHRESH*/
1888#define R0900_P2_HYSTTHRESH 0xf354 1875#define R0900_P2_HYSTTHRESH 0xf354
1889#define F0900_P2_UNLCK_THRESH 0xf35400f0 1876#define F0900_P2_UNLCK_THRESH 0xf35400f0
1890#define F0900_P2_DELIN_LCK_THRESH 0xf354000f 1877#define F0900_P2_DELIN_LCK_THRESH 0xf354000f
1891 1878
1892/*P2_ISIENTRY*/ 1879/*P2_ISIENTRY*/
1893#define R0900_P2_ISIENTRY 0xf35e 1880#define R0900_P2_ISIENTRY 0xf35e
1894#define F0900_P2_ISI_ENTRY 0xf35e00ff 1881#define F0900_P2_ISI_ENTRY 0xf35e00ff
1895 1882
1896/*P2_ISIBITENA*/ 1883/*P2_ISIBITENA*/
1897#define R0900_P2_ISIBITENA 0xf35f 1884#define R0900_P2_ISIBITENA 0xf35f
1898#define F0900_P2_ISI_BIT_EN 0xf35f00ff 1885#define F0900_P2_ISI_BIT_EN 0xf35f00ff
1899 1886
1900/*P2_MATSTR1*/ 1887/*P2_MATSTR1*/
1901#define R0900_P2_MATSTR1 0xf360 1888#define R0900_P2_MATSTR1 0xf360
1902#define F0900_P2_MATYPE_CURRENT1 0xf36000ff 1889#define F0900_P2_MATYPE_CURRENT1 0xf36000ff
1903 1890
1904/*P2_MATSTR0*/ 1891/*P2_MATSTR0*/
1905#define R0900_P2_MATSTR0 0xf361 1892#define R0900_P2_MATSTR0 0xf361
1906#define F0900_P2_MATYPE_CURRENT0 0xf36100ff 1893#define F0900_P2_MATYPE_CURRENT0 0xf36100ff
1907 1894
1908/*P2_UPLSTR1*/ 1895/*P2_UPLSTR1*/
1909#define R0900_P2_UPLSTR1 0xf362 1896#define R0900_P2_UPLSTR1 0xf362
1910#define F0900_P2_UPL_CURRENT1 0xf36200ff 1897#define F0900_P2_UPL_CURRENT1 0xf36200ff
1911 1898
1912/*P2_UPLSTR0*/ 1899/*P2_UPLSTR0*/
1913#define R0900_P2_UPLSTR0 0xf363 1900#define R0900_P2_UPLSTR0 0xf363
1914#define F0900_P2_UPL_CURRENT0 0xf36300ff 1901#define F0900_P2_UPL_CURRENT0 0xf36300ff
1915 1902
1916/*P2_DFLSTR1*/ 1903/*P2_DFLSTR1*/
1917#define R0900_P2_DFLSTR1 0xf364 1904#define R0900_P2_DFLSTR1 0xf364
1918#define F0900_P2_DFL_CURRENT1 0xf36400ff 1905#define F0900_P2_DFL_CURRENT1 0xf36400ff
1919 1906
1920/*P2_DFLSTR0*/ 1907/*P2_DFLSTR0*/
1921#define R0900_P2_DFLSTR0 0xf365 1908#define R0900_P2_DFLSTR0 0xf365
1922#define F0900_P2_DFL_CURRENT0 0xf36500ff 1909#define F0900_P2_DFL_CURRENT0 0xf36500ff
1923 1910
1924/*P2_SYNCSTR*/ 1911/*P2_SYNCSTR*/
1925#define R0900_P2_SYNCSTR 0xf366 1912#define R0900_P2_SYNCSTR 0xf366
1926#define F0900_P2_SYNC_CURRENT 0xf36600ff 1913#define F0900_P2_SYNC_CURRENT 0xf36600ff
1927 1914
1928/*P2_SYNCDSTR1*/ 1915/*P2_SYNCDSTR1*/
1929#define R0900_P2_SYNCDSTR1 0xf367 1916#define R0900_P2_SYNCDSTR1 0xf367
1930#define F0900_P2_SYNCD_CURRENT1 0xf36700ff 1917#define F0900_P2_SYNCD_CURRENT1 0xf36700ff
1931 1918
1932/*P2_SYNCDSTR0*/ 1919/*P2_SYNCDSTR0*/
1933#define R0900_P2_SYNCDSTR0 0xf368 1920#define R0900_P2_SYNCDSTR0 0xf368
1934#define F0900_P2_SYNCD_CURRENT0 0xf36800ff 1921#define F0900_P2_SYNCD_CURRENT0 0xf36800ff
1935 1922
1936/*P2_PDELSTATUS1*/ 1923/*P2_PDELSTATUS1*/
1937#define R0900_P2_PDELSTATUS1 0xf369 1924#define R0900_P2_PDELSTATUS1 0xf369
1938#define F0900_P2_PKTDELIN_DELOCK 0xf3690080 1925#define F0900_P2_PKTDELIN_DELOCK 0xf3690080
1939#define F0900_P2_SYNCDUPDFL_BADDFL 0xf3690040 1926#define F0900_P2_SYNCDUPDFL_BADDFL 0xf3690040
1940#define F0900_P2_CONTINUOUS_STREAM 0xf3690020 1927#define F0900_P2_CONTINUOUS_STREAM 0xf3690020
1941#define F0900_P2_UNACCEPTED_STREAM 0xf3690010 1928#define F0900_P2_UNACCEPTED_STREAM 0xf3690010
1942#define F0900_P2_BCH_ERROR_FLAG 0xf3690008 1929#define F0900_P2_BCH_ERROR_FLAG 0xf3690008
1943#define F0900_P2_BBHCRCKO 0xf3690004 1930#define F0900_P2_PKTDELIN_LOCK 0xf3690002
1944#define F0900_P2_PKTDELIN_LOCK 0xf3690002 1931#define F0900_P2_FIRST_LOCK 0xf3690001
1945#define F0900_P2_FIRST_LOCK 0xf3690001
1946 1932
1947/*P2_PDELSTATUS2*/ 1933/*P2_PDELSTATUS2*/
1948#define R0900_P2_PDELSTATUS2 0xf36a 1934#define R0900_P2_PDELSTATUS2 0xf36a
1949#define F0900_P2_PKTDEL_DEMODSEL 0xf36a0080 1935#define F0900_P2_FRAME_MODCOD 0xf36a007c
1950#define F0900_P2_FRAME_MODCOD 0xf36a007c 1936#define F0900_P2_FRAME_TYPE 0xf36a0003
1951#define F0900_P2_FRAME_TYPE 0xf36a0003
1952 1937
1953/*P2_BBFCRCKO1*/ 1938/*P2_BBFCRCKO1*/
1954#define R0900_P2_BBFCRCKO1 0xf36b 1939#define R0900_P2_BBFCRCKO1 0xf36b
1955#define F0900_P2_BBHCRC_KOCNT1 0xf36b00ff 1940#define F0900_P2_BBHCRC_KOCNT1 0xf36b00ff
1956 1941
1957/*P2_BBFCRCKO0*/ 1942/*P2_BBFCRCKO0*/
1958#define R0900_P2_BBFCRCKO0 0xf36c 1943#define R0900_P2_BBFCRCKO0 0xf36c
1959#define F0900_P2_BBHCRC_KOCNT0 0xf36c00ff 1944#define F0900_P2_BBHCRC_KOCNT0 0xf36c00ff
1960 1945
1961/*P2_UPCRCKO1*/ 1946/*P2_UPCRCKO1*/
1962#define R0900_P2_UPCRCKO1 0xf36d 1947#define R0900_P2_UPCRCKO1 0xf36d
1963#define F0900_P2_PKTCRC_KOCNT1 0xf36d00ff 1948#define F0900_P2_PKTCRC_KOCNT1 0xf36d00ff
1964 1949
1965/*P2_UPCRCKO0*/ 1950/*P2_UPCRCKO0*/
1966#define R0900_P2_UPCRCKO0 0xf36e 1951#define R0900_P2_UPCRCKO0 0xf36e
1967#define F0900_P2_PKTCRC_KOCNT0 0xf36e00ff 1952#define F0900_P2_PKTCRC_KOCNT0 0xf36e00ff
1953
1954/*P2_PDELCTRL3*/
1955#define R0900_P2_PDELCTRL3 0xf36f
1956#define F0900_P2_PKTDEL_CONTFAIL 0xf36f0080
1957#define F0900_P2_NOFIFO_BCHERR 0xf36f0020
1968 1958
1969/*P2_TSSTATEM*/ 1959/*P2_TSSTATEM*/
1970#define R0900_P2_TSSTATEM 0xf370 1960#define R0900_P2_TSSTATEM 0xf370
1971#define F0900_P2_TSDIL_ON 0xf3700080 1961#define F0900_P2_TSDIL_ON 0xf3700080
1972#define F0900_P2_TSSKIPRS_ON 0xf3700040 1962#define F0900_P2_TSRS_ON 0xf3700020
1973#define F0900_P2_TSRS_ON 0xf3700020 1963#define F0900_P2_TSDESCRAMB_ON 0xf3700010
1974#define F0900_P2_TSDESCRAMB_ON 0xf3700010 1964#define F0900_P2_TSFRAME_MODE 0xf3700008
1975#define F0900_P2_TSFRAME_MODE 0xf3700008 1965#define F0900_P2_TS_DISABLE 0xf3700004
1976#define F0900_P2_TS_DISABLE 0xf3700004 1966#define F0900_P2_TSOUT_NOSYNC 0xf3700001
1977#define F0900_P2_TSACM_MODE 0xf3700002
1978#define F0900_P2_TSOUT_NOSYNC 0xf3700001
1979 1967
1980/*P2_TSCFGH*/ 1968/*P2_TSCFGH*/
1981#define R0900_P2_TSCFGH 0xf372 1969#define R0900_P2_TSCFGH 0xf372
1982#define F0900_P2_TSFIFO_DVBCI 0xf3720080 1970#define F0900_P2_TSFIFO_DVBCI 0xf3720080
1983#define F0900_P2_TSFIFO_SERIAL 0xf3720040 1971#define F0900_P2_TSFIFO_SERIAL 0xf3720040
1984#define F0900_P2_TSFIFO_TEIUPDATE 0xf3720020 1972#define F0900_P2_TSFIFO_TEIUPDATE 0xf3720020
1985#define F0900_P2_TSFIFO_DUTY50 0xf3720010 1973#define F0900_P2_TSFIFO_DUTY50 0xf3720010
1986#define F0900_P2_TSFIFO_HSGNLOUT 0xf3720008 1974#define F0900_P2_TSFIFO_HSGNLOUT 0xf3720008
1987#define F0900_P2_TSFIFO_ERRMODE 0xf3720006 1975#define F0900_P2_TSFIFO_ERRMODE 0xf3720006
1988#define F0900_P2_RST_HWARE 0xf3720001 1976#define F0900_P2_RST_HWARE 0xf3720001
1989 1977
1990/*P2_TSCFGM*/ 1978/*P2_TSCFGM*/
1991#define R0900_P2_TSCFGM 0xf373 1979#define R0900_P2_TSCFGM 0xf373
1992#define F0900_P2_TSFIFO_MANSPEED 0xf37300c0 1980#define F0900_P2_TSFIFO_MANSPEED 0xf37300c0
1993#define F0900_P2_TSFIFO_PERMDATA 0xf3730020 1981#define F0900_P2_TSFIFO_PERMDATA 0xf3730020
1994#define F0900_P2_TSFIFO_NONEWSGNL 0xf3730010 1982#define F0900_P2_TSFIFO_DPUNACT 0xf3730002
1995#define F0900_P2_TSFIFO_BITSPEED 0xf3730008 1983#define F0900_P2_TSFIFO_INVDATA 0xf3730001
1996#define F0900_P2_NPD_SPECDVBS2 0xf3730004
1997#define F0900_P2_TSFIFO_STOPCKDIS 0xf3730002
1998#define F0900_P2_TSFIFO_INVDATA 0xf3730001
1999 1984
2000/*P2_TSCFGL*/ 1985/*P2_TSCFGL*/
2001#define R0900_P2_TSCFGL 0xf374 1986#define R0900_P2_TSCFGL 0xf374
2002#define F0900_P2_TSFIFO_BCLKDEL1CK 0xf37400c0 1987#define F0900_P2_TSFIFO_BCLKDEL1CK 0xf37400c0
2003#define F0900_P2_BCHERROR_MODE 0xf3740030 1988#define F0900_P2_BCHERROR_MODE 0xf3740030
2004#define F0900_P2_TSFIFO_NSGNL2DATA 0xf3740008 1989#define F0900_P2_TSFIFO_NSGNL2DATA 0xf3740008
2005#define F0900_P2_TSFIFO_EMBINDVB 0xf3740004 1990#define F0900_P2_TSFIFO_EMBINDVB 0xf3740004
2006#define F0900_P2_TSFIFO_DPUNACT 0xf3740002 1991#define F0900_P2_TSFIFO_BITSPEED 0xf3740003
2007#define F0900_P2_TSFIFO_NPDOFF 0xf3740001
2008 1992
2009/*P2_TSINSDELH*/ 1993/*P2_TSINSDELH*/
2010#define R0900_P2_TSINSDELH 0xf376 1994#define R0900_P2_TSINSDELH 0xf376
2011#define F0900_P2_TSDEL_SYNCBYTE 0xf3760080 1995#define F0900_P2_TSDEL_SYNCBYTE 0xf3760080
2012#define F0900_P2_TSDEL_XXHEADER 0xf3760040 1996#define F0900_P2_TSDEL_XXHEADER 0xf3760040
2013#define F0900_P2_TSDEL_BBHEADER 0xf3760020 1997#define F0900_P2_TSDEL_BBHEADER 0xf3760020
2014#define F0900_P2_TSDEL_DATAFIELD 0xf3760010 1998#define F0900_P2_TSDEL_DATAFIELD 0xf3760010
2015#define F0900_P2_TSINSDEL_ISCR 0xf3760008 1999#define F0900_P2_TSINSDEL_ISCR 0xf3760008
2016#define F0900_P2_TSINSDEL_NPD 0xf3760004 2000#define F0900_P2_TSINSDEL_NPD 0xf3760004
2017#define F0900_P2_TSINSDEL_RSPARITY 0xf3760002 2001#define F0900_P2_TSINSDEL_RSPARITY 0xf3760002
2018#define F0900_P2_TSINSDEL_CRC8 0xf3760001 2002#define F0900_P2_TSINSDEL_CRC8 0xf3760001
2003
2004/*P2_TSDIVN*/
2005#define R0900_P2_TSDIVN 0xf379
2006#define F0900_P2_TSFIFO_SPEEDMODE 0xf37900c0
2007
2008/*P2_TSCFG4*/
2009#define R0900_P2_TSCFG4 0xf37a
2010#define F0900_P2_TSFIFO_TSSPEEDMODE 0xf37a00c0
2019 2011
2020/*P2_TSSPEED*/ 2012/*P2_TSSPEED*/
2021#define R0900_P2_TSSPEED 0xf380 2013#define R0900_P2_TSSPEED 0xf380
2022#define F0900_P2_TSFIFO_OUTSPEED 0xf38000ff 2014#define F0900_P2_TSFIFO_OUTSPEED 0xf38000ff
2023 2015
2024/*P2_TSSTATUS*/ 2016/*P2_TSSTATUS*/
2025#define R0900_P2_TSSTATUS 0xf381 2017#define R0900_P2_TSSTATUS 0xf381
2026#define F0900_P2_TSFIFO_LINEOK 0xf3810080 2018#define F0900_P2_TSFIFO_LINEOK 0xf3810080
2027#define F0900_P2_TSFIFO_ERROR 0xf3810040 2019#define F0900_P2_TSFIFO_ERROR 0xf3810040
2028#define F0900_P2_TSFIFO_DATA7 0xf3810020 2020#define F0900_P2_DIL_READY 0xf3810001
2029#define F0900_P2_TSFIFO_NOSYNC 0xf3810010
2030#define F0900_P2_ISCR_INITIALIZED 0xf3810008
2031#define F0900_P2_ISCR_UPDATED 0xf3810004
2032#define F0900_P2_SOFFIFO_UNREGUL 0xf3810002
2033#define F0900_P2_DIL_READY 0xf3810001
2034 2021
2035/*P2_TSSTATUS2*/ 2022/*P2_TSSTATUS2*/
2036#define R0900_P2_TSSTATUS2 0xf382 2023#define R0900_P2_TSSTATUS2 0xf382
2037#define F0900_P2_TSFIFO_DEMODSEL 0xf3820080 2024#define F0900_P2_TSFIFO_DEMODSEL 0xf3820080
2038#define F0900_P2_TSFIFOSPEED_STORE 0xf3820040 2025#define F0900_P2_TSFIFOSPEED_STORE 0xf3820040
2039#define F0900_P2_DILXX_RESET 0xf3820020 2026#define F0900_P2_DILXX_RESET 0xf3820020
2040#define F0900_P2_TSSERIAL_IMPOS 0xf3820010 2027#define F0900_P2_TSSERIAL_IMPOS 0xf3820010
2041#define F0900_P2_TSFIFO_LINENOK 0xf3820008 2028#define F0900_P2_SCRAMBDETECT 0xf3820002
2042#define F0900_P2_BITSPEED_EVENT 0xf3820004
2043#define F0900_P2_SCRAMBDETECT 0xf3820002
2044#define F0900_P2_ULDTV67_FALSELOCK 0xf3820001
2045 2029
2046/*P2_TSBITRATE1*/ 2030/*P2_TSBITRATE1*/
2047#define R0900_P2_TSBITRATE1 0xf383 2031#define R0900_P2_TSBITRATE1 0xf383
2048#define F0900_P2_TSFIFO_BITRATE1 0xf38300ff 2032#define F0900_P2_TSFIFO_BITRATE1 0xf38300ff
2049 2033
2050/*P2_TSBITRATE0*/ 2034/*P2_TSBITRATE0*/
2051#define R0900_P2_TSBITRATE0 0xf384 2035#define R0900_P2_TSBITRATE0 0xf384
2052#define F0900_P2_TSFIFO_BITRATE0 0xf38400ff 2036#define F0900_P2_TSFIFO_BITRATE0 0xf38400ff
2053 2037
2054/*P2_ERRCTRL1*/ 2038/*P2_ERRCTRL1*/
2055#define R0900_P2_ERRCTRL1 0xf398 2039#define R0900_P2_ERRCTRL1 0xf398
2056#define F0900_P2_ERR_SOURCE1 0xf39800f0 2040#define F0900_P2_ERR_SOURCE1 0xf39800f0
2057#define F0900_P2_NUM_EVENT1 0xf3980007 2041#define F0900_P2_NUM_EVENT1 0xf3980007
2058 2042
2059/*P2_ERRCNT12*/ 2043/*P2_ERRCNT12*/
2060#define R0900_P2_ERRCNT12 0xf399 2044#define R0900_P2_ERRCNT12 0xf399
2061#define F0900_P2_ERRCNT1_OLDVALUE 0xf3990080 2045#define F0900_P2_ERRCNT1_OLDVALUE 0xf3990080
2062#define F0900_P2_ERR_CNT12 0xf399007f 2046#define F0900_P2_ERR_CNT12 0xf399007f
2063 2047
2064/*P2_ERRCNT11*/ 2048/*P2_ERRCNT11*/
2065#define R0900_P2_ERRCNT11 0xf39a 2049#define R0900_P2_ERRCNT11 0xf39a
2066#define F0900_P2_ERR_CNT11 0xf39a00ff 2050#define F0900_P2_ERR_CNT11 0xf39a00ff
2067 2051
2068/*P2_ERRCNT10*/ 2052/*P2_ERRCNT10*/
2069#define R0900_P2_ERRCNT10 0xf39b 2053#define R0900_P2_ERRCNT10 0xf39b
2070#define F0900_P2_ERR_CNT10 0xf39b00ff 2054#define F0900_P2_ERR_CNT10 0xf39b00ff
2071 2055
2072/*P2_ERRCTRL2*/ 2056/*P2_ERRCTRL2*/
2073#define R0900_P2_ERRCTRL2 0xf39c 2057#define R0900_P2_ERRCTRL2 0xf39c
2074#define F0900_P2_ERR_SOURCE2 0xf39c00f0 2058#define F0900_P2_ERR_SOURCE2 0xf39c00f0
2075#define F0900_P2_NUM_EVENT2 0xf39c0007 2059#define F0900_P2_NUM_EVENT2 0xf39c0007
2076 2060
2077/*P2_ERRCNT22*/ 2061/*P2_ERRCNT22*/
2078#define R0900_P2_ERRCNT22 0xf39d 2062#define R0900_P2_ERRCNT22 0xf39d
2079#define F0900_P2_ERRCNT2_OLDVALUE 0xf39d0080 2063#define F0900_P2_ERRCNT2_OLDVALUE 0xf39d0080
2080#define F0900_P2_ERR_CNT22 0xf39d007f 2064#define F0900_P2_ERR_CNT22 0xf39d007f
2081 2065
2082/*P2_ERRCNT21*/ 2066/*P2_ERRCNT21*/
2083#define R0900_P2_ERRCNT21 0xf39e 2067#define R0900_P2_ERRCNT21 0xf39e
2084#define F0900_P2_ERR_CNT21 0xf39e00ff 2068#define F0900_P2_ERR_CNT21 0xf39e00ff
2085 2069
2086/*P2_ERRCNT20*/ 2070/*P2_ERRCNT20*/
2087#define R0900_P2_ERRCNT20 0xf39f 2071#define R0900_P2_ERRCNT20 0xf39f
2088#define F0900_P2_ERR_CNT20 0xf39f00ff 2072#define F0900_P2_ERR_CNT20 0xf39f00ff
2089 2073
2090/*P2_FECSPY*/ 2074/*P2_FECSPY*/
2091#define R0900_P2_FECSPY 0xf3a0 2075#define R0900_P2_FECSPY 0xf3a0
2092#define F0900_P2_SPY_ENABLE 0xf3a00080 2076#define F0900_P2_SPY_ENABLE 0xf3a00080
2093#define F0900_P2_NO_SYNCBYTE 0xf3a00040 2077#define F0900_P2_NO_SYNCBYTE 0xf3a00040
2094#define F0900_P2_SERIAL_MODE 0xf3a00020 2078#define F0900_P2_SERIAL_MODE 0xf3a00020
2095#define F0900_P2_UNUSUAL_PACKET 0xf3a00010 2079#define F0900_P2_UNUSUAL_PACKET 0xf3a00010
2096#define F0900_P2_BER_PACKMODE 0xf3a00008 2080#define F0900_P2_BERMETER_DATAMODE 0xf3a00008
2097#define F0900_P2_BERMETER_LMODE 0xf3a00002 2081#define F0900_P2_BERMETER_LMODE 0xf3a00002
2098#define F0900_P2_BERMETER_RESET 0xf3a00001 2082#define F0900_P2_BERMETER_RESET 0xf3a00001
2099 2083
2100/*P2_FSPYCFG*/ 2084/*P2_FSPYCFG*/
2101#define R0900_P2_FSPYCFG 0xf3a1 2085#define R0900_P2_FSPYCFG 0xf3a1
2102#define F0900_P2_FECSPY_INPUT 0xf3a100c0 2086#define F0900_P2_FECSPY_INPUT 0xf3a100c0
2103#define F0900_P2_RST_ON_ERROR 0xf3a10020 2087#define F0900_P2_RST_ON_ERROR 0xf3a10020
2104#define F0900_P2_ONE_SHOT 0xf3a10010 2088#define F0900_P2_ONE_SHOT 0xf3a10010
2105#define F0900_P2_I2C_MODE 0xf3a1000c 2089#define F0900_P2_I2C_MODE 0xf3a1000c
2106#define F0900_P2_SPY_HYSTERESIS 0xf3a10003 2090#define F0900_P2_SPY_HYSTERESIS 0xf3a10003
2107 2091
2108/*P2_FSPYDATA*/ 2092/*P2_FSPYDATA*/
2109#define R0900_P2_FSPYDATA 0xf3a2 2093#define R0900_P2_FSPYDATA 0xf3a2
2110#define F0900_P2_SPY_STUFFING 0xf3a20080 2094#define F0900_P2_SPY_STUFFING 0xf3a20080
2111#define F0900_P2_NOERROR_PKTJITTER 0xf3a20040 2095#define F0900_P2_SPY_CNULLPKT 0xf3a20020
2112#define F0900_P2_SPY_CNULLPKT 0xf3a20020 2096#define F0900_P2_SPY_OUTDATA_MODE 0xf3a2001f
2113#define F0900_P2_SPY_OUTDATA_MODE 0xf3a2001f
2114 2097
2115/*P2_FSPYOUT*/ 2098/*P2_FSPYOUT*/
2116#define R0900_P2_FSPYOUT 0xf3a3 2099#define R0900_P2_FSPYOUT 0xf3a3
2117#define F0900_P2_FSPY_DIRECT 0xf3a30080 2100#define F0900_P2_FSPY_DIRECT 0xf3a30080
2118#define F0900_P2_SPY_OUTDATA_BUS 0xf3a30038 2101#define F0900_P2_STUFF_MODE 0xf3a30007
2119#define F0900_P2_STUFF_MODE 0xf3a30007
2120 2102
2121/*P2_FSTATUS*/ 2103/*P2_FSTATUS*/
2122#define R0900_P2_FSTATUS 0xf3a4 2104#define R0900_P2_FSTATUS 0xf3a4
2123#define F0900_P2_SPY_ENDSIM 0xf3a40080 2105#define F0900_P2_SPY_ENDSIM 0xf3a40080
2124#define F0900_P2_VALID_SIM 0xf3a40040 2106#define F0900_P2_VALID_SIM 0xf3a40040
2125#define F0900_P2_FOUND_SIGNAL 0xf3a40020 2107#define F0900_P2_FOUND_SIGNAL 0xf3a40020
2126#define F0900_P2_DSS_SYNCBYTE 0xf3a40010 2108#define F0900_P2_DSS_SYNCBYTE 0xf3a40010
2127#define F0900_P2_RESULT_STATE 0xf3a4000f 2109#define F0900_P2_RESULT_STATE 0xf3a4000f
2128 2110
2129/*P2_FBERCPT4*/ 2111/*P2_FBERCPT4*/
2130#define R0900_P2_FBERCPT4 0xf3a8 2112#define R0900_P2_FBERCPT4 0xf3a8
2131#define F0900_P2_FBERMETER_CPT4 0xf3a800ff 2113#define F0900_P2_FBERMETER_CPT4 0xf3a800ff
2132 2114
2133/*P2_FBERCPT3*/ 2115/*P2_FBERCPT3*/
2134#define R0900_P2_FBERCPT3 0xf3a9 2116#define R0900_P2_FBERCPT3 0xf3a9
2135#define F0900_P2_FBERMETER_CPT3 0xf3a900ff 2117#define F0900_P2_FBERMETER_CPT3 0xf3a900ff
2136 2118
2137/*P2_FBERCPT2*/ 2119/*P2_FBERCPT2*/
2138#define R0900_P2_FBERCPT2 0xf3aa 2120#define R0900_P2_FBERCPT2 0xf3aa
2139#define F0900_P2_FBERMETER_CPT2 0xf3aa00ff 2121#define F0900_P2_FBERMETER_CPT2 0xf3aa00ff
2140 2122
2141/*P2_FBERCPT1*/ 2123/*P2_FBERCPT1*/
2142#define R0900_P2_FBERCPT1 0xf3ab 2124#define R0900_P2_FBERCPT1 0xf3ab
2143#define F0900_P2_FBERMETER_CPT1 0xf3ab00ff 2125#define F0900_P2_FBERMETER_CPT1 0xf3ab00ff
2144 2126
2145/*P2_FBERCPT0*/ 2127/*P2_FBERCPT0*/
2146#define R0900_P2_FBERCPT0 0xf3ac 2128#define R0900_P2_FBERCPT0 0xf3ac
2147#define F0900_P2_FBERMETER_CPT0 0xf3ac00ff 2129#define F0900_P2_FBERMETER_CPT0 0xf3ac00ff
2148 2130
2149/*P2_FBERERR2*/ 2131/*P2_FBERERR2*/
2150#define R0900_P2_FBERERR2 0xf3ad 2132#define R0900_P2_FBERERR2 0xf3ad
2151#define F0900_P2_FBERMETER_ERR2 0xf3ad00ff 2133#define F0900_P2_FBERMETER_ERR2 0xf3ad00ff
2152 2134
2153/*P2_FBERERR1*/ 2135/*P2_FBERERR1*/
2154#define R0900_P2_FBERERR1 0xf3ae 2136#define R0900_P2_FBERERR1 0xf3ae
2155#define F0900_P2_FBERMETER_ERR1 0xf3ae00ff 2137#define F0900_P2_FBERMETER_ERR1 0xf3ae00ff
2156 2138
2157/*P2_FBERERR0*/ 2139/*P2_FBERERR0*/
2158#define R0900_P2_FBERERR0 0xf3af 2140#define R0900_P2_FBERERR0 0xf3af
2159#define F0900_P2_FBERMETER_ERR0 0xf3af00ff 2141#define F0900_P2_FBERMETER_ERR0 0xf3af00ff
2160 2142
2161/*P2_FSPYBER*/ 2143/*P2_FSPYBER*/
2162#define R0900_P2_FSPYBER 0xf3b2 2144#define R0900_P2_FSPYBER 0xf3b2
2163#define F0900_P2_FSPYOBS_XORREAD 0xf3b20040 2145#define F0900_P2_FSPYBER_SYNCBYTE 0xf3b20010
2164#define F0900_P2_FSPYBER_OBSMODE 0xf3b20020 2146#define F0900_P2_FSPYBER_UNSYNC 0xf3b20008
2165#define F0900_P2_FSPYBER_SYNCBYTE 0xf3b20010 2147#define F0900_P2_FSPYBER_CTIME 0xf3b20007
2166#define F0900_P2_FSPYBER_UNSYNC 0xf3b20008
2167#define F0900_P2_FSPYBER_CTIME 0xf3b20007
2168 2148
2169/*P1_IQCONST*/ 2149/*P1_IQCONST*/
2170#define R0900_P1_IQCONST 0xf400 2150#define R0900_P1_IQCONST 0xf400
2171#define F0900_P1_CONSTEL_SELECT 0xf4000060 2151#define IQCONST REGx(R0900_P1_IQCONST)
2172#define F0900_P1_IQSYMB_SEL 0xf400001f 2152#define F0900_P1_CONSTEL_SELECT 0xf4000060
2153#define F0900_P1_IQSYMB_SEL 0xf400001f
2173 2154
2174/*P1_NOSCFG*/ 2155/*P1_NOSCFG*/
2175#define R0900_P1_NOSCFG 0xf401 2156#define R0900_P1_NOSCFG 0xf401
2176#define F0900_P1_DUMMYPL_NOSDATA 0xf4010020 2157#define NOSCFG REGx(R0900_P1_NOSCFG)
2177#define F0900_P1_NOSPLH_BETA 0xf4010018 2158#define F0900_P1_DUMMYPL_NOSDATA 0xf4010020
2178#define F0900_P1_NOSDATA_BETA 0xf4010007 2159#define F0900_P1_NOSPLH_BETA 0xf4010018
2160#define F0900_P1_NOSDATA_BETA 0xf4010007
2179 2161
2180/*P1_ISYMB*/ 2162/*P1_ISYMB*/
2181#define R0900_P1_ISYMB 0xf402 2163#define R0900_P1_ISYMB 0xf402
2182#define F0900_P1_I_SYMBOL 0xf40201ff 2164#define ISYMB REGx(R0900_P1_ISYMB)
2165#define F0900_P1_I_SYMBOL 0xf40201ff
2183 2166
2184/*P1_QSYMB*/ 2167/*P1_QSYMB*/
2185#define R0900_P1_QSYMB 0xf403 2168#define R0900_P1_QSYMB 0xf403
2186#define F0900_P1_Q_SYMBOL 0xf40301ff 2169#define QSYMB REGx(R0900_P1_QSYMB)
2170#define F0900_P1_Q_SYMBOL 0xf40301ff
2187 2171
2188/*P1_AGC1CFG*/ 2172/*P1_AGC1CFG*/
2189#define R0900_P1_AGC1CFG 0xf404 2173#define R0900_P1_AGC1CFG 0xf404
2190#define F0900_P1_DC_FROZEN 0xf4040080 2174#define AGC1CFG REGx(R0900_P1_AGC1CFG)
2191#define F0900_P1_DC_CORRECT 0xf4040040 2175#define F0900_P1_DC_FROZEN 0xf4040080
2192#define F0900_P1_AMM_FROZEN 0xf4040020 2176#define F0900_P1_DC_CORRECT 0xf4040040
2193#define F0900_P1_AMM_CORRECT 0xf4040010 2177#define F0900_P1_AMM_FROZEN 0xf4040020
2194#define F0900_P1_QUAD_FROZEN 0xf4040008 2178#define F0900_P1_AMM_CORRECT 0xf4040010
2195#define F0900_P1_QUAD_CORRECT 0xf4040004 2179#define F0900_P1_QUAD_FROZEN 0xf4040008
2196#define F0900_P1_DCCOMP_SLOW 0xf4040002 2180#define F0900_P1_QUAD_CORRECT 0xf4040004
2197#define F0900_P1_IQMISM_SLOW 0xf4040001
2198 2181
2199/*P1_AGC1CN*/ 2182/*P1_AGC1CN*/
2200#define R0900_P1_AGC1CN 0xf406 2183#define R0900_P1_AGC1CN 0xf406
2201#define F0900_P1_AGC1_LOCKED 0xf4060080 2184#define AGC1CN REGx(R0900_P1_AGC1CN)
2202#define F0900_P1_AGC1_OVERFLOW 0xf4060040 2185#define F0900_P1_AGC1_LOCKED 0xf4060080
2203#define F0900_P1_AGC1_NOSLOWLK 0xf4060020 2186#define F0900_P1_AGC1_MINPOWER 0xf4060010
2204#define F0900_P1_AGC1_MINPOWER 0xf4060010 2187#define F0900_P1_AGCOUT_FAST 0xf4060008
2205#define F0900_P1_AGCOUT_FAST 0xf4060008 2188#define F0900_P1_AGCIQ_BETA 0xf4060007
2206#define F0900_P1_AGCIQ_BETA 0xf4060007
2207 2189
2208/*P1_AGC1REF*/ 2190/*P1_AGC1REF*/
2209#define R0900_P1_AGC1REF 0xf407 2191#define R0900_P1_AGC1REF 0xf407
2210#define F0900_P1_AGCIQ_REF 0xf40700ff 2192#define AGC1REF REGx(R0900_P1_AGC1REF)
2193#define F0900_P1_AGCIQ_REF 0xf40700ff
2211 2194
2212/*P1_IDCCOMP*/ 2195/*P1_IDCCOMP*/
2213#define R0900_P1_IDCCOMP 0xf408 2196#define R0900_P1_IDCCOMP 0xf408
2214#define F0900_P1_IAVERAGE_ADJ 0xf40801ff 2197#define IDCCOMP REGx(R0900_P1_IDCCOMP)
2198#define F0900_P1_IAVERAGE_ADJ 0xf40801ff
2215 2199
2216/*P1_QDCCOMP*/ 2200/*P1_QDCCOMP*/
2217#define R0900_P1_QDCCOMP 0xf409 2201#define R0900_P1_QDCCOMP 0xf409
2218#define F0900_P1_QAVERAGE_ADJ 0xf40901ff 2202#define QDCCOMP REGx(R0900_P1_QDCCOMP)
2203#define F0900_P1_QAVERAGE_ADJ 0xf40901ff
2219 2204
2220/*P1_POWERI*/ 2205/*P1_POWERI*/
2221#define R0900_P1_POWERI 0xf40a 2206#define R0900_P1_POWERI 0xf40a
2222#define F0900_P1_POWER_I 0xf40a00ff 2207#define POWERI REGx(R0900_P1_POWERI)
2208#define F0900_P1_POWER_I 0xf40a00ff
2209#define POWER_I FLDx(F0900_P1_POWER_I)
2223 2210
2224/*P1_POWERQ*/ 2211/*P1_POWERQ*/
2225#define R0900_P1_POWERQ 0xf40b 2212#define R0900_P1_POWERQ 0xf40b
2226#define F0900_P1_POWER_Q 0xf40b00ff 2213#define POWERQ REGx(R0900_P1_POWERQ)
2214#define F0900_P1_POWER_Q 0xf40b00ff
2215#define POWER_Q FLDx(F0900_P1_POWER_Q)
2227 2216
2228/*P1_AGC1AMM*/ 2217/*P1_AGC1AMM*/
2229#define R0900_P1_AGC1AMM 0xf40c 2218#define R0900_P1_AGC1AMM 0xf40c
2230#define F0900_P1_AMM_VALUE 0xf40c00ff 2219#define AGC1AMM REGx(R0900_P1_AGC1AMM)
2220#define F0900_P1_AMM_VALUE 0xf40c00ff
2231 2221
2232/*P1_AGC1QUAD*/ 2222/*P1_AGC1QUAD*/
2233#define R0900_P1_AGC1QUAD 0xf40d 2223#define R0900_P1_AGC1QUAD 0xf40d
2234#define F0900_P1_QUAD_VALUE 0xf40d01ff 2224#define AGC1QUAD REGx(R0900_P1_AGC1QUAD)
2225#define F0900_P1_QUAD_VALUE 0xf40d01ff
2235 2226
2236/*P1_AGCIQIN1*/ 2227/*P1_AGCIQIN1*/
2237#define R0900_P1_AGCIQIN1 0xf40e 2228#define R0900_P1_AGCIQIN1 0xf40e
2238#define F0900_P1_AGCIQ_VALUE1 0xf40e00ff 2229#define AGCIQIN1 REGx(R0900_P1_AGCIQIN1)
2230#define F0900_P1_AGCIQ_VALUE1 0xf40e00ff
2231#define AGCIQ_VALUE1 FLDx(F0900_P1_AGCIQ_VALUE1)
2239 2232
2240/*P1_AGCIQIN0*/ 2233/*P1_AGCIQIN0*/
2241#define R0900_P1_AGCIQIN0 0xf40f 2234#define R0900_P1_AGCIQIN0 0xf40f
2242#define F0900_P1_AGCIQ_VALUE0 0xf40f00ff 2235#define AGCIQIN0 REGx(R0900_P1_AGCIQIN0)
2236#define F0900_P1_AGCIQ_VALUE0 0xf40f00ff
2237#define AGCIQ_VALUE0 FLDx(F0900_P1_AGCIQ_VALUE0)
2243 2238
2244/*P1_DEMOD*/ 2239/*P1_DEMOD*/
2245#define R0900_P1_DEMOD 0xf410 2240#define R0900_P1_DEMOD 0xf410
2246#define F0900_P1_DEMOD_STOP 0xf4100040 2241#define DEMOD REGx(R0900_P1_DEMOD)
2247#define F0900_P1_SPECINV_CONTROL 0xf4100030 2242#define F0900_P1_MANUALS2_ROLLOFF 0xf4100080
2248#define F0900_P1_FORCE_ENASAMP 0xf4100008 2243#define MANUALS2_ROLLOFF FLDx(F0900_P1_MANUALS2_ROLLOFF)
2249#define F0900_P1_MANUAL_ROLLOFF 0xf4100004 2244
2250#define F0900_P1_ROLLOFF_CONTROL 0xf4100003 2245#define F0900_P1_SPECINV_CONTROL 0xf4100030
2246#define SPECINV_CONTROL FLDx(F0900_P1_SPECINV_CONTROL)
2247#define F0900_P1_FORCE_ENASAMP 0xf4100008
2248#define F0900_P1_MANUALSX_ROLLOFF 0xf4100004
2249#define MANUALSX_ROLLOFF FLDx(F0900_P1_MANUALSX_ROLLOFF)
2250#define F0900_P1_ROLLOFF_CONTROL 0xf4100003
2251#define ROLLOFF_CONTROL FLDx(F0900_P1_ROLLOFF_CONTROL)
2251 2252
2252/*P1_DMDMODCOD*/ 2253/*P1_DMDMODCOD*/
2253#define R0900_P1_DMDMODCOD 0xf411 2254#define R0900_P1_DMDMODCOD 0xf411
2254#define F0900_P1_MANUAL_MODCOD 0xf4110080 2255#define DMDMODCOD REGx(R0900_P1_DMDMODCOD)
2255#define F0900_P1_DEMOD_MODCOD 0xf411007c 2256#define F0900_P1_MANUAL_MODCOD 0xf4110080
2256#define F0900_P1_DEMOD_TYPE 0xf4110003 2257#define F0900_P1_DEMOD_MODCOD 0xf411007c
2258#define DEMOD_MODCOD FLDx(F0900_P1_DEMOD_MODCOD)
2259#define F0900_P1_DEMOD_TYPE 0xf4110003
2260#define DEMOD_TYPE FLDx(F0900_P1_DEMOD_TYPE)
2257 2261
2258/*P1_DSTATUS*/ 2262/*P1_DSTATUS*/
2259#define R0900_P1_DSTATUS 0xf412 2263#define R0900_P1_DSTATUS 0xf412
2260#define F0900_P1_CAR_LOCK 0xf4120080 2264#define DSTATUS REGx(R0900_P1_DSTATUS)
2261#define F0900_P1_TMGLOCK_QUALITY 0xf4120060 2265#define F0900_P1_CAR_LOCK 0xf4120080
2262#define F0900_P1_SDVBS1_ENABLE 0xf4120010 2266#define F0900_P1_TMGLOCK_QUALITY 0xf4120060
2263#define F0900_P1_LOCK_DEFINITIF 0xf4120008 2267#define TMGLOCK_QUALITY FLDx(F0900_P1_TMGLOCK_QUALITY)
2264#define F0900_P1_TIMING_IS_LOCKED 0xf4120004 2268#define F0900_P1_LOCK_DEFINITIF 0xf4120008
2265#define F0900_P1_COARSE_TMGLOCK 0xf4120002 2269#define LOCK_DEFINITIF FLDx(F0900_P1_LOCK_DEFINITIF)
2266#define F0900_P1_COARSE_CARLOCK 0xf4120001 2270#define F0900_P1_OVADC_DETECT 0xf4120001
2267 2271
2268/*P1_DSTATUS2*/ 2272/*P1_DSTATUS2*/
2269#define R0900_P1_DSTATUS2 0xf413 2273#define R0900_P1_DSTATUS2 0xf413
2270#define F0900_P1_DEMOD_DELOCK 0xf4130080 2274#define DSTATUS2 REGx(R0900_P1_DSTATUS2)
2271#define F0900_P1_DEMOD_TIMEOUT 0xf4130040 2275#define F0900_P1_DEMOD_DELOCK 0xf4130080
2272#define F0900_P1_MODCODRQ_SYNCTAG 0xf4130020 2276#define F0900_P1_AGC1_NOSIGNALACK 0xf4130008
2273#define F0900_P1_POLYPH_SATEVENT 0xf4130010 2277#define F0900_P1_AGC2_OVERFLOW 0xf4130004
2274#define F0900_P1_AGC1_NOSIGNALACK 0xf4130008 2278#define F0900_P1_CFR_OVERFLOW 0xf4130002
2275#define F0900_P1_AGC2_OVERFLOW 0xf4130004 2279#define F0900_P1_GAMMA_OVERUNDER 0xf4130001
2276#define F0900_P1_CFR_OVERFLOW 0xf4130002
2277#define F0900_P1_GAMMA_OVERUNDER 0xf4130001
2278 2280
2279/*P1_DMDCFGMD*/ 2281/*P1_DMDCFGMD*/
2280#define R0900_P1_DMDCFGMD 0xf414 2282#define R0900_P1_DMDCFGMD 0xf414
2281#define F0900_P1_DVBS2_ENABLE 0xf4140080 2283#define DMDCFGMD REGx(R0900_P1_DMDCFGMD)
2282#define F0900_P1_DVBS1_ENABLE 0xf4140040 2284#define F0900_P1_DVBS2_ENABLE 0xf4140080
2283#define F0900_P1_CFR_AUTOSCAN 0xf4140020 2285#define DVBS2_ENABLE FLDx(F0900_P1_DVBS2_ENABLE)
2284#define F0900_P1_SCAN_ENABLE 0xf4140010 2286#define F0900_P1_DVBS1_ENABLE 0xf4140040
2285#define F0900_P1_TUN_AUTOSCAN 0xf4140008 2287#define DVBS1_ENABLE FLDx(F0900_P1_DVBS1_ENABLE)
2286#define F0900_P1_NOFORCE_RELOCK 0xf4140004 2288#define F0900_P1_SCAN_ENABLE 0xf4140010
2287#define F0900_P1_TUN_RNG 0xf4140003 2289#define SCAN_ENABLE FLDx(F0900_P1_SCAN_ENABLE)
2290#define F0900_P1_CFR_AUTOSCAN 0xf4140008
2291#define CFR_AUTOSCAN FLDx(F0900_P1_CFR_AUTOSCAN)
2292#define F0900_P1_TUN_RNG 0xf4140003
2288 2293
2289/*P1_DMDCFG2*/ 2294/*P1_DMDCFG2*/
2290#define R0900_P1_DMDCFG2 0xf415 2295#define R0900_P1_DMDCFG2 0xf415
2291#define F0900_P1_AGC1_WAITLOCK 0xf4150080 2296#define DMDCFG2 REGx(R0900_P1_DMDCFG2)
2292#define F0900_P1_S1S2_SEQUENTIAL 0xf4150040 2297#define F0900_P1_S1S2_SEQUENTIAL 0xf4150040
2293#define F0900_P1_OVERFLOW_TIMEOUT 0xf4150020 2298#define S1S2_SEQUENTIAL FLDx(F0900_P1_S1S2_SEQUENTIAL)
2294#define F0900_P1_SCANFAIL_TIMEOUT 0xf4150010 2299#define F0900_P1_INFINITE_RELOCK 0xf4150010
2295#define F0900_P1_DMDTOUT_BACK 0xf4150008
2296#define F0900_P1_CARLOCK_S1ENABLE 0xf4150004
2297#define F0900_P1_COARSE_LK3MODE 0xf4150002
2298#define F0900_P1_COARSE_LK2MODE 0xf4150001
2299 2300
2300/*P1_DMDISTATE*/ 2301/*P1_DMDISTATE*/
2301#define R0900_P1_DMDISTATE 0xf416 2302#define R0900_P1_DMDISTATE 0xf416
2302#define F0900_P1_I2C_NORESETDMODE 0xf4160080 2303#define DMDISTATE REGx(R0900_P1_DMDISTATE)
2303#define F0900_P1_FORCE_ETAPED 0xf4160040 2304#define F0900_P1_I2C_DEMOD_MODE 0xf416001f
2304#define F0900_P1_SDMDRST_DIRCLK 0xf4160020 2305#define DEMOD_MODE FLDx(F0900_P1_I2C_DEMOD_MODE)
2305#define F0900_P1_I2C_DEMOD_MODE 0xf416001f
2306 2306
2307/*P1_DMDT0M*/ 2307/*P1_DMDT0M*/
2308#define R0900_P1_DMDT0M 0xf417 2308#define R0900_P1_DMDT0M 0xf417
2309#define F0900_P1_DMDT0_MIN 0xf41700ff 2309#define DMDT0M REGx(R0900_P1_DMDT0M)
2310#define F0900_P1_DMDT0_MIN 0xf41700ff
2310 2311
2311/*P1_DMDSTATE*/ 2312/*P1_DMDSTATE*/
2312#define R0900_P1_DMDSTATE 0xf41b 2313#define R0900_P1_DMDSTATE 0xf41b
2313#define F0900_P1_DEMOD_LOCKED 0xf41b0080 2314#define DMDSTATE REGx(R0900_P1_DMDSTATE)
2314#define F0900_P1_HEADER_MODE 0xf41b0060 2315#define F0900_P1_HEADER_MODE 0xf41b0060
2315#define F0900_P1_DEMOD_MODE 0xf41b001f 2316#define HEADER_MODE FLDx(F0900_P1_HEADER_MODE)
2316 2317
2317/*P1_DMDFLYW*/ 2318/*P1_DMDFLYW*/
2318#define R0900_P1_DMDFLYW 0xf41c 2319#define R0900_P1_DMDFLYW 0xf41c
2319#define F0900_P1_I2C_IRQVAL 0xf41c00f0 2320#define DMDFLYW REGx(R0900_P1_DMDFLYW)
2320#define F0900_P1_FLYWHEEL_CPT 0xf41c000f 2321#define F0900_P1_I2C_IRQVAL 0xf41c00f0
2322#define F0900_P1_FLYWHEEL_CPT 0xf41c000f
2323#define FLYWHEEL_CPT FLDx(F0900_P1_FLYWHEEL_CPT)
2321 2324
2322/*P1_DSTATUS3*/ 2325/*P1_DSTATUS3*/
2323#define R0900_P1_DSTATUS3 0xf41d 2326#define R0900_P1_DSTATUS3 0xf41d
2324#define F0900_P1_CFR_ZIGZAG 0xf41d0080 2327#define DSTATUS3 REGx(R0900_P1_DSTATUS3)
2325#define F0900_P1_DEMOD_CFGMODE 0xf41d0060 2328#define F0900_P1_DEMOD_CFGMODE 0xf41d0060
2326#define F0900_P1_GAMMA_LOWBAUDRATE 0xf41d0010
2327#define F0900_P1_RELOCK_MODE 0xf41d0008
2328#define F0900_P1_DEMOD_FAIL 0xf41d0004
2329#define F0900_P1_ETAPE1A_DVBXMEM 0xf41d0003
2330 2329
2331/*P1_DMDCFG3*/ 2330/*P1_DMDCFG3*/
2332#define R0900_P1_DMDCFG3 0xf41e 2331#define R0900_P1_DMDCFG3 0xf41e
2333#define F0900_P1_DVBS1_TMGWAIT 0xf41e0080 2332#define DMDCFG3 REGx(R0900_P1_DMDCFG3)
2334#define F0900_P1_NO_BWCENTERING 0xf41e0040 2333#define F0900_P1_NOSTOP_FIFOFULL 0xf41e0008
2335#define F0900_P1_INV_SEQSRCH 0xf41e0020
2336#define F0900_P1_DIS_SFRUPLOW_TRK 0xf41e0010
2337#define F0900_P1_NOSTOP_FIFOFULL 0xf41e0008
2338#define F0900_P1_LOCKTIME_MODE 0xf41e0007
2339 2334
2340/*P1_DMDCFG4*/ 2335/*P1_DMDCFG4*/
2341#define R0900_P1_DMDCFG4 0xf41f 2336#define R0900_P1_DMDCFG4 0xf41f
2342#define F0900_P1_TUNER_NRELAUNCH 0xf41f0008 2337#define DMDCFG4 REGx(R0900_P1_DMDCFG4)
2343#define F0900_P1_DIS_CLKENABLE 0xf41f0004 2338#define F0900_P1_TUNER_NRELAUNCH 0xf41f0008
2344#define F0900_P1_DIS_HDRDIVLOCK 0xf41f0002
2345#define F0900_P1_NO_TNRWBINIT 0xf41f0001
2346 2339
2347/*P1_CORRELMANT*/ 2340/*P1_CORRELMANT*/
2348#define R0900_P1_CORRELMANT 0xf420 2341#define R0900_P1_CORRELMANT 0xf420
2349#define F0900_P1_CORREL_MANT 0xf42000ff 2342#define CORRELMANT REGx(R0900_P1_CORRELMANT)
2343#define F0900_P1_CORREL_MANT 0xf42000ff
2350 2344
2351/*P1_CORRELABS*/ 2345/*P1_CORRELABS*/
2352#define R0900_P1_CORRELABS 0xf421 2346#define R0900_P1_CORRELABS 0xf421
2353#define F0900_P1_CORREL_ABS 0xf42100ff 2347#define CORRELABS REGx(R0900_P1_CORRELABS)
2348#define F0900_P1_CORREL_ABS 0xf42100ff
2354 2349
2355/*P1_CORRELEXP*/ 2350/*P1_CORRELEXP*/
2356#define R0900_P1_CORRELEXP 0xf422 2351#define R0900_P1_CORRELEXP 0xf422
2357#define F0900_P1_CORREL_ABSEXP 0xf42200f0 2352#define CORRELEXP REGx(R0900_P1_CORRELEXP)
2358#define F0900_P1_CORREL_EXP 0xf422000f 2353#define F0900_P1_CORREL_ABSEXP 0xf42200f0
2354#define F0900_P1_CORREL_EXP 0xf422000f
2359 2355
2360/*P1_PLHMODCOD*/ 2356/*P1_PLHMODCOD*/
2361#define R0900_P1_PLHMODCOD 0xf424 2357#define R0900_P1_PLHMODCOD 0xf424
2362#define F0900_P1_SPECINV_DEMOD 0xf4240080 2358#define PLHMODCOD REGx(R0900_P1_PLHMODCOD)
2363#define F0900_P1_PLH_MODCOD 0xf424007c 2359#define F0900_P1_SPECINV_DEMOD 0xf4240080
2364#define F0900_P1_PLH_TYPE 0xf4240003 2360#define SPECINV_DEMOD FLDx(F0900_P1_SPECINV_DEMOD)
2365 2361#define F0900_P1_PLH_MODCOD 0xf424007c
2366/*P1_AGCK32*/ 2362#define F0900_P1_PLH_TYPE 0xf4240003
2367#define R0900_P1_AGCK32 0xf42b 2363
2368#define F0900_P1_R3ADJOFF_32APSK 0xf42b0080 2364/*P1_DMDREG*/
2369#define F0900_P1_R2ADJOFF_32APSK 0xf42b0040 2365#define R0900_P1_DMDREG 0xf425
2370#define F0900_P1_R1ADJOFF_32APSK 0xf42b0020 2366#define DMDREG REGx(R0900_P1_DMDREG)
2371#define F0900_P1_RADJ_32APSK 0xf42b001f 2367#define F0900_P1_DECIM_PLFRAMES 0xf4250001
2372 2368
2373/*P1_AGC2O*/ 2369/*P1_AGC2O*/
2374#define R0900_P1_AGC2O 0xf42c 2370#define R0900_P1_AGC2O 0xf42c
2375#define F0900_P1_AGC2REF_ADJUSTING 0xf42c0080 2371#define AGC2O REGx(R0900_P1_AGC2O)
2376#define F0900_P1_AGC2_COARSEFAST 0xf42c0040 2372#define F0900_P1_AGC2_COEF 0xf42c0007
2377#define F0900_P1_AGC2_LKSQRT 0xf42c0020
2378#define F0900_P1_AGC2_LKMODE 0xf42c0010
2379#define F0900_P1_AGC2_LKEQUA 0xf42c0008
2380#define F0900_P1_AGC2_COEF 0xf42c0007
2381 2373
2382/*P1_AGC2REF*/ 2374/*P1_AGC2REF*/
2383#define R0900_P1_AGC2REF 0xf42d 2375#define R0900_P1_AGC2REF 0xf42d
2384#define F0900_P1_AGC2_REF 0xf42d00ff 2376#define AGC2REF REGx(R0900_P1_AGC2REF)
2377#define F0900_P1_AGC2_REF 0xf42d00ff
2385 2378
2386/*P1_AGC1ADJ*/ 2379/*P1_AGC1ADJ*/
2387#define R0900_P1_AGC1ADJ 0xf42e 2380#define R0900_P1_AGC1ADJ 0xf42e
2388#define F0900_P1_AGC1ADJ_MANUAL 0xf42e0080 2381#define AGC1ADJ REGx(R0900_P1_AGC1ADJ)
2389#define F0900_P1_AGC1_ADJUSTED 0xf42e017f 2382#define F0900_P1_AGC1_ADJUSTED 0xf42e007f
2390 2383
2391/*P1_AGC2I1*/ 2384/*P1_AGC2I1*/
2392#define R0900_P1_AGC2I1 0xf436 2385#define R0900_P1_AGC2I1 0xf436
2393#define F0900_P1_AGC2_INTEGRATOR1 0xf43600ff 2386#define AGC2I1 REGx(R0900_P1_AGC2I1)
2387#define F0900_P1_AGC2_INTEGRATOR1 0xf43600ff
2394 2388
2395/*P1_AGC2I0*/ 2389/*P1_AGC2I0*/
2396#define R0900_P1_AGC2I0 0xf437 2390#define R0900_P1_AGC2I0 0xf437
2397#define F0900_P1_AGC2_INTEGRATOR0 0xf43700ff 2391#define AGC2I0 REGx(R0900_P1_AGC2I0)
2392#define F0900_P1_AGC2_INTEGRATOR0 0xf43700ff
2398 2393
2399/*P1_CARCFG*/ 2394/*P1_CARCFG*/
2400#define R0900_P1_CARCFG 0xf438 2395#define R0900_P1_CARCFG 0xf438
2401#define F0900_P1_CFRUPLOW_AUTO 0xf4380080 2396#define CARCFG REGx(R0900_P1_CARCFG)
2402#define F0900_P1_CFRUPLOW_TEST 0xf4380040 2397#define F0900_P1_CFRUPLOW_AUTO 0xf4380080
2403#define F0900_P1_EN_CAR2CENTER 0xf4380020 2398#define F0900_P1_CFRUPLOW_TEST 0xf4380040
2404#define F0900_P1_CARHDR_NODIV8 0xf4380010 2399#define F0900_P1_ROTAON 0xf4380004
2405#define F0900_P1_I2C_ROTA 0xf4380008 2400#define F0900_P1_PH_DET_ALGO 0xf4380003
2406#define F0900_P1_ROTAON 0xf4380004
2407#define F0900_P1_PH_DET_ALGO 0xf4380003
2408 2401
2409/*P1_ACLC*/ 2402/*P1_ACLC*/
2410#define R0900_P1_ACLC 0xf439 2403#define R0900_P1_ACLC 0xf439
2411#define F0900_P1_STOP_S2ALPHA 0xf43900c0 2404#define ACLC REGx(R0900_P1_ACLC)
2412#define F0900_P1_CAR_ALPHA_MANT 0xf4390030 2405#define F0900_P1_CAR_ALPHA_MANT 0xf4390030
2413#define F0900_P1_CAR_ALPHA_EXP 0xf439000f 2406#define F0900_P1_CAR_ALPHA_EXP 0xf439000f
2414 2407
2415/*P1_BCLC*/ 2408/*P1_BCLC*/
2416#define R0900_P1_BCLC 0xf43a 2409#define R0900_P1_BCLC 0xf43a
2417#define F0900_P1_STOP_S2BETA 0xf43a00c0 2410#define BCLC REGx(R0900_P1_BCLC)
2418#define F0900_P1_CAR_BETA_MANT 0xf43a0030 2411#define F0900_P1_CAR_BETA_MANT 0xf43a0030
2419#define F0900_P1_CAR_BETA_EXP 0xf43a000f 2412#define F0900_P1_CAR_BETA_EXP 0xf43a000f
2420 2413
2421/*P1_CARFREQ*/ 2414/*P1_CARFREQ*/
2422#define R0900_P1_CARFREQ 0xf43d 2415#define R0900_P1_CARFREQ 0xf43d
2423#define F0900_P1_KC_COARSE_EXP 0xf43d00f0 2416#define CARFREQ REGx(R0900_P1_CARFREQ)
2424#define F0900_P1_BETA_FREQ 0xf43d000f 2417#define F0900_P1_KC_COARSE_EXP 0xf43d00f0
2418#define F0900_P1_BETA_FREQ 0xf43d000f
2425 2419
2426/*P1_CARHDR*/ 2420/*P1_CARHDR*/
2427#define R0900_P1_CARHDR 0xf43e 2421#define R0900_P1_CARHDR 0xf43e
2428#define F0900_P1_K_FREQ_HDR 0xf43e00ff 2422#define CARHDR REGx(R0900_P1_CARHDR)
2423#define F0900_P1_K_FREQ_HDR 0xf43e00ff
2429 2424
2430/*P1_LDT*/ 2425/*P1_LDT*/
2431#define R0900_P1_LDT 0xf43f 2426#define R0900_P1_LDT 0xf43f
2432#define F0900_P1_CARLOCK_THRES 0xf43f01ff 2427#define LDT REGx(R0900_P1_LDT)
2428#define F0900_P1_CARLOCK_THRES 0xf43f01ff
2433 2429
2434/*P1_LDT2*/ 2430/*P1_LDT2*/
2435#define R0900_P1_LDT2 0xf440 2431#define R0900_P1_LDT2 0xf440
2436#define F0900_P1_CARLOCK_THRES2 0xf44001ff 2432#define LDT2 REGx(R0900_P1_LDT2)
2433#define F0900_P1_CARLOCK_THRES2 0xf44001ff
2437 2434
2438/*P1_CFRICFG*/ 2435/*P1_CFRICFG*/
2439#define R0900_P1_CFRICFG 0xf441 2436#define R0900_P1_CFRICFG 0xf441
2440#define F0900_P1_CFRINIT_UNVALRNG 0xf4410080 2437#define CFRICFG REGx(R0900_P1_CFRICFG)
2441#define F0900_P1_CFRINIT_LUNVALCPT 0xf4410040 2438#define F0900_P1_NEG_CFRSTEP 0xf4410001
2442#define F0900_P1_CFRINIT_ABORTDBL 0xf4410020
2443#define F0900_P1_CFRINIT_ABORTPRED 0xf4410010
2444#define F0900_P1_CFRINIT_UNVALSKIP 0xf4410008
2445#define F0900_P1_CFRINIT_CSTINC 0xf4410004
2446#define F0900_P1_NEG_CFRSTEP 0xf4410001
2447 2439
2448/*P1_CFRUP1*/ 2440/*P1_CFRUP1*/
2449#define R0900_P1_CFRUP1 0xf442 2441#define R0900_P1_CFRUP1 0xf442
2450#define F0900_P1_CFR_UP1 0xf44201ff 2442#define CFRUP1 REGx(R0900_P1_CFRUP1)
2443#define F0900_P1_CFR_UP1 0xf44201ff
2444#define CFR_UP1 FLDx(F0900_P1_CFR_UP1)
2451 2445
2452/*P1_CFRUP0*/ 2446/*P1_CFRUP0*/
2453#define R0900_P1_CFRUP0 0xf443 2447#define R0900_P1_CFRUP0 0xf443
2454#define F0900_P1_CFR_UP0 0xf44300ff 2448#define CFRUP0 REGx(R0900_P1_CFRUP0)
2449#define F0900_P1_CFR_UP0 0xf44300ff
2450#define CFR_UP0 FLDx(F0900_P1_CFR_UP0)
2455 2451
2456/*P1_CFRLOW1*/ 2452/*P1_CFRLOW1*/
2457#define R0900_P1_CFRLOW1 0xf446 2453#define R0900_P1_CFRLOW1 0xf446
2458#define F0900_P1_CFR_LOW1 0xf44601ff 2454#define CFRLOW1 REGx(R0900_P1_CFRLOW1)
2455#define F0900_P1_CFR_LOW1 0xf44601ff
2456#define CFR_LOW1 FLDx(F0900_P1_CFR_LOW1)
2459 2457
2460/*P1_CFRLOW0*/ 2458/*P1_CFRLOW0*/
2461#define R0900_P1_CFRLOW0 0xf447 2459#define R0900_P1_CFRLOW0 0xf447
2462#define F0900_P1_CFR_LOW0 0xf44700ff 2460#define CFRLOW0 REGx(R0900_P1_CFRLOW0)
2461#define F0900_P1_CFR_LOW0 0xf44700ff
2462#define CFR_LOW0 FLDx(F0900_P1_CFR_LOW0)
2463 2463
2464/*P1_CFRINIT1*/ 2464/*P1_CFRINIT1*/
2465#define R0900_P1_CFRINIT1 0xf448 2465#define R0900_P1_CFRINIT1 0xf448
2466#define F0900_P1_CFR_INIT1 0xf44801ff 2466#define CFRINIT1 REGx(R0900_P1_CFRINIT1)
2467#define F0900_P1_CFR_INIT1 0xf44801ff
2468#define CFR_INIT1 FLDx(F0900_P1_CFR_INIT1)
2467 2469
2468/*P1_CFRINIT0*/ 2470/*P1_CFRINIT0*/
2469#define R0900_P1_CFRINIT0 0xf449 2471#define R0900_P1_CFRINIT0 0xf449
2470#define F0900_P1_CFR_INIT0 0xf44900ff 2472#define CFRINIT0 REGx(R0900_P1_CFRINIT0)
2473#define F0900_P1_CFR_INIT0 0xf44900ff
2474#define CFR_INIT0 FLDx(F0900_P1_CFR_INIT0)
2471 2475
2472/*P1_CFRINC1*/ 2476/*P1_CFRINC1*/
2473#define R0900_P1_CFRINC1 0xf44a 2477#define R0900_P1_CFRINC1 0xf44a
2474#define F0900_P1_MANUAL_CFRINC 0xf44a0080 2478#define CFRINC1 REGx(R0900_P1_CFRINC1)
2475#define F0900_P1_CFR_INC1 0xf44a017f 2479#define F0900_P1_MANUAL_CFRINC 0xf44a0080
2480#define F0900_P1_CFR_INC1 0xf44a003f
2476 2481
2477/*P1_CFRINC0*/ 2482/*P1_CFRINC0*/
2478#define R0900_P1_CFRINC0 0xf44b 2483#define R0900_P1_CFRINC0 0xf44b
2479#define F0900_P1_CFR_INC0 0xf44b00f0 2484#define CFRINC0 REGx(R0900_P1_CFRINC0)
2485#define F0900_P1_CFR_INC0 0xf44b00f8
2480 2486
2481/*P1_CFR2*/ 2487/*P1_CFR2*/
2482#define R0900_P1_CFR2 0xf44c 2488#define R0900_P1_CFR2 0xf44c
2483#define F0900_P1_CAR_FREQ2 0xf44c01ff 2489#define CFR2 REGx(R0900_P1_CFR2)
2490#define F0900_P1_CAR_FREQ2 0xf44c01ff
2491#define CAR_FREQ2 FLDx(F0900_P1_CAR_FREQ2)
2484 2492
2485/*P1_CFR1*/ 2493/*P1_CFR1*/
2486#define R0900_P1_CFR1 0xf44d 2494#define R0900_P1_CFR1 0xf44d
2487#define F0900_P1_CAR_FREQ1 0xf44d00ff 2495#define CFR1 REGx(R0900_P1_CFR1)
2496#define F0900_P1_CAR_FREQ1 0xf44d00ff
2497#define CAR_FREQ1 FLDx(F0900_P1_CAR_FREQ1)
2488 2498
2489/*P1_CFR0*/ 2499/*P1_CFR0*/
2490#define R0900_P1_CFR0 0xf44e 2500#define R0900_P1_CFR0 0xf44e
2491#define F0900_P1_CAR_FREQ0 0xf44e00ff 2501#define CFR0 REGx(R0900_P1_CFR0)
2502#define F0900_P1_CAR_FREQ0 0xf44e00ff
2503#define CAR_FREQ0 FLDx(F0900_P1_CAR_FREQ0)
2492 2504
2493/*P1_LDI*/ 2505/*P1_LDI*/
2494#define R0900_P1_LDI 0xf44f 2506#define R0900_P1_LDI 0xf44f
2495#define F0900_P1_LOCK_DET_INTEGR 0xf44f01ff 2507#define LDI REGx(R0900_P1_LDI)
2508#define F0900_P1_LOCK_DET_INTEGR 0xf44f01ff
2496 2509
2497/*P1_TMGCFG*/ 2510/*P1_TMGCFG*/
2498#define R0900_P1_TMGCFG 0xf450 2511#define R0900_P1_TMGCFG 0xf450
2499#define F0900_P1_TMGLOCK_BETA 0xf45000c0 2512#define TMGCFG REGx(R0900_P1_TMGCFG)
2500#define F0900_P1_NOTMG_GROUPDELAY 0xf4500020 2513#define F0900_P1_TMGLOCK_BETA 0xf45000c0
2501#define F0900_P1_DO_TIMING_CORR 0xf4500010 2514#define F0900_P1_DO_TIMING_CORR 0xf4500010
2502#define F0900_P1_MANUAL_SCAN 0xf450000c 2515#define F0900_P1_TMG_MINFREQ 0xf4500003
2503#define F0900_P1_TMG_MINFREQ 0xf4500003
2504 2516
2505/*P1_RTC*/ 2517/*P1_RTC*/
2506#define R0900_P1_RTC 0xf451 2518#define R0900_P1_RTC 0xf451
2507#define F0900_P1_TMGALPHA_EXP 0xf45100f0 2519#define RTC REGx(R0900_P1_RTC)
2508#define F0900_P1_TMGBETA_EXP 0xf451000f 2520#define F0900_P1_TMGALPHA_EXP 0xf45100f0
2521#define F0900_P1_TMGBETA_EXP 0xf451000f
2509 2522
2510/*P1_RTCS2*/ 2523/*P1_RTCS2*/
2511#define R0900_P1_RTCS2 0xf452 2524#define R0900_P1_RTCS2 0xf452
2512#define F0900_P1_TMGALPHAS2_EXP 0xf45200f0 2525#define RTCS2 REGx(R0900_P1_RTCS2)
2513#define F0900_P1_TMGBETAS2_EXP 0xf452000f 2526#define F0900_P1_TMGALPHAS2_EXP 0xf45200f0
2527#define F0900_P1_TMGBETAS2_EXP 0xf452000f
2514 2528
2515/*P1_TMGTHRISE*/ 2529/*P1_TMGTHRISE*/
2516#define R0900_P1_TMGTHRISE 0xf453 2530#define R0900_P1_TMGTHRISE 0xf453
2517#define F0900_P1_TMGLOCK_THRISE 0xf45300ff 2531#define TMGTHRISE REGx(R0900_P1_TMGTHRISE)
2532#define F0900_P1_TMGLOCK_THRISE 0xf45300ff
2518 2533
2519/*P1_TMGTHFALL*/ 2534/*P1_TMGTHFALL*/
2520#define R0900_P1_TMGTHFALL 0xf454 2535#define R0900_P1_TMGTHFALL 0xf454
2521#define F0900_P1_TMGLOCK_THFALL 0xf45400ff 2536#define TMGTHFALL REGx(R0900_P1_TMGTHFALL)
2537#define F0900_P1_TMGLOCK_THFALL 0xf45400ff
2522 2538
2523/*P1_SFRUPRATIO*/ 2539/*P1_SFRUPRATIO*/
2524#define R0900_P1_SFRUPRATIO 0xf455 2540#define R0900_P1_SFRUPRATIO 0xf455
2525#define F0900_P1_SFR_UPRATIO 0xf45500ff 2541#define SFRUPRATIO REGx(R0900_P1_SFRUPRATIO)
2542#define F0900_P1_SFR_UPRATIO 0xf45500ff
2526 2543
2527/*P1_SFRLOWRATIO*/ 2544/*P1_SFRLOWRATIO*/
2528#define R0900_P1_SFRLOWRATIO 0xf456 2545#define R0900_P1_SFRLOWRATIO 0xf456
2529#define F0900_P1_SFR_LOWRATIO 0xf45600ff 2546#define F0900_P1_SFR_LOWRATIO 0xf45600ff
2530 2547
2531/*P1_KREFTMG*/ 2548/*P1_KREFTMG*/
2532#define R0900_P1_KREFTMG 0xf458 2549#define R0900_P1_KREFTMG 0xf458
2533#define F0900_P1_KREF_TMG 0xf45800ff 2550#define KREFTMG REGx(R0900_P1_KREFTMG)
2551#define F0900_P1_KREF_TMG 0xf45800ff
2534 2552
2535/*P1_SFRSTEP*/ 2553/*P1_SFRSTEP*/
2536#define R0900_P1_SFRSTEP 0xf459 2554#define R0900_P1_SFRSTEP 0xf459
2537#define F0900_P1_SFR_SCANSTEP 0xf45900f0 2555#define SFRSTEP REGx(R0900_P1_SFRSTEP)
2538#define F0900_P1_SFR_CENTERSTEP 0xf459000f 2556#define F0900_P1_SFR_SCANSTEP 0xf45900f0
2557#define F0900_P1_SFR_CENTERSTEP 0xf459000f
2539 2558
2540/*P1_TMGCFG2*/ 2559/*P1_TMGCFG2*/
2541#define R0900_P1_TMGCFG2 0xf45a 2560#define R0900_P1_TMGCFG2 0xf45a
2542#define F0900_P1_DIS_AUTOSAMP 0xf45a0008 2561#define TMGCFG2 REGx(R0900_P1_TMGCFG2)
2543#define F0900_P1_SCANINIT_QUART 0xf45a0004 2562#define F0900_P1_SFRRATIO_FINE 0xf45a0001
2544#define F0900_P1_NOTMG_DVBS1DERAT 0xf45a0002 2563
2545#define F0900_P1_SFRRATIO_FINE 0xf45a0001 2564/*P1_KREFTMG2*/
2565#define R0900_P1_KREFTMG2 0xf45b
2566#define KREFTMG2 REGx(R0900_P1_KREFTMG2)
2567#define F0900_P1_KREF_TMG2 0xf45b00ff
2546 2568
2547/*P1_SFRINIT1*/ 2569/*P1_SFRINIT1*/
2548#define R0900_P1_SFRINIT1 0xf45e 2570#define R0900_P1_SFRINIT1 0xf45e
2549#define F0900_P1_SFR_INIT1 0xf45e00ff 2571#define SFRINIT1 REGx(R0900_P1_SFRINIT1)
2572#define F0900_P1_SFR_INIT1 0xf45e007f
2550 2573
2551/*P1_SFRINIT0*/ 2574/*P1_SFRINIT0*/
2552#define R0900_P1_SFRINIT0 0xf45f 2575#define R0900_P1_SFRINIT0 0xf45f
2553#define F0900_P1_SFR_INIT0 0xf45f00ff 2576#define SFRINIT0 REGx(R0900_P1_SFRINIT0)
2577#define F0900_P1_SFR_INIT0 0xf45f00ff
2554 2578
2555/*P1_SFRUP1*/ 2579/*P1_SFRUP1*/
2556#define R0900_P1_SFRUP1 0xf460 2580#define R0900_P1_SFRUP1 0xf460
2557#define F0900_P1_AUTO_GUP 0xf4600080 2581#define SFRUP1 REGx(R0900_P1_SFRUP1)
2558#define F0900_P1_SYMB_FREQ_UP1 0xf460007f 2582#define F0900_P1_AUTO_GUP 0xf4600080
2583#define AUTO_GUP FLDx(F0900_P1_AUTO_GUP)
2584#define F0900_P1_SYMB_FREQ_UP1 0xf460007f
2559 2585
2560/*P1_SFRUP0*/ 2586/*P1_SFRUP0*/
2561#define R0900_P1_SFRUP0 0xf461 2587#define R0900_P1_SFRUP0 0xf461
2562#define F0900_P1_SYMB_FREQ_UP0 0xf46100ff 2588#define SFRUP0 REGx(R0900_P1_SFRUP0)
2589#define F0900_P1_SYMB_FREQ_UP0 0xf46100ff
2563 2590
2564/*P1_SFRLOW1*/ 2591/*P1_SFRLOW1*/
2565#define R0900_P1_SFRLOW1 0xf462 2592#define R0900_P1_SFRLOW1 0xf462
2566#define F0900_P1_AUTO_GLOW 0xf4620080 2593#define SFRLOW1 REGx(R0900_P1_SFRLOW1)
2567#define F0900_P1_SYMB_FREQ_LOW1 0xf462007f 2594#define F0900_P1_AUTO_GLOW 0xf4620080
2595#define AUTO_GLOW FLDx(F0900_P1_AUTO_GLOW)
2596#define F0900_P1_SYMB_FREQ_LOW1 0xf462007f
2568 2597
2569/*P1_SFRLOW0*/ 2598/*P1_SFRLOW0*/
2570#define R0900_P1_SFRLOW0 0xf463 2599#define R0900_P1_SFRLOW0 0xf463
2571#define F0900_P1_SYMB_FREQ_LOW0 0xf46300ff 2600#define SFRLOW0 REGx(R0900_P1_SFRLOW0)
2601#define F0900_P1_SYMB_FREQ_LOW0 0xf46300ff
2572 2602
2573/*P1_SFR3*/ 2603/*P1_SFR3*/
2574#define R0900_P1_SFR3 0xf464 2604#define R0900_P1_SFR3 0xf464
2575#define F0900_P1_SYMB_FREQ3 0xf46400ff 2605#define SFR3 REGx(R0900_P1_SFR3)
2606#define F0900_P1_SYMB_FREQ3 0xf46400ff
2607#define SYMB_FREQ3 FLDx(F0900_P1_SYMB_FREQ3)
2576 2608
2577/*P1_SFR2*/ 2609/*P1_SFR2*/
2578#define R0900_P1_SFR2 0xf465 2610#define R0900_P1_SFR2 0xf465
2579#define F0900_P1_SYMB_FREQ2 0xf46500ff 2611#define SFR2 REGx(R0900_P1_SFR2)
2612#define F0900_P1_SYMB_FREQ2 0xf46500ff
2613#define SYMB_FREQ2 FLDx(F0900_P1_SYMB_FREQ2)
2580 2614
2581/*P1_SFR1*/ 2615/*P1_SFR1*/
2582#define R0900_P1_SFR1 0xf466 2616#define R0900_P1_SFR1 0xf466
2583#define F0900_P1_SYMB_FREQ1 0xf46600ff 2617#define SFR1 REGx(R0900_P1_SFR1)
2618#define F0900_P1_SYMB_FREQ1 0xf46600ff
2619#define SYMB_FREQ1 FLDx(F0900_P1_SYMB_FREQ1)
2584 2620
2585/*P1_SFR0*/ 2621/*P1_SFR0*/
2586#define R0900_P1_SFR0 0xf467 2622#define R0900_P1_SFR0 0xf467
2587#define F0900_P1_SYMB_FREQ0 0xf46700ff 2623#define SFR0 REGx(R0900_P1_SFR0)
2624#define F0900_P1_SYMB_FREQ0 0xf46700ff
2625#define SYMB_FREQ0 FLDx(F0900_P1_SYMB_FREQ0)
2588 2626
2589/*P1_TMGREG2*/ 2627/*P1_TMGREG2*/
2590#define R0900_P1_TMGREG2 0xf468 2628#define R0900_P1_TMGREG2 0xf468
2591#define F0900_P1_TMGREG2 0xf46800ff 2629#define TMGREG2 REGx(R0900_P1_TMGREG2)
2630#define F0900_P1_TMGREG2 0xf46800ff
2592 2631
2593/*P1_TMGREG1*/ 2632/*P1_TMGREG1*/
2594#define R0900_P1_TMGREG1 0xf469 2633#define R0900_P1_TMGREG1 0xf469
2595#define F0900_P1_TMGREG1 0xf46900ff 2634#define TMGREG1 REGx(R0900_P1_TMGREG1)
2635#define F0900_P1_TMGREG1 0xf46900ff
2596 2636
2597/*P1_TMGREG0*/ 2637/*P1_TMGREG0*/
2598#define R0900_P1_TMGREG0 0xf46a 2638#define R0900_P1_TMGREG0 0xf46a
2599#define F0900_P1_TMGREG0 0xf46a00ff 2639#define TMGREG0 REGx(R0900_P1_TMGREG0)
2640#define F0900_P1_TMGREG0 0xf46a00ff
2600 2641
2601/*P1_TMGLOCK1*/ 2642/*P1_TMGLOCK1*/
2602#define R0900_P1_TMGLOCK1 0xf46b 2643#define R0900_P1_TMGLOCK1 0xf46b
2603#define F0900_P1_TMGLOCK_LEVEL1 0xf46b01ff 2644#define TMGLOCK1 REGx(R0900_P1_TMGLOCK1)
2645#define F0900_P1_TMGLOCK_LEVEL1 0xf46b01ff
2604 2646
2605/*P1_TMGLOCK0*/ 2647/*P1_TMGLOCK0*/
2606#define R0900_P1_TMGLOCK0 0xf46c 2648#define R0900_P1_TMGLOCK0 0xf46c
2607#define F0900_P1_TMGLOCK_LEVEL0 0xf46c00ff 2649#define TMGLOCK0 REGx(R0900_P1_TMGLOCK0)
2650#define F0900_P1_TMGLOCK_LEVEL0 0xf46c00ff
2608 2651
2609/*P1_TMGOBS*/ 2652/*P1_TMGOBS*/
2610#define R0900_P1_TMGOBS 0xf46d 2653#define R0900_P1_TMGOBS 0xf46d
2611#define F0900_P1_ROLLOFF_STATUS 0xf46d00c0 2654#define TMGOBS REGx(R0900_P1_TMGOBS)
2612#define F0900_P1_SCAN_SIGN 0xf46d0030 2655#define F0900_P1_ROLLOFF_STATUS 0xf46d00c0
2613#define F0900_P1_TMG_SCANNING 0xf46d0008 2656#define ROLLOFF_STATUS FLDx(F0900_P1_ROLLOFF_STATUS)
2614#define F0900_P1_CHCENTERING_MODE 0xf46d0004
2615#define F0900_P1_TMG_SCANFAIL 0xf46d0002
2616 2657
2617/*P1_EQUALCFG*/ 2658/*P1_EQUALCFG*/
2618#define R0900_P1_EQUALCFG 0xf46f 2659#define R0900_P1_EQUALCFG 0xf46f
2619#define F0900_P1_NOTMG_NEGALWAIT 0xf46f0080 2660#define EQUALCFG REGx(R0900_P1_EQUALCFG)
2620#define F0900_P1_EQUAL_ON 0xf46f0040 2661#define F0900_P1_EQUAL_ON 0xf46f0040
2621#define F0900_P1_SEL_EQUALCOR 0xf46f0038 2662#define F0900_P1_MU_EQUALDFE 0xf46f0007
2622#define F0900_P1_MU_EQUALDFE 0xf46f0007
2623 2663
2624/*P1_EQUAI1*/ 2664/*P1_EQUAI1*/
2625#define R0900_P1_EQUAI1 0xf470 2665#define R0900_P1_EQUAI1 0xf470
2626#define F0900_P1_EQUA_ACCI1 0xf47001ff 2666#define EQUAI1 REGx(R0900_P1_EQUAI1)
2667#define F0900_P1_EQUA_ACCI1 0xf47001ff
2627 2668
2628/*P1_EQUAQ1*/ 2669/*P1_EQUAQ1*/
2629#define R0900_P1_EQUAQ1 0xf471 2670#define R0900_P1_EQUAQ1 0xf471
2630#define F0900_P1_EQUA_ACCQ1 0xf47101ff 2671#define EQUAQ1 REGx(R0900_P1_EQUAQ1)
2672#define F0900_P1_EQUA_ACCQ1 0xf47101ff
2631 2673
2632/*P1_EQUAI2*/ 2674/*P1_EQUAI2*/
2633#define R0900_P1_EQUAI2 0xf472 2675#define R0900_P1_EQUAI2 0xf472
2634#define F0900_P1_EQUA_ACCI2 0xf47201ff 2676#define EQUAI2 REGx(R0900_P1_EQUAI2)
2677#define F0900_P1_EQUA_ACCI2 0xf47201ff
2635 2678
2636/*P1_EQUAQ2*/ 2679/*P1_EQUAQ2*/
2637#define R0900_P1_EQUAQ2 0xf473 2680#define R0900_P1_EQUAQ2 0xf473
2638#define F0900_P1_EQUA_ACCQ2 0xf47301ff 2681#define EQUAQ2 REGx(R0900_P1_EQUAQ2)
2682#define F0900_P1_EQUA_ACCQ2 0xf47301ff
2639 2683
2640/*P1_EQUAI3*/ 2684/*P1_EQUAI3*/
2641#define R0900_P1_EQUAI3 0xf474 2685#define R0900_P1_EQUAI3 0xf474
2642#define F0900_P1_EQUA_ACCI3 0xf47401ff 2686#define EQUAI3 REGx(R0900_P1_EQUAI3)
2687#define F0900_P1_EQUA_ACCI3 0xf47401ff
2643 2688
2644/*P1_EQUAQ3*/ 2689/*P1_EQUAQ3*/
2645#define R0900_P1_EQUAQ3 0xf475 2690#define R0900_P1_EQUAQ3 0xf475
2646#define F0900_P1_EQUA_ACCQ3 0xf47501ff 2691#define EQUAQ3 REGx(R0900_P1_EQUAQ3)
2692#define F0900_P1_EQUA_ACCQ3 0xf47501ff
2647 2693
2648/*P1_EQUAI4*/ 2694/*P1_EQUAI4*/
2649#define R0900_P1_EQUAI4 0xf476 2695#define R0900_P1_EQUAI4 0xf476
2650#define F0900_P1_EQUA_ACCI4 0xf47601ff 2696#define EQUAI4 REGx(R0900_P1_EQUAI4)
2697#define F0900_P1_EQUA_ACCI4 0xf47601ff
2651 2698
2652/*P1_EQUAQ4*/ 2699/*P1_EQUAQ4*/
2653#define R0900_P1_EQUAQ4 0xf477 2700#define R0900_P1_EQUAQ4 0xf477
2654#define F0900_P1_EQUA_ACCQ4 0xf47701ff 2701#define EQUAQ4 REGx(R0900_P1_EQUAQ4)
2702#define F0900_P1_EQUA_ACCQ4 0xf47701ff
2655 2703
2656/*P1_EQUAI5*/ 2704/*P1_EQUAI5*/
2657#define R0900_P1_EQUAI5 0xf478 2705#define R0900_P1_EQUAI5 0xf478
2658#define F0900_P1_EQUA_ACCI5 0xf47801ff 2706#define EQUAI5 REGx(R0900_P1_EQUAI5)
2707#define F0900_P1_EQUA_ACCI5 0xf47801ff
2659 2708
2660/*P1_EQUAQ5*/ 2709/*P1_EQUAQ5*/
2661#define R0900_P1_EQUAQ5 0xf479 2710#define R0900_P1_EQUAQ5 0xf479
2662#define F0900_P1_EQUA_ACCQ5 0xf47901ff 2711#define EQUAQ5 REGx(R0900_P1_EQUAQ5)
2712#define F0900_P1_EQUA_ACCQ5 0xf47901ff
2663 2713
2664/*P1_EQUAI6*/ 2714/*P1_EQUAI6*/
2665#define R0900_P1_EQUAI6 0xf47a 2715#define R0900_P1_EQUAI6 0xf47a
2666#define F0900_P1_EQUA_ACCI6 0xf47a01ff 2716#define EQUAI6 REGx(R0900_P1_EQUAI6)
2717#define F0900_P1_EQUA_ACCI6 0xf47a01ff
2667 2718
2668/*P1_EQUAQ6*/ 2719/*P1_EQUAQ6*/
2669#define R0900_P1_EQUAQ6 0xf47b 2720#define R0900_P1_EQUAQ6 0xf47b
2670#define F0900_P1_EQUA_ACCQ6 0xf47b01ff 2721#define EQUAQ6 REGx(R0900_P1_EQUAQ6)
2722#define F0900_P1_EQUA_ACCQ6 0xf47b01ff
2671 2723
2672/*P1_EQUAI7*/ 2724/*P1_EQUAI7*/
2673#define R0900_P1_EQUAI7 0xf47c 2725#define R0900_P1_EQUAI7 0xf47c
2674#define F0900_P1_EQUA_ACCI7 0xf47c01ff 2726#define EQUAI7 REGx(R0900_P1_EQUAI7)
2727#define F0900_P1_EQUA_ACCI7 0xf47c01ff
2675 2728
2676/*P1_EQUAQ7*/ 2729/*P1_EQUAQ7*/
2677#define R0900_P1_EQUAQ7 0xf47d 2730#define R0900_P1_EQUAQ7 0xf47d
2678#define F0900_P1_EQUA_ACCQ7 0xf47d01ff 2731#define EQUAQ7 REGx(R0900_P1_EQUAQ7)
2732#define F0900_P1_EQUA_ACCQ7 0xf47d01ff
2679 2733
2680/*P1_EQUAI8*/ 2734/*P1_EQUAI8*/
2681#define R0900_P1_EQUAI8 0xf47e 2735#define R0900_P1_EQUAI8 0xf47e
2682#define F0900_P1_EQUA_ACCI8 0xf47e01ff 2736#define EQUAI8 REGx(R0900_P1_EQUAI8)
2737#define F0900_P1_EQUA_ACCI8 0xf47e01ff
2683 2738
2684/*P1_EQUAQ8*/ 2739/*P1_EQUAQ8*/
2685#define R0900_P1_EQUAQ8 0xf47f 2740#define R0900_P1_EQUAQ8 0xf47f
2686#define F0900_P1_EQUA_ACCQ8 0xf47f01ff 2741#define EQUAQ8 REGx(R0900_P1_EQUAQ8)
2742#define F0900_P1_EQUA_ACCQ8 0xf47f01ff
2687 2743
2688/*P1_NNOSDATAT1*/ 2744/*P1_NNOSDATAT1*/
2689#define R0900_P1_NNOSDATAT1 0xf480 2745#define R0900_P1_NNOSDATAT1 0xf480
2690#define F0900_P1_NOSDATAT_NORMED1 0xf48000ff 2746#define NNOSDATAT1 REGx(R0900_P1_NNOSDATAT1)
2747#define F0900_P1_NOSDATAT_NORMED1 0xf48000ff
2748#define NOSDATAT_NORMED1 FLDx(F0900_P1_NOSDATAT_NORMED1)
2691 2749
2692/*P1_NNOSDATAT0*/ 2750/*P1_NNOSDATAT0*/
2693#define R0900_P1_NNOSDATAT0 0xf481 2751#define R0900_P1_NNOSDATAT0 0xf481
2694#define F0900_P1_NOSDATAT_NORMED0 0xf48100ff 2752#define NNOSDATAT0 REGx(R0900_P1_NNOSDATAT0)
2753#define F0900_P1_NOSDATAT_NORMED0 0xf48100ff
2754#define NOSDATAT_NORMED0 FLDx(F0900_P1_NOSDATAT_NORMED0)
2695 2755
2696/*P1_NNOSDATA1*/ 2756/*P1_NNOSDATA1*/
2697#define R0900_P1_NNOSDATA1 0xf482 2757#define R0900_P1_NNOSDATA1 0xf482
2698#define F0900_P1_NOSDATA_NORMED1 0xf48200ff 2758#define NNOSDATA1 REGx(R0900_P1_NNOSDATA1)
2759#define F0900_P1_NOSDATA_NORMED1 0xf48200ff
2699 2760
2700/*P1_NNOSDATA0*/ 2761/*P1_NNOSDATA0*/
2701#define R0900_P1_NNOSDATA0 0xf483 2762#define R0900_P1_NNOSDATA0 0xf483
2702#define F0900_P1_NOSDATA_NORMED0 0xf48300ff 2763#define NNOSDATA0 REGx(R0900_P1_NNOSDATA0)
2764#define F0900_P1_NOSDATA_NORMED0 0xf48300ff
2703 2765
2704/*P1_NNOSPLHT1*/ 2766/*P1_NNOSPLHT1*/
2705#define R0900_P1_NNOSPLHT1 0xf484 2767#define R0900_P1_NNOSPLHT1 0xf484
2706#define F0900_P1_NOSPLHT_NORMED1 0xf48400ff 2768#define NNOSPLHT1 REGx(R0900_P1_NNOSPLHT1)
2769#define F0900_P1_NOSPLHT_NORMED1 0xf48400ff
2770#define NOSPLHT_NORMED1 FLDx(F0900_P1_NOSPLHT_NORMED1)
2707 2771
2708/*P1_NNOSPLHT0*/ 2772/*P1_NNOSPLHT0*/
2709#define R0900_P1_NNOSPLHT0 0xf485 2773#define R0900_P1_NNOSPLHT0 0xf485
2710#define F0900_P1_NOSPLHT_NORMED0 0xf48500ff 2774#define NNOSPLHT0 REGx(R0900_P1_NNOSPLHT0)
2775#define F0900_P1_NOSPLHT_NORMED0 0xf48500ff
2776#define NOSPLHT_NORMED0 FLDx(F0900_P1_NOSPLHT_NORMED0)
2711 2777
2712/*P1_NNOSPLH1*/ 2778/*P1_NNOSPLH1*/
2713#define R0900_P1_NNOSPLH1 0xf486 2779#define R0900_P1_NNOSPLH1 0xf486
2714#define F0900_P1_NOSPLH_NORMED1 0xf48600ff 2780#define NNOSPLH1 REGx(R0900_P1_NNOSPLH1)
2781#define F0900_P1_NOSPLH_NORMED1 0xf48600ff
2715 2782
2716/*P1_NNOSPLH0*/ 2783/*P1_NNOSPLH0*/
2717#define R0900_P1_NNOSPLH0 0xf487 2784#define R0900_P1_NNOSPLH0 0xf487
2718#define F0900_P1_NOSPLH_NORMED0 0xf48700ff 2785#define NNOSPLH0 REGx(R0900_P1_NNOSPLH0)
2786#define F0900_P1_NOSPLH_NORMED0 0xf48700ff
2719 2787
2720/*P1_NOSDATAT1*/ 2788/*P1_NOSDATAT1*/
2721#define R0900_P1_NOSDATAT1 0xf488 2789#define R0900_P1_NOSDATAT1 0xf488
2722#define F0900_P1_NOSDATAT_UNNORMED1 0xf48800ff 2790#define NOSDATAT1 REGx(R0900_P1_NOSDATAT1)
2791#define F0900_P1_NOSDATAT_UNNORMED1 0xf48800ff
2723 2792
2724/*P1_NOSDATAT0*/ 2793/*P1_NOSDATAT0*/
2725#define R0900_P1_NOSDATAT0 0xf489 2794#define R0900_P1_NOSDATAT0 0xf489
2726#define F0900_P1_NOSDATAT_UNNORMED0 0xf48900ff 2795#define NOSDATAT0 REGx(R0900_P1_NOSDATAT0)
2796#define F0900_P1_NOSDATAT_UNNORMED0 0xf48900ff
2727 2797
2728/*P1_NOSDATA1*/ 2798/*P1_NOSDATA1*/
2729#define R0900_P1_NOSDATA1 0xf48a 2799#define R0900_P1_NOSDATA1 0xf48a
2730#define F0900_P1_NOSDATA_UNNORMED1 0xf48a00ff 2800#define NOSDATA1 REGx(R0900_P1_NOSDATA1)
2801#define F0900_P1_NOSDATA_UNNORMED1 0xf48a00ff
2731 2802
2732/*P1_NOSDATA0*/ 2803/*P1_NOSDATA0*/
2733#define R0900_P1_NOSDATA0 0xf48b 2804#define R0900_P1_NOSDATA0 0xf48b
2734#define F0900_P1_NOSDATA_UNNORMED0 0xf48b00ff 2805#define NOSDATA0 REGx(R0900_P1_NOSDATA0)
2806#define F0900_P1_NOSDATA_UNNORMED0 0xf48b00ff
2735 2807
2736/*P1_NOSPLHT1*/ 2808/*P1_NOSPLHT1*/
2737#define R0900_P1_NOSPLHT1 0xf48c 2809#define R0900_P1_NOSPLHT1 0xf48c
2738#define F0900_P1_NOSPLHT_UNNORMED1 0xf48c00ff 2810#define NOSPLHT1 REGx(R0900_P1_NOSPLHT1)
2811#define F0900_P1_NOSPLHT_UNNORMED1 0xf48c00ff
2739 2812
2740/*P1_NOSPLHT0*/ 2813/*P1_NOSPLHT0*/
2741#define R0900_P1_NOSPLHT0 0xf48d 2814#define R0900_P1_NOSPLHT0 0xf48d
2742#define F0900_P1_NOSPLHT_UNNORMED0 0xf48d00ff 2815#define NOSPLHT0 REGx(R0900_P1_NOSPLHT0)
2816#define F0900_P1_NOSPLHT_UNNORMED0 0xf48d00ff
2743 2817
2744/*P1_NOSPLH1*/ 2818/*P1_NOSPLH1*/
2745#define R0900_P1_NOSPLH1 0xf48e 2819#define R0900_P1_NOSPLH1 0xf48e
2746#define F0900_P1_NOSPLH_UNNORMED1 0xf48e00ff 2820#define NOSPLH1 REGx(R0900_P1_NOSPLH1)
2821#define F0900_P1_NOSPLH_UNNORMED1 0xf48e00ff
2747 2822
2748/*P1_NOSPLH0*/ 2823/*P1_NOSPLH0*/
2749#define R0900_P1_NOSPLH0 0xf48f 2824#define R0900_P1_NOSPLH0 0xf48f
2750#define F0900_P1_NOSPLH_UNNORMED0 0xf48f00ff 2825#define NOSPLH0 REGx(R0900_P1_NOSPLH0)
2826#define F0900_P1_NOSPLH_UNNORMED0 0xf48f00ff
2751 2827
2752/*P1_CAR2CFG*/ 2828/*P1_CAR2CFG*/
2753#define R0900_P1_CAR2CFG 0xf490 2829#define R0900_P1_CAR2CFG 0xf490
2754#define F0900_P1_DESCRAMB_OFF 0xf4900080 2830#define CAR2CFG REGx(R0900_P1_CAR2CFG)
2755#define F0900_P1_PN4_SELECT 0xf4900040 2831#define F0900_P1_CARRIER3_DISABLE 0xf4900040
2756#define F0900_P1_CFR2_STOPDVBS1 0xf4900020 2832#define F0900_P1_ROTA2ON 0xf4900004
2757#define F0900_P1_STOP_CFR2UPDATE 0xf4900010 2833#define F0900_P1_PH_DET_ALGO2 0xf4900003
2758#define F0900_P1_STOP_NCO2UPDATE 0xf4900008 2834
2759#define F0900_P1_ROTA2ON 0xf4900004 2835/*P1_CFR2CFR1*/
2760#define F0900_P1_PH_DET_ALGO2 0xf4900003 2836#define R0900_P1_CFR2CFR1 0xf491
2761 2837#define CFR2CFR1 REGx(R0900_P1_CFR2CFR1)
2762/*P1_ACLC2*/ 2838#define F0900_P1_CFR2TOCFR1_DVBS1 0xf49100c0
2763#define R0900_P1_ACLC2 0xf491 2839#define F0900_P1_EN_S2CAR2CENTER 0xf4910020
2764#define F0900_P1_CAR2_PUNCT_ADERAT 0xf4910040 2840#define F0900_P1_DIS_BCHERRCFR2 0xf4910010
2765#define F0900_P1_CAR2_ALPHA_MANT 0xf4910030 2841#define F0900_P1_CFR2TOCFR1_BETA 0xf4910007
2766#define F0900_P1_CAR2_ALPHA_EXP 0xf491000f
2767
2768/*P1_BCLC2*/
2769#define R0900_P1_BCLC2 0xf492
2770#define F0900_P1_DVBS2_NIP 0xf4920080
2771#define F0900_P1_CAR2_PUNCT_BDERAT 0xf4920040
2772#define F0900_P1_CAR2_BETA_MANT 0xf4920030
2773#define F0900_P1_CAR2_BETA_EXP 0xf492000f
2774 2842
2775/*P1_CFR22*/ 2843/*P1_CFR22*/
2776#define R0900_P1_CFR22 0xf493 2844#define R0900_P1_CFR22 0xf493
2777#define F0900_P1_CAR2_FREQ2 0xf49301ff 2845#define CFR22 REGx(R0900_P1_CFR22)
2846#define F0900_P1_CAR2_FREQ2 0xf49301ff
2778 2847
2779/*P1_CFR21*/ 2848/*P1_CFR21*/
2780#define R0900_P1_CFR21 0xf494 2849#define R0900_P1_CFR21 0xf494
2781#define F0900_P1_CAR2_FREQ1 0xf49400ff 2850#define CFR21 REGx(R0900_P1_CFR21)
2851#define F0900_P1_CAR2_FREQ1 0xf49400ff
2782 2852
2783/*P1_CFR20*/ 2853/*P1_CFR20*/
2784#define R0900_P1_CFR20 0xf495 2854#define R0900_P1_CFR20 0xf495
2785#define F0900_P1_CAR2_FREQ0 0xf49500ff 2855#define CFR20 REGx(R0900_P1_CFR20)
2856#define F0900_P1_CAR2_FREQ0 0xf49500ff
2786 2857
2787/*P1_ACLC2S2Q*/ 2858/*P1_ACLC2S2Q*/
2788#define R0900_P1_ACLC2S2Q 0xf497 2859#define R0900_P1_ACLC2S2Q 0xf497
2789#define F0900_P1_ENAB_SPSKSYMB 0xf4970080 2860#define ACLC2S2Q REGx(R0900_P1_ACLC2S2Q)
2790#define F0900_P1_CAR2S2_QADERAT 0xf4970040 2861#define F0900_P1_ENAB_SPSKSYMB 0xf4970080
2791#define F0900_P1_CAR2S2_Q_ALPH_M 0xf4970030 2862#define F0900_P1_CAR2S2_Q_ALPH_M 0xf4970030
2792#define F0900_P1_CAR2S2_Q_ALPH_E 0xf497000f 2863#define F0900_P1_CAR2S2_Q_ALPH_E 0xf497000f
2793 2864
2794/*P1_ACLC2S28*/ 2865/*P1_ACLC2S28*/
2795#define R0900_P1_ACLC2S28 0xf498 2866#define R0900_P1_ACLC2S28 0xf498
2796#define F0900_P1_OLDI3Q_MODE 0xf4980080 2867#define ACLC2S28 REGx(R0900_P1_ACLC2S28)
2797#define F0900_P1_CAR2S2_8ADERAT 0xf4980040 2868#define F0900_P1_OLDI3Q_MODE 0xf4980080
2798#define F0900_P1_CAR2S2_8_ALPH_M 0xf4980030 2869#define F0900_P1_CAR2S2_8_ALPH_M 0xf4980030
2799#define F0900_P1_CAR2S2_8_ALPH_E 0xf498000f 2870#define F0900_P1_CAR2S2_8_ALPH_E 0xf498000f
2800 2871
2801/*P1_ACLC2S216A*/ 2872/*P1_ACLC2S216A*/
2802#define R0900_P1_ACLC2S216A 0xf499 2873#define R0900_P1_ACLC2S216A 0xf499
2803#define F0900_P1_CAR2S2_16ADERAT 0xf4990040 2874#define ACLC2S216A REGx(R0900_P1_ACLC2S216A)
2804#define F0900_P1_CAR2S2_16A_ALPH_M 0xf4990030 2875#define F0900_P1_DIS_C3STOPA2 0xf4990080
2805#define F0900_P1_CAR2S2_16A_ALPH_E 0xf499000f 2876#define F0900_P1_CAR2S2_16ADERAT 0xf4990040
2877#define F0900_P1_CAR2S2_16A_ALPH_M 0xf4990030
2878#define F0900_P1_CAR2S2_16A_ALPH_E 0xf499000f
2806 2879
2807/*P1_ACLC2S232A*/ 2880/*P1_ACLC2S232A*/
2808#define R0900_P1_ACLC2S232A 0xf49a 2881#define R0900_P1_ACLC2S232A 0xf49a
2809#define F0900_P1_CAR2S2_32ADERAT 0xf49a0040 2882#define ACLC2S232A REGx(R0900_P1_ACLC2S232A)
2810#define F0900_P1_CAR2S2_32A_ALPH_M 0xf49a0030 2883#define F0900_P1_CAR2S2_32ADERAT 0xf49a0040
2811#define F0900_P1_CAR2S2_32A_ALPH_E 0xf49a000f 2884#define F0900_P1_CAR2S2_32A_ALPH_M 0xf49a0030
2885#define F0900_P1_CAR2S2_32A_ALPH_E 0xf49a000f
2812 2886
2813/*P1_BCLC2S2Q*/ 2887/*P1_BCLC2S2Q*/
2814#define R0900_P1_BCLC2S2Q 0xf49c 2888#define R0900_P1_BCLC2S2Q 0xf49c
2815#define F0900_P1_DVBS2S2Q_NIP 0xf49c0080 2889#define BCLC2S2Q REGx(R0900_P1_BCLC2S2Q)
2816#define F0900_P1_CAR2S2_QBDERAT 0xf49c0040 2890#define F0900_P1_CAR2S2_Q_BETA_M 0xf49c0030
2817#define F0900_P1_CAR2S2_Q_BETA_M 0xf49c0030 2891#define F0900_P1_CAR2S2_Q_BETA_E 0xf49c000f
2818#define F0900_P1_CAR2S2_Q_BETA_E 0xf49c000f
2819 2892
2820/*P1_BCLC2S28*/ 2893/*P1_BCLC2S28*/
2821#define R0900_P1_BCLC2S28 0xf49d 2894#define R0900_P1_BCLC2S28 0xf49d
2822#define F0900_P1_DVBS2S28_NIP 0xf49d0080 2895#define BCLC2S28 REGx(R0900_P1_BCLC2S28)
2823#define F0900_P1_CAR2S2_8BDERAT 0xf49d0040 2896#define F0900_P1_CAR2S2_8_BETA_M 0xf49d0030
2824#define F0900_P1_CAR2S2_8_BETA_M 0xf49d0030 2897#define F0900_P1_CAR2S2_8_BETA_E 0xf49d000f
2825#define F0900_P1_CAR2S2_8_BETA_E 0xf49d000f
2826 2898
2827/*P1_BCLC2S216A*/ 2899/*P1_BCLC2S216A*/
2828#define R0900_P1_BCLC2S216A 0xf49e 2900#define R0900_P1_BCLC2S216A 0xf49e
2829#define F0900_P1_DVBS2S216A_NIP 0xf49e0080 2901#define BCLC2S216A REGx(R0900_P1_BCLC2S216A)
2830#define F0900_P1_CAR2S2_16BDERAT 0xf49e0040
2831#define F0900_P1_CAR2S2_16A_BETA_M 0xf49e0030
2832#define F0900_P1_CAR2S2_16A_BETA_E 0xf49e000f
2833 2902
2834/*P1_BCLC2S232A*/ 2903/*P1_BCLC2S232A*/
2835#define R0900_P1_BCLC2S232A 0xf49f 2904#define R0900_P1_BCLC2S232A 0xf49f
2836#define F0900_P1_DVBS2S232A_NIP 0xf49f0080 2905#define BCLC2S232A REGx(R0900_P1_BCLC2S232A)
2837#define F0900_P1_CAR2S2_32BDERAT 0xf49f0040
2838#define F0900_P1_CAR2S2_32A_BETA_M 0xf49f0030
2839#define F0900_P1_CAR2S2_32A_BETA_E 0xf49f000f
2840 2906
2841/*P1_PLROOT2*/ 2907/*P1_PLROOT2*/
2842#define R0900_P1_PLROOT2 0xf4ac 2908#define R0900_P1_PLROOT2 0xf4ac
2843#define F0900_P1_SHORTFR_DISABLE 0xf4ac0080 2909#define PLROOT2 REGx(R0900_P1_PLROOT2)
2844#define F0900_P1_LONGFR_DISABLE 0xf4ac0040 2910#define F0900_P1_PLSCRAMB_MODE 0xf4ac000c
2845#define F0900_P1_DUMMYPL_DISABLE 0xf4ac0020 2911#define F0900_P1_PLSCRAMB_ROOT2 0xf4ac0003
2846#define F0900_P1_SHORTFR_AVOID 0xf4ac0010
2847#define F0900_P1_PLSCRAMB_MODE 0xf4ac000c
2848#define F0900_P1_PLSCRAMB_ROOT2 0xf4ac0003
2849 2912
2850/*P1_PLROOT1*/ 2913/*P1_PLROOT1*/
2851#define R0900_P1_PLROOT1 0xf4ad 2914#define R0900_P1_PLROOT1 0xf4ad
2852#define F0900_P1_PLSCRAMB_ROOT1 0xf4ad00ff 2915#define PLROOT1 REGx(R0900_P1_PLROOT1)
2916#define F0900_P1_PLSCRAMB_ROOT1 0xf4ad00ff
2853 2917
2854/*P1_PLROOT0*/ 2918/*P1_PLROOT0*/
2855#define R0900_P1_PLROOT0 0xf4ae 2919#define R0900_P1_PLROOT0 0xf4ae
2856#define F0900_P1_PLSCRAMB_ROOT0 0xf4ae00ff 2920#define PLROOT0 REGx(R0900_P1_PLROOT0)
2921#define F0900_P1_PLSCRAMB_ROOT0 0xf4ae00ff
2857 2922
2858/*P1_MODCODLST0*/ 2923/*P1_MODCODLST0*/
2859#define R0900_P1_MODCODLST0 0xf4b0 2924#define R0900_P1_MODCODLST0 0xf4b0
2860#define F0900_P1_EN_TOKEN31 0xf4b00080 2925#define MODCODLST0 REGx(R0900_P1_MODCODLST0)
2861#define F0900_P1_SYNCTAG_SELECT 0xf4b00040
2862#define F0900_P1_MODCODRQ_MODE 0xf4b00030
2863 2926
2864/*P1_MODCODLST1*/ 2927/*P1_MODCODLST1*/
2865#define R0900_P1_MODCODLST1 0xf4b1 2928#define R0900_P1_MODCODLST1 0xf4b1
2866#define F0900_P1_DIS_MODCOD29 0xf4b100f0 2929#define MODCODLST1 REGx(R0900_P1_MODCODLST1)
2867#define F0900_P1_DIS_32PSK_9_10 0xf4b1000f 2930#define F0900_P1_DIS_MODCOD29 0xf4b100f0
2931#define F0900_P1_DIS_32PSK_9_10 0xf4b1000f
2868 2932
2869/*P1_MODCODLST2*/ 2933/*P1_MODCODLST2*/
2870#define R0900_P1_MODCODLST2 0xf4b2 2934#define R0900_P1_MODCODLST2 0xf4b2
2871#define F0900_P1_DIS_32PSK_8_9 0xf4b200f0 2935#define MODCODLST2 REGx(R0900_P1_MODCODLST2)
2872#define F0900_P1_DIS_32PSK_5_6 0xf4b2000f 2936#define F0900_P1_DIS_32PSK_8_9 0xf4b200f0
2937#define F0900_P1_DIS_32PSK_5_6 0xf4b2000f
2873 2938
2874/*P1_MODCODLST3*/ 2939/*P1_MODCODLST3*/
2875#define R0900_P1_MODCODLST3 0xf4b3 2940#define R0900_P1_MODCODLST3 0xf4b3
2876#define F0900_P1_DIS_32PSK_4_5 0xf4b300f0 2941#define MODCODLST3 REGx(R0900_P1_MODCODLST3)
2877#define F0900_P1_DIS_32PSK_3_4 0xf4b3000f 2942#define F0900_P1_DIS_32PSK_4_5 0xf4b300f0
2943#define F0900_P1_DIS_32PSK_3_4 0xf4b3000f
2878 2944
2879/*P1_MODCODLST4*/ 2945/*P1_MODCODLST4*/
2880#define R0900_P1_MODCODLST4 0xf4b4 2946#define R0900_P1_MODCODLST4 0xf4b4
2881#define F0900_P1_DIS_16PSK_9_10 0xf4b400f0 2947#define MODCODLST4 REGx(R0900_P1_MODCODLST4)
2882#define F0900_P1_DIS_16PSK_8_9 0xf4b4000f 2948#define F0900_P1_DIS_16PSK_9_10 0xf4b400f0
2949#define F0900_P1_DIS_16PSK_8_9 0xf4b4000f
2883 2950
2884/*P1_MODCODLST5*/ 2951/*P1_MODCODLST5*/
2885#define R0900_P1_MODCODLST5 0xf4b5 2952#define R0900_P1_MODCODLST5 0xf4b5
2886#define F0900_P1_DIS_16PSK_5_6 0xf4b500f0 2953#define MODCODLST5 REGx(R0900_P1_MODCODLST5)
2887#define F0900_P1_DIS_16PSK_4_5 0xf4b5000f 2954#define F0900_P1_DIS_16PSK_5_6 0xf4b500f0
2955#define F0900_P1_DIS_16PSK_4_5 0xf4b5000f
2888 2956
2889/*P1_MODCODLST6*/ 2957/*P1_MODCODLST6*/
2890#define R0900_P1_MODCODLST6 0xf4b6 2958#define R0900_P1_MODCODLST6 0xf4b6
2891#define F0900_P1_DIS_16PSK_3_4 0xf4b600f0 2959#define MODCODLST6 REGx(R0900_P1_MODCODLST6)
2892#define F0900_P1_DIS_16PSK_2_3 0xf4b6000f 2960#define F0900_P1_DIS_16PSK_3_4 0xf4b600f0
2961#define F0900_P1_DIS_16PSK_2_3 0xf4b6000f
2893 2962
2894/*P1_MODCODLST7*/ 2963/*P1_MODCODLST7*/
2895#define R0900_P1_MODCODLST7 0xf4b7 2964#define R0900_P1_MODCODLST7 0xf4b7
2896#define F0900_P1_DIS_8P_9_10 0xf4b700f0 2965#define MODCODLST7 REGx(R0900_P1_MODCODLST7)
2897#define F0900_P1_DIS_8P_8_9 0xf4b7000f 2966#define F0900_P1_DIS_8P_9_10 0xf4b700f0
2967#define F0900_P1_DIS_8P_8_9 0xf4b7000f
2898 2968
2899/*P1_MODCODLST8*/ 2969/*P1_MODCODLST8*/
2900#define R0900_P1_MODCODLST8 0xf4b8 2970#define R0900_P1_MODCODLST8 0xf4b8
2901#define F0900_P1_DIS_8P_5_6 0xf4b800f0 2971#define MODCODLST8 REGx(R0900_P1_MODCODLST8)
2902#define F0900_P1_DIS_8P_3_4 0xf4b8000f 2972#define F0900_P1_DIS_8P_5_6 0xf4b800f0
2973#define F0900_P1_DIS_8P_3_4 0xf4b8000f
2903 2974
2904/*P1_MODCODLST9*/ 2975/*P1_MODCODLST9*/
2905#define R0900_P1_MODCODLST9 0xf4b9 2976#define R0900_P1_MODCODLST9 0xf4b9
2906#define F0900_P1_DIS_8P_2_3 0xf4b900f0 2977#define MODCODLST9 REGx(R0900_P1_MODCODLST9)
2907#define F0900_P1_DIS_8P_3_5 0xf4b9000f 2978#define F0900_P1_DIS_8P_2_3 0xf4b900f0
2979#define F0900_P1_DIS_8P_3_5 0xf4b9000f
2908 2980
2909/*P1_MODCODLSTA*/ 2981/*P1_MODCODLSTA*/
2910#define R0900_P1_MODCODLSTA 0xf4ba 2982#define R0900_P1_MODCODLSTA 0xf4ba
2911#define F0900_P1_DIS_QP_9_10 0xf4ba00f0 2983#define MODCODLSTA REGx(R0900_P1_MODCODLSTA)
2912#define F0900_P1_DIS_QP_8_9 0xf4ba000f 2984#define F0900_P1_DIS_QP_9_10 0xf4ba00f0
2985#define F0900_P1_DIS_QP_8_9 0xf4ba000f
2913 2986
2914/*P1_MODCODLSTB*/ 2987/*P1_MODCODLSTB*/
2915#define R0900_P1_MODCODLSTB 0xf4bb 2988#define R0900_P1_MODCODLSTB 0xf4bb
2916#define F0900_P1_DIS_QP_5_6 0xf4bb00f0 2989#define MODCODLSTB REGx(R0900_P1_MODCODLSTB)
2917#define F0900_P1_DIS_QP_4_5 0xf4bb000f 2990#define F0900_P1_DIS_QP_5_6 0xf4bb00f0
2991#define F0900_P1_DIS_QP_4_5 0xf4bb000f
2918 2992
2919/*P1_MODCODLSTC*/ 2993/*P1_MODCODLSTC*/
2920#define R0900_P1_MODCODLSTC 0xf4bc 2994#define R0900_P1_MODCODLSTC 0xf4bc
2921#define F0900_P1_DIS_QP_3_4 0xf4bc00f0 2995#define MODCODLSTC REGx(R0900_P1_MODCODLSTC)
2922#define F0900_P1_DIS_QP_2_3 0xf4bc000f 2996#define F0900_P1_DIS_QP_3_4 0xf4bc00f0
2997#define F0900_P1_DIS_QP_2_3 0xf4bc000f
2923 2998
2924/*P1_MODCODLSTD*/ 2999/*P1_MODCODLSTD*/
2925#define R0900_P1_MODCODLSTD 0xf4bd 3000#define R0900_P1_MODCODLSTD 0xf4bd
2926#define F0900_P1_DIS_QP_3_5 0xf4bd00f0 3001#define MODCODLSTD REGx(R0900_P1_MODCODLSTD)
2927#define F0900_P1_DIS_QP_1_2 0xf4bd000f 3002#define F0900_P1_DIS_QP_3_5 0xf4bd00f0
3003#define F0900_P1_DIS_QP_1_2 0xf4bd000f
2928 3004
2929/*P1_MODCODLSTE*/ 3005/*P1_MODCODLSTE*/
2930#define R0900_P1_MODCODLSTE 0xf4be 3006#define R0900_P1_MODCODLSTE 0xf4be
2931#define F0900_P1_DIS_QP_2_5 0xf4be00f0 3007#define MODCODLSTE REGx(R0900_P1_MODCODLSTE)
2932#define F0900_P1_DIS_QP_1_3 0xf4be000f 3008#define F0900_P1_DIS_QP_2_5 0xf4be00f0
3009#define F0900_P1_DIS_QP_1_3 0xf4be000f
2933 3010
2934/*P1_MODCODLSTF*/ 3011/*P1_MODCODLSTF*/
2935#define R0900_P1_MODCODLSTF 0xf4bf 3012#define R0900_P1_MODCODLSTF 0xf4bf
2936#define F0900_P1_DIS_QP_1_4 0xf4bf00f0 3013#define MODCODLSTF REGx(R0900_P1_MODCODLSTF)
2937#define F0900_P1_DDEMOD_SET 0xf4bf0002 3014#define F0900_P1_DIS_QP_1_4 0xf4bf00f0
2938#define F0900_P1_DDEMOD_MASK 0xf4bf0001 3015
3016/*P1_GAUSSR0*/
3017#define R0900_P1_GAUSSR0 0xf4c0
3018#define GAUSSR0 REGx(R0900_P1_GAUSSR0)
3019#define F0900_P1_EN_CCIMODE 0xf4c00080
3020#define F0900_P1_R0_GAUSSIEN 0xf4c0007f
3021
3022/*P1_CCIR0*/
3023#define R0900_P1_CCIR0 0xf4c1
3024#define CCIR0 REGx(R0900_P1_CCIR0)
3025#define F0900_P1_CCIDETECT_PLHONLY 0xf4c10080
3026#define F0900_P1_R0_CCI 0xf4c1007f
3027
3028/*P1_CCIQUANT*/
3029#define R0900_P1_CCIQUANT 0xf4c2
3030#define CCIQUANT REGx(R0900_P1_CCIQUANT)
3031#define F0900_P1_CCI_BETA 0xf4c200e0
3032#define F0900_P1_CCI_QUANT 0xf4c2001f
3033
3034/*P1_CCITHRES*/
3035#define R0900_P1_CCITHRES 0xf4c3
3036#define CCITHRES REGx(R0900_P1_CCITHRES)
3037#define F0900_P1_CCI_THRESHOLD 0xf4c300ff
3038
3039/*P1_CCIACC*/
3040#define R0900_P1_CCIACC 0xf4c4
3041#define CCIACC REGx(R0900_P1_CCIACC)
3042#define F0900_P1_CCI_VALUE 0xf4c400ff
2939 3043
2940/*P1_DMDRESCFG*/ 3044/*P1_DMDRESCFG*/
2941#define R0900_P1_DMDRESCFG 0xf4c6 3045#define R0900_P1_DMDRESCFG 0xf4c6
2942#define F0900_P1_DMDRES_RESET 0xf4c60080 3046#define DMDRESCFG REGx(R0900_P1_DMDRESCFG)
2943#define F0900_P1_DMDRES_NOISESQR 0xf4c60010 3047#define F0900_P1_DMDRES_RESET 0xf4c60080
2944#define F0900_P1_DMDRES_STRALL 0xf4c60008 3048#define F0900_P1_DMDRES_STRALL 0xf4c60008
2945#define F0900_P1_DMDRES_NEWONLY 0xf4c60004 3049#define F0900_P1_DMDRES_NEWONLY 0xf4c60004
2946#define F0900_P1_DMDRES_NOSTORE 0xf4c60002 3050#define F0900_P1_DMDRES_NOSTORE 0xf4c60002
2947#define F0900_P1_DMDRES_AGC2MEM 0xf4c60001
2948 3051
2949/*P1_DMDRESADR*/ 3052/*P1_DMDRESADR*/
2950#define R0900_P1_DMDRESADR 0xf4c7 3053#define R0900_P1_DMDRESADR 0xf4c7
2951#define F0900_P1_SUSP_PREDCANAL 0xf4c70080 3054#define DMDRESADR REGx(R0900_P1_DMDRESADR)
2952#define F0900_P1_DMDRES_VALIDCFR 0xf4c70040 3055#define F0900_P1_DMDRES_VALIDCFR 0xf4c70040
2953#define F0900_P1_DMDRES_MEMFULL 0xf4c70030 3056#define F0900_P1_DMDRES_MEMFULL 0xf4c70030
2954#define F0900_P1_DMDRES_RESNBR 0xf4c7000f 3057#define F0900_P1_DMDRES_RESNBR 0xf4c7000f
2955 3058
2956/*P1_DMDRESDATA7*/ 3059/*P1_DMDRESDATA7*/
2957#define R0900_P1_DMDRESDATA7 0xf4c8 3060#define R0900_P1_DMDRESDATA7 0xf4c8
2958#define F0900_P1_DMDRES_DATA7 0xf4c800ff 3061#define F0900_P1_DMDRES_DATA7 0xf4c800ff
2959 3062
2960/*P1_DMDRESDATA6*/ 3063/*P1_DMDRESDATA6*/
2961#define R0900_P1_DMDRESDATA6 0xf4c9 3064#define R0900_P1_DMDRESDATA6 0xf4c9
2962#define F0900_P1_DMDRES_DATA6 0xf4c900ff 3065#define F0900_P1_DMDRES_DATA6 0xf4c900ff
2963 3066
2964/*P1_DMDRESDATA5*/ 3067/*P1_DMDRESDATA5*/
2965#define R0900_P1_DMDRESDATA5 0xf4ca 3068#define R0900_P1_DMDRESDATA5 0xf4ca
2966#define F0900_P1_DMDRES_DATA5 0xf4ca00ff 3069#define F0900_P1_DMDRES_DATA5 0xf4ca00ff
2967 3070
2968/*P1_DMDRESDATA4*/ 3071/*P1_DMDRESDATA4*/
2969#define R0900_P1_DMDRESDATA4 0xf4cb 3072#define R0900_P1_DMDRESDATA4 0xf4cb
2970#define F0900_P1_DMDRES_DATA4 0xf4cb00ff 3073#define F0900_P1_DMDRES_DATA4 0xf4cb00ff
2971 3074
2972/*P1_DMDRESDATA3*/ 3075/*P1_DMDRESDATA3*/
2973#define R0900_P1_DMDRESDATA3 0xf4cc 3076#define R0900_P1_DMDRESDATA3 0xf4cc
2974#define F0900_P1_DMDRES_DATA3 0xf4cc00ff 3077#define F0900_P1_DMDRES_DATA3 0xf4cc00ff
2975 3078
2976/*P1_DMDRESDATA2*/ 3079/*P1_DMDRESDATA2*/
2977#define R0900_P1_DMDRESDATA2 0xf4cd 3080#define R0900_P1_DMDRESDATA2 0xf4cd
2978#define F0900_P1_DMDRES_DATA2 0xf4cd00ff 3081#define F0900_P1_DMDRES_DATA2 0xf4cd00ff
2979 3082
2980/*P1_DMDRESDATA1*/ 3083/*P1_DMDRESDATA1*/
2981#define R0900_P1_DMDRESDATA1 0xf4ce 3084#define R0900_P1_DMDRESDATA1 0xf4ce
2982#define F0900_P1_DMDRES_DATA1 0xf4ce00ff 3085#define F0900_P1_DMDRES_DATA1 0xf4ce00ff
2983 3086
2984/*P1_DMDRESDATA0*/ 3087/*P1_DMDRESDATA0*/
2985#define R0900_P1_DMDRESDATA0 0xf4cf 3088#define R0900_P1_DMDRESDATA0 0xf4cf
2986#define F0900_P1_DMDRES_DATA0 0xf4cf00ff 3089#define F0900_P1_DMDRES_DATA0 0xf4cf00ff
2987 3090
2988/*P1_FFEI1*/ 3091/*P1_FFEI1*/
2989#define R0900_P1_FFEI1 0xf4d0 3092#define R0900_P1_FFEI1 0xf4d0
2990#define F0900_P1_FFE_ACCI1 0xf4d001ff 3093#define FFEI1 REGx(R0900_P1_FFEI1)
3094#define F0900_P1_FFE_ACCI1 0xf4d001ff
2991 3095
2992/*P1_FFEQ1*/ 3096/*P1_FFEQ1*/
2993#define R0900_P1_FFEQ1 0xf4d1 3097#define R0900_P1_FFEQ1 0xf4d1
2994#define F0900_P1_FFE_ACCQ1 0xf4d101ff 3098#define FFEQ1 REGx(R0900_P1_FFEQ1)
3099#define F0900_P1_FFE_ACCQ1 0xf4d101ff
2995 3100
2996/*P1_FFEI2*/ 3101/*P1_FFEI2*/
2997#define R0900_P1_FFEI2 0xf4d2 3102#define R0900_P1_FFEI2 0xf4d2
2998#define F0900_P1_FFE_ACCI2 0xf4d201ff 3103#define FFEI2 REGx(R0900_P1_FFEI2)
3104#define F0900_P1_FFE_ACCI2 0xf4d201ff
2999 3105
3000/*P1_FFEQ2*/ 3106/*P1_FFEQ2*/
3001#define R0900_P1_FFEQ2 0xf4d3 3107#define R0900_P1_FFEQ2 0xf4d3
3002#define F0900_P1_FFE_ACCQ2 0xf4d301ff 3108#define FFEQ2 REGx(R0900_P1_FFEQ2)
3109#define F0900_P1_FFE_ACCQ2 0xf4d301ff
3003 3110
3004/*P1_FFEI3*/ 3111/*P1_FFEI3*/
3005#define R0900_P1_FFEI3 0xf4d4 3112#define R0900_P1_FFEI3 0xf4d4
3006#define F0900_P1_FFE_ACCI3 0xf4d401ff 3113#define FFEI3 REGx(R0900_P1_FFEI3)
3114#define F0900_P1_FFE_ACCI3 0xf4d401ff
3007 3115
3008/*P1_FFEQ3*/ 3116/*P1_FFEQ3*/
3009#define R0900_P1_FFEQ3 0xf4d5 3117#define R0900_P1_FFEQ3 0xf4d5
3010#define F0900_P1_FFE_ACCQ3 0xf4d501ff 3118#define FFEQ3 REGx(R0900_P1_FFEQ3)
3119#define F0900_P1_FFE_ACCQ3 0xf4d501ff
3011 3120
3012/*P1_FFEI4*/ 3121/*P1_FFEI4*/
3013#define R0900_P1_FFEI4 0xf4d6 3122#define R0900_P1_FFEI4 0xf4d6
3014#define F0900_P1_FFE_ACCI4 0xf4d601ff 3123#define FFEI4 REGx(R0900_P1_FFEI4)
3124#define F0900_P1_FFE_ACCI4 0xf4d601ff
3015 3125
3016/*P1_FFEQ4*/ 3126/*P1_FFEQ4*/
3017#define R0900_P1_FFEQ4 0xf4d7 3127#define R0900_P1_FFEQ4 0xf4d7
3018#define F0900_P1_FFE_ACCQ4 0xf4d701ff 3128#define FFEQ4 REGx(R0900_P1_FFEQ4)
3129#define F0900_P1_FFE_ACCQ4 0xf4d701ff
3019 3130
3020/*P1_FFECFG*/ 3131/*P1_FFECFG*/
3021#define R0900_P1_FFECFG 0xf4d8 3132#define R0900_P1_FFECFG 0xf4d8
3022#define F0900_P1_EQUALFFE_ON 0xf4d80040 3133#define FFECFG REGx(R0900_P1_FFECFG)
3023#define F0900_P1_EQUAL_USEDSYMB 0xf4d80030 3134#define F0900_P1_EQUALFFE_ON 0xf4d80040
3024#define F0900_P1_MU_EQUALFFE 0xf4d80007 3135#define F0900_P1_MU_EQUALFFE 0xf4d80007
3025 3136
3026/*P1_TNRCFG*/ 3137/*P1_TNRCFG*/
3027#define R0900_P1_TNRCFG 0xf4e0 3138#define R0900_P1_TNRCFG 0xf4e0
3028#define F0900_P1_TUN_ACKFAIL 0xf4e00080 3139#define TNRCFG REGx(R0900_P1_TNRCFG)
3029#define F0900_P1_TUN_TYPE 0xf4e00070 3140#define F0900_P1_TUN_ACKFAIL 0xf4e00080
3030#define F0900_P1_TUN_SECSTOP 0xf4e00008 3141#define F0900_P1_TUN_TYPE 0xf4e00070
3031#define F0900_P1_TUN_VCOSRCH 0xf4e00004 3142#define F0900_P1_TUN_SECSTOP 0xf4e00008
3032#define F0900_P1_TUN_MADDRESS 0xf4e00003 3143#define F0900_P1_TUN_VCOSRCH 0xf4e00004
3144#define F0900_P1_TUN_MADDRESS 0xf4e00003
3033 3145
3034/*P1_TNRCFG2*/ 3146/*P1_TNRCFG2*/
3035#define R0900_P1_TNRCFG2 0xf4e1 3147#define R0900_P1_TNRCFG2 0xf4e1
3036#define F0900_P1_TUN_IQSWAP 0xf4e10080 3148#define TNRCFG2 REGx(R0900_P1_TNRCFG2)
3037#define F0900_P1_STB6110_STEP2MHZ 0xf4e10040 3149#define F0900_P1_TUN_IQSWAP 0xf4e10080
3038#define F0900_P1_STB6120_DBLI2C 0xf4e10020 3150#define F0900_P1_DIS_BWCALC 0xf4e10004
3039#define F0900_P1_DIS_FCCK 0xf4e10010 3151#define F0900_P1_SHORT_WAITSTATES 0xf4e10002
3040#define F0900_P1_DIS_LPEN 0xf4e10008
3041#define F0900_P1_DIS_BWCALC 0xf4e10004
3042#define F0900_P1_SHORT_WAITSTATES 0xf4e10002
3043#define F0900_P1_DIS_2BWAGC1 0xf4e10001
3044 3152
3045/*P1_TNRXTAL*/ 3153/*P1_TNRXTAL*/
3046#define R0900_P1_TNRXTAL 0xf4e4 3154#define R0900_P1_TNRXTAL 0xf4e4
3047#define F0900_P1_TUN_MCLKDECIMAL 0xf4e400e0 3155#define TNRXTAL REGx(R0900_P1_TNRXTAL)
3048#define F0900_P1_TUN_XTALFREQ 0xf4e4001f 3156#define F0900_P1_TUN_XTALFREQ 0xf4e4001f
3049 3157
3050/*P1_TNRSTEPS*/ 3158/*P1_TNRSTEPS*/
3051#define R0900_P1_TNRSTEPS 0xf4e7 3159#define R0900_P1_TNRSTEPS 0xf4e7
3052#define F0900_P1_TUNER_BW1P6 0xf4e70080 3160#define TNRSTEPS REGx(R0900_P1_TNRSTEPS)
3053#define F0900_P1_BWINC_OFFSET 0xf4e70070 3161#define F0900_P1_TUNER_BW0P125 0xf4e70080
3054#define F0900_P1_SOFTSTEP_RNG 0xf4e70008 3162#define F0900_P1_BWINC_OFFSET 0xf4e70170
3055#define F0900_P1_TUN_BWOFFSET 0xf4e70107 3163#define F0900_P1_SOFTSTEP_RNG 0xf4e70008
3164#define F0900_P1_TUN_BWOFFSET 0xf4e70007
3056 3165
3057/*P1_TNRGAIN*/ 3166/*P1_TNRGAIN*/
3058#define R0900_P1_TNRGAIN 0xf4e8 3167#define R0900_P1_TNRGAIN 0xf4e8
3059#define F0900_P1_TUN_KDIVEN 0xf4e800c0 3168#define TNRGAIN REGx(R0900_P1_TNRGAIN)
3060#define F0900_P1_STB6X00_OCK 0xf4e80030 3169#define F0900_P1_TUN_KDIVEN 0xf4e800c0
3061#define F0900_P1_TUN_GAIN 0xf4e8000f 3170#define F0900_P1_STB6X00_OCK 0xf4e80030
3171#define F0900_P1_TUN_GAIN 0xf4e8000f
3062 3172
3063/*P1_TNRRF1*/ 3173/*P1_TNRRF1*/
3064#define R0900_P1_TNRRF1 0xf4e9 3174#define R0900_P1_TNRRF1 0xf4e9
3065#define F0900_P1_TUN_RFFREQ2 0xf4e900ff 3175#define TNRRF1 REGx(R0900_P1_TNRRF1)
3176#define F0900_P1_TUN_RFFREQ2 0xf4e900ff
3066 3177
3067/*P1_TNRRF0*/ 3178/*P1_TNRRF0*/
3068#define R0900_P1_TNRRF0 0xf4ea 3179#define R0900_P1_TNRRF0 0xf4ea
3069#define F0900_P1_TUN_RFFREQ1 0xf4ea00ff 3180#define TNRRF0 REGx(R0900_P1_TNRRF0)
3181#define F0900_P1_TUN_RFFREQ1 0xf4ea00ff
3070 3182
3071/*P1_TNRBW*/ 3183/*P1_TNRBW*/
3072#define R0900_P1_TNRBW 0xf4eb 3184#define R0900_P1_TNRBW 0xf4eb
3073#define F0900_P1_TUN_RFFREQ0 0xf4eb00c0 3185#define TNRBW REGx(R0900_P1_TNRBW)
3074#define F0900_P1_TUN_BW 0xf4eb003f 3186#define F0900_P1_TUN_RFFREQ0 0xf4eb00c0
3187#define F0900_P1_TUN_BW 0xf4eb003f
3075 3188
3076/*P1_TNRADJ*/ 3189/*P1_TNRADJ*/
3077#define R0900_P1_TNRADJ 0xf4ec 3190#define R0900_P1_TNRADJ 0xf4ec
3078#define F0900_P1_STB61X0_RCLK 0xf4ec0080 3191#define TNRADJ REGx(R0900_P1_TNRADJ)
3079#define F0900_P1_STB61X0_CALTIME 0xf4ec0040 3192#define F0900_P1_STB61X0_CALTIME 0xf4ec0040
3080#define F0900_P1_STB6X00_DLB 0xf4ec0038
3081#define F0900_P1_STB6000_FCL 0xf4ec0007
3082 3193
3083/*P1_TNRCTL2*/ 3194/*P1_TNRCTL2*/
3084#define R0900_P1_TNRCTL2 0xf4ed 3195#define R0900_P1_TNRCTL2 0xf4ed
3085#define F0900_P1_STB61X0_LCP1_RCCKOFF 0xf4ed0080 3196#define TNRCTL2 REGx(R0900_P1_TNRCTL2)
3086#define F0900_P1_STB61X0_LCP0 0xf4ed0040 3197#define F0900_P1_STB61X0_RCCKOFF 0xf4ed0080
3087#define F0900_P1_STB61X0_XTOUT_RFOUTS 0xf4ed0020 3198#define F0900_P1_STB61X0_ICP_SDOFF 0xf4ed0040
3088#define F0900_P1_STB61X0_XTON_MCKDV 0xf4ed0010 3199#define F0900_P1_STB61X0_DCLOOPOFF 0xf4ed0020
3089#define F0900_P1_STB61X0_CALOFF_DCOFF 0xf4ed0008 3200#define F0900_P1_STB61X0_REFOUTSEL 0xf4ed0010
3090#define F0900_P1_STB6110_LPT 0xf4ed0004 3201#define F0900_P1_STB61X0_CALOFF 0xf4ed0008
3091#define F0900_P1_STB6110_RX 0xf4ed0002 3202#define F0900_P1_STB6XX0_LPT_BEN 0xf4ed0004
3092#define F0900_P1_STB6110_SYN 0xf4ed0001 3203#define F0900_P1_STB6XX0_RX_OSCP 0xf4ed0002
3204#define F0900_P1_STB6XX0_SYN 0xf4ed0001
3093 3205
3094/*P1_TNRCFG3*/ 3206/*P1_TNRCFG3*/
3095#define R0900_P1_TNRCFG3 0xf4ee 3207#define R0900_P1_TNRCFG3 0xf4ee
3096#define F0900_P1_STB6120_DISCTRL1 0xf4ee0080 3208#define TNRCFG3 REGx(R0900_P1_TNRCFG3)
3097#define F0900_P1_STB6120_INVORDER 0xf4ee0040 3209#define F0900_P1_TUN_PLLFREQ 0xf4ee001c
3098#define F0900_P1_STB6120_ENCTRL6 0xf4ee0020 3210#define F0900_P1_TUN_I2CFREQ_MODE 0xf4ee0003
3099#define F0900_P1_TUN_PLLFREQ 0xf4ee001c
3100#define F0900_P1_TUN_I2CFREQ_MODE 0xf4ee0003
3101 3211
3102/*P1_TNRLAUNCH*/ 3212/*P1_TNRLAUNCH*/
3103#define R0900_P1_TNRLAUNCH 0xf4f0 3213#define R0900_P1_TNRLAUNCH 0xf4f0
3214#define TNRLAUNCH REGx(R0900_P1_TNRLAUNCH)
3104 3215
3105/*P1_TNRLD*/ 3216/*P1_TNRLD*/
3106#define R0900_P1_TNRLD 0xf4f0 3217#define R0900_P1_TNRLD 0xf4f0
3107#define F0900_P1_TUNLD_VCOING 0xf4f00080 3218#define TNRLD REGx(R0900_P1_TNRLD)
3108#define F0900_P1_TUN_REG1FAIL 0xf4f00040 3219#define F0900_P1_TUNLD_VCOING 0xf4f00080
3109#define F0900_P1_TUN_REG2FAIL 0xf4f00020 3220#define F0900_P1_TUN_REG1FAIL 0xf4f00040
3110#define F0900_P1_TUN_REG3FAIL 0xf4f00010 3221#define F0900_P1_TUN_REG2FAIL 0xf4f00020
3111#define F0900_P1_TUN_REG4FAIL 0xf4f00008 3222#define F0900_P1_TUN_REG3FAIL 0xf4f00010
3112#define F0900_P1_TUN_REG5FAIL 0xf4f00004 3223#define F0900_P1_TUN_REG4FAIL 0xf4f00008
3113#define F0900_P1_TUN_BWING 0xf4f00002 3224#define F0900_P1_TUN_REG5FAIL 0xf4f00004
3114#define F0900_P1_TUN_LOCKED 0xf4f00001 3225#define F0900_P1_TUN_BWING 0xf4f00002
3226#define F0900_P1_TUN_LOCKED 0xf4f00001
3115 3227
3116/*P1_TNROBSL*/ 3228/*P1_TNROBSL*/
3117#define R0900_P1_TNROBSL 0xf4f6 3229#define R0900_P1_TNROBSL 0xf4f6
3118#define F0900_P1_TUN_I2CABORTED 0xf4f60080 3230#define TNROBSL REGx(R0900_P1_TNROBSL)
3119#define F0900_P1_TUN_LPEN 0xf4f60040 3231#define F0900_P1_TUN_I2CABORTED 0xf4f60080
3120#define F0900_P1_TUN_FCCK 0xf4f60020 3232#define F0900_P1_TUN_LPEN 0xf4f60040
3121#define F0900_P1_TUN_I2CLOCKED 0xf4f60010 3233#define F0900_P1_TUN_FCCK 0xf4f60020
3122#define F0900_P1_TUN_PROGDONE 0xf4f6000c 3234#define F0900_P1_TUN_I2CLOCKED 0xf4f60010
3123#define F0900_P1_TUN_RFRESTE1 0xf4f60003 3235#define F0900_P1_TUN_PROGDONE 0xf4f6000c
3236#define F0900_P1_TUN_RFRESTE1 0xf4f60003
3124 3237
3125/*P1_TNRRESTE*/ 3238/*P1_TNRRESTE*/
3126#define R0900_P1_TNRRESTE 0xf4f7 3239#define R0900_P1_TNRRESTE 0xf4f7
3127#define F0900_P1_TUN_RFRESTE0 0xf4f700ff 3240#define TNRRESTE REGx(R0900_P1_TNRRESTE)
3241#define F0900_P1_TUN_RFRESTE0 0xf4f700ff
3128 3242
3129/*P1_SMAPCOEF7*/ 3243/*P1_SMAPCOEF7*/
3130#define R0900_P1_SMAPCOEF7 0xf500 3244#define R0900_P1_SMAPCOEF7 0xf500
3131#define F0900_P1_DIS_QSCALE 0xf5000080 3245#define SMAPCOEF7 REGx(R0900_P1_SMAPCOEF7)
3132#define F0900_P1_SMAPCOEF_Q_LLR12 0xf500017f 3246#define F0900_P1_DIS_QSCALE 0xf5000080
3247#define F0900_P1_SMAPCOEF_Q_LLR12 0xf500017f
3133 3248
3134/*P1_SMAPCOEF6*/ 3249/*P1_SMAPCOEF6*/
3135#define R0900_P1_SMAPCOEF6 0xf501 3250#define R0900_P1_SMAPCOEF6 0xf501
3136#define F0900_P1_DIS_NEWSCALE 0xf5010008 3251#define SMAPCOEF6 REGx(R0900_P1_SMAPCOEF6)
3137#define F0900_P1_ADJ_8PSKLLR1 0xf5010004 3252#define F0900_P1_ADJ_8PSKLLR1 0xf5010004
3138#define F0900_P1_OLD_8PSKLLR1 0xf5010002 3253#define F0900_P1_OLD_8PSKLLR1 0xf5010002
3139#define F0900_P1_DIS_AB8PSK 0xf5010001 3254#define F0900_P1_DIS_AB8PSK 0xf5010001
3140 3255
3141/*P1_SMAPCOEF5*/ 3256/*P1_SMAPCOEF5*/
3142#define R0900_P1_SMAPCOEF5 0xf502 3257#define R0900_P1_SMAPCOEF5 0xf502
3143#define F0900_P1_DIS_8SCALE 0xf5020080 3258#define SMAPCOEF5 REGx(R0900_P1_SMAPCOEF5)
3144#define F0900_P1_SMAPCOEF_8P_LLR23 0xf502017f 3259#define F0900_P1_DIS_8SCALE 0xf5020080
3260#define F0900_P1_SMAPCOEF_8P_LLR23 0xf502017f
3261
3262/*P1_NCO2MAX1*/
3263#define R0900_P1_NCO2MAX1 0xf514
3264#define NCO2MAX1 REGx(R0900_P1_NCO2MAX1)
3265#define F0900_P1_TETA2_MAXVABS1 0xf51400ff
3266
3267/*P1_NCO2MAX0*/
3268#define R0900_P1_NCO2MAX0 0xf515
3269#define NCO2MAX0 REGx(R0900_P1_NCO2MAX0)
3270#define F0900_P1_TETA2_MAXVABS0 0xf51500ff
3271
3272/*P1_NCO2FR1*/
3273#define R0900_P1_NCO2FR1 0xf516
3274#define NCO2FR1 REGx(R0900_P1_NCO2FR1)
3275#define F0900_P1_NCO2FINAL_ANGLE1 0xf51600ff
3276
3277/*P1_NCO2FR0*/
3278#define R0900_P1_NCO2FR0 0xf517
3279#define NCO2FR0 REGx(R0900_P1_NCO2FR0)
3280#define F0900_P1_NCO2FINAL_ANGLE0 0xf51700ff
3281
3282/*P1_CFR2AVRGE1*/
3283#define R0900_P1_CFR2AVRGE1 0xf518
3284#define CFR2AVRGE1 REGx(R0900_P1_CFR2AVRGE1)
3285#define F0900_P1_I2C_CFR2AVERAGE1 0xf51800ff
3286
3287/*P1_CFR2AVRGE0*/
3288#define R0900_P1_CFR2AVRGE0 0xf519
3289#define CFR2AVRGE0 REGx(R0900_P1_CFR2AVRGE0)
3290#define F0900_P1_I2C_CFR2AVERAGE0 0xf51900ff
3145 3291
3146/*P1_DMDPLHSTAT*/ 3292/*P1_DMDPLHSTAT*/
3147#define R0900_P1_DMDPLHSTAT 0xf520 3293#define R0900_P1_DMDPLHSTAT 0xf520
3148#define F0900_P1_PLH_STATISTIC 0xf52000ff 3294#define DMDPLHSTAT REGx(R0900_P1_DMDPLHSTAT)
3295#define F0900_P1_PLH_STATISTIC 0xf52000ff
3149 3296
3150/*P1_LOCKTIME3*/ 3297/*P1_LOCKTIME3*/
3151#define R0900_P1_LOCKTIME3 0xf522 3298#define R0900_P1_LOCKTIME3 0xf522
3152#define F0900_P1_DEMOD_LOCKTIME3 0xf52200ff 3299#define LOCKTIME3 REGx(R0900_P1_LOCKTIME3)
3300#define F0900_P1_DEMOD_LOCKTIME3 0xf52200ff
3153 3301
3154/*P1_LOCKTIME2*/ 3302/*P1_LOCKTIME2*/
3155#define R0900_P1_LOCKTIME2 0xf523 3303#define R0900_P1_LOCKTIME2 0xf523
3156#define F0900_P1_DEMOD_LOCKTIME2 0xf52300ff 3304#define LOCKTIME2 REGx(R0900_P1_LOCKTIME2)
3305#define F0900_P1_DEMOD_LOCKTIME2 0xf52300ff
3157 3306
3158/*P1_LOCKTIME1*/ 3307/*P1_LOCKTIME1*/
3159#define R0900_P1_LOCKTIME1 0xf524 3308#define R0900_P1_LOCKTIME1 0xf524
3160#define F0900_P1_DEMOD_LOCKTIME1 0xf52400ff 3309#define LOCKTIME1 REGx(R0900_P1_LOCKTIME1)
3310#define F0900_P1_DEMOD_LOCKTIME1 0xf52400ff
3161 3311
3162/*P1_LOCKTIME0*/ 3312/*P1_LOCKTIME0*/
3163#define R0900_P1_LOCKTIME0 0xf525 3313#define R0900_P1_LOCKTIME0 0xf525
3164#define F0900_P1_DEMOD_LOCKTIME0 0xf52500ff 3314#define LOCKTIME0 REGx(R0900_P1_LOCKTIME0)
3315#define F0900_P1_DEMOD_LOCKTIME0 0xf52500ff
3165 3316
3166/*P1_VITSCALE*/ 3317/*P1_VITSCALE*/
3167#define R0900_P1_VITSCALE 0xf532 3318#define R0900_P1_VITSCALE 0xf532
3168#define F0900_P1_NVTH_NOSRANGE 0xf5320080 3319#define VITSCALE REGx(R0900_P1_VITSCALE)
3169#define F0900_P1_VERROR_MAXMODE 0xf5320040 3320#define F0900_P1_NVTH_NOSRANGE 0xf5320080
3170#define F0900_P1_KDIV_MODE 0xf5320030 3321#define F0900_P1_VERROR_MAXMODE 0xf5320040
3171#define F0900_P1_NSLOWSN_LOCKED 0xf5320008 3322#define F0900_P1_NSLOWSN_LOCKED 0xf5320008
3172#define F0900_P1_DELOCK_PRFLOSS 0xf5320004 3323#define F0900_P1_DIS_RSFLOCK 0xf5320002
3173#define F0900_P1_DIS_RSFLOCK 0xf5320002
3174 3324
3175/*P1_FECM*/ 3325/*P1_FECM*/
3176#define R0900_P1_FECM 0xf533 3326#define R0900_P1_FECM 0xf533
3177#define F0900_P1_DSS_DVB 0xf5330080 3327#define FECM REGx(R0900_P1_FECM)
3178#define F0900_P1_DEMOD_BYPASS 0xf5330040 3328#define F0900_P1_DSS_DVB 0xf5330080
3179#define F0900_P1_CMP_SLOWMODE 0xf5330020 3329#define DSS_DVB FLDx(F0900_P1_DSS_DVB)
3180#define F0900_P1_DSS_SRCH 0xf5330010 3330#define F0900_P1_DSS_SRCH 0xf5330010
3181#define F0900_P1_DIFF_MODEVIT 0xf5330004 3331#define F0900_P1_SYNCVIT 0xf5330002
3182#define F0900_P1_SYNCVIT 0xf5330002 3332#define F0900_P1_IQINV 0xf5330001
3183#define F0900_P1_IQINV 0xf5330001 3333#define IQINV FLDx(F0900_P1_IQINV)
3184 3334
3185/*P1_VTH12*/ 3335/*P1_VTH12*/
3186#define R0900_P1_VTH12 0xf534 3336#define R0900_P1_VTH12 0xf534
3187#define F0900_P1_VTH12 0xf53400ff 3337#define VTH12 REGx(R0900_P1_VTH12)
3338#define F0900_P1_VTH12 0xf53400ff
3188 3339
3189/*P1_VTH23*/ 3340/*P1_VTH23*/
3190#define R0900_P1_VTH23 0xf535 3341#define R0900_P1_VTH23 0xf535
3191#define F0900_P1_VTH23 0xf53500ff 3342#define VTH23 REGx(R0900_P1_VTH23)
3343#define F0900_P1_VTH23 0xf53500ff
3192 3344
3193/*P1_VTH34*/ 3345/*P1_VTH34*/
3194#define R0900_P1_VTH34 0xf536 3346#define R0900_P1_VTH34 0xf536
3195#define F0900_P1_VTH34 0xf53600ff 3347#define VTH34 REGx(R0900_P1_VTH34)
3348#define F0900_P1_VTH34 0xf53600ff
3196 3349
3197/*P1_VTH56*/ 3350/*P1_VTH56*/
3198#define R0900_P1_VTH56 0xf537 3351#define R0900_P1_VTH56 0xf537
3199#define F0900_P1_VTH56 0xf53700ff 3352#define VTH56 REGx(R0900_P1_VTH56)
3353#define F0900_P1_VTH56 0xf53700ff
3200 3354
3201/*P1_VTH67*/ 3355/*P1_VTH67*/
3202#define R0900_P1_VTH67 0xf538 3356#define R0900_P1_VTH67 0xf538
3203#define F0900_P1_VTH67 0xf53800ff 3357#define VTH67 REGx(R0900_P1_VTH67)
3358#define F0900_P1_VTH67 0xf53800ff
3204 3359
3205/*P1_VTH78*/ 3360/*P1_VTH78*/
3206#define R0900_P1_VTH78 0xf539 3361#define R0900_P1_VTH78 0xf539
3207#define F0900_P1_VTH78 0xf53900ff 3362#define VTH78 REGx(R0900_P1_VTH78)
3363#define F0900_P1_VTH78 0xf53900ff
3208 3364
3209/*P1_VITCURPUN*/ 3365/*P1_VITCURPUN*/
3210#define R0900_P1_VITCURPUN 0xf53a 3366#define R0900_P1_VITCURPUN 0xf53a
3211#define F0900_P1_VIT_MAPPING 0xf53a00e0 3367#define VITCURPUN REGx(R0900_P1_VITCURPUN)
3212#define F0900_P1_VIT_CURPUN 0xf53a001f 3368#define F0900_P1_VIT_CURPUN 0xf53a001f
3369#define VIT_CURPUN FLDx(F0900_P1_VIT_CURPUN)
3213 3370
3214/*P1_VERROR*/ 3371/*P1_VERROR*/
3215#define R0900_P1_VERROR 0xf53b 3372#define R0900_P1_VERROR 0xf53b
3216#define F0900_P1_REGERR_VIT 0xf53b00ff 3373#define VERROR REGx(R0900_P1_VERROR)
3374#define F0900_P1_REGERR_VIT 0xf53b00ff
3217 3375
3218/*P1_PRVIT*/ 3376/*P1_PRVIT*/
3219#define R0900_P1_PRVIT 0xf53c 3377#define R0900_P1_PRVIT 0xf53c
3220#define F0900_P1_DIS_VTHLOCK 0xf53c0040 3378#define PRVIT REGx(R0900_P1_PRVIT)
3221#define F0900_P1_E7_8VIT 0xf53c0020 3379#define F0900_P1_DIS_VTHLOCK 0xf53c0040
3222#define F0900_P1_E6_7VIT 0xf53c0010 3380#define F0900_P1_E7_8VIT 0xf53c0020
3223#define F0900_P1_E5_6VIT 0xf53c0008 3381#define F0900_P1_E6_7VIT 0xf53c0010
3224#define F0900_P1_E3_4VIT 0xf53c0004 3382#define F0900_P1_E5_6VIT 0xf53c0008
3225#define F0900_P1_E2_3VIT 0xf53c0002 3383#define F0900_P1_E3_4VIT 0xf53c0004
3226#define F0900_P1_E1_2VIT 0xf53c0001 3384#define F0900_P1_E2_3VIT 0xf53c0002
3385#define F0900_P1_E1_2VIT 0xf53c0001
3227 3386
3228/*P1_VAVSRVIT*/ 3387/*P1_VAVSRVIT*/
3229#define R0900_P1_VAVSRVIT 0xf53d 3388#define R0900_P1_VAVSRVIT 0xf53d
3230#define F0900_P1_AMVIT 0xf53d0080 3389#define VAVSRVIT REGx(R0900_P1_VAVSRVIT)
3231#define F0900_P1_FROZENVIT 0xf53d0040 3390#define F0900_P1_AMVIT 0xf53d0080
3232#define F0900_P1_SNVIT 0xf53d0030 3391#define F0900_P1_FROZENVIT 0xf53d0040
3233#define F0900_P1_TOVVIT 0xf53d000c 3392#define F0900_P1_SNVIT 0xf53d0030
3234#define F0900_P1_HYPVIT 0xf53d0003 3393#define F0900_P1_TOVVIT 0xf53d000c
3394#define F0900_P1_HYPVIT 0xf53d0003
3235 3395
3236/*P1_VSTATUSVIT*/ 3396/*P1_VSTATUSVIT*/
3237#define R0900_P1_VSTATUSVIT 0xf53e 3397#define R0900_P1_VSTATUSVIT 0xf53e
3238#define F0900_P1_VITERBI_ON 0xf53e0080 3398#define VSTATUSVIT REGx(R0900_P1_VSTATUSVIT)
3239#define F0900_P1_END_LOOPVIT 0xf53e0040 3399#define F0900_P1_PRFVIT 0xf53e0010
3240#define F0900_P1_VITERBI_DEPRF 0xf53e0020 3400#define PRFVIT FLDx(F0900_P1_PRFVIT)
3241#define F0900_P1_PRFVIT 0xf53e0010 3401#define F0900_P1_LOCKEDVIT 0xf53e0008
3242#define F0900_P1_LOCKEDVIT 0xf53e0008 3402#define LOCKEDVIT FLDx(F0900_P1_LOCKEDVIT)
3243#define F0900_P1_VITERBI_DELOCK 0xf53e0004
3244#define F0900_P1_VIT_DEMODSEL 0xf53e0002
3245#define F0900_P1_VITERBI_COMPOUT 0xf53e0001
3246 3403
3247/*P1_VTHINUSE*/ 3404/*P1_VTHINUSE*/
3248#define R0900_P1_VTHINUSE 0xf53f 3405#define R0900_P1_VTHINUSE 0xf53f
3249#define F0900_P1_VIT_INUSE 0xf53f00ff 3406#define VTHINUSE REGx(R0900_P1_VTHINUSE)
3407#define F0900_P1_VIT_INUSE 0xf53f00ff
3250 3408
3251/*P1_KDIV12*/ 3409/*P1_KDIV12*/
3252#define R0900_P1_KDIV12 0xf540 3410#define R0900_P1_KDIV12 0xf540
3253#define F0900_P1_KDIV12_MANUAL 0xf5400080 3411#define KDIV12 REGx(R0900_P1_KDIV12)
3254#define F0900_P1_K_DIVIDER_12 0xf540007f 3412#define F0900_P1_K_DIVIDER_12 0xf540007f
3255 3413
3256/*P1_KDIV23*/ 3414/*P1_KDIV23*/
3257#define R0900_P1_KDIV23 0xf541 3415#define R0900_P1_KDIV23 0xf541
3258#define F0900_P1_KDIV23_MANUAL 0xf5410080 3416#define KDIV23 REGx(R0900_P1_KDIV23)
3259#define F0900_P1_K_DIVIDER_23 0xf541007f 3417#define F0900_P1_K_DIVIDER_23 0xf541007f
3260 3418
3261/*P1_KDIV34*/ 3419/*P1_KDIV34*/
3262#define R0900_P1_KDIV34 0xf542 3420#define R0900_P1_KDIV34 0xf542
3263#define F0900_P1_KDIV34_MANUAL 0xf5420080 3421#define KDIV34 REGx(R0900_P1_KDIV34)
3264#define F0900_P1_K_DIVIDER_34 0xf542007f 3422#define F0900_P1_K_DIVIDER_34 0xf542007f
3265 3423
3266/*P1_KDIV56*/ 3424/*P1_KDIV56*/
3267#define R0900_P1_KDIV56 0xf543 3425#define R0900_P1_KDIV56 0xf543
3268#define F0900_P1_KDIV56_MANUAL 0xf5430080 3426#define KDIV56 REGx(R0900_P1_KDIV56)
3269#define F0900_P1_K_DIVIDER_56 0xf543007f 3427#define F0900_P1_K_DIVIDER_56 0xf543007f
3270 3428
3271/*P1_KDIV67*/ 3429/*P1_KDIV67*/
3272#define R0900_P1_KDIV67 0xf544 3430#define R0900_P1_KDIV67 0xf544
3273#define F0900_P1_KDIV67_MANUAL 0xf5440080 3431#define KDIV67 REGx(R0900_P1_KDIV67)
3274#define F0900_P1_K_DIVIDER_67 0xf544007f 3432#define F0900_P1_K_DIVIDER_67 0xf544007f
3275 3433
3276/*P1_KDIV78*/ 3434/*P1_KDIV78*/
3277#define R0900_P1_KDIV78 0xf545 3435#define R0900_P1_KDIV78 0xf545
3278#define F0900_P1_KDIV78_MANUAL 0xf5450080 3436#define KDIV78 REGx(R0900_P1_KDIV78)
3279#define F0900_P1_K_DIVIDER_78 0xf545007f 3437#define F0900_P1_K_DIVIDER_78 0xf545007f
3280 3438
3281/*P1_PDELCTRL1*/ 3439/*P1_PDELCTRL1*/
3282#define R0900_P1_PDELCTRL1 0xf550 3440#define R0900_P1_PDELCTRL1 0xf550
3283#define F0900_P1_INV_MISMASK 0xf5500080 3441#define PDELCTRL1 REGx(R0900_P1_PDELCTRL1)
3284#define F0900_P1_FORCE_ACCEPTED 0xf5500040 3442#define F0900_P1_INV_MISMASK 0xf5500080
3285#define F0900_P1_FILTER_EN 0xf5500020 3443#define F0900_P1_FILTER_EN 0xf5500020
3286#define F0900_P1_FORCE_PKTDELINUSE 0xf5500010 3444#define F0900_P1_EN_MIS00 0xf5500002
3287#define F0900_P1_HYSTEN 0xf5500008 3445#define F0900_P1_ALGOSWRST 0xf5500001
3288#define F0900_P1_HYSTSWRST 0xf5500004 3446#define ALGOSWRST FLDx(F0900_P1_ALGOSWRST)
3289#define F0900_P1_EN_MIS00 0xf5500002
3290#define F0900_P1_ALGOSWRST 0xf5500001
3291 3447
3292/*P1_PDELCTRL2*/ 3448/*P1_PDELCTRL2*/
3293#define R0900_P1_PDELCTRL2 0xf551 3449#define R0900_P1_PDELCTRL2 0xf551
3294#define F0900_P1_FORCE_CONTINUOUS 0xf5510080 3450#define PDELCTRL2 REGx(R0900_P1_PDELCTRL2)
3295#define F0900_P1_RESET_UPKO_COUNT 0xf5510040 3451#define F0900_P1_RESET_UPKO_COUNT 0xf5510040
3296#define F0900_P1_USER_PKTDELIN_NB 0xf5510020 3452#define RESET_UPKO_COUNT FLDx(F0900_P1_RESET_UPKO_COUNT)
3297#define F0900_P1_FORCE_LOCKED 0xf5510010 3453#define F0900_P1_FRAME_MODE 0xf5510002
3298#define F0900_P1_DATA_UNBBSCRAM 0xf5510008 3454#define F0900_P1_NOBCHERRFLG_USE 0xf5510001
3299#define F0900_P1_FORCE_LONGPKT 0xf5510004
3300#define F0900_P1_FRAME_MODE 0xf5510002
3301 3455
3302/*P1_HYSTTHRESH*/ 3456/*P1_HYSTTHRESH*/
3303#define R0900_P1_HYSTTHRESH 0xf554 3457#define R0900_P1_HYSTTHRESH 0xf554
3304#define F0900_P1_UNLCK_THRESH 0xf55400f0 3458#define HYSTTHRESH REGx(R0900_P1_HYSTTHRESH)
3305#define F0900_P1_DELIN_LCK_THRESH 0xf554000f 3459#define F0900_P1_UNLCK_THRESH 0xf55400f0
3460#define F0900_P1_DELIN_LCK_THRESH 0xf554000f
3306 3461
3307/*P1_ISIENTRY*/ 3462/*P1_ISIENTRY*/
3308#define R0900_P1_ISIENTRY 0xf55e 3463#define R0900_P1_ISIENTRY 0xf55e
3309#define F0900_P1_ISI_ENTRY 0xf55e00ff 3464#define ISIENTRY REGx(R0900_P1_ISIENTRY)
3465#define F0900_P1_ISI_ENTRY 0xf55e00ff
3310 3466
3311/*P1_ISIBITENA*/ 3467/*P1_ISIBITENA*/
3312#define R0900_P1_ISIBITENA 0xf55f 3468#define R0900_P1_ISIBITENA 0xf55f
3313#define F0900_P1_ISI_BIT_EN 0xf55f00ff 3469#define ISIBITENA REGx(R0900_P1_ISIBITENA)
3470#define F0900_P1_ISI_BIT_EN 0xf55f00ff
3314 3471
3315/*P1_MATSTR1*/ 3472/*P1_MATSTR1*/
3316#define R0900_P1_MATSTR1 0xf560 3473#define R0900_P1_MATSTR1 0xf560
3317#define F0900_P1_MATYPE_CURRENT1 0xf56000ff 3474#define MATSTR1 REGx(R0900_P1_MATSTR1)
3475#define F0900_P1_MATYPE_CURRENT1 0xf56000ff
3318 3476
3319/*P1_MATSTR0*/ 3477/*P1_MATSTR0*/
3320#define R0900_P1_MATSTR0 0xf561 3478#define R0900_P1_MATSTR0 0xf561
3321#define F0900_P1_MATYPE_CURRENT0 0xf56100ff 3479#define MATSTR0 REGx(R0900_P1_MATSTR0)
3480#define F0900_P1_MATYPE_CURRENT0 0xf56100ff
3322 3481
3323/*P1_UPLSTR1*/ 3482/*P1_UPLSTR1*/
3324#define R0900_P1_UPLSTR1 0xf562 3483#define R0900_P1_UPLSTR1 0xf562
3325#define F0900_P1_UPL_CURRENT1 0xf56200ff 3484#define UPLSTR1 REGx(R0900_P1_UPLSTR1)
3485#define F0900_P1_UPL_CURRENT1 0xf56200ff
3326 3486
3327/*P1_UPLSTR0*/ 3487/*P1_UPLSTR0*/
3328#define R0900_P1_UPLSTR0 0xf563 3488#define R0900_P1_UPLSTR0 0xf563
3329#define F0900_P1_UPL_CURRENT0 0xf56300ff 3489#define UPLSTR0 REGx(R0900_P1_UPLSTR0)
3490#define F0900_P1_UPL_CURRENT0 0xf56300ff
3330 3491
3331/*P1_DFLSTR1*/ 3492/*P1_DFLSTR1*/
3332#define R0900_P1_DFLSTR1 0xf564 3493#define R0900_P1_DFLSTR1 0xf564
3333#define F0900_P1_DFL_CURRENT1 0xf56400ff 3494#define DFLSTR1 REGx(R0900_P1_DFLSTR1)
3495#define F0900_P1_DFL_CURRENT1 0xf56400ff
3334 3496
3335/*P1_DFLSTR0*/ 3497/*P1_DFLSTR0*/
3336#define R0900_P1_DFLSTR0 0xf565 3498#define R0900_P1_DFLSTR0 0xf565
3337#define F0900_P1_DFL_CURRENT0 0xf56500ff 3499#define DFLSTR0 REGx(R0900_P1_DFLSTR0)
3500#define F0900_P1_DFL_CURRENT0 0xf56500ff
3338 3501
3339/*P1_SYNCSTR*/ 3502/*P1_SYNCSTR*/
3340#define R0900_P1_SYNCSTR 0xf566 3503#define R0900_P1_SYNCSTR 0xf566
3341#define F0900_P1_SYNC_CURRENT 0xf56600ff 3504#define SYNCSTR REGx(R0900_P1_SYNCSTR)
3505#define F0900_P1_SYNC_CURRENT 0xf56600ff
3342 3506
3343/*P1_SYNCDSTR1*/ 3507/*P1_SYNCDSTR1*/
3344#define R0900_P1_SYNCDSTR1 0xf567 3508#define R0900_P1_SYNCDSTR1 0xf567
3345#define F0900_P1_SYNCD_CURRENT1 0xf56700ff 3509#define SYNCDSTR1 REGx(R0900_P1_SYNCDSTR1)
3510#define F0900_P1_SYNCD_CURRENT1 0xf56700ff
3346 3511
3347/*P1_SYNCDSTR0*/ 3512/*P1_SYNCDSTR0*/
3348#define R0900_P1_SYNCDSTR0 0xf568 3513#define R0900_P1_SYNCDSTR0 0xf568
3349#define F0900_P1_SYNCD_CURRENT0 0xf56800ff 3514#define SYNCDSTR0 REGx(R0900_P1_SYNCDSTR0)
3515#define F0900_P1_SYNCD_CURRENT0 0xf56800ff
3350 3516
3351/*P1_PDELSTATUS1*/ 3517/*P1_PDELSTATUS1*/
3352#define R0900_P1_PDELSTATUS1 0xf569 3518#define R0900_P1_PDELSTATUS1 0xf569
3353#define F0900_P1_PKTDELIN_DELOCK 0xf5690080 3519#define F0900_P1_PKTDELIN_DELOCK 0xf5690080
3354#define F0900_P1_SYNCDUPDFL_BADDFL 0xf5690040 3520#define F0900_P1_SYNCDUPDFL_BADDFL 0xf5690040
3355#define F0900_P1_CONTINUOUS_STREAM 0xf5690020 3521#define F0900_P1_CONTINUOUS_STREAM 0xf5690020
3356#define F0900_P1_UNACCEPTED_STREAM 0xf5690010 3522#define F0900_P1_UNACCEPTED_STREAM 0xf5690010
3357#define F0900_P1_BCH_ERROR_FLAG 0xf5690008 3523#define F0900_P1_BCH_ERROR_FLAG 0xf5690008
3358#define F0900_P1_BBHCRCKO 0xf5690004 3524#define F0900_P1_PKTDELIN_LOCK 0xf5690002
3359#define F0900_P1_PKTDELIN_LOCK 0xf5690002 3525#define PKTDELIN_LOCK FLDx(F0900_P1_PKTDELIN_LOCK)
3360#define F0900_P1_FIRST_LOCK 0xf5690001 3526#define F0900_P1_FIRST_LOCK 0xf5690001
3361 3527
3362/*P1_PDELSTATUS2*/ 3528/*P1_PDELSTATUS2*/
3363#define R0900_P1_PDELSTATUS2 0xf56a 3529#define R0900_P1_PDELSTATUS2 0xf56a
3364#define F0900_P1_PKTDEL_DEMODSEL 0xf56a0080 3530#define F0900_P1_FRAME_MODCOD 0xf56a007c
3365#define F0900_P1_FRAME_MODCOD 0xf56a007c 3531#define F0900_P1_FRAME_TYPE 0xf56a0003
3366#define F0900_P1_FRAME_TYPE 0xf56a0003
3367 3532
3368/*P1_BBFCRCKO1*/ 3533/*P1_BBFCRCKO1*/
3369#define R0900_P1_BBFCRCKO1 0xf56b 3534#define R0900_P1_BBFCRCKO1 0xf56b
3370#define F0900_P1_BBHCRC_KOCNT1 0xf56b00ff 3535#define BBFCRCKO1 REGx(R0900_P1_BBFCRCKO1)
3536#define F0900_P1_BBHCRC_KOCNT1 0xf56b00ff
3371 3537
3372/*P1_BBFCRCKO0*/ 3538/*P1_BBFCRCKO0*/
3373#define R0900_P1_BBFCRCKO0 0xf56c 3539#define R0900_P1_BBFCRCKO0 0xf56c
3374#define F0900_P1_BBHCRC_KOCNT0 0xf56c00ff 3540#define BBFCRCKO0 REGx(R0900_P1_BBFCRCKO0)
3541#define F0900_P1_BBHCRC_KOCNT0 0xf56c00ff
3375 3542
3376/*P1_UPCRCKO1*/ 3543/*P1_UPCRCKO1*/
3377#define R0900_P1_UPCRCKO1 0xf56d 3544#define R0900_P1_UPCRCKO1 0xf56d
3378#define F0900_P1_PKTCRC_KOCNT1 0xf56d00ff 3545#define UPCRCKO1 REGx(R0900_P1_UPCRCKO1)
3546#define F0900_P1_PKTCRC_KOCNT1 0xf56d00ff
3379 3547
3380/*P1_UPCRCKO0*/ 3548/*P1_UPCRCKO0*/
3381#define R0900_P1_UPCRCKO0 0xf56e 3549#define R0900_P1_UPCRCKO0 0xf56e
3382#define F0900_P1_PKTCRC_KOCNT0 0xf56e00ff 3550#define UPCRCKO0 REGx(R0900_P1_UPCRCKO0)
3551#define F0900_P1_PKTCRC_KOCNT0 0xf56e00ff
3552
3553/*P1_PDELCTRL3*/
3554#define R0900_P1_PDELCTRL3 0xf56f
3555#define PDELCTRL3 REGx(R0900_P1_PDELCTRL3)
3556#define F0900_P1_PKTDEL_CONTFAIL 0xf56f0080
3557#define F0900_P1_NOFIFO_BCHERR 0xf56f0020
3383 3558
3384/*P1_TSSTATEM*/ 3559/*P1_TSSTATEM*/
3385#define R0900_P1_TSSTATEM 0xf570 3560#define R0900_P1_TSSTATEM 0xf570
3386#define F0900_P1_TSDIL_ON 0xf5700080 3561#define TSSTATEM REGx(R0900_P1_TSSTATEM)
3387#define F0900_P1_TSSKIPRS_ON 0xf5700040 3562#define F0900_P1_TSDIL_ON 0xf5700080
3388#define F0900_P1_TSRS_ON 0xf5700020 3563#define F0900_P1_TSRS_ON 0xf5700020
3389#define F0900_P1_TSDESCRAMB_ON 0xf5700010 3564#define F0900_P1_TSDESCRAMB_ON 0xf5700010
3390#define F0900_P1_TSFRAME_MODE 0xf5700008 3565#define F0900_P1_TSFRAME_MODE 0xf5700008
3391#define F0900_P1_TS_DISABLE 0xf5700004 3566#define F0900_P1_TS_DISABLE 0xf5700004
3392#define F0900_P1_TSACM_MODE 0xf5700002 3567#define F0900_P1_TSOUT_NOSYNC 0xf5700001
3393#define F0900_P1_TSOUT_NOSYNC 0xf5700001
3394 3568
3395/*P1_TSCFGH*/ 3569/*P1_TSCFGH*/
3396#define R0900_P1_TSCFGH 0xf572 3570#define R0900_P1_TSCFGH 0xf572
3397#define F0900_P1_TSFIFO_DVBCI 0xf5720080 3571#define TSCFGH REGx(R0900_P1_TSCFGH)
3398#define F0900_P1_TSFIFO_SERIAL 0xf5720040 3572#define F0900_P1_TSFIFO_DVBCI 0xf5720080
3399#define F0900_P1_TSFIFO_TEIUPDATE 0xf5720020 3573#define F0900_P1_TSFIFO_SERIAL 0xf5720040
3400#define F0900_P1_TSFIFO_DUTY50 0xf5720010 3574#define F0900_P1_TSFIFO_TEIUPDATE 0xf5720020
3401#define F0900_P1_TSFIFO_HSGNLOUT 0xf5720008 3575#define F0900_P1_TSFIFO_DUTY50 0xf5720010
3402#define F0900_P1_TSFIFO_ERRMODE 0xf5720006 3576#define F0900_P1_TSFIFO_HSGNLOUT 0xf5720008
3403#define F0900_P1_RST_HWARE 0xf5720001 3577#define F0900_P1_TSFIFO_ERRMODE 0xf5720006
3578#define F0900_P1_RST_HWARE 0xf5720001
3579#define RST_HWARE FLDx(F0900_P1_RST_HWARE)
3404 3580
3405/*P1_TSCFGM*/ 3581/*P1_TSCFGM*/
3406#define R0900_P1_TSCFGM 0xf573 3582#define R0900_P1_TSCFGM 0xf573
3407#define F0900_P1_TSFIFO_MANSPEED 0xf57300c0 3583#define TSCFGM REGx(R0900_P1_TSCFGM)
3408#define F0900_P1_TSFIFO_PERMDATA 0xf5730020 3584#define F0900_P1_TSFIFO_MANSPEED 0xf57300c0
3409#define F0900_P1_TSFIFO_NONEWSGNL 0xf5730010 3585#define F0900_P1_TSFIFO_PERMDATA 0xf5730020
3410#define F0900_P1_TSFIFO_BITSPEED 0xf5730008 3586#define F0900_P1_TSFIFO_DPUNACT 0xf5730002
3411#define F0900_P1_NPD_SPECDVBS2 0xf5730004 3587#define F0900_P1_TSFIFO_INVDATA 0xf5730001
3412#define F0900_P1_TSFIFO_STOPCKDIS 0xf5730002
3413#define F0900_P1_TSFIFO_INVDATA 0xf5730001
3414 3588
3415/*P1_TSCFGL*/ 3589/*P1_TSCFGL*/
3416#define R0900_P1_TSCFGL 0xf574 3590#define R0900_P1_TSCFGL 0xf574
3417#define F0900_P1_TSFIFO_BCLKDEL1CK 0xf57400c0 3591#define TSCFGL REGx(R0900_P1_TSCFGL)
3418#define F0900_P1_BCHERROR_MODE 0xf5740030 3592#define F0900_P1_TSFIFO_BCLKDEL1CK 0xf57400c0
3419#define F0900_P1_TSFIFO_NSGNL2DATA 0xf5740008 3593#define F0900_P1_BCHERROR_MODE 0xf5740030
3420#define F0900_P1_TSFIFO_EMBINDVB 0xf5740004 3594#define F0900_P1_TSFIFO_NSGNL2DATA 0xf5740008
3421#define F0900_P1_TSFIFO_DPUNACT 0xf5740002 3595#define F0900_P1_TSFIFO_EMBINDVB 0xf5740004
3422#define F0900_P1_TSFIFO_NPDOFF 0xf5740001 3596#define F0900_P1_TSFIFO_BITSPEED 0xf5740003
3423 3597
3424/*P1_TSINSDELH*/ 3598/*P1_TSINSDELH*/
3425#define R0900_P1_TSINSDELH 0xf576 3599#define R0900_P1_TSINSDELH 0xf576
3426#define F0900_P1_TSDEL_SYNCBYTE 0xf5760080 3600#define TSINSDELH REGx(R0900_P1_TSINSDELH)
3427#define F0900_P1_TSDEL_XXHEADER 0xf5760040 3601#define F0900_P1_TSDEL_SYNCBYTE 0xf5760080
3428#define F0900_P1_TSDEL_BBHEADER 0xf5760020 3602#define F0900_P1_TSDEL_XXHEADER 0xf5760040
3429#define F0900_P1_TSDEL_DATAFIELD 0xf5760010 3603#define F0900_P1_TSDEL_BBHEADER 0xf5760020
3430#define F0900_P1_TSINSDEL_ISCR 0xf5760008 3604#define F0900_P1_TSDEL_DATAFIELD 0xf5760010
3431#define F0900_P1_TSINSDEL_NPD 0xf5760004 3605#define F0900_P1_TSINSDEL_ISCR 0xf5760008
3432#define F0900_P1_TSINSDEL_RSPARITY 0xf5760002 3606#define F0900_P1_TSINSDEL_NPD 0xf5760004
3433#define F0900_P1_TSINSDEL_CRC8 0xf5760001 3607#define F0900_P1_TSINSDEL_RSPARITY 0xf5760002
3608#define F0900_P1_TSINSDEL_CRC8 0xf5760001
3609
3610/*P1_TSDIVN*/
3611#define R0900_P1_TSDIVN 0xf579
3612#define TSDIVN REGx(R0900_P1_TSDIVN)
3613#define F0900_P1_TSFIFO_SPEEDMODE 0xf57900c0
3614
3615/*P1_TSCFG4*/
3616#define R0900_P1_TSCFG4 0xf57a
3617#define TSCFG4 REGx(R0900_P1_TSCFG4)
3618#define F0900_P1_TSFIFO_TSSPEEDMODE 0xf57a00c0
3434 3619
3435/*P1_TSSPEED*/ 3620/*P1_TSSPEED*/
3436#define R0900_P1_TSSPEED 0xf580 3621#define R0900_P1_TSSPEED 0xf580
3437#define F0900_P1_TSFIFO_OUTSPEED 0xf58000ff 3622#define TSSPEED REGx(R0900_P1_TSSPEED)
3623#define F0900_P1_TSFIFO_OUTSPEED 0xf58000ff
3438 3624
3439/*P1_TSSTATUS*/ 3625/*P1_TSSTATUS*/
3440#define R0900_P1_TSSTATUS 0xf581 3626#define R0900_P1_TSSTATUS 0xf581
3441#define F0900_P1_TSFIFO_LINEOK 0xf5810080 3627#define TSSTATUS REGx(R0900_P1_TSSTATUS)
3442#define F0900_P1_TSFIFO_ERROR 0xf5810040 3628#define F0900_P1_TSFIFO_LINEOK 0xf5810080
3443#define F0900_P1_TSFIFO_DATA7 0xf5810020 3629#define TSFIFO_LINEOK FLDx(F0900_P1_TSFIFO_LINEOK)
3444#define F0900_P1_TSFIFO_NOSYNC 0xf5810010 3630#define F0900_P1_TSFIFO_ERROR 0xf5810040
3445#define F0900_P1_ISCR_INITIALIZED 0xf5810008 3631#define F0900_P1_DIL_READY 0xf5810001
3446#define F0900_P1_ISCR_UPDATED 0xf5810004
3447#define F0900_P1_SOFFIFO_UNREGUL 0xf5810002
3448#define F0900_P1_DIL_READY 0xf5810001
3449 3632
3450/*P1_TSSTATUS2*/ 3633/*P1_TSSTATUS2*/
3451#define R0900_P1_TSSTATUS2 0xf582 3634#define R0900_P1_TSSTATUS2 0xf582
3452#define F0900_P1_TSFIFO_DEMODSEL 0xf5820080 3635#define TSSTATUS2 REGx(R0900_P1_TSSTATUS2)
3453#define F0900_P1_TSFIFOSPEED_STORE 0xf5820040 3636#define F0900_P1_TSFIFO_DEMODSEL 0xf5820080
3454#define F0900_P1_DILXX_RESET 0xf5820020 3637#define F0900_P1_TSFIFOSPEED_STORE 0xf5820040
3455#define F0900_P1_TSSERIAL_IMPOS 0xf5820010 3638#define F0900_P1_DILXX_RESET 0xf5820020
3456#define F0900_P1_TSFIFO_LINENOK 0xf5820008 3639#define F0900_P1_TSSERIAL_IMPOS 0xf5820010
3457#define F0900_P1_BITSPEED_EVENT 0xf5820004 3640#define F0900_P1_SCRAMBDETECT 0xf5820002
3458#define F0900_P1_SCRAMBDETECT 0xf5820002
3459#define F0900_P1_ULDTV67_FALSELOCK 0xf5820001
3460 3641
3461/*P1_TSBITRATE1*/ 3642/*P1_TSBITRATE1*/
3462#define R0900_P1_TSBITRATE1 0xf583 3643#define R0900_P1_TSBITRATE1 0xf583
3463#define F0900_P1_TSFIFO_BITRATE1 0xf58300ff 3644#define TSBITRATE1 REGx(R0900_P1_TSBITRATE1)
3645#define F0900_P1_TSFIFO_BITRATE1 0xf58300ff
3464 3646
3465/*P1_TSBITRATE0*/ 3647/*P1_TSBITRATE0*/
3466#define R0900_P1_TSBITRATE0 0xf584 3648#define R0900_P1_TSBITRATE0 0xf584
3467#define F0900_P1_TSFIFO_BITRATE0 0xf58400ff 3649#define TSBITRATE0 REGx(R0900_P1_TSBITRATE0)
3650#define F0900_P1_TSFIFO_BITRATE0 0xf58400ff
3468 3651
3469/*P1_ERRCTRL1*/ 3652/*P1_ERRCTRL1*/
3470#define R0900_P1_ERRCTRL1 0xf598 3653#define R0900_P1_ERRCTRL1 0xf598
3471#define F0900_P1_ERR_SOURCE1 0xf59800f0 3654#define ERRCTRL1 REGx(R0900_P1_ERRCTRL1)
3472#define F0900_P1_NUM_EVENT1 0xf5980007 3655#define F0900_P1_ERR_SOURCE1 0xf59800f0
3656#define F0900_P1_NUM_EVENT1 0xf5980007
3473 3657
3474/*P1_ERRCNT12*/ 3658/*P1_ERRCNT12*/
3475#define R0900_P1_ERRCNT12 0xf599 3659#define R0900_P1_ERRCNT12 0xf599
3476#define F0900_P1_ERRCNT1_OLDVALUE 0xf5990080 3660#define ERRCNT12 REGx(R0900_P1_ERRCNT12)
3477#define F0900_P1_ERR_CNT12 0xf599007f 3661#define F0900_P1_ERRCNT1_OLDVALUE 0xf5990080
3662#define F0900_P1_ERR_CNT12 0xf599007f
3663#define ERR_CNT12 FLDx(F0900_P1_ERR_CNT12)
3478 3664
3479/*P1_ERRCNT11*/ 3665/*P1_ERRCNT11*/
3480#define R0900_P1_ERRCNT11 0xf59a 3666#define R0900_P1_ERRCNT11 0xf59a
3481#define F0900_P1_ERR_CNT11 0xf59a00ff 3667#define ERRCNT11 REGx(R0900_P1_ERRCNT11)
3668#define F0900_P1_ERR_CNT11 0xf59a00ff
3669#define ERR_CNT11 FLDx(F0900_P1_ERR_CNT11)
3482 3670
3483/*P1_ERRCNT10*/ 3671/*P1_ERRCNT10*/
3484#define R0900_P1_ERRCNT10 0xf59b 3672#define R0900_P1_ERRCNT10 0xf59b
3485#define F0900_P1_ERR_CNT10 0xf59b00ff 3673#define ERRCNT10 REGx(R0900_P1_ERRCNT10)
3674#define F0900_P1_ERR_CNT10 0xf59b00ff
3675#define ERR_CNT10 FLDx(F0900_P1_ERR_CNT10)
3486 3676
3487/*P1_ERRCTRL2*/ 3677/*P1_ERRCTRL2*/
3488#define R0900_P1_ERRCTRL2 0xf59c 3678#define R0900_P1_ERRCTRL2 0xf59c
3489#define F0900_P1_ERR_SOURCE2 0xf59c00f0 3679#define ERRCTRL2 REGx(R0900_P1_ERRCTRL2)
3490#define F0900_P1_NUM_EVENT2 0xf59c0007 3680#define F0900_P1_ERR_SOURCE2 0xf59c00f0
3681#define F0900_P1_NUM_EVENT2 0xf59c0007
3491 3682
3492/*P1_ERRCNT22*/ 3683/*P1_ERRCNT22*/
3493#define R0900_P1_ERRCNT22 0xf59d 3684#define R0900_P1_ERRCNT22 0xf59d
3494#define F0900_P1_ERRCNT2_OLDVALUE 0xf59d0080 3685#define ERRCNT22 REGx(R0900_P1_ERRCNT22)
3495#define F0900_P1_ERR_CNT22 0xf59d007f 3686#define F0900_P1_ERRCNT2_OLDVALUE 0xf59d0080
3687#define F0900_P1_ERR_CNT22 0xf59d007f
3688#define ERR_CNT22 FLDx(F0900_P1_ERR_CNT22)
3496 3689
3497/*P1_ERRCNT21*/ 3690/*P1_ERRCNT21*/
3498#define R0900_P1_ERRCNT21 0xf59e 3691#define R0900_P1_ERRCNT21 0xf59e
3499#define F0900_P1_ERR_CNT21 0xf59e00ff 3692#define ERRCNT21 REGx(R0900_P1_ERRCNT21)
3693#define F0900_P1_ERR_CNT21 0xf59e00ff
3694#define ERR_CNT21 FLDx(F0900_P1_ERR_CNT21)
3500 3695
3501/*P1_ERRCNT20*/ 3696/*P1_ERRCNT20*/
3502#define R0900_P1_ERRCNT20 0xf59f 3697#define R0900_P1_ERRCNT20 0xf59f
3503#define F0900_P1_ERR_CNT20 0xf59f00ff 3698#define ERRCNT20 REGx(R0900_P1_ERRCNT20)
3699#define F0900_P1_ERR_CNT20 0xf59f00ff
3700#define ERR_CNT20 FLDx(F0900_P1_ERR_CNT20)
3504 3701
3505/*P1_FECSPY*/ 3702/*P1_FECSPY*/
3506#define R0900_P1_FECSPY 0xf5a0 3703#define R0900_P1_FECSPY 0xf5a0
3507#define F0900_P1_SPY_ENABLE 0xf5a00080 3704#define FECSPY REGx(R0900_P1_FECSPY)
3508#define F0900_P1_NO_SYNCBYTE 0xf5a00040 3705#define F0900_P1_SPY_ENABLE 0xf5a00080
3509#define F0900_P1_SERIAL_MODE 0xf5a00020 3706#define F0900_P1_NO_SYNCBYTE 0xf5a00040
3510#define F0900_P1_UNUSUAL_PACKET 0xf5a00010 3707#define F0900_P1_SERIAL_MODE 0xf5a00020
3511#define F0900_P1_BER_PACKMODE 0xf5a00008 3708#define F0900_P1_UNUSUAL_PACKET 0xf5a00010
3512#define F0900_P1_BERMETER_LMODE 0xf5a00002 3709#define F0900_P1_BERMETER_DATAMODE 0xf5a00008
3513#define F0900_P1_BERMETER_RESET 0xf5a00001 3710#define F0900_P1_BERMETER_LMODE 0xf5a00002
3711#define F0900_P1_BERMETER_RESET 0xf5a00001
3514 3712
3515/*P1_FSPYCFG*/ 3713/*P1_FSPYCFG*/
3516#define R0900_P1_FSPYCFG 0xf5a1 3714#define R0900_P1_FSPYCFG 0xf5a1
3517#define F0900_P1_FECSPY_INPUT 0xf5a100c0 3715#define FSPYCFG REGx(R0900_P1_FSPYCFG)
3518#define F0900_P1_RST_ON_ERROR 0xf5a10020 3716#define F0900_P1_FECSPY_INPUT 0xf5a100c0
3519#define F0900_P1_ONE_SHOT 0xf5a10010 3717#define F0900_P1_RST_ON_ERROR 0xf5a10020
3520#define F0900_P1_I2C_MODE 0xf5a1000c 3718#define F0900_P1_ONE_SHOT 0xf5a10010
3521#define F0900_P1_SPY_HYSTERESIS 0xf5a10003 3719#define F0900_P1_I2C_MODE 0xf5a1000c
3720#define F0900_P1_SPY_HYSTERESIS 0xf5a10003
3522 3721
3523/*P1_FSPYDATA*/ 3722/*P1_FSPYDATA*/
3524#define R0900_P1_FSPYDATA 0xf5a2 3723#define R0900_P1_FSPYDATA 0xf5a2
3525#define F0900_P1_SPY_STUFFING 0xf5a20080 3724#define FSPYDATA REGx(R0900_P1_FSPYDATA)
3526#define F0900_P1_NOERROR_PKTJITTER 0xf5a20040 3725#define F0900_P1_SPY_STUFFING 0xf5a20080
3527#define F0900_P1_SPY_CNULLPKT 0xf5a20020 3726#define F0900_P1_SPY_CNULLPKT 0xf5a20020
3528#define F0900_P1_SPY_OUTDATA_MODE 0xf5a2001f 3727#define F0900_P1_SPY_OUTDATA_MODE 0xf5a2001f
3529 3728
3530/*P1_FSPYOUT*/ 3729/*P1_FSPYOUT*/
3531#define R0900_P1_FSPYOUT 0xf5a3 3730#define R0900_P1_FSPYOUT 0xf5a3
3532#define F0900_P1_FSPY_DIRECT 0xf5a30080 3731#define FSPYOUT REGx(R0900_P1_FSPYOUT)
3533#define F0900_P1_SPY_OUTDATA_BUS 0xf5a30038 3732#define F0900_P1_FSPY_DIRECT 0xf5a30080
3534#define F0900_P1_STUFF_MODE 0xf5a30007 3733#define F0900_P1_STUFF_MODE 0xf5a30007
3535 3734
3536/*P1_FSTATUS*/ 3735/*P1_FSTATUS*/
3537#define R0900_P1_FSTATUS 0xf5a4 3736#define R0900_P1_FSTATUS 0xf5a4
3538#define F0900_P1_SPY_ENDSIM 0xf5a40080 3737#define FSTATUS REGx(R0900_P1_FSTATUS)
3539#define F0900_P1_VALID_SIM 0xf5a40040 3738#define F0900_P1_SPY_ENDSIM 0xf5a40080
3540#define F0900_P1_FOUND_SIGNAL 0xf5a40020 3739#define F0900_P1_VALID_SIM 0xf5a40040
3541#define F0900_P1_DSS_SYNCBYTE 0xf5a40010 3740#define F0900_P1_FOUND_SIGNAL 0xf5a40020
3542#define F0900_P1_RESULT_STATE 0xf5a4000f 3741#define F0900_P1_DSS_SYNCBYTE 0xf5a40010
3742#define F0900_P1_RESULT_STATE 0xf5a4000f
3543 3743
3544/*P1_FBERCPT4*/ 3744/*P1_FBERCPT4*/
3545#define R0900_P1_FBERCPT4 0xf5a8 3745#define R0900_P1_FBERCPT4 0xf5a8
3546#define F0900_P1_FBERMETER_CPT4 0xf5a800ff 3746#define FBERCPT4 REGx(R0900_P1_FBERCPT4)
3747#define F0900_P1_FBERMETER_CPT4 0xf5a800ff
3547 3748
3548/*P1_FBERCPT3*/ 3749/*P1_FBERCPT3*/
3549#define R0900_P1_FBERCPT3 0xf5a9 3750#define R0900_P1_FBERCPT3 0xf5a9
3550#define F0900_P1_FBERMETER_CPT3 0xf5a900ff 3751#define FBERCPT3 REGx(R0900_P1_FBERCPT3)
3752#define F0900_P1_FBERMETER_CPT3 0xf5a900ff
3551 3753
3552/*P1_FBERCPT2*/ 3754/*P1_FBERCPT2*/
3553#define R0900_P1_FBERCPT2 0xf5aa 3755#define R0900_P1_FBERCPT2 0xf5aa
3554#define F0900_P1_FBERMETER_CPT2 0xf5aa00ff 3756#define FBERCPT2 REGx(R0900_P1_FBERCPT2)
3757#define F0900_P1_FBERMETER_CPT2 0xf5aa00ff
3555 3758
3556/*P1_FBERCPT1*/ 3759/*P1_FBERCPT1*/
3557#define R0900_P1_FBERCPT1 0xf5ab 3760#define R0900_P1_FBERCPT1 0xf5ab
3558#define F0900_P1_FBERMETER_CPT1 0xf5ab00ff 3761#define FBERCPT1 REGx(R0900_P1_FBERCPT1)
3762#define F0900_P1_FBERMETER_CPT1 0xf5ab00ff
3559 3763
3560/*P1_FBERCPT0*/ 3764/*P1_FBERCPT0*/
3561#define R0900_P1_FBERCPT0 0xf5ac 3765#define R0900_P1_FBERCPT0 0xf5ac
3562#define F0900_P1_FBERMETER_CPT0 0xf5ac00ff 3766#define FBERCPT0 REGx(R0900_P1_FBERCPT0)
3767#define F0900_P1_FBERMETER_CPT0 0xf5ac00ff
3563 3768
3564/*P1_FBERERR2*/ 3769/*P1_FBERERR2*/
3565#define R0900_P1_FBERERR2 0xf5ad 3770#define R0900_P1_FBERERR2 0xf5ad
3566#define F0900_P1_FBERMETER_ERR2 0xf5ad00ff 3771#define FBERERR2 REGx(R0900_P1_FBERERR2)
3772#define F0900_P1_FBERMETER_ERR2 0xf5ad00ff
3567 3773
3568/*P1_FBERERR1*/ 3774/*P1_FBERERR1*/
3569#define R0900_P1_FBERERR1 0xf5ae 3775#define R0900_P1_FBERERR1 0xf5ae
3570#define F0900_P1_FBERMETER_ERR1 0xf5ae00ff 3776#define FBERERR1 REGx(R0900_P1_FBERERR1)
3777#define F0900_P1_FBERMETER_ERR1 0xf5ae00ff
3571 3778
3572/*P1_FBERERR0*/ 3779/*P1_FBERERR0*/
3573#define R0900_P1_FBERERR0 0xf5af 3780#define R0900_P1_FBERERR0 0xf5af
3574#define F0900_P1_FBERMETER_ERR0 0xf5af00ff 3781#define FBERERR0 REGx(R0900_P1_FBERERR0)
3782#define F0900_P1_FBERMETER_ERR0 0xf5af00ff
3575 3783
3576/*P1_FSPYBER*/ 3784/*P1_FSPYBER*/
3577#define R0900_P1_FSPYBER 0xf5b2 3785#define R0900_P1_FSPYBER 0xf5b2
3578#define F0900_P1_FSPYOBS_XORREAD 0xf5b20040 3786#define FSPYBER REGx(R0900_P1_FSPYBER)
3579#define F0900_P1_FSPYBER_OBSMODE 0xf5b20020 3787#define F0900_P1_FSPYBER_SYNCBYTE 0xf5b20010
3580#define F0900_P1_FSPYBER_SYNCBYTE 0xf5b20010 3788#define F0900_P1_FSPYBER_UNSYNC 0xf5b20008
3581#define F0900_P1_FSPYBER_UNSYNC 0xf5b20008 3789#define F0900_P1_FSPYBER_CTIME 0xf5b20007
3582#define F0900_P1_FSPYBER_CTIME 0xf5b20007 3790
3583 3791/*RCCFG2*/
3584/*RCCFGH*/ 3792#define R0900_RCCFG2 0xf600
3585#define R0900_RCCFGH 0xf600
3586#define F0900_TSRCFIFO_DVBCI 0xf6000080
3587#define F0900_TSRCFIFO_SERIAL 0xf6000040
3588#define F0900_TSRCFIFO_DISABLE 0xf6000020
3589#define F0900_TSFIFO_2TORC 0xf6000010
3590#define F0900_TSRCFIFO_HSGNLOUT 0xf6000008
3591#define F0900_TSRCFIFO_ERRMODE 0xf6000006
3592 3793
3593/*TSGENERAL*/ 3794/*TSGENERAL*/
3594#define R0900_TSGENERAL 0xf630 3795#define R0900_TSGENERAL 0xf630
3595#define F0900_TSFIFO_BCLK1ALL 0xf6300020 3796#define F0900_TSFIFO_DISTS2PAR 0xf6300040
3596#define F0900_MUXSTREAM_OUTMODE 0xf6300008 3797#define F0900_MUXSTREAM_OUTMODE 0xf6300008
3597#define F0900_TSFIFO_PERMPARAL 0xf6300006 3798#define F0900_TSFIFO_PERMPARAL 0xf6300006
3598#define F0900_RST_REEDSOLO 0xf6300001
3599 3799
3600/*TSGENERAL1X*/ 3800/*TSGENERAL1X*/
3601#define R0900_TSGENERAL1X 0xf670 3801#define R0900_TSGENERAL1X 0xf670
3602#define F0900_TSFIFO1X_BCLK1ALL 0xf6700020
3603#define F0900_MUXSTREAM1X_OUTMODE 0xf6700008
3604#define F0900_TSFIFO1X_PERMPARAL 0xf6700006
3605#define F0900_RST1X_REEDSOLO 0xf6700001
3606 3802
3607/*NBITER_NF4*/ 3803/*NBITER_NF4*/
3608#define R0900_NBITER_NF4 0xfa03 3804#define R0900_NBITER_NF4 0xfa03
3609#define F0900_NBITER_NF_QP_1_2 0xfa0300ff 3805#define F0900_NBITER_NF_QP_1_2 0xfa0300ff
3610 3806
3611/*NBITER_NF5*/ 3807/*NBITER_NF5*/
3612#define R0900_NBITER_NF5 0xfa04 3808#define R0900_NBITER_NF5 0xfa04
3613#define F0900_NBITER_NF_QP_3_5 0xfa0400ff 3809#define F0900_NBITER_NF_QP_3_5 0xfa0400ff
3614 3810
3615/*NBITER_NF6*/ 3811/*NBITER_NF6*/
3616#define R0900_NBITER_NF6 0xfa05 3812#define R0900_NBITER_NF6 0xfa05
3617#define F0900_NBITER_NF_QP_2_3 0xfa0500ff 3813#define F0900_NBITER_NF_QP_2_3 0xfa0500ff
3618 3814
3619/*NBITER_NF7*/ 3815/*NBITER_NF7*/
3620#define R0900_NBITER_NF7 0xfa06 3816#define R0900_NBITER_NF7 0xfa06
3621#define F0900_NBITER_NF_QP_3_4 0xfa0600ff 3817#define F0900_NBITER_NF_QP_3_4 0xfa0600ff
3622 3818
3623/*NBITER_NF8*/ 3819/*NBITER_NF8*/
3624#define R0900_NBITER_NF8 0xfa07 3820#define R0900_NBITER_NF8 0xfa07
3625#define F0900_NBITER_NF_QP_4_5 0xfa0700ff 3821#define F0900_NBITER_NF_QP_4_5 0xfa0700ff
3626 3822
3627/*NBITER_NF9*/ 3823/*NBITER_NF9*/
3628#define R0900_NBITER_NF9 0xfa08 3824#define R0900_NBITER_NF9 0xfa08
3629#define F0900_NBITER_NF_QP_5_6 0xfa0800ff 3825#define F0900_NBITER_NF_QP_5_6 0xfa0800ff
3630 3826
3631/*NBITER_NF10*/ 3827/*NBITER_NF10*/
3632#define R0900_NBITER_NF10 0xfa09 3828#define R0900_NBITER_NF10 0xfa09
3633#define F0900_NBITER_NF_QP_8_9 0xfa0900ff 3829#define F0900_NBITER_NF_QP_8_9 0xfa0900ff
3634 3830
3635/*NBITER_NF11*/ 3831/*NBITER_NF11*/
3636#define R0900_NBITER_NF11 0xfa0a 3832#define R0900_NBITER_NF11 0xfa0a
3637#define F0900_NBITER_NF_QP_9_10 0xfa0a00ff 3833#define F0900_NBITER_NF_QP_9_10 0xfa0a00ff
3638 3834
3639/*NBITER_NF12*/ 3835/*NBITER_NF12*/
3640#define R0900_NBITER_NF12 0xfa0b 3836#define R0900_NBITER_NF12 0xfa0b
3641#define F0900_NBITER_NF_8P_3_5 0xfa0b00ff 3837#define F0900_NBITER_NF_8P_3_5 0xfa0b00ff
3642 3838
3643/*NBITER_NF13*/ 3839/*NBITER_NF13*/
3644#define R0900_NBITER_NF13 0xfa0c 3840#define R0900_NBITER_NF13 0xfa0c
3645#define F0900_NBITER_NF_8P_2_3 0xfa0c00ff 3841#define F0900_NBITER_NF_8P_2_3 0xfa0c00ff
3646 3842
3647/*NBITER_NF14*/ 3843/*NBITER_NF14*/
3648#define R0900_NBITER_NF14 0xfa0d 3844#define R0900_NBITER_NF14 0xfa0d
3649#define F0900_NBITER_NF_8P_3_4 0xfa0d00ff 3845#define F0900_NBITER_NF_8P_3_4 0xfa0d00ff
3650 3846
3651/*NBITER_NF15*/ 3847/*NBITER_NF15*/
3652#define R0900_NBITER_NF15 0xfa0e 3848#define R0900_NBITER_NF15 0xfa0e
3653#define F0900_NBITER_NF_8P_5_6 0xfa0e00ff 3849#define F0900_NBITER_NF_8P_5_6 0xfa0e00ff
3654 3850
3655/*NBITER_NF16*/ 3851/*NBITER_NF16*/
3656#define R0900_NBITER_NF16 0xfa0f 3852#define R0900_NBITER_NF16 0xfa0f
3657#define F0900_NBITER_NF_8P_8_9 0xfa0f00ff 3853#define F0900_NBITER_NF_8P_8_9 0xfa0f00ff
3658 3854
3659/*NBITER_NF17*/ 3855/*NBITER_NF17*/
3660#define R0900_NBITER_NF17 0xfa10 3856#define R0900_NBITER_NF17 0xfa10
3661#define F0900_NBITER_NF_8P_9_10 0xfa1000ff 3857#define F0900_NBITER_NF_8P_9_10 0xfa1000ff
3662 3858
3663/*NBITERNOERR*/ 3859/*NBITERNOERR*/
3664#define R0900_NBITERNOERR 0xfa3f 3860#define R0900_NBITERNOERR 0xfa3f
3665#define F0900_NBITER_STOP_CRIT 0xfa3f000f 3861#define F0900_NBITER_STOP_CRIT 0xfa3f000f
3666 3862
3667/*GAINLLR_NF4*/ 3863/*GAINLLR_NF4*/
3668#define R0900_GAINLLR_NF4 0xfa43 3864#define R0900_GAINLLR_NF4 0xfa43
3669#define F0900_GAINLLR_NF_QP_1_2 0xfa43007f 3865#define F0900_GAINLLR_NF_QP_1_2 0xfa43007f
3670 3866
3671/*GAINLLR_NF5*/ 3867/*GAINLLR_NF5*/
3672#define R0900_GAINLLR_NF5 0xfa44 3868#define R0900_GAINLLR_NF5 0xfa44
3673#define F0900_GAINLLR_NF_QP_3_5 0xfa44007f 3869#define F0900_GAINLLR_NF_QP_3_5 0xfa44007f
3674 3870
3675/*GAINLLR_NF6*/ 3871/*GAINLLR_NF6*/
3676#define R0900_GAINLLR_NF6 0xfa45 3872#define R0900_GAINLLR_NF6 0xfa45
3677#define F0900_GAINLLR_NF_QP_2_3 0xfa45007f 3873#define F0900_GAINLLR_NF_QP_2_3 0xfa45007f
3678 3874
3679/*GAINLLR_NF7*/ 3875/*GAINLLR_NF7*/
3680#define R0900_GAINLLR_NF7 0xfa46 3876#define R0900_GAINLLR_NF7 0xfa46
3681#define F0900_GAINLLR_NF_QP_3_4 0xfa46007f 3877#define F0900_GAINLLR_NF_QP_3_4 0xfa46007f
3682 3878
3683/*GAINLLR_NF8*/ 3879/*GAINLLR_NF8*/
3684#define R0900_GAINLLR_NF8 0xfa47 3880#define R0900_GAINLLR_NF8 0xfa47
3685#define F0900_GAINLLR_NF_QP_4_5 0xfa47007f 3881#define F0900_GAINLLR_NF_QP_4_5 0xfa47007f
3686 3882
3687/*GAINLLR_NF9*/ 3883/*GAINLLR_NF9*/
3688#define R0900_GAINLLR_NF9 0xfa48 3884#define R0900_GAINLLR_NF9 0xfa48
3689#define F0900_GAINLLR_NF_QP_5_6 0xfa48007f 3885#define F0900_GAINLLR_NF_QP_5_6 0xfa48007f
3690 3886
3691/*GAINLLR_NF10*/ 3887/*GAINLLR_NF10*/
3692#define R0900_GAINLLR_NF10 0xfa49 3888#define R0900_GAINLLR_NF10 0xfa49
3693#define F0900_GAINLLR_NF_QP_8_9 0xfa49007f 3889#define F0900_GAINLLR_NF_QP_8_9 0xfa49007f
3694 3890
3695/*GAINLLR_NF11*/ 3891/*GAINLLR_NF11*/
3696#define R0900_GAINLLR_NF11 0xfa4a 3892#define R0900_GAINLLR_NF11 0xfa4a
3697#define F0900_GAINLLR_NF_QP_9_10 0xfa4a007f 3893#define F0900_GAINLLR_NF_QP_9_10 0xfa4a007f
3698 3894
3699/*GAINLLR_NF12*/ 3895/*GAINLLR_NF12*/
3700#define R0900_GAINLLR_NF12 0xfa4b 3896#define R0900_GAINLLR_NF12 0xfa4b
3701#define F0900_GAINLLR_NF_8P_3_5 0xfa4b007f 3897#define F0900_GAINLLR_NF_8P_3_5 0xfa4b007f
3702 3898
3703/*GAINLLR_NF13*/ 3899/*GAINLLR_NF13*/
3704#define R0900_GAINLLR_NF13 0xfa4c 3900#define R0900_GAINLLR_NF13 0xfa4c
3705#define F0900_GAINLLR_NF_8P_2_3 0xfa4c007f 3901#define F0900_GAINLLR_NF_8P_2_3 0xfa4c007f
3706 3902
3707/*GAINLLR_NF14*/ 3903/*GAINLLR_NF14*/
3708#define R0900_GAINLLR_NF14 0xfa4d 3904#define R0900_GAINLLR_NF14 0xfa4d
3709#define F0900_GAINLLR_NF_8P_3_4 0xfa4d007f 3905#define F0900_GAINLLR_NF_8P_3_4 0xfa4d007f
3710 3906
3711/*GAINLLR_NF15*/ 3907/*GAINLLR_NF15*/
3712#define R0900_GAINLLR_NF15 0xfa4e 3908#define R0900_GAINLLR_NF15 0xfa4e
3713#define F0900_GAINLLR_NF_8P_5_6 0xfa4e007f 3909#define F0900_GAINLLR_NF_8P_5_6 0xfa4e007f
3714 3910
3715/*GAINLLR_NF16*/ 3911/*GAINLLR_NF16*/
3716#define R0900_GAINLLR_NF16 0xfa4f 3912#define R0900_GAINLLR_NF16 0xfa4f
3717#define F0900_GAINLLR_NF_8P_8_9 0xfa4f007f 3913#define F0900_GAINLLR_NF_8P_8_9 0xfa4f007f
3718 3914
3719/*GAINLLR_NF17*/ 3915/*GAINLLR_NF17*/
3720#define R0900_GAINLLR_NF17 0xfa50 3916#define R0900_GAINLLR_NF17 0xfa50
3721#define F0900_GAINLLR_NF_8P_9_10 0xfa50007f 3917#define F0900_GAINLLR_NF_8P_9_10 0xfa50007f
3722 3918
3723/*CFGEXT*/ 3919/*CFGEXT*/
3724#define R0900_CFGEXT 0xfa80 3920#define R0900_CFGEXT 0xfa80
3725#define F0900_STAGMODE 0xfa800080 3921#define F0900_STAGMODE 0xfa800080
3726#define F0900_BYPBCH 0xfa800040 3922#define F0900_BYPBCH 0xfa800040
3727#define F0900_BYPLDPC 0xfa800020 3923#define F0900_BYPLDPC 0xfa800020
3728#define F0900_LDPCMODE 0xfa800010 3924#define F0900_LDPCMODE 0xfa800010
3729#define F0900_INVLLRSIGN 0xfa800008 3925#define F0900_INVLLRSIGN 0xfa800008
3730#define F0900_SHORTMULT 0xfa800004 3926#define F0900_SHORTMULT 0xfa800004
3731#define F0900_EXTERNTX 0xfa800001 3927#define F0900_EXTERNTX 0xfa800001
3732 3928
3733/*GENCFG*/ 3929/*GENCFG*/
3734#define R0900_GENCFG 0xfa86 3930#define R0900_GENCFG 0xfa86
3735#define F0900_BROADCAST 0xfa860010 3931#define F0900_BROADCAST 0xfa860010
3736#define F0900_NOSHFRD2 0xfa860008 3932#define F0900_PRIORITY 0xfa860002
3737#define F0900_BCHERRFLAG 0xfa860004 3933#define F0900_DDEMOD 0xfa860001
3738#define F0900_PRIORITY 0xfa860002
3739#define F0900_DDEMOD 0xfa860001
3740 3934
3741/*LDPCERR1*/ 3935/*LDPCERR1*/
3742#define R0900_LDPCERR1 0xfa96 3936#define R0900_LDPCERR1 0xfa96
3743#define F0900_LDPC_ERRORS_COUNTER1 0xfa9600ff 3937#define F0900_LDPC_ERRORS_COUNTER1 0xfa9600ff
3744 3938
3745/*LDPCERR0*/ 3939/*LDPCERR0*/
3746#define R0900_LDPCERR0 0xfa97 3940#define R0900_LDPCERR0 0xfa97
3747#define F0900_LDPC_ERRORS_COUNTER0 0xfa9700ff 3941#define F0900_LDPC_ERRORS_COUNTER0 0xfa9700ff
3748 3942
3749/*BCHERR*/ 3943/*BCHERR*/
3750#define R0900_BCHERR 0xfa98 3944#define R0900_BCHERR 0xfa98
3751#define F0900_ERRORFLAG 0xfa980010 3945#define F0900_ERRORFLAG 0xfa980010
3752#define F0900_BCH_ERRORS_COUNTER 0xfa98000f 3946#define F0900_BCH_ERRORS_COUNTER 0xfa98000f
3753 3947
3754/*TSTRES0*/ 3948/*TSTRES0*/
3755#define R0900_TSTRES0 0xff11 3949#define R0900_TSTRES0 0xff11
3756#define F0900_FRESFEC 0xff110080 3950#define F0900_FRESFEC 0xff110080
3757#define F0900_FRESTS 0xff110040 3951
3758#define F0900_FRESVIT1 0xff110020 3952/*P2_TCTL4*/
3759#define F0900_FRESVIT2 0xff110010 3953#define R0900_P2_TCTL4 0xff28
3760#define F0900_FRESSYM1 0xff110008 3954#define F0900_P2_PN4_SELECT 0xff280020
3761#define F0900_FRESSYM2 0xff110004 3955
3762#define F0900_FRESMAS 0xff110002 3956/*P1_TCTL4*/
3763#define F0900_FRESINT 0xff110001 3957#define R0900_P1_TCTL4 0xff48
3958#define TCTL4 shiftx(R0900_P1_TCTL4, demod, 0x20)
3959#define F0900_P1_PN4_SELECT 0xff480020
3764 3960
3765/*P2_TSTDISRX*/ 3961/*P2_TSTDISRX*/
3766#define R0900_P2_TSTDISRX 0xff65 3962#define R0900_P2_TSTDISRX 0xff65
3767#define F0900_P2_EN_DISRX 0xff650080 3963#define F0900_P2_PIN_SELECT1 0xff650008
3768#define F0900_P2_TST_CURRSRC 0xff650040
3769#define F0900_P2_IN_DIGSIGNAL 0xff650020
3770#define F0900_P2_HIZ_CURRENTSRC 0xff650010
3771#define F0900_TST_P2_PIN_SELECT 0xff650008
3772#define F0900_P2_TST_DISRX 0xff650007
3773 3964
3774/*P1_TSTDISRX*/ 3965/*P1_TSTDISRX*/
3775#define R0900_P1_TSTDISRX 0xff67 3966#define R0900_P1_TSTDISRX 0xff67
3776#define F0900_P1_EN_DISRX 0xff670080 3967#define TSTDISRX shiftx(R0900_P1_TSTDISRX, demod, 2)
3777#define F0900_P1_TST_CURRSRC 0xff670040 3968#define F0900_P1_PIN_SELECT1 0xff670008
3778#define F0900_P1_IN_DIGSIGNAL 0xff670020 3969#define PIN_SELECT1 shiftx(F0900_P1_PIN_SELECT1, demod, 0x20000)
3779#define F0900_P1_HIZ_CURRENTSRC 0xff670010 3970
3780#define F0900_TST_P1_PIN_SELECT 0xff670008 3971#define STV0900_NBREGS 723
3781#define F0900_P1_TST_DISRX 0xff670007 3972#define STV0900_NBFIELDS 1420
3782
3783#define STV0900_NBREGS 684
3784#define STV0900_NBFIELDS 1702
3785 3973
3786#endif 3974#endif
3787 3975
diff --git a/drivers/media/dvb/frontends/stv0900_sw.c b/drivers/media/dvb/frontends/stv0900_sw.c
index 962fde1437ce..b8da87fa637f 100644
--- a/drivers/media/dvb/frontends/stv0900_sw.c
+++ b/drivers/media/dvb/frontends/stv0900_sw.c
@@ -27,56 +27,45 @@
27#include "stv0900_reg.h" 27#include "stv0900_reg.h"
28#include "stv0900_priv.h" 28#include "stv0900_priv.h"
29 29
30int stv0900_check_signal_presence(struct stv0900_internal *i_params, 30s32 shiftx(s32 x, int demod, s32 shift)
31{
32 if (demod == 1)
33 return x - shift;
34
35 return x;
36}
37
38int stv0900_check_signal_presence(struct stv0900_internal *intp,
31 enum fe_stv0900_demod_num demod) 39 enum fe_stv0900_demod_num demod)
32{ 40{
33 s32 carr_offset, 41 s32 carr_offset,
34 agc2_integr, 42 agc2_integr,
35 max_carrier; 43 max_carrier;
36 44
37 int no_signal; 45 int no_signal = FALSE;
38 46
39 switch (demod) { 47 carr_offset = (stv0900_read_reg(intp, CFR2) << 8)
40 case STV0900_DEMOD_1: 48 | stv0900_read_reg(intp, CFR1);
41 default: 49 carr_offset = ge2comp(carr_offset, 16);
42 carr_offset = (stv0900_read_reg(i_params, R0900_P1_CFR2) << 8) 50 agc2_integr = (stv0900_read_reg(intp, AGC2I1) << 8)
43 | stv0900_read_reg(i_params, 51 | stv0900_read_reg(intp, AGC2I0);
44 R0900_P1_CFR1); 52 max_carrier = intp->srch_range[demod] / 1000;
45 carr_offset = ge2comp(carr_offset, 16);
46 agc2_integr = (stv0900_read_reg(i_params, R0900_P1_AGC2I1) << 8)
47 | stv0900_read_reg(i_params,
48 R0900_P1_AGC2I0);
49 max_carrier = i_params->dmd1_srch_range / 1000;
50 break;
51 case STV0900_DEMOD_2:
52 carr_offset = (stv0900_read_reg(i_params, R0900_P2_CFR2) << 8)
53 | stv0900_read_reg(i_params,
54 R0900_P2_CFR1);
55 carr_offset = ge2comp(carr_offset, 16);
56 agc2_integr = (stv0900_read_reg(i_params, R0900_P2_AGC2I1) << 8)
57 | stv0900_read_reg(i_params,
58 R0900_P2_AGC2I0);
59 max_carrier = i_params->dmd2_srch_range / 1000;
60 break;
61 }
62 53
63 max_carrier += (max_carrier / 10); 54 max_carrier += (max_carrier / 10);
64 max_carrier = 65536 * (max_carrier / 2); 55 max_carrier = 65536 * (max_carrier / 2);
65 max_carrier /= i_params->mclk / 1000; 56 max_carrier /= intp->mclk / 1000;
66 if (max_carrier > 0x4000) 57 if (max_carrier > 0x4000)
67 max_carrier = 0x4000; 58 max_carrier = 0x4000;
68 59
69 if ((agc2_integr > 0x2000) 60 if ((agc2_integr > 0x2000)
70 || (carr_offset > + 2*max_carrier) 61 || (carr_offset > (2 * max_carrier))
71 || (carr_offset < -2*max_carrier)) 62 || (carr_offset < (-2 * max_carrier)))
72 no_signal = TRUE; 63 no_signal = TRUE;
73 else
74 no_signal = FALSE;
75 64
76 return no_signal; 65 return no_signal;
77} 66}
78 67
79static void stv0900_get_sw_loop_params(struct stv0900_internal *i_params, 68static void stv0900_get_sw_loop_params(struct stv0900_internal *intp,
80 s32 *frequency_inc, s32 *sw_timeout, 69 s32 *frequency_inc, s32 *sw_timeout,
81 s32 *steps, 70 s32 *steps,
82 enum fe_stv0900_demod_num demod) 71 enum fe_stv0900_demod_num demod)
@@ -85,30 +74,19 @@ static void stv0900_get_sw_loop_params(struct stv0900_internal *i_params,
85 74
86 enum fe_stv0900_search_standard standard; 75 enum fe_stv0900_search_standard standard;
87 76
88 switch (demod) { 77 srate = intp->symbol_rate[demod];
89 case STV0900_DEMOD_1: 78 max_carrier = intp->srch_range[demod] / 1000;
90 default: 79 max_carrier += max_carrier / 10;
91 srate = i_params->dmd1_symbol_rate; 80 standard = intp->srch_standard[demod];
92 max_carrier = i_params->dmd1_srch_range / 1000;
93 max_carrier += max_carrier / 10;
94 standard = i_params->dmd1_srch_standard;
95 break;
96 case STV0900_DEMOD_2:
97 srate = i_params->dmd2_symbol_rate;
98 max_carrier = i_params->dmd2_srch_range / 1000;
99 max_carrier += max_carrier / 10;
100 standard = i_params->dmd2_srch_stndrd;
101 break;
102 }
103 81
104 max_carrier = 65536 * (max_carrier / 2); 82 max_carrier = 65536 * (max_carrier / 2);
105 max_carrier /= i_params->mclk / 1000; 83 max_carrier /= intp->mclk / 1000;
106 84
107 if (max_carrier > 0x4000) 85 if (max_carrier > 0x4000)
108 max_carrier = 0x4000; 86 max_carrier = 0x4000;
109 87
110 freq_inc = srate; 88 freq_inc = srate;
111 freq_inc /= i_params->mclk >> 10; 89 freq_inc /= intp->mclk >> 10;
112 freq_inc = freq_inc << 6; 90 freq_inc = freq_inc << 6;
113 91
114 switch (standard) { 92 switch (standard) {
@@ -154,7 +132,7 @@ static void stv0900_get_sw_loop_params(struct stv0900_internal *i_params,
154 132
155} 133}
156 134
157static int stv0900_search_carr_sw_loop(struct stv0900_internal *i_params, 135static int stv0900_search_carr_sw_loop(struct stv0900_internal *intp,
158 s32 FreqIncr, s32 Timeout, int zigzag, 136 s32 FreqIncr, s32 Timeout, int zigzag,
159 s32 MaxStep, enum fe_stv0900_demod_num demod) 137 s32 MaxStep, enum fe_stv0900_demod_num demod)
160{ 138{
@@ -164,20 +142,11 @@ static int stv0900_search_carr_sw_loop(struct stv0900_internal *i_params,
164 freqOffset, 142 freqOffset,
165 max_carrier; 143 max_carrier;
166 144
167 switch (demod) { 145 max_carrier = intp->srch_range[demod] / 1000;
168 case STV0900_DEMOD_1: 146 max_carrier += (max_carrier / 10);
169 default:
170 max_carrier = i_params->dmd1_srch_range / 1000;
171 max_carrier += (max_carrier / 10);
172 break;
173 case STV0900_DEMOD_2:
174 max_carrier = i_params->dmd2_srch_range / 1000;
175 max_carrier += (max_carrier / 10);
176 break;
177 }
178 147
179 max_carrier = 65536 * (max_carrier / 2); 148 max_carrier = 65536 * (max_carrier / 2);
180 max_carrier /= i_params->mclk / 1000; 149 max_carrier /= intp->mclk / 1000;
181 150
182 if (max_carrier > 0x4000) 151 if (max_carrier > 0x4000)
183 max_carrier = 0x4000; 152 max_carrier = 0x4000;
@@ -190,40 +159,15 @@ static int stv0900_search_carr_sw_loop(struct stv0900_internal *i_params,
190 stepCpt = 0; 159 stepCpt = 0;
191 160
192 do { 161 do {
193 switch (demod) { 162 stv0900_write_reg(intp, DMDISTATE, 0x1c);
194 case STV0900_DEMOD_1: 163 stv0900_write_reg(intp, CFRINIT1, (freqOffset / 256) & 0xff);
195 default: 164 stv0900_write_reg(intp, CFRINIT0, freqOffset & 0xff);
196 stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1C); 165 stv0900_write_reg(intp, DMDISTATE, 0x18);
197 stv0900_write_reg(i_params, R0900_P1_CFRINIT1, 166 stv0900_write_bits(intp, ALGOSWRST, 1);
198 (freqOffset / 256) & 0xFF); 167
199 stv0900_write_reg(i_params, R0900_P1_CFRINIT0, 168 if (intp->chip_id == 0x12) {
200 freqOffset & 0xFF); 169 stv0900_write_bits(intp, RST_HWARE, 1);
201 stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x18); 170 stv0900_write_bits(intp, RST_HWARE, 0);
202 stv0900_write_bits(i_params, F0900_P1_ALGOSWRST, 1);
203
204 if (i_params->chip_id == 0x12) {
205 stv0900_write_bits(i_params,
206 F0900_P1_RST_HWARE, 1);
207 stv0900_write_bits(i_params,
208 F0900_P1_RST_HWARE, 0);
209 }
210 break;
211 case STV0900_DEMOD_2:
212 stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1C);
213 stv0900_write_reg(i_params, R0900_P2_CFRINIT1,
214 (freqOffset / 256) & 0xFF);
215 stv0900_write_reg(i_params, R0900_P2_CFRINIT0,
216 freqOffset & 0xFF);
217 stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x18);
218 stv0900_write_bits(i_params, F0900_P2_ALGOSWRST, 1);
219
220 if (i_params->chip_id == 0x12) {
221 stv0900_write_bits(i_params,
222 F0900_P2_RST_HWARE, 1);
223 stv0900_write_bits(i_params,
224 F0900_P2_RST_HWARE, 0);
225 }
226 break;
227 } 171 }
228 172
229 if (zigzag == TRUE) { 173 if (zigzag == TRUE) {
@@ -235,8 +179,8 @@ static int stv0900_search_carr_sw_loop(struct stv0900_internal *i_params,
235 freqOffset += + 2 * FreqIncr; 179 freqOffset += + 2 * FreqIncr;
236 180
237 stepCpt++; 181 stepCpt++;
238 lock = stv0900_get_demod_lock(i_params, demod, Timeout); 182 lock = stv0900_get_demod_lock(intp, demod, Timeout);
239 no_signal = stv0900_check_signal_presence(i_params, demod); 183 no_signal = stv0900_check_signal_presence(intp, demod);
240 184
241 } while ((lock == FALSE) 185 } while ((lock == FALSE)
242 && (no_signal == FALSE) 186 && (no_signal == FALSE)
@@ -244,269 +188,138 @@ static int stv0900_search_carr_sw_loop(struct stv0900_internal *i_params,
244 && ((freqOffset + FreqIncr) > -max_carrier) 188 && ((freqOffset + FreqIncr) > -max_carrier)
245 && (stepCpt < MaxStep)); 189 && (stepCpt < MaxStep));
246 190
247 switch (demod) { 191 stv0900_write_bits(intp, ALGOSWRST, 0);
248 case STV0900_DEMOD_1:
249 default:
250 stv0900_write_bits(i_params, F0900_P1_ALGOSWRST, 0);
251 break;
252 case STV0900_DEMOD_2:
253 stv0900_write_bits(i_params, F0900_P2_ALGOSWRST, 0);
254 break;
255 }
256 192
257 return lock; 193 return lock;
258} 194}
259 195
260int stv0900_sw_algo(struct stv0900_internal *i_params, 196int stv0900_sw_algo(struct stv0900_internal *intp,
261 enum fe_stv0900_demod_num demod) 197 enum fe_stv0900_demod_num demod)
262{ 198{
263 int lock = FALSE; 199 int lock = FALSE,
264 200 no_signal,
265 int no_signal, 201 zigzag;
266 zigzag; 202 s32 s2fw,
267 s32 dvbs2_fly_wheel; 203 fqc_inc,
268 204 sft_stp_tout,
269 s32 freqIncrement, softStepTimeout, trialCounter, max_steps; 205 trial_cntr,
270 206 max_steps;
271 stv0900_get_sw_loop_params(i_params, &freqIncrement, &softStepTimeout, 207
208 stv0900_get_sw_loop_params(intp, &fqc_inc, &sft_stp_tout,
272 &max_steps, demod); 209 &max_steps, demod);
273 switch (demod) { 210 switch (intp->srch_standard[demod]) {
274 case STV0900_DEMOD_1: 211 case STV0900_SEARCH_DVBS1:
275 default: 212 case STV0900_SEARCH_DSS:
276 switch (i_params->dmd1_srch_standard) { 213 if (intp->chip_id >= 0x20)
277 case STV0900_SEARCH_DVBS1: 214 stv0900_write_reg(intp, CARFREQ, 0x3b);
278 case STV0900_SEARCH_DSS: 215 else
279 if (i_params->chip_id >= 0x20) 216 stv0900_write_reg(intp, CARFREQ, 0xef);
280 stv0900_write_reg(i_params, R0900_P1_CARFREQ,
281 0x3B);
282 else
283 stv0900_write_reg(i_params, R0900_P1_CARFREQ,
284 0xef);
285
286 stv0900_write_reg(i_params, R0900_P1_DMDCFGMD, 0x49);
287 zigzag = FALSE;
288 break;
289 case STV0900_SEARCH_DVBS2:
290 if (i_params->chip_id >= 0x20)
291 stv0900_write_reg(i_params, R0900_P1_CORRELABS,
292 0x79);
293 else
294 stv0900_write_reg(i_params, R0900_P1_CORRELABS,
295 0x68);
296 217
297 stv0900_write_reg(i_params, R0900_P1_DMDCFGMD, 218 stv0900_write_reg(intp, DMDCFGMD, 0x49);
298 0x89); 219 zigzag = FALSE;
220 break;
221 case STV0900_SEARCH_DVBS2:
222 if (intp->chip_id >= 0x20)
223 stv0900_write_reg(intp, CORRELABS, 0x79);
224 else
225 stv0900_write_reg(intp, CORRELABS, 0x68);
299 226
300 zigzag = TRUE; 227 stv0900_write_reg(intp, DMDCFGMD, 0x89);
301 break;
302 case STV0900_AUTO_SEARCH:
303 default:
304 if (i_params->chip_id >= 0x20) {
305 stv0900_write_reg(i_params, R0900_P1_CARFREQ,
306 0x3B);
307 stv0900_write_reg(i_params, R0900_P1_CORRELABS,
308 0x79);
309 } else {
310 stv0900_write_reg(i_params, R0900_P1_CARFREQ,
311 0xef);
312 stv0900_write_reg(i_params, R0900_P1_CORRELABS,
313 0x68);
314 }
315 228
316 stv0900_write_reg(i_params, R0900_P1_DMDCFGMD, 229 zigzag = TRUE;
317 0xc9); 230 break;
318 zigzag = FALSE; 231 case STV0900_AUTO_SEARCH:
319 break; 232 default:
233 if (intp->chip_id >= 0x20) {
234 stv0900_write_reg(intp, CARFREQ, 0x3b);
235 stv0900_write_reg(intp, CORRELABS, 0x79);
236 } else {
237 stv0900_write_reg(intp, CARFREQ, 0xef);
238 stv0900_write_reg(intp, CORRELABS, 0x68);
320 } 239 }
321 240
322 trialCounter = 0; 241 stv0900_write_reg(intp, DMDCFGMD, 0xc9);
323 do { 242 zigzag = FALSE;
324 lock = stv0900_search_carr_sw_loop(i_params,
325 freqIncrement,
326 softStepTimeout,
327 zigzag,
328 max_steps,
329 demod);
330 no_signal = stv0900_check_signal_presence(i_params,
331 demod);
332 trialCounter++;
333 if ((lock == TRUE)
334 || (no_signal == TRUE)
335 || (trialCounter == 2)) {
336
337 if (i_params->chip_id >= 0x20) {
338 stv0900_write_reg(i_params,
339 R0900_P1_CARFREQ,
340 0x49);
341 stv0900_write_reg(i_params,
342 R0900_P1_CORRELABS,
343 0x9e);
344 } else {
345 stv0900_write_reg(i_params,
346 R0900_P1_CARFREQ,
347 0xed);
348 stv0900_write_reg(i_params,
349 R0900_P1_CORRELABS,
350 0x88);
351 }
352
353 if ((lock == TRUE) && (stv0900_get_bits(i_params, F0900_P1_HEADER_MODE) == STV0900_DVBS2_FOUND)) {
354 msleep(softStepTimeout);
355 dvbs2_fly_wheel = stv0900_get_bits(i_params, F0900_P1_FLYWHEEL_CPT);
356
357 if (dvbs2_fly_wheel < 0xd) {
358 msleep(softStepTimeout);
359 dvbs2_fly_wheel = stv0900_get_bits(i_params, F0900_P1_FLYWHEEL_CPT);
360 }
361
362 if (dvbs2_fly_wheel < 0xd) {
363 lock = FALSE;
364
365 if (trialCounter < 2) {
366 if (i_params->chip_id >= 0x20)
367 stv0900_write_reg(i_params, R0900_P1_CORRELABS, 0x79);
368 else
369 stv0900_write_reg(i_params, R0900_P1_CORRELABS, 0x68);
370
371 stv0900_write_reg(i_params, R0900_P1_DMDCFGMD, 0x89);
372 }
373 }
374 }
375 }
376
377 } while ((lock == FALSE)
378 && (trialCounter < 2)
379 && (no_signal == FALSE));
380
381 break; 243 break;
382 case STV0900_DEMOD_2: 244 }
383 switch (i_params->dmd2_srch_stndrd) {
384 case STV0900_SEARCH_DVBS1:
385 case STV0900_SEARCH_DSS:
386 if (i_params->chip_id >= 0x20)
387 stv0900_write_reg(i_params, R0900_P2_CARFREQ,
388 0x3b);
389 else
390 stv0900_write_reg(i_params, R0900_P2_CARFREQ,
391 0xef);
392
393 stv0900_write_reg(i_params, R0900_P2_DMDCFGMD,
394 0x49);
395 zigzag = FALSE;
396 break;
397 case STV0900_SEARCH_DVBS2:
398 if (i_params->chip_id >= 0x20)
399 stv0900_write_reg(i_params, R0900_P2_CORRELABS,
400 0x79);
401 else
402 stv0900_write_reg(i_params, R0900_P2_CORRELABS,
403 0x68);
404 245
405 stv0900_write_reg(i_params, R0900_P2_DMDCFGMD, 0x89); 246 trial_cntr = 0;
406 zigzag = TRUE; 247 do {
407 break; 248 lock = stv0900_search_carr_sw_loop(intp,
408 case STV0900_AUTO_SEARCH: 249 fqc_inc,
409 default: 250 sft_stp_tout,
410 if (i_params->chip_id >= 0x20) { 251 zigzag,
411 stv0900_write_reg(i_params, R0900_P2_CARFREQ, 252 max_steps,
412 0x3b); 253 demod);
413 stv0900_write_reg(i_params, R0900_P2_CORRELABS, 254 no_signal = stv0900_check_signal_presence(intp, demod);
414 0x79); 255 trial_cntr++;
256 if ((lock == TRUE)
257 || (no_signal == TRUE)
258 || (trial_cntr == 2)) {
259
260 if (intp->chip_id >= 0x20) {
261 stv0900_write_reg(intp, CARFREQ, 0x49);
262 stv0900_write_reg(intp, CORRELABS, 0x9e);
415 } else { 263 } else {
416 stv0900_write_reg(i_params, R0900_P2_CARFREQ, 264 stv0900_write_reg(intp, CARFREQ, 0xed);
417 0xef); 265 stv0900_write_reg(intp, CORRELABS, 0x88);
418 stv0900_write_reg(i_params, R0900_P2_CORRELABS,
419 0x68);
420 } 266 }
421 267
422 stv0900_write_reg(i_params, R0900_P2_DMDCFGMD, 0xc9); 268 if ((stv0900_get_bits(intp, HEADER_MODE) ==
423 269 STV0900_DVBS2_FOUND) &&
424 zigzag = FALSE; 270 (lock == TRUE)) {
425 break; 271 msleep(sft_stp_tout);
426 } 272 s2fw = stv0900_get_bits(intp, FLYWHEEL_CPT);
427 273
428 trialCounter = 0; 274 if (s2fw < 0xd) {
429 275 msleep(sft_stp_tout);
430 do { 276 s2fw = stv0900_get_bits(intp,
431 lock = stv0900_search_carr_sw_loop(i_params, 277 FLYWHEEL_CPT);
432 freqIncrement,
433 softStepTimeout,
434 zigzag,
435 max_steps,
436 demod);
437 no_signal = stv0900_check_signal_presence(i_params,
438 demod);
439 trialCounter++;
440 if ((lock == TRUE)
441 || (no_signal == TRUE)
442 || (trialCounter == 2)) {
443 if (i_params->chip_id >= 0x20) {
444 stv0900_write_reg(i_params,
445 R0900_P2_CARFREQ,
446 0x49);
447 stv0900_write_reg(i_params,
448 R0900_P2_CORRELABS,
449 0x9e);
450 } else {
451 stv0900_write_reg(i_params,
452 R0900_P2_CARFREQ,
453 0xed);
454 stv0900_write_reg(i_params,
455 R0900_P2_CORRELABS,
456 0x88);
457 } 278 }
458 279
459 if ((lock == TRUE) && (stv0900_get_bits(i_params, F0900_P2_HEADER_MODE) == STV0900_DVBS2_FOUND)) { 280 if (s2fw < 0xd) {
460 msleep(softStepTimeout); 281 lock = FALSE;
461 dvbs2_fly_wheel = stv0900_get_bits(i_params, F0900_P2_FLYWHEEL_CPT);
462 if (dvbs2_fly_wheel < 0xd) {
463 msleep(softStepTimeout);
464 dvbs2_fly_wheel = stv0900_get_bits(i_params, F0900_P2_FLYWHEEL_CPT);
465 }
466 282
467 if (dvbs2_fly_wheel < 0xd) { 283 if (trial_cntr < 2) {
468 lock = FALSE; 284 if (intp->chip_id >= 0x20)
469 if (trialCounter < 2) { 285 stv0900_write_reg(intp,
470 if (i_params->chip_id >= 0x20) 286 CORRELABS,
471 stv0900_write_reg(i_params, R0900_P2_CORRELABS, 0x79); 287 0x79);
472 else 288 else
473 stv0900_write_reg(i_params, R0900_P2_CORRELABS, 0x68); 289 stv0900_write_reg(intp,
290 CORRELABS,
291 0x68);
474 292
475 stv0900_write_reg(i_params, R0900_P2_DMDCFGMD, 0x89); 293 stv0900_write_reg(intp,
476 } 294 DMDCFGMD,
295 0x89);
477 } 296 }
478 } 297 }
479 } 298 }
299 }
480 300
481 } while ((lock == FALSE) && (trialCounter < 2) && (no_signal == FALSE)); 301 } while ((lock == FALSE)
482 302 && (trial_cntr < 2)
483 break; 303 && (no_signal == FALSE));
484 }
485 304
486 return lock; 305 return lock;
487} 306}
488 307
489static u32 stv0900_get_symbol_rate(struct stv0900_internal *i_params, 308static u32 stv0900_get_symbol_rate(struct stv0900_internal *intp,
490 u32 mclk, 309 u32 mclk,
491 enum fe_stv0900_demod_num demod) 310 enum fe_stv0900_demod_num demod)
492{ 311{
493 s32 sfr_field3, sfr_field2, sfr_field1, sfr_field0, 312 s32 rem1, rem2, intval1, intval2, srate;
494 rem1, rem2, intval1, intval2, srate; 313
495 314 srate = (stv0900_get_bits(intp, SYMB_FREQ3) << 24) +
496 dmd_reg(sfr_field3, F0900_P1_SYMB_FREQ3, F0900_P2_SYMB_FREQ3); 315 (stv0900_get_bits(intp, SYMB_FREQ2) << 16) +
497 dmd_reg(sfr_field2, F0900_P1_SYMB_FREQ2, F0900_P2_SYMB_FREQ2); 316 (stv0900_get_bits(intp, SYMB_FREQ1) << 8) +
498 dmd_reg(sfr_field1, F0900_P1_SYMB_FREQ1, F0900_P2_SYMB_FREQ1); 317 (stv0900_get_bits(intp, SYMB_FREQ0));
499 dmd_reg(sfr_field0, F0900_P1_SYMB_FREQ0, F0900_P2_SYMB_FREQ0);
500
501 srate = (stv0900_get_bits(i_params, sfr_field3) << 24) +
502 (stv0900_get_bits(i_params, sfr_field2) << 16) +
503 (stv0900_get_bits(i_params, sfr_field1) << 8) +
504 (stv0900_get_bits(i_params, sfr_field0));
505 dprintk("lock: srate=%d r0=0x%x r1=0x%x r2=0x%x r3=0x%x \n", 318 dprintk("lock: srate=%d r0=0x%x r1=0x%x r2=0x%x r3=0x%x \n",
506 srate, stv0900_get_bits(i_params, sfr_field0), 319 srate, stv0900_get_bits(intp, SYMB_FREQ0),
507 stv0900_get_bits(i_params, sfr_field1), 320 stv0900_get_bits(intp, SYMB_FREQ1),
508 stv0900_get_bits(i_params, sfr_field2), 321 stv0900_get_bits(intp, SYMB_FREQ2),
509 stv0900_get_bits(i_params, sfr_field3)); 322 stv0900_get_bits(intp, SYMB_FREQ3));
510 323
511 intval1 = (mclk) >> 16; 324 intval1 = (mclk) >> 16;
512 intval2 = (srate) >> 16; 325 intval2 = (srate) >> 16;
@@ -520,18 +333,15 @@ static u32 stv0900_get_symbol_rate(struct stv0900_internal *i_params,
520 return srate; 333 return srate;
521} 334}
522 335
523static void stv0900_set_symbol_rate(struct stv0900_internal *i_params, 336static void stv0900_set_symbol_rate(struct stv0900_internal *intp,
524 u32 mclk, u32 srate, 337 u32 mclk, u32 srate,
525 enum fe_stv0900_demod_num demod) 338 enum fe_stv0900_demod_num demod)
526{ 339{
527 s32 sfr_init_reg;
528 u32 symb; 340 u32 symb;
529 341
530 dprintk(KERN_INFO "%s: Mclk %d, SR %d, Dmd %d\n", __func__, mclk, 342 dprintk("%s: Mclk %d, SR %d, Dmd %d\n", __func__, mclk,
531 srate, demod); 343 srate, demod);
532 344
533 dmd_reg(sfr_init_reg, R0900_P1_SFRINIT1, R0900_P2_SFRINIT1);
534
535 if (srate > 60000000) { 345 if (srate > 60000000) {
536 symb = srate << 4; 346 symb = srate << 4;
537 symb /= (mclk >> 12); 347 symb /= (mclk >> 12);
@@ -543,19 +353,16 @@ static void stv0900_set_symbol_rate(struct stv0900_internal *i_params,
543 symb /= (mclk >> 7); 353 symb /= (mclk >> 7);
544 } 354 }
545 355
546 stv0900_write_reg(i_params, sfr_init_reg, (symb >> 8) & 0x7F); 356 stv0900_write_reg(intp, SFRINIT1, (symb >> 8) & 0x7f);
547 stv0900_write_reg(i_params, sfr_init_reg + 1, (symb & 0xFF)); 357 stv0900_write_reg(intp, SFRINIT1 + 1, (symb & 0xff));
548} 358}
549 359
550static void stv0900_set_max_symbol_rate(struct stv0900_internal *i_params, 360static void stv0900_set_max_symbol_rate(struct stv0900_internal *intp,
551 u32 mclk, u32 srate, 361 u32 mclk, u32 srate,
552 enum fe_stv0900_demod_num demod) 362 enum fe_stv0900_demod_num demod)
553{ 363{
554 s32 sfr_max_reg;
555 u32 symb; 364 u32 symb;
556 365
557 dmd_reg(sfr_max_reg, R0900_P1_SFRUP1, R0900_P2_SFRUP1);
558
559 srate = 105 * (srate / 100); 366 srate = 105 * (srate / 100);
560 367
561 if (srate > 60000000) { 368 if (srate > 60000000) {
@@ -570,23 +377,20 @@ static void stv0900_set_max_symbol_rate(struct stv0900_internal *i_params,
570 } 377 }
571 378
572 if (symb < 0x7fff) { 379 if (symb < 0x7fff) {
573 stv0900_write_reg(i_params, sfr_max_reg, (symb >> 8) & 0x7F); 380 stv0900_write_reg(intp, SFRUP1, (symb >> 8) & 0x7f);
574 stv0900_write_reg(i_params, sfr_max_reg + 1, (symb & 0xFF)); 381 stv0900_write_reg(intp, SFRUP1 + 1, (symb & 0xff));
575 } else { 382 } else {
576 stv0900_write_reg(i_params, sfr_max_reg, 0x7F); 383 stv0900_write_reg(intp, SFRUP1, 0x7f);
577 stv0900_write_reg(i_params, sfr_max_reg + 1, 0xFF); 384 stv0900_write_reg(intp, SFRUP1 + 1, 0xff);
578 } 385 }
579} 386}
580 387
581static void stv0900_set_min_symbol_rate(struct stv0900_internal *i_params, 388static void stv0900_set_min_symbol_rate(struct stv0900_internal *intp,
582 u32 mclk, u32 srate, 389 u32 mclk, u32 srate,
583 enum fe_stv0900_demod_num demod) 390 enum fe_stv0900_demod_num demod)
584{ 391{
585 s32 sfr_min_reg;
586 u32 symb; 392 u32 symb;
587 393
588 dmd_reg(sfr_min_reg, R0900_P1_SFRLOW1, R0900_P2_SFRLOW1);
589
590 srate = 95 * (srate / 100); 394 srate = 95 * (srate / 100);
591 if (srate > 60000000) { 395 if (srate > 60000000) {
592 symb = srate << 4; 396 symb = srate << 4;
@@ -601,22 +405,20 @@ static void stv0900_set_min_symbol_rate(struct stv0900_internal *i_params,
601 symb /= (mclk >> 7); 405 symb /= (mclk >> 7);
602 } 406 }
603 407
604 stv0900_write_reg(i_params, sfr_min_reg, (symb >> 8) & 0xFF); 408 stv0900_write_reg(intp, SFRLOW1, (symb >> 8) & 0xff);
605 stv0900_write_reg(i_params, sfr_min_reg + 1, (symb & 0xFF)); 409 stv0900_write_reg(intp, SFRLOW1 + 1, (symb & 0xff));
606} 410}
607 411
608static s32 stv0900_get_timing_offst(struct stv0900_internal *i_params, 412static s32 stv0900_get_timing_offst(struct stv0900_internal *intp,
609 u32 srate, 413 u32 srate,
610 enum fe_stv0900_demod_num demod) 414 enum fe_stv0900_demod_num demod)
611{ 415{
612 s32 tmgreg, 416 s32 timingoffset;
613 timingoffset;
614 417
615 dmd_reg(tmgreg, R0900_P1_TMGREG2, R0900_P2_TMGREG2);
616 418
617 timingoffset = (stv0900_read_reg(i_params, tmgreg) << 16) + 419 timingoffset = (stv0900_read_reg(intp, TMGREG2) << 16) +
618 (stv0900_read_reg(i_params, tmgreg + 1) << 8) + 420 (stv0900_read_reg(intp, TMGREG2 + 1) << 8) +
619 (stv0900_read_reg(i_params, tmgreg + 2)); 421 (stv0900_read_reg(intp, TMGREG2 + 2));
620 422
621 timingoffset = ge2comp(timingoffset, 24); 423 timingoffset = ge2comp(timingoffset, 24);
622 424
@@ -630,22 +432,19 @@ static s32 stv0900_get_timing_offst(struct stv0900_internal *i_params,
630 return timingoffset; 432 return timingoffset;
631} 433}
632 434
633static void stv0900_set_dvbs2_rolloff(struct stv0900_internal *i_params, 435static void stv0900_set_dvbs2_rolloff(struct stv0900_internal *intp,
634 enum fe_stv0900_demod_num demod) 436 enum fe_stv0900_demod_num demod)
635{ 437{
636 s32 rolloff, man_fld, matstr_reg, rolloff_ctl_fld; 438 s32 rolloff;
637 439
638 dmd_reg(man_fld, F0900_P1_MANUAL_ROLLOFF, F0900_P2_MANUAL_ROLLOFF); 440 if (intp->chip_id == 0x10) {
639 dmd_reg(matstr_reg, R0900_P1_MATSTR1, R0900_P2_MATSTR1); 441 stv0900_write_bits(intp, MANUALSX_ROLLOFF, 1);
640 dmd_reg(rolloff_ctl_fld, F0900_P1_ROLLOFF_CONTROL, 442 rolloff = stv0900_read_reg(intp, MATSTR1) & 0x03;
641 F0900_P2_ROLLOFF_CONTROL); 443 stv0900_write_bits(intp, ROLLOFF_CONTROL, rolloff);
642 444 } else if (intp->chip_id <= 0x20)
643 if (i_params->chip_id == 0x10) { 445 stv0900_write_bits(intp, MANUALSX_ROLLOFF, 0);
644 stv0900_write_bits(i_params, man_fld, 1); 446 else /* cut 3.0 */
645 rolloff = stv0900_read_reg(i_params, matstr_reg) & 0x03; 447 stv0900_write_bits(intp, MANUALS2_ROLLOFF, 0);
646 stv0900_write_bits(i_params, rolloff_ctl_fld, rolloff);
647 } else
648 stv0900_write_bits(i_params, man_fld, 0);
649} 448}
650 449
651static u32 stv0900_carrier_width(u32 srate, enum fe_stv0900_rolloff ro) 450static u32 stv0900_carrier_width(u32 srate, enum fe_stv0900_rolloff ro)
@@ -668,84 +467,47 @@ static u32 stv0900_carrier_width(u32 srate, enum fe_stv0900_rolloff ro)
668 return srate + (srate * rolloff) / 100; 467 return srate + (srate * rolloff) / 100;
669} 468}
670 469
671static int stv0900_check_timing_lock(struct stv0900_internal *i_params, 470static int stv0900_check_timing_lock(struct stv0900_internal *intp,
672 enum fe_stv0900_demod_num demod) 471 enum fe_stv0900_demod_num demod)
673{ 472{
674 int timingLock = FALSE; 473 int timingLock = FALSE;
675 s32 i, 474 s32 i,
676 timingcpt = 0; 475 timingcpt = 0;
677 u8 carFreq, 476 u8 car_freq,
678 tmgTHhigh, 477 tmg_th_high,
679 tmgTHLow; 478 tmg_th_low;
680 479
681 switch (demod) { 480 car_freq = stv0900_read_reg(intp, CARFREQ);
682 case STV0900_DEMOD_1: 481 tmg_th_high = stv0900_read_reg(intp, TMGTHRISE);
683 default: 482 tmg_th_low = stv0900_read_reg(intp, TMGTHFALL);
684 carFreq = stv0900_read_reg(i_params, R0900_P1_CARFREQ); 483 stv0900_write_reg(intp, TMGTHRISE, 0x20);
685 tmgTHhigh = stv0900_read_reg(i_params, R0900_P1_TMGTHRISE); 484 stv0900_write_reg(intp, TMGTHFALL, 0x0);
686 tmgTHLow = stv0900_read_reg(i_params, R0900_P1_TMGTHFALL); 485 stv0900_write_bits(intp, CFR_AUTOSCAN, 0);
687 stv0900_write_reg(i_params, R0900_P1_TMGTHRISE, 0x20); 486 stv0900_write_reg(intp, RTC, 0x80);
688 stv0900_write_reg(i_params, R0900_P1_TMGTHFALL, 0x0); 487 stv0900_write_reg(intp, RTCS2, 0x40);
689 stv0900_write_bits(i_params, F0900_P1_CFR_AUTOSCAN, 0); 488 stv0900_write_reg(intp, CARFREQ, 0x0);
690 stv0900_write_reg(i_params, R0900_P1_RTC, 0x80); 489 stv0900_write_reg(intp, CFRINIT1, 0x0);
691 stv0900_write_reg(i_params, R0900_P1_RTCS2, 0x40); 490 stv0900_write_reg(intp, CFRINIT0, 0x0);
692 stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0x0); 491 stv0900_write_reg(intp, AGC2REF, 0x65);
693 stv0900_write_reg(i_params, R0900_P1_CFRINIT1, 0x0); 492 stv0900_write_reg(intp, DMDISTATE, 0x18);
694 stv0900_write_reg(i_params, R0900_P1_CFRINIT0, 0x0); 493 msleep(7);
695 stv0900_write_reg(i_params, R0900_P1_AGC2REF, 0x65); 494
696 stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x18); 495 for (i = 0; i < 10; i++) {
697 msleep(7); 496 if (stv0900_get_bits(intp, TMGLOCK_QUALITY) >= 2)
698 497 timingcpt++;
699 for (i = 0; i < 10; i++) { 498
700 if (stv0900_get_bits(i_params, F0900_P1_TMGLOCK_QUALITY) >= 2) 499 msleep(1);
701 timingcpt++; 500 }
702
703 msleep(1);
704 }
705
706 if (timingcpt >= 3)
707 timingLock = TRUE;
708
709 stv0900_write_reg(i_params, R0900_P1_AGC2REF, 0x38);
710 stv0900_write_reg(i_params, R0900_P1_RTC, 0x88);
711 stv0900_write_reg(i_params, R0900_P1_RTCS2, 0x68);
712 stv0900_write_reg(i_params, R0900_P1_CARFREQ, carFreq);
713 stv0900_write_reg(i_params, R0900_P1_TMGTHRISE, tmgTHhigh);
714 stv0900_write_reg(i_params, R0900_P1_TMGTHFALL, tmgTHLow);
715 break;
716 case STV0900_DEMOD_2:
717 carFreq = stv0900_read_reg(i_params, R0900_P2_CARFREQ);
718 tmgTHhigh = stv0900_read_reg(i_params, R0900_P2_TMGTHRISE);
719 tmgTHLow = stv0900_read_reg(i_params, R0900_P2_TMGTHFALL);
720 stv0900_write_reg(i_params, R0900_P2_TMGTHRISE, 0x20);
721 stv0900_write_reg(i_params, R0900_P2_TMGTHFALL, 0);
722 stv0900_write_bits(i_params, F0900_P2_CFR_AUTOSCAN, 0);
723 stv0900_write_reg(i_params, R0900_P2_RTC, 0x80);
724 stv0900_write_reg(i_params, R0900_P2_RTCS2, 0x40);
725 stv0900_write_reg(i_params, R0900_P2_CARFREQ, 0x0);
726 stv0900_write_reg(i_params, R0900_P2_CFRINIT1, 0x0);
727 stv0900_write_reg(i_params, R0900_P2_CFRINIT0, 0x0);
728 stv0900_write_reg(i_params, R0900_P2_AGC2REF, 0x65);
729 stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x18);
730 msleep(5);
731 for (i = 0; i < 10; i++) {
732 if (stv0900_get_bits(i_params, F0900_P2_TMGLOCK_QUALITY) >= 2)
733 timingcpt++;
734 501
735 msleep(1); 502 if (timingcpt >= 3)
736 } 503 timingLock = TRUE;
737 504
738 if (timingcpt >= 3) 505 stv0900_write_reg(intp, AGC2REF, 0x38);
739 timingLock = TRUE; 506 stv0900_write_reg(intp, RTC, 0x88);
740 507 stv0900_write_reg(intp, RTCS2, 0x68);
741 stv0900_write_reg(i_params, R0900_P2_AGC2REF, 0x38); 508 stv0900_write_reg(intp, CARFREQ, car_freq);
742 stv0900_write_reg(i_params, R0900_P2_RTC, 0x88); 509 stv0900_write_reg(intp, TMGTHRISE, tmg_th_high);
743 stv0900_write_reg(i_params, R0900_P2_RTCS2, 0x68); 510 stv0900_write_reg(intp, TMGTHFALL, tmg_th_low);
744 stv0900_write_reg(i_params, R0900_P2_CARFREQ, carFreq);
745 stv0900_write_reg(i_params, R0900_P2_TMGTHRISE, tmgTHhigh);
746 stv0900_write_reg(i_params, R0900_P2_TMGTHFALL, tmgTHLow);
747 break;
748 }
749 511
750 return timingLock; 512 return timingLock;
751} 513}
@@ -754,142 +516,114 @@ static int stv0900_get_demod_cold_lock(struct dvb_frontend *fe,
754 s32 demod_timeout) 516 s32 demod_timeout)
755{ 517{
756 struct stv0900_state *state = fe->demodulator_priv; 518 struct stv0900_state *state = fe->demodulator_priv;
757 struct stv0900_internal *i_params = state->internal; 519 struct stv0900_internal *intp = state->internal;
758 enum fe_stv0900_demod_num demod = state->demod; 520 enum fe_stv0900_demod_num demod = state->demod;
521 int lock = FALSE,
522 d = demod;
523 s32 srate,
524 search_range,
525 locktimeout,
526 currier_step,
527 nb_steps,
528 current_step,
529 direction,
530 tuner_freq,
531 timeout,
532 freq;
759 533
760 int lock = FALSE; 534 srate = intp->symbol_rate[d];
761 s32 srate, search_range, locktimeout, 535 search_range = intp->srch_range[d];
762 currier_step, nb_steps, current_step,
763 direction, tuner_freq, timeout;
764
765 switch (demod) {
766 case STV0900_DEMOD_1:
767 default:
768 srate = i_params->dmd1_symbol_rate;
769 search_range = i_params->dmd1_srch_range;
770 break;
771
772 case STV0900_DEMOD_2:
773 srate = i_params->dmd2_symbol_rate;
774 search_range = i_params->dmd2_srch_range;
775 break;
776 }
777 536
778 if (srate >= 10000000) 537 if (srate >= 10000000)
779 locktimeout = demod_timeout / 3; 538 locktimeout = demod_timeout / 3;
780 else 539 else
781 locktimeout = demod_timeout / 2; 540 locktimeout = demod_timeout / 2;
782 541
783 lock = stv0900_get_demod_lock(i_params, demod, locktimeout); 542 lock = stv0900_get_demod_lock(intp, d, locktimeout);
784
785 if (lock == FALSE) {
786 if (srate >= 10000000) {
787 if (stv0900_check_timing_lock(i_params, demod) == TRUE) {
788 switch (demod) {
789 case STV0900_DEMOD_1:
790 default:
791 stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1f);
792 stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x15);
793 break;
794 case STV0900_DEMOD_2:
795 stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1f);
796 stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x15);
797 break;
798 }
799 543
800 lock = stv0900_get_demod_lock(i_params, demod, demod_timeout); 544 if (lock != FALSE)
801 } else 545 return lock;
802 lock = FALSE; 546
803 } else { 547 if (srate >= 10000000) {
804 if (srate <= 4000000) 548 if (stv0900_check_timing_lock(intp, d) == TRUE) {
805 currier_step = 1000; 549 stv0900_write_reg(intp, DMDISTATE, 0x1f);
806 else if (srate <= 7000000) 550 stv0900_write_reg(intp, DMDISTATE, 0x15);
807 currier_step = 2000; 551 lock = stv0900_get_demod_lock(intp, d, demod_timeout);
808 else if (srate <= 10000000) 552 } else
809 currier_step = 3000; 553 lock = FALSE;
810 else 554
811 currier_step = 5000; 555 return lock;
812 556 }
813 nb_steps = ((search_range / 1000) / currier_step); 557
814 nb_steps /= 2; 558 if (intp->chip_id <= 0x20) {
815 nb_steps = (2 * (nb_steps + 1)); 559 if (srate <= 1000000)
816 if (nb_steps < 0) 560 currier_step = 500;
817 nb_steps = 2; 561 else if (srate <= 4000000)
818 else if (nb_steps > 12) 562 currier_step = 1000;
819 nb_steps = 12; 563 else if (srate <= 7000000)
820 564 currier_step = 2000;
821 current_step = 1; 565 else if (srate <= 10000000)
822 direction = 1; 566 currier_step = 3000;
567 else
568 currier_step = 5000;
569
570 if (srate >= 2000000) {
823 timeout = (demod_timeout / 3); 571 timeout = (demod_timeout / 3);
824 if (timeout > 1000) 572 if (timeout > 1000)
825 timeout = 1000; 573 timeout = 1000;
574 } else
575 timeout = (demod_timeout / 2);
576 } else {
577 /*cut 3.0 */
578 currier_step = srate / 4000;
579 timeout = (demod_timeout * 3) / 4;
580 }
826 581
827 switch (demod) { 582 nb_steps = ((search_range / 1000) / currier_step);
828 case STV0900_DEMOD_1:
829 default:
830 if (lock == FALSE) {
831 tuner_freq = i_params->tuner1_freq;
832 i_params->tuner1_bw = stv0900_carrier_width(i_params->dmd1_symbol_rate, i_params->rolloff) + i_params->dmd1_symbol_rate;
833 583
834 while ((current_step <= nb_steps) && (lock == FALSE)) { 584 if ((nb_steps % 2) != 0)
585 nb_steps += 1;
835 586
836 if (direction > 0) 587 if (nb_steps <= 0)
837 tuner_freq += (current_step * currier_step); 588 nb_steps = 2;
838 else 589 else if (nb_steps > 12)
839 tuner_freq -= (current_step * currier_step); 590 nb_steps = 12;
840
841 stv0900_set_tuner(fe, tuner_freq, i_params->tuner1_bw);
842 stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1C);
843 if (i_params->dmd1_srch_standard == STV0900_SEARCH_DVBS2) {
844 stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 0);
845 stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 0);
846 stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 1);
847 stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 1);
848 }
849
850 stv0900_write_reg(i_params, R0900_P1_CFRINIT1, 0);
851 stv0900_write_reg(i_params, R0900_P1_CFRINIT0, 0);
852 stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1F);
853 stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x15);
854 lock = stv0900_get_demod_lock(i_params, demod, timeout);
855 direction *= -1;
856 current_step++;
857 }
858 }
859 break;
860 case STV0900_DEMOD_2:
861 if (lock == FALSE) {
862 tuner_freq = i_params->tuner2_freq;
863 i_params->tuner2_bw = stv0900_carrier_width(srate, i_params->rolloff) + srate;
864 591
865 while ((current_step <= nb_steps) && (lock == FALSE)) { 592 current_step = 1;
593 direction = 1;
866 594
867 if (direction > 0) 595 if (intp->chip_id <= 0x20) {
868 tuner_freq += (current_step * currier_step); 596 tuner_freq = intp->freq[d];
869 else 597 intp->bw[d] = stv0900_carrier_width(intp->symbol_rate[d],
870 tuner_freq -= (current_step * currier_step); 598 intp->rolloff) + intp->symbol_rate[d];
871 599 } else
872 stv0900_set_tuner(fe, tuner_freq, i_params->tuner2_bw); 600 tuner_freq = 0;
873 stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1C); 601
874 if (i_params->dmd2_srch_stndrd == STV0900_SEARCH_DVBS2) { 602 while ((current_step <= nb_steps) && (lock == FALSE)) {
875 stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 0); 603 if (direction > 0)
876 stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 0); 604 tuner_freq += (current_step * currier_step);
877 stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 1); 605 else
878 stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 1); 606 tuner_freq -= (current_step * currier_step);
879 } 607
880 608 if (intp->chip_id <= 0x20) {
881 stv0900_write_reg(i_params, R0900_P2_CFRINIT1, 0); 609 stv0900_set_tuner(fe, tuner_freq, intp->bw[d]);
882 stv0900_write_reg(i_params, R0900_P2_CFRINIT0, 0); 610 stv0900_write_reg(intp, DMDISTATE, 0x1c);
883 stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1F); 611 stv0900_write_reg(intp, CFRINIT1, 0);
884 stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x15); 612 stv0900_write_reg(intp, CFRINIT0, 0);
885 lock = stv0900_get_demod_lock(i_params, demod, timeout); 613 stv0900_write_reg(intp, DMDISTATE, 0x1f);
886 direction *= -1; 614 stv0900_write_reg(intp, DMDISTATE, 0x15);
887 current_step++; 615 } else {
888 } 616 stv0900_write_reg(intp, DMDISTATE, 0x1c);
889 } 617 freq = (tuner_freq * 65536) / (intp->mclk / 1000);
890 break; 618 stv0900_write_bits(intp, CFR_INIT1, MSB(freq));
891 } 619 stv0900_write_bits(intp, CFR_INIT0, LSB(freq));
620 stv0900_write_reg(intp, DMDISTATE, 0x1f);
621 stv0900_write_reg(intp, DMDISTATE, 0x05);
892 } 622 }
623
624 lock = stv0900_get_demod_lock(intp, d, timeout);
625 direction *= -1;
626 current_step++;
893 } 627 }
894 628
895 return lock; 629 return lock;
@@ -931,9 +665,7 @@ static void stv0900_get_lock_timeout(s32 *demod_timeout, s32 *fec_timeout,
931 } else if (srate <= 20000000) { 665 } else if (srate <= 20000000) {
932 (*demod_timeout) = 400; 666 (*demod_timeout) = 400;
933 (*fec_timeout) = 130; 667 (*fec_timeout) = 130;
934 } 668 } else {
935
936 else {
937 (*demod_timeout) = 300; 669 (*demod_timeout) = 300;
938 (*fec_timeout) = 100; 670 (*fec_timeout) = 100;
939 } 671 }
@@ -946,95 +678,77 @@ static void stv0900_get_lock_timeout(s32 *demod_timeout, s32 *fec_timeout,
946 (*demod_timeout) /= 2; 678 (*demod_timeout) /= 2;
947} 679}
948 680
949static void stv0900_set_viterbi_tracq(struct stv0900_internal *i_params, 681static void stv0900_set_viterbi_tracq(struct stv0900_internal *intp,
950 enum fe_stv0900_demod_num demod) 682 enum fe_stv0900_demod_num demod)
951{ 683{
952 684
953 s32 vth_reg; 685 s32 vth_reg = VTH12;
954 686
955 dprintk(KERN_INFO "%s\n", __func__); 687 dprintk("%s\n", __func__);
956 688
957 dmd_reg(vth_reg, R0900_P1_VTH12, R0900_P2_VTH12); 689 stv0900_write_reg(intp, vth_reg++, 0xd0);
958 690 stv0900_write_reg(intp, vth_reg++, 0x7d);
959 stv0900_write_reg(i_params, vth_reg++, 0xd0); 691 stv0900_write_reg(intp, vth_reg++, 0x53);
960 stv0900_write_reg(i_params, vth_reg++, 0x7d); 692 stv0900_write_reg(intp, vth_reg++, 0x2f);
961 stv0900_write_reg(i_params, vth_reg++, 0x53); 693 stv0900_write_reg(intp, vth_reg++, 0x24);
962 stv0900_write_reg(i_params, vth_reg++, 0x2F); 694 stv0900_write_reg(intp, vth_reg++, 0x1f);
963 stv0900_write_reg(i_params, vth_reg++, 0x24);
964 stv0900_write_reg(i_params, vth_reg++, 0x1F);
965} 695}
966 696
967static void stv0900_set_viterbi_standard(struct stv0900_internal *i_params, 697static void stv0900_set_viterbi_standard(struct stv0900_internal *intp,
968 enum fe_stv0900_search_standard Standard, 698 enum fe_stv0900_search_standard standard,
969 enum fe_stv0900_fec PunctureRate, 699 enum fe_stv0900_fec fec,
970 enum fe_stv0900_demod_num demod) 700 enum fe_stv0900_demod_num demod)
971{ 701{
702 dprintk("%s: ViterbiStandard = ", __func__);
972 703
973 s32 fecmReg, 704 switch (standard) {
974 prvitReg;
975
976 dprintk(KERN_INFO "%s: ViterbiStandard = ", __func__);
977
978 switch (demod) {
979 case STV0900_DEMOD_1:
980 default:
981 fecmReg = R0900_P1_FECM;
982 prvitReg = R0900_P1_PRVIT;
983 break;
984 case STV0900_DEMOD_2:
985 fecmReg = R0900_P2_FECM;
986 prvitReg = R0900_P2_PRVIT;
987 break;
988 }
989
990 switch (Standard) {
991 case STV0900_AUTO_SEARCH: 705 case STV0900_AUTO_SEARCH:
992 dprintk("Auto\n"); 706 dprintk("Auto\n");
993 stv0900_write_reg(i_params, fecmReg, 0x10); 707 stv0900_write_reg(intp, FECM, 0x10);
994 stv0900_write_reg(i_params, prvitReg, 0x3F); 708 stv0900_write_reg(intp, PRVIT, 0x3f);
995 break; 709 break;
996 case STV0900_SEARCH_DVBS1: 710 case STV0900_SEARCH_DVBS1:
997 dprintk("DVBS1\n"); 711 dprintk("DVBS1\n");
998 stv0900_write_reg(i_params, fecmReg, 0x00); 712 stv0900_write_reg(intp, FECM, 0x00);
999 switch (PunctureRate) { 713 switch (fec) {
1000 case STV0900_FEC_UNKNOWN: 714 case STV0900_FEC_UNKNOWN:
1001 default: 715 default:
1002 stv0900_write_reg(i_params, prvitReg, 0x2F); 716 stv0900_write_reg(intp, PRVIT, 0x2f);
1003 break; 717 break;
1004 case STV0900_FEC_1_2: 718 case STV0900_FEC_1_2:
1005 stv0900_write_reg(i_params, prvitReg, 0x01); 719 stv0900_write_reg(intp, PRVIT, 0x01);
1006 break; 720 break;
1007 case STV0900_FEC_2_3: 721 case STV0900_FEC_2_3:
1008 stv0900_write_reg(i_params, prvitReg, 0x02); 722 stv0900_write_reg(intp, PRVIT, 0x02);
1009 break; 723 break;
1010 case STV0900_FEC_3_4: 724 case STV0900_FEC_3_4:
1011 stv0900_write_reg(i_params, prvitReg, 0x04); 725 stv0900_write_reg(intp, PRVIT, 0x04);
1012 break; 726 break;
1013 case STV0900_FEC_5_6: 727 case STV0900_FEC_5_6:
1014 stv0900_write_reg(i_params, prvitReg, 0x08); 728 stv0900_write_reg(intp, PRVIT, 0x08);
1015 break; 729 break;
1016 case STV0900_FEC_7_8: 730 case STV0900_FEC_7_8:
1017 stv0900_write_reg(i_params, prvitReg, 0x20); 731 stv0900_write_reg(intp, PRVIT, 0x20);
1018 break; 732 break;
1019 } 733 }
1020 734
1021 break; 735 break;
1022 case STV0900_SEARCH_DSS: 736 case STV0900_SEARCH_DSS:
1023 dprintk("DSS\n"); 737 dprintk("DSS\n");
1024 stv0900_write_reg(i_params, fecmReg, 0x80); 738 stv0900_write_reg(intp, FECM, 0x80);
1025 switch (PunctureRate) { 739 switch (fec) {
1026 case STV0900_FEC_UNKNOWN: 740 case STV0900_FEC_UNKNOWN:
1027 default: 741 default:
1028 stv0900_write_reg(i_params, prvitReg, 0x13); 742 stv0900_write_reg(intp, PRVIT, 0x13);
1029 break; 743 break;
1030 case STV0900_FEC_1_2: 744 case STV0900_FEC_1_2:
1031 stv0900_write_reg(i_params, prvitReg, 0x01); 745 stv0900_write_reg(intp, PRVIT, 0x01);
1032 break; 746 break;
1033 case STV0900_FEC_2_3: 747 case STV0900_FEC_2_3:
1034 stv0900_write_reg(i_params, prvitReg, 0x02); 748 stv0900_write_reg(intp, PRVIT, 0x02);
1035 break; 749 break;
1036 case STV0900_FEC_6_7: 750 case STV0900_FEC_6_7:
1037 stv0900_write_reg(i_params, prvitReg, 0x10); 751 stv0900_write_reg(intp, PRVIT, 0x10);
1038 break; 752 break;
1039 } 753 }
1040 break; 754 break;
@@ -1043,340 +757,277 @@ static void stv0900_set_viterbi_standard(struct stv0900_internal *i_params,
1043 } 757 }
1044} 758}
1045 759
1046static void stv0900_track_optimization(struct dvb_frontend *fe) 760static enum fe_stv0900_fec stv0900_get_vit_fec(struct stv0900_internal *intp,
761 enum fe_stv0900_demod_num demod)
1047{ 762{
1048 struct stv0900_state *state = fe->demodulator_priv; 763 enum fe_stv0900_fec prate;
1049 struct stv0900_internal *i_params = state->internal; 764 s32 rate_fld = stv0900_get_bits(intp, VIT_CURPUN);
1050 enum fe_stv0900_demod_num demod = state->demod;
1051 765
1052 s32 srate, pilots, aclc, freq1, freq0, 766 switch (rate_fld) {
1053 i = 0, timed, timef, blindTunSw = 0; 767 case 13:
768 prate = STV0900_FEC_1_2;
769 break;
770 case 18:
771 prate = STV0900_FEC_2_3;
772 break;
773 case 21:
774 prate = STV0900_FEC_3_4;
775 break;
776 case 24:
777 prate = STV0900_FEC_5_6;
778 break;
779 case 25:
780 prate = STV0900_FEC_6_7;
781 break;
782 case 26:
783 prate = STV0900_FEC_7_8;
784 break;
785 default:
786 prate = STV0900_FEC_UNKNOWN;
787 break;
788 }
1054 789
1055 enum fe_stv0900_rolloff rolloff; 790 return prate;
1056 enum fe_stv0900_modcode foundModcod; 791}
1057 792
1058 dprintk(KERN_INFO "%s\n", __func__); 793void stv0900_set_dvbs1_track_car_loop(struct stv0900_internal *intp,
794 enum fe_stv0900_demod_num demod,
795 u32 srate)
796{
797 if (intp->chip_id >= 0x30) {
798 if (srate >= 15000000) {
799 stv0900_write_reg(intp, ACLC, 0x2b);
800 stv0900_write_reg(intp, BCLC, 0x1a);
801 } else if ((srate >= 7000000) && (15000000 > srate)) {
802 stv0900_write_reg(intp, ACLC, 0x0c);
803 stv0900_write_reg(intp, BCLC, 0x1b);
804 } else if (srate < 7000000) {
805 stv0900_write_reg(intp, ACLC, 0x2c);
806 stv0900_write_reg(intp, BCLC, 0x1c);
807 }
1059 808
1060 srate = stv0900_get_symbol_rate(i_params, i_params->mclk, demod); 809 } else { /*cut 2.0 and 1.x*/
1061 srate += stv0900_get_timing_offst(i_params, srate, demod); 810 stv0900_write_reg(intp, ACLC, 0x1a);
811 stv0900_write_reg(intp, BCLC, 0x09);
812 }
1062 813
1063 switch (demod) { 814}
1064 case STV0900_DEMOD_1:
1065 default:
1066 switch (i_params->dmd1_rslts.standard) {
1067 case STV0900_DVBS1_STANDARD:
1068 if (i_params->dmd1_srch_standard == STV0900_AUTO_SEARCH) {
1069 stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 1);
1070 stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 0);
1071 }
1072 815
1073 stv0900_write_bits(i_params, F0900_P1_ROLLOFF_CONTROL, i_params->rolloff); 816static void stv0900_track_optimization(struct dvb_frontend *fe)
1074 stv0900_write_bits(i_params, F0900_P1_MANUAL_ROLLOFF, 1); 817{
1075 stv0900_write_reg(i_params, R0900_P1_ERRCTRL1, 0x75); 818 struct stv0900_state *state = fe->demodulator_priv;
1076 break; 819 struct stv0900_internal *intp = state->internal;
1077 case STV0900_DSS_STANDARD: 820 enum fe_stv0900_demod_num demod = state->demod;
1078 if (i_params->dmd1_srch_standard == STV0900_AUTO_SEARCH) {
1079 stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 1);
1080 stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 0);
1081 }
1082 821
1083 stv0900_write_bits(i_params, F0900_P1_ROLLOFF_CONTROL, i_params->rolloff); 822 s32 srate,
1084 stv0900_write_bits(i_params, F0900_P1_MANUAL_ROLLOFF, 1); 823 pilots,
1085 stv0900_write_reg(i_params, R0900_P1_ERRCTRL1, 0x75); 824 aclc,
1086 break; 825 freq1,
1087 case STV0900_DVBS2_STANDARD: 826 freq0,
1088 stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 0); 827 i = 0,
1089 stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 1); 828 timed,
1090 stv0900_write_reg(i_params, R0900_P1_ACLC, 0); 829 timef,
1091 stv0900_write_reg(i_params, R0900_P1_BCLC, 0); 830 blind_tun_sw = 0,
1092 if (i_params->dmd1_rslts.frame_length == STV0900_LONG_FRAME) { 831 modulation;
1093 foundModcod = stv0900_get_bits(i_params, F0900_P1_DEMOD_MODCOD);
1094 pilots = stv0900_get_bits(i_params, F0900_P1_DEMOD_TYPE) & 0x01;
1095 aclc = stv0900_get_optim_carr_loop(srate, foundModcod, pilots, i_params->chip_id);
1096 if (foundModcod <= STV0900_QPSK_910)
1097 stv0900_write_reg(i_params, R0900_P1_ACLC2S2Q, aclc);
1098 else if (foundModcod <= STV0900_8PSK_910) {
1099 stv0900_write_reg(i_params, R0900_P1_ACLC2S2Q, 0x2a);
1100 stv0900_write_reg(i_params, R0900_P1_ACLC2S28, aclc);
1101 }
1102 832
1103 if ((i_params->demod_mode == STV0900_SINGLE) && (foundModcod > STV0900_8PSK_910)) { 833 enum fe_stv0900_rolloff rolloff;
1104 if (foundModcod <= STV0900_16APSK_910) { 834 enum fe_stv0900_modcode foundModcod;
1105 stv0900_write_reg(i_params, R0900_P1_ACLC2S2Q, 0x2a);
1106 stv0900_write_reg(i_params, R0900_P1_ACLC2S216A, aclc);
1107 } else if (foundModcod <= STV0900_32APSK_910) {
1108 stv0900_write_reg(i_params, R0900_P1_ACLC2S2Q, 0x2a);
1109 stv0900_write_reg(i_params, R0900_P1_ACLC2S232A, aclc);
1110 }
1111 }
1112 835
1113 } else { 836 dprintk("%s\n", __func__);
1114 aclc = stv0900_get_optim_short_carr_loop(srate, i_params->dmd1_rslts.modulation, i_params->chip_id);
1115 if (i_params->dmd1_rslts.modulation == STV0900_QPSK)
1116 stv0900_write_reg(i_params, R0900_P1_ACLC2S2Q, aclc);
1117
1118 else if (i_params->dmd1_rslts.modulation == STV0900_8PSK) {
1119 stv0900_write_reg(i_params, R0900_P1_ACLC2S2Q, 0x2a);
1120 stv0900_write_reg(i_params, R0900_P1_ACLC2S28, aclc);
1121 } else if (i_params->dmd1_rslts.modulation == STV0900_16APSK) {
1122 stv0900_write_reg(i_params, R0900_P1_ACLC2S2Q, 0x2a);
1123 stv0900_write_reg(i_params, R0900_P1_ACLC2S216A, aclc);
1124 } else if (i_params->dmd1_rslts.modulation == STV0900_32APSK) {
1125 stv0900_write_reg(i_params, R0900_P1_ACLC2S2Q, 0x2a);
1126 stv0900_write_reg(i_params, R0900_P1_ACLC2S232A, aclc);
1127 }
1128 837
1129 } 838 srate = stv0900_get_symbol_rate(intp, intp->mclk, demod);
839 srate += stv0900_get_timing_offst(intp, srate, demod);
1130 840
1131 if (i_params->chip_id <= 0x11) { 841 switch (intp->result[demod].standard) {
1132 if (i_params->demod_mode != STV0900_SINGLE) 842 case STV0900_DVBS1_STANDARD:
1133 stv0900_activate_s2_modcode(i_params, demod); 843 case STV0900_DSS_STANDARD:
844 dprintk("%s: found DVB-S or DSS\n", __func__);
845 if (intp->srch_standard[demod] == STV0900_AUTO_SEARCH) {
846 stv0900_write_bits(intp, DVBS1_ENABLE, 1);
847 stv0900_write_bits(intp, DVBS2_ENABLE, 0);
848 }
1134 849
1135 } 850 stv0900_write_bits(intp, ROLLOFF_CONTROL, intp->rolloff);
851 stv0900_write_bits(intp, MANUALSX_ROLLOFF, 1);
1136 852
1137 stv0900_write_reg(i_params, R0900_P1_ERRCTRL1, 0x67); 853 if (intp->chip_id < 0x30) {
1138 break; 854 stv0900_write_reg(intp, ERRCTRL1, 0x75);
1139 case STV0900_UNKNOWN_STANDARD:
1140 default:
1141 stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 1);
1142 stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 1);
1143 break; 855 break;
1144 } 856 }
1145 857
1146 freq1 = stv0900_read_reg(i_params, R0900_P1_CFR2); 858 if (stv0900_get_vit_fec(intp, demod) == STV0900_FEC_1_2) {
1147 freq0 = stv0900_read_reg(i_params, R0900_P1_CFR1); 859 stv0900_write_reg(intp, GAUSSR0, 0x98);
1148 rolloff = stv0900_get_bits(i_params, F0900_P1_ROLLOFF_STATUS); 860 stv0900_write_reg(intp, CCIR0, 0x18);
1149 if (i_params->dmd1_srch_algo == STV0900_BLIND_SEARCH) { 861 } else {
1150 stv0900_write_reg(i_params, R0900_P1_SFRSTEP, 0x00); 862 stv0900_write_reg(intp, GAUSSR0, 0x18);
1151 stv0900_write_bits(i_params, F0900_P1_SCAN_ENABLE, 0); 863 stv0900_write_reg(intp, CCIR0, 0x18);
1152 stv0900_write_bits(i_params, F0900_P1_CFR_AUTOSCAN, 0);
1153 stv0900_write_reg(i_params, R0900_P1_TMGCFG2, 0x01);
1154 stv0900_set_symbol_rate(i_params, i_params->mclk, srate, demod);
1155 stv0900_set_max_symbol_rate(i_params, i_params->mclk, srate, demod);
1156 stv0900_set_min_symbol_rate(i_params, i_params->mclk, srate, demod);
1157 blindTunSw = 1;
1158 } 864 }
1159 865
1160 if (i_params->chip_id >= 0x20) { 866 stv0900_write_reg(intp, ERRCTRL1, 0x75);
1161 if ((i_params->dmd1_srch_standard == STV0900_SEARCH_DVBS1) || (i_params->dmd1_srch_standard == STV0900_SEARCH_DSS) || (i_params->dmd1_srch_standard == STV0900_AUTO_SEARCH)) { 867 break;
1162 stv0900_write_reg(i_params, R0900_P1_VAVSRVIT, 0x0a); 868 case STV0900_DVBS2_STANDARD:
1163 stv0900_write_reg(i_params, R0900_P1_VITSCALE, 0x0); 869 dprintk("%s: found DVB-S2\n", __func__);
870 stv0900_write_bits(intp, DVBS1_ENABLE, 0);
871 stv0900_write_bits(intp, DVBS2_ENABLE, 1);
872 stv0900_write_reg(intp, ACLC, 0);
873 stv0900_write_reg(intp, BCLC, 0);
874 if (intp->result[demod].frame_len == STV0900_LONG_FRAME) {
875 foundModcod = stv0900_get_bits(intp, DEMOD_MODCOD);
876 pilots = stv0900_get_bits(intp, DEMOD_TYPE) & 0x01;
877 aclc = stv0900_get_optim_carr_loop(srate,
878 foundModcod,
879 pilots,
880 intp->chip_id);
881 if (foundModcod <= STV0900_QPSK_910)
882 stv0900_write_reg(intp, ACLC2S2Q, aclc);
883 else if (foundModcod <= STV0900_8PSK_910) {
884 stv0900_write_reg(intp, ACLC2S2Q, 0x2a);
885 stv0900_write_reg(intp, ACLC2S28, aclc);
1164 } 886 }
1165 }
1166
1167 if (i_params->chip_id < 0x20)
1168 stv0900_write_reg(i_params, R0900_P1_CARHDR, 0x08);
1169
1170 if (i_params->chip_id == 0x10)
1171 stv0900_write_reg(i_params, R0900_P1_CORRELEXP, 0x0A);
1172 887
1173 stv0900_write_reg(i_params, R0900_P1_AGC2REF, 0x38); 888 if ((intp->demod_mode == STV0900_SINGLE) &&
1174 889 (foundModcod > STV0900_8PSK_910)) {
1175 if ((i_params->chip_id >= 0x20) || (blindTunSw == 1) || (i_params->dmd1_symbol_rate < 10000000)) { 890 if (foundModcod <= STV0900_16APSK_910) {
1176 stv0900_write_reg(i_params, R0900_P1_CFRINIT1, freq1); 891 stv0900_write_reg(intp, ACLC2S2Q, 0x2a);
1177 stv0900_write_reg(i_params, R0900_P1_CFRINIT0, freq0); 892 stv0900_write_reg(intp, ACLC2S216A,
1178 i_params->tuner1_bw = stv0900_carrier_width(srate, i_params->rolloff) + 10000000; 893 aclc);
1179 894 } else if (foundModcod <= STV0900_32APSK_910) {
1180 if ((i_params->chip_id >= 0x20) || (blindTunSw == 1)) { 895 stv0900_write_reg(intp, ACLC2S2Q, 0x2a);
1181 if (i_params->dmd1_srch_algo != STV0900_WARM_START) 896 stv0900_write_reg(intp, ACLC2S232A,
1182 stv0900_set_bandwidth(fe, i_params->tuner1_bw); 897 aclc);
898 }
1183 } 899 }
1184 900
1185 if ((i_params->dmd1_srch_algo == STV0900_BLIND_SEARCH) || (i_params->dmd1_symbol_rate < 10000000)) 901 } else {
1186 msleep(50); 902 modulation = intp->result[demod].modulation;
1187 else 903 aclc = stv0900_get_optim_short_carr_loop(srate,
1188 msleep(5); 904 modulation, intp->chip_id);
1189 905 if (modulation == STV0900_QPSK)
1190 stv0900_get_lock_timeout(&timed, &timef, srate, STV0900_WARM_START); 906 stv0900_write_reg(intp, ACLC2S2Q, aclc);
1191 907 else if (modulation == STV0900_8PSK) {
1192 if (stv0900_get_demod_lock(i_params, demod, timed / 2) == FALSE) { 908 stv0900_write_reg(intp, ACLC2S2Q, 0x2a);
1193 stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1F); 909 stv0900_write_reg(intp, ACLC2S28, aclc);
1194 stv0900_write_reg(i_params, R0900_P1_CFRINIT1, freq1); 910 } else if (modulation == STV0900_16APSK) {
1195 stv0900_write_reg(i_params, R0900_P1_CFRINIT0, freq0); 911 stv0900_write_reg(intp, ACLC2S2Q, 0x2a);
1196 stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x18); 912 stv0900_write_reg(intp, ACLC2S216A, aclc);
1197 i = 0; 913 } else if (modulation == STV0900_32APSK) {
1198 while ((stv0900_get_demod_lock(i_params, demod, timed / 2) == FALSE) && (i <= 2)) { 914 stv0900_write_reg(intp, ACLC2S2Q, 0x2a);
1199 stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1F); 915 stv0900_write_reg(intp, ACLC2S232A, aclc);
1200 stv0900_write_reg(i_params, R0900_P1_CFRINIT1, freq1);
1201 stv0900_write_reg(i_params, R0900_P1_CFRINIT0, freq0);
1202 stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x18);
1203 i++;
1204 }
1205 } 916 }
1206 917
1207 } 918 }
1208 919
1209 if (i_params->chip_id >= 0x20) 920 if (intp->chip_id <= 0x11) {
1210 stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0x49); 921 if (intp->demod_mode != STV0900_SINGLE)
922 stv0900_activate_s2_modcod(intp, demod);
1211 923
1212 if ((i_params->dmd1_rslts.standard == STV0900_DVBS1_STANDARD) || (i_params->dmd1_rslts.standard == STV0900_DSS_STANDARD)) 924 }
1213 stv0900_set_viterbi_tracq(i_params, demod);
1214 925
926 stv0900_write_reg(intp, ERRCTRL1, 0x67);
1215 break; 927 break;
928 case STV0900_UNKNOWN_STANDARD:
929 default:
930 dprintk("%s: found unknown standard\n", __func__);
931 stv0900_write_bits(intp, DVBS1_ENABLE, 1);
932 stv0900_write_bits(intp, DVBS2_ENABLE, 1);
933 break;
934 }
1216 935
1217 case STV0900_DEMOD_2: 936 freq1 = stv0900_read_reg(intp, CFR2);
1218 switch (i_params->dmd2_rslts.standard) { 937 freq0 = stv0900_read_reg(intp, CFR1);
1219 case STV0900_DVBS1_STANDARD: 938 rolloff = stv0900_get_bits(intp, ROLLOFF_STATUS);
1220 939 if (intp->srch_algo[demod] == STV0900_BLIND_SEARCH) {
1221 if (i_params->dmd2_srch_stndrd == STV0900_AUTO_SEARCH) { 940 stv0900_write_reg(intp, SFRSTEP, 0x00);
1222 stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 1); 941 stv0900_write_bits(intp, SCAN_ENABLE, 0);
1223 stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 0); 942 stv0900_write_bits(intp, CFR_AUTOSCAN, 0);
1224 } 943 stv0900_write_reg(intp, TMGCFG2, 0xc1);
1225 944 stv0900_set_symbol_rate(intp, intp->mclk, srate, demod);
1226 stv0900_write_bits(i_params, F0900_P2_ROLLOFF_CONTROL, i_params->rolloff); 945 blind_tun_sw = 1;
1227 stv0900_write_bits(i_params, F0900_P2_MANUAL_ROLLOFF, 1); 946 if (intp->result[demod].standard != STV0900_DVBS2_STANDARD)
1228 stv0900_write_reg(i_params, R0900_P2_ERRCTRL1, 0x75); 947 stv0900_set_dvbs1_track_car_loop(intp, demod, srate);
1229 break;
1230 case STV0900_DSS_STANDARD:
1231 if (i_params->dmd2_srch_stndrd == STV0900_AUTO_SEARCH) {
1232 stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 1);
1233 stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 0);
1234 }
1235
1236 stv0900_write_bits(i_params, F0900_P2_ROLLOFF_CONTROL, i_params->rolloff);
1237 stv0900_write_bits(i_params, F0900_P2_MANUAL_ROLLOFF, 1);
1238 stv0900_write_reg(i_params, R0900_P2_ERRCTRL1, 0x75);
1239 break;
1240 case STV0900_DVBS2_STANDARD:
1241 stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 0);
1242 stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 1);
1243 stv0900_write_reg(i_params, R0900_P2_ACLC, 0);
1244 stv0900_write_reg(i_params, R0900_P2_BCLC, 0);
1245 if (i_params->dmd2_rslts.frame_length == STV0900_LONG_FRAME) {
1246 foundModcod = stv0900_get_bits(i_params, F0900_P2_DEMOD_MODCOD);
1247 pilots = stv0900_get_bits(i_params, F0900_P2_DEMOD_TYPE) & 0x01;
1248 aclc = stv0900_get_optim_carr_loop(srate, foundModcod, pilots, i_params->chip_id);
1249 if (foundModcod <= STV0900_QPSK_910)
1250 stv0900_write_reg(i_params, R0900_P2_ACLC2S2Q, aclc);
1251 else if (foundModcod <= STV0900_8PSK_910) {
1252 stv0900_write_reg(i_params, R0900_P2_ACLC2S2Q, 0x2a);
1253 stv0900_write_reg(i_params, R0900_P2_ACLC2S28, aclc);
1254 }
1255 948
1256 if ((i_params->demod_mode == STV0900_SINGLE) && (foundModcod > STV0900_8PSK_910)) { 949 }
1257 if (foundModcod <= STV0900_16APSK_910) {
1258 stv0900_write_reg(i_params, R0900_P2_ACLC2S2Q, 0x2a);
1259 stv0900_write_reg(i_params, R0900_P2_ACLC2S216A, aclc);
1260 } else if (foundModcod <= STV0900_32APSK_910) {
1261 stv0900_write_reg(i_params, R0900_P2_ACLC2S2Q, 0x2a);
1262 stv0900_write_reg(i_params, R0900_P2_ACLC2S232A, aclc);
1263 }
1264 950
1265 } 951 if (intp->chip_id >= 0x20) {
952 if ((intp->srch_standard[demod] == STV0900_SEARCH_DVBS1) ||
953 (intp->srch_standard[demod] ==
954 STV0900_SEARCH_DSS) ||
955 (intp->srch_standard[demod] ==
956 STV0900_AUTO_SEARCH)) {
957 stv0900_write_reg(intp, VAVSRVIT, 0x0a);
958 stv0900_write_reg(intp, VITSCALE, 0x0);
959 }
960 }
1266 961
1267 } else { 962 if (intp->chip_id < 0x20)
1268 aclc = stv0900_get_optim_short_carr_loop(srate, 963 stv0900_write_reg(intp, CARHDR, 0x08);
1269 i_params->dmd2_rslts.modulation,
1270 i_params->chip_id);
1271
1272 if (i_params->dmd2_rslts.modulation == STV0900_QPSK)
1273 stv0900_write_reg(i_params, R0900_P2_ACLC2S2Q, aclc);
1274
1275 else if (i_params->dmd2_rslts.modulation == STV0900_8PSK) {
1276 stv0900_write_reg(i_params, R0900_P2_ACLC2S2Q, 0x2a);
1277 stv0900_write_reg(i_params, R0900_P2_ACLC2S28, aclc);
1278 } else if (i_params->dmd2_rslts.modulation == STV0900_16APSK) {
1279 stv0900_write_reg(i_params, R0900_P2_ACLC2S2Q, 0x2a);
1280 stv0900_write_reg(i_params, R0900_P2_ACLC2S216A, aclc);
1281 } else if (i_params->dmd2_rslts.modulation == STV0900_32APSK) {
1282 stv0900_write_reg(i_params, R0900_P2_ACLC2S2Q, 0x2a);
1283 stv0900_write_reg(i_params, R0900_P2_ACLC2S232A, aclc);
1284 }
1285 }
1286 964
1287 stv0900_write_reg(i_params, R0900_P2_ERRCTRL1, 0x67); 965 if (intp->chip_id == 0x10)
966 stv0900_write_reg(intp, CORRELEXP, 0x0a);
1288 967
1289 break; 968 stv0900_write_reg(intp, AGC2REF, 0x38);
1290 case STV0900_UNKNOWN_STANDARD:
1291 default:
1292 stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 1);
1293 stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 1);
1294 break;
1295 }
1296 969
1297 freq1 = stv0900_read_reg(i_params, R0900_P2_CFR2); 970 if ((intp->chip_id >= 0x20) ||
1298 freq0 = stv0900_read_reg(i_params, R0900_P2_CFR1); 971 (blind_tun_sw == 1) ||
1299 rolloff = stv0900_get_bits(i_params, F0900_P2_ROLLOFF_STATUS); 972 (intp->symbol_rate[demod] < 10000000)) {
1300 if (i_params->dmd2_srch_algo == STV0900_BLIND_SEARCH) { 973 stv0900_write_reg(intp, CFRINIT1, freq1);
1301 stv0900_write_reg(i_params, R0900_P2_SFRSTEP, 0x00); 974 stv0900_write_reg(intp, CFRINIT0, freq0);
1302 stv0900_write_bits(i_params, F0900_P2_SCAN_ENABLE, 0); 975 intp->bw[demod] = stv0900_carrier_width(srate,
1303 stv0900_write_bits(i_params, F0900_P2_CFR_AUTOSCAN, 0); 976 intp->rolloff) + 10000000;
1304 stv0900_write_reg(i_params, R0900_P2_TMGCFG2, 0x01);
1305 stv0900_set_symbol_rate(i_params, i_params->mclk, srate, demod);
1306 stv0900_set_max_symbol_rate(i_params, i_params->mclk, srate, demod);
1307 stv0900_set_min_symbol_rate(i_params, i_params->mclk, srate, demod);
1308 blindTunSw = 1;
1309 }
1310 977
1311 if (i_params->chip_id >= 0x20) { 978 if ((intp->chip_id >= 0x20) || (blind_tun_sw == 1)) {
1312 if ((i_params->dmd2_srch_stndrd == STV0900_SEARCH_DVBS1) || (i_params->dmd2_srch_stndrd == STV0900_SEARCH_DSS) || (i_params->dmd2_srch_stndrd == STV0900_AUTO_SEARCH)) { 979 if (intp->srch_algo[demod] != STV0900_WARM_START)
1313 stv0900_write_reg(i_params, R0900_P2_VAVSRVIT, 0x0a); 980 stv0900_set_bandwidth(fe, intp->bw[demod]);
1314 stv0900_write_reg(i_params, R0900_P2_VITSCALE, 0x0);
1315 }
1316 } 981 }
1317 982
1318 if (i_params->chip_id < 0x20) 983 if ((intp->srch_algo[demod] == STV0900_BLIND_SEARCH) ||
1319 stv0900_write_reg(i_params, R0900_P2_CARHDR, 0x08); 984 (intp->symbol_rate[demod] < 10000000))
1320 985 msleep(50);
1321 if (i_params->chip_id == 0x10) 986 else
1322 stv0900_write_reg(i_params, R0900_P2_CORRELEXP, 0x0a); 987 msleep(5);
1323
1324 stv0900_write_reg(i_params, R0900_P2_AGC2REF, 0x38);
1325 if ((i_params->chip_id >= 0x20) || (blindTunSw == 1) || (i_params->dmd2_symbol_rate < 10000000)) {
1326 stv0900_write_reg(i_params, R0900_P2_CFRINIT1, freq1);
1327 stv0900_write_reg(i_params, R0900_P2_CFRINIT0, freq0);
1328 i_params->tuner2_bw = stv0900_carrier_width(srate, i_params->rolloff) + 10000000;
1329 988
1330 if ((i_params->chip_id >= 0x20) || (blindTunSw == 1)) { 989 stv0900_get_lock_timeout(&timed, &timef, srate,
1331 if (i_params->dmd2_srch_algo != STV0900_WARM_START) 990 STV0900_WARM_START);
1332 stv0900_set_bandwidth(fe, i_params->tuner2_bw);
1333 }
1334 991
1335 if ((i_params->dmd2_srch_algo == STV0900_BLIND_SEARCH) || (i_params->dmd2_symbol_rate < 10000000)) 992 if (stv0900_get_demod_lock(intp, demod, timed / 2) == FALSE) {
1336 msleep(50); 993 stv0900_write_reg(intp, DMDISTATE, 0x1f);
1337 else 994 stv0900_write_reg(intp, CFRINIT1, freq1);
1338 msleep(5); 995 stv0900_write_reg(intp, CFRINIT0, freq0);
1339 996 stv0900_write_reg(intp, DMDISTATE, 0x18);
1340 stv0900_get_lock_timeout(&timed, &timef, srate, STV0900_WARM_START); 997 i = 0;
1341 if (stv0900_get_demod_lock(i_params, demod, timed / 2) == FALSE) { 998 while ((stv0900_get_demod_lock(intp,
1342 stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1F); 999 demod,
1343 stv0900_write_reg(i_params, R0900_P2_CFRINIT1, freq1); 1000 timed / 2) == FALSE) &&
1344 stv0900_write_reg(i_params, R0900_P2_CFRINIT0, freq0); 1001 (i <= 2)) {
1345 stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x18); 1002 stv0900_write_reg(intp, DMDISTATE, 0x1f);
1346 i = 0; 1003 stv0900_write_reg(intp, CFRINIT1, freq1);
1347 while ((stv0900_get_demod_lock(i_params, demod, timed / 2) == FALSE) && (i <= 2)) { 1004 stv0900_write_reg(intp, CFRINIT0, freq0);
1348 stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1F); 1005 stv0900_write_reg(intp, DMDISTATE, 0x18);
1349 stv0900_write_reg(i_params, R0900_P2_CFRINIT1, freq1); 1006 i++;
1350 stv0900_write_reg(i_params, R0900_P2_CFRINIT0, freq0);
1351 stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x18);
1352 i++;
1353 }
1354 } 1007 }
1355 } 1008 }
1356 1009
1357 if (i_params->chip_id >= 0x20) 1010 }
1358 stv0900_write_reg(i_params, R0900_P2_CARFREQ, 0x49);
1359 1011
1360 if ((i_params->dmd2_rslts.standard == STV0900_DVBS1_STANDARD) || (i_params->dmd2_rslts.standard == STV0900_DSS_STANDARD)) 1012 if (intp->chip_id >= 0x20)
1361 stv0900_set_viterbi_tracq(i_params, demod); 1013 stv0900_write_reg(intp, CARFREQ, 0x49);
1014
1015 if ((intp->result[demod].standard == STV0900_DVBS1_STANDARD) ||
1016 (intp->result[demod].standard == STV0900_DSS_STANDARD))
1017 stv0900_set_viterbi_tracq(intp, demod);
1362 1018
1363 break;
1364 }
1365} 1019}
1366 1020
1367static int stv0900_get_fec_lock(struct stv0900_internal *i_params, enum fe_stv0900_demod_num demod, s32 time_out) 1021static int stv0900_get_fec_lock(struct stv0900_internal *intp,
1022 enum fe_stv0900_demod_num demod, s32 time_out)
1368{ 1023{
1369 s32 timer = 0, lock = 0, header_field, pktdelin_field, lock_vit_field; 1024 s32 timer = 0, lock = 0;
1370 1025
1371 enum fe_stv0900_search_state dmd_state; 1026 enum fe_stv0900_search_state dmd_state;
1372 1027
1373 dprintk(KERN_INFO "%s\n", __func__); 1028 dprintk("%s\n", __func__);
1374 1029
1375 dmd_reg(header_field, F0900_P1_HEADER_MODE, F0900_P2_HEADER_MODE); 1030 dmd_state = stv0900_get_bits(intp, HEADER_MODE);
1376 dmd_reg(pktdelin_field, F0900_P1_PKTDELIN_LOCK, F0900_P2_PKTDELIN_LOCK);
1377 dmd_reg(lock_vit_field, F0900_P1_LOCKEDVIT, F0900_P2_LOCKEDVIT);
1378
1379 dmd_state = stv0900_get_bits(i_params, header_field);
1380 1031
1381 while ((timer < time_out) && (lock == 0)) { 1032 while ((timer < time_out) && (lock == 0)) {
1382 switch (dmd_state) { 1033 switch (dmd_state) {
@@ -1386,10 +1037,10 @@ static int stv0900_get_fec_lock(struct stv0900_internal *i_params, enum fe_stv09
1386 lock = 0; 1037 lock = 0;
1387 break; 1038 break;
1388 case STV0900_DVBS2_FOUND: 1039 case STV0900_DVBS2_FOUND:
1389 lock = stv0900_get_bits(i_params, pktdelin_field); 1040 lock = stv0900_get_bits(intp, PKTDELIN_LOCK);
1390 break; 1041 break;
1391 case STV0900_DVBS_FOUND: 1042 case STV0900_DVBS_FOUND:
1392 lock = stv0900_get_bits(i_params, lock_vit_field); 1043 lock = stv0900_get_bits(intp, LOCKEDVIT);
1393 break; 1044 break;
1394 } 1045 }
1395 1046
@@ -1400,46 +1051,44 @@ static int stv0900_get_fec_lock(struct stv0900_internal *i_params, enum fe_stv09
1400 } 1051 }
1401 1052
1402 if (lock) 1053 if (lock)
1403 dprintk("DEMOD FEC LOCK OK\n"); 1054 dprintk("%s: DEMOD FEC LOCK OK\n", __func__);
1404 else 1055 else
1405 dprintk("DEMOD FEC LOCK FAIL\n"); 1056 dprintk("%s: DEMOD FEC LOCK FAIL\n", __func__);
1406 1057
1407 return lock; 1058 return lock;
1408} 1059}
1409 1060
1410static int stv0900_wait_for_lock(struct stv0900_internal *i_params, 1061static int stv0900_wait_for_lock(struct stv0900_internal *intp,
1411 enum fe_stv0900_demod_num demod, 1062 enum fe_stv0900_demod_num demod,
1412 s32 dmd_timeout, s32 fec_timeout) 1063 s32 dmd_timeout, s32 fec_timeout)
1413{ 1064{
1414 1065
1415 s32 timer = 0, lock = 0, str_merg_rst_fld, str_merg_lock_fld; 1066 s32 timer = 0, lock = 0;
1416
1417 dprintk(KERN_INFO "%s\n", __func__);
1418 1067
1419 dmd_reg(str_merg_rst_fld, F0900_P1_RST_HWARE, F0900_P2_RST_HWARE); 1068 dprintk("%s\n", __func__);
1420 dmd_reg(str_merg_lock_fld, F0900_P1_TSFIFO_LINEOK, F0900_P2_TSFIFO_LINEOK);
1421 1069
1422 lock = stv0900_get_demod_lock(i_params, demod, dmd_timeout); 1070 lock = stv0900_get_demod_lock(intp, demod, dmd_timeout);
1423 1071
1424 if (lock) 1072 if (lock)
1425 lock = lock && stv0900_get_fec_lock(i_params, demod, fec_timeout); 1073 lock = lock && stv0900_get_fec_lock(intp, demod, fec_timeout);
1426 1074
1427 if (lock) { 1075 if (lock) {
1428 lock = 0; 1076 lock = 0;
1429 1077
1430 dprintk(KERN_INFO "%s: Timer = %d, time_out = %d\n", __func__, timer, fec_timeout); 1078 dprintk("%s: Timer = %d, time_out = %d\n",
1079 __func__, timer, fec_timeout);
1431 1080
1432 while ((timer < fec_timeout) && (lock == 0)) { 1081 while ((timer < fec_timeout) && (lock == 0)) {
1433 lock = stv0900_get_bits(i_params, str_merg_lock_fld); 1082 lock = stv0900_get_bits(intp, TSFIFO_LINEOK);
1434 msleep(1); 1083 msleep(1);
1435 timer++; 1084 timer++;
1436 } 1085 }
1437 } 1086 }
1438 1087
1439 if (lock) 1088 if (lock)
1440 dprintk(KERN_INFO "%s: DEMOD LOCK OK\n", __func__); 1089 dprintk("%s: DEMOD LOCK OK\n", __func__);
1441 else 1090 else
1442 dprintk(KERN_INFO "%s: DEMOD LOCK FAIL\n", __func__); 1091 dprintk("%s: DEMOD LOCK FAIL\n", __func__);
1443 1092
1444 if (lock) 1093 if (lock)
1445 return TRUE; 1094 return TRUE;
@@ -1451,43 +1100,43 @@ enum fe_stv0900_tracking_standard stv0900_get_standard(struct dvb_frontend *fe,
1451 enum fe_stv0900_demod_num demod) 1100 enum fe_stv0900_demod_num demod)
1452{ 1101{
1453 struct stv0900_state *state = fe->demodulator_priv; 1102 struct stv0900_state *state = fe->demodulator_priv;
1454 struct stv0900_internal *i_params = state->internal; 1103 struct stv0900_internal *intp = state->internal;
1455 enum fe_stv0900_tracking_standard fnd_standard; 1104 enum fe_stv0900_tracking_standard fnd_standard;
1456 s32 state_field,
1457 dss_dvb_field;
1458 1105
1459 dprintk(KERN_INFO "%s\n", __func__); 1106 int hdr_mode = stv0900_get_bits(intp, HEADER_MODE);
1460 1107
1461 dmd_reg(state_field, F0900_P1_HEADER_MODE, F0900_P2_HEADER_MODE); 1108 switch (hdr_mode) {
1462 dmd_reg(dss_dvb_field, F0900_P1_DSS_DVB, F0900_P2_DSS_DVB); 1109 case 2:
1463
1464 if (stv0900_get_bits(i_params, state_field) == 2)
1465 fnd_standard = STV0900_DVBS2_STANDARD; 1110 fnd_standard = STV0900_DVBS2_STANDARD;
1466 1111 break;
1467 else if (stv0900_get_bits(i_params, state_field) == 3) { 1112 case 3:
1468 if (stv0900_get_bits(i_params, dss_dvb_field) == 1) 1113 if (stv0900_get_bits(intp, DSS_DVB) == 1)
1469 fnd_standard = STV0900_DSS_STANDARD; 1114 fnd_standard = STV0900_DSS_STANDARD;
1470 else 1115 else
1471 fnd_standard = STV0900_DVBS1_STANDARD; 1116 fnd_standard = STV0900_DVBS1_STANDARD;
1472 } else 1117
1118 break;
1119 default:
1473 fnd_standard = STV0900_UNKNOWN_STANDARD; 1120 fnd_standard = STV0900_UNKNOWN_STANDARD;
1121 }
1122
1123 dprintk("%s: standard %d\n", __func__, fnd_standard);
1474 1124
1475 return fnd_standard; 1125 return fnd_standard;
1476} 1126}
1477 1127
1478static s32 stv0900_get_carr_freq(struct stv0900_internal *i_params, u32 mclk, 1128static s32 stv0900_get_carr_freq(struct stv0900_internal *intp, u32 mclk,
1479 enum fe_stv0900_demod_num demod) 1129 enum fe_stv0900_demod_num demod)
1480{ 1130{
1481 s32 cfr_field2, cfr_field1, cfr_field0, 1131 s32 derot,
1482 derot, rem1, rem2, intval1, intval2; 1132 rem1,
1133 rem2,
1134 intval1,
1135 intval2;
1483 1136
1484 dmd_reg(cfr_field2, F0900_P1_CAR_FREQ2, F0900_P2_CAR_FREQ2); 1137 derot = (stv0900_get_bits(intp, CAR_FREQ2) << 16) +
1485 dmd_reg(cfr_field1, F0900_P1_CAR_FREQ1, F0900_P2_CAR_FREQ1); 1138 (stv0900_get_bits(intp, CAR_FREQ1) << 8) +
1486 dmd_reg(cfr_field0, F0900_P1_CAR_FREQ0, F0900_P2_CAR_FREQ0); 1139 (stv0900_get_bits(intp, CAR_FREQ0));
1487
1488 derot = (stv0900_get_bits(i_params, cfr_field2) << 16) +
1489 (stv0900_get_bits(i_params, cfr_field1) << 8) +
1490 (stv0900_get_bits(i_params, cfr_field0));
1491 1140
1492 derot = ge2comp(derot, 24); 1141 derot = ge2comp(derot, 24);
1493 intval1 = mclk >> 12; 1142 intval1 = mclk >> 12;
@@ -1505,7 +1154,7 @@ static u32 stv0900_get_tuner_freq(struct dvb_frontend *fe)
1505{ 1154{
1506 struct dvb_frontend_ops *frontend_ops = NULL; 1155 struct dvb_frontend_ops *frontend_ops = NULL;
1507 struct dvb_tuner_ops *tuner_ops = NULL; 1156 struct dvb_tuner_ops *tuner_ops = NULL;
1508 u32 frequency = 0; 1157 u32 freq = 0;
1509 1158
1510 if (&fe->ops) 1159 if (&fe->ops)
1511 frontend_ops = &fe->ops; 1160 frontend_ops = &fe->ops;
@@ -1514,304 +1163,159 @@ static u32 stv0900_get_tuner_freq(struct dvb_frontend *fe)
1514 tuner_ops = &frontend_ops->tuner_ops; 1163 tuner_ops = &frontend_ops->tuner_ops;
1515 1164
1516 if (tuner_ops->get_frequency) { 1165 if (tuner_ops->get_frequency) {
1517 if ((tuner_ops->get_frequency(fe, &frequency)) < 0) 1166 if ((tuner_ops->get_frequency(fe, &freq)) < 0)
1518 dprintk("%s: Invalid parameter\n", __func__); 1167 dprintk("%s: Invalid parameter\n", __func__);
1519 else 1168 else
1520 dprintk("%s: Frequency=%d\n", __func__, frequency); 1169 dprintk("%s: Frequency=%d\n", __func__, freq);
1521
1522 }
1523
1524 return frequency;
1525}
1526
1527static enum fe_stv0900_fec stv0900_get_vit_fec(struct stv0900_internal *i_params,
1528 enum fe_stv0900_demod_num demod)
1529{
1530 s32 rate_fld, vit_curpun_fld;
1531 enum fe_stv0900_fec prate;
1532 1170
1533 dmd_reg(vit_curpun_fld, F0900_P1_VIT_CURPUN, F0900_P2_VIT_CURPUN);
1534 rate_fld = stv0900_get_bits(i_params, vit_curpun_fld);
1535
1536 switch (rate_fld) {
1537 case 13:
1538 prate = STV0900_FEC_1_2;
1539 break;
1540 case 18:
1541 prate = STV0900_FEC_2_3;
1542 break;
1543 case 21:
1544 prate = STV0900_FEC_3_4;
1545 break;
1546 case 24:
1547 prate = STV0900_FEC_5_6;
1548 break;
1549 case 25:
1550 prate = STV0900_FEC_6_7;
1551 break;
1552 case 26:
1553 prate = STV0900_FEC_7_8;
1554 break;
1555 default:
1556 prate = STV0900_FEC_UNKNOWN;
1557 break;
1558 } 1171 }
1559 1172
1560 return prate; 1173 return freq;
1561} 1174}
1562 1175
1563static enum fe_stv0900_signal_type stv0900_get_signal_params(struct dvb_frontend *fe) 1176static enum
1177fe_stv0900_signal_type stv0900_get_signal_params(struct dvb_frontend *fe)
1564{ 1178{
1565 struct stv0900_state *state = fe->demodulator_priv; 1179 struct stv0900_state *state = fe->demodulator_priv;
1566 struct stv0900_internal *i_params = state->internal; 1180 struct stv0900_internal *intp = state->internal;
1567 enum fe_stv0900_demod_num demod = state->demod; 1181 enum fe_stv0900_demod_num demod = state->demod;
1568 enum fe_stv0900_signal_type range = STV0900_OUTOFRANGE; 1182 enum fe_stv0900_signal_type range = STV0900_OUTOFRANGE;
1569 s32 offsetFreq, 1183 struct stv0900_signal_info *result = &intp->result[demod];
1570 srate_offset, 1184 s32 offsetFreq,
1571 i = 0; 1185 srate_offset;
1186 int i = 0,
1187 d = demod;
1572 1188
1573 u8 timing; 1189 u8 timing;
1574 1190
1575 msleep(5); 1191 msleep(5);
1576 switch (demod) { 1192 if (intp->srch_algo[d] == STV0900_BLIND_SEARCH) {
1577 case STV0900_DEMOD_1: 1193 timing = stv0900_read_reg(intp, TMGREG2);
1578 default: 1194 i = 0;
1579 if (i_params->dmd1_srch_algo == STV0900_BLIND_SEARCH) { 1195 stv0900_write_reg(intp, SFRSTEP, 0x5c);
1580 timing = stv0900_read_reg(i_params, R0900_P1_TMGREG2); 1196
1581 i = 0; 1197 while ((i <= 50) && (timing != 0) && (timing != 0xff)) {
1582 stv0900_write_reg(i_params, R0900_P1_SFRSTEP, 0x5c); 1198 timing = stv0900_read_reg(intp, TMGREG2);
1583 1199 msleep(5);
1584 while ((i <= 50) && (timing != 0) && (timing != 0xFF)) { 1200 i += 5;
1585 timing = stv0900_read_reg(i_params, R0900_P1_TMGREG2);
1586 msleep(5);
1587 i += 5;
1588 }
1589 } 1201 }
1202 }
1590 1203
1591 i_params->dmd1_rslts.standard = stv0900_get_standard(fe, demod); 1204 result->standard = stv0900_get_standard(fe, d);
1592 i_params->dmd1_rslts.frequency = stv0900_get_tuner_freq(fe); 1205 result->frequency = stv0900_get_tuner_freq(fe);
1593 offsetFreq = stv0900_get_carr_freq(i_params, i_params->mclk, demod) / 1000; 1206 offsetFreq = stv0900_get_carr_freq(intp, intp->mclk, d) / 1000;
1594 i_params->dmd1_rslts.frequency += offsetFreq; 1207 result->frequency += offsetFreq;
1595 i_params->dmd1_rslts.symbol_rate = stv0900_get_symbol_rate(i_params, i_params->mclk, demod); 1208 result->symbol_rate = stv0900_get_symbol_rate(intp, intp->mclk, d);
1596 srate_offset = stv0900_get_timing_offst(i_params, i_params->dmd1_rslts.symbol_rate, demod); 1209 srate_offset = stv0900_get_timing_offst(intp, result->symbol_rate, d);
1597 i_params->dmd1_rslts.symbol_rate += srate_offset; 1210 result->symbol_rate += srate_offset;
1598 i_params->dmd1_rslts.fec = stv0900_get_vit_fec(i_params, demod); 1211 result->fec = stv0900_get_vit_fec(intp, d);
1599 i_params->dmd1_rslts.modcode = stv0900_get_bits(i_params, F0900_P1_DEMOD_MODCOD); 1212 result->modcode = stv0900_get_bits(intp, DEMOD_MODCOD);
1600 i_params->dmd1_rslts.pilot = stv0900_get_bits(i_params, F0900_P1_DEMOD_TYPE) & 0x01; 1213 result->pilot = stv0900_get_bits(intp, DEMOD_TYPE) & 0x01;
1601 i_params->dmd1_rslts.frame_length = ((u32)stv0900_get_bits(i_params, F0900_P1_DEMOD_TYPE)) >> 1; 1214 result->frame_len = ((u32)stv0900_get_bits(intp, DEMOD_TYPE)) >> 1;
1602 i_params->dmd1_rslts.rolloff = stv0900_get_bits(i_params, F0900_P1_ROLLOFF_STATUS); 1215 result->rolloff = stv0900_get_bits(intp, ROLLOFF_STATUS);
1603 switch (i_params->dmd1_rslts.standard) { 1216 switch (result->standard) {
1604 case STV0900_DVBS2_STANDARD: 1217 case STV0900_DVBS2_STANDARD:
1605 i_params->dmd1_rslts.spectrum = stv0900_get_bits(i_params, F0900_P1_SPECINV_DEMOD); 1218 result->spectrum = stv0900_get_bits(intp, SPECINV_DEMOD);
1606 if (i_params->dmd1_rslts.modcode <= STV0900_QPSK_910) 1219 if (result->modcode <= STV0900_QPSK_910)
1607 i_params->dmd1_rslts.modulation = STV0900_QPSK; 1220 result->modulation = STV0900_QPSK;
1608 else if (i_params->dmd1_rslts.modcode <= STV0900_8PSK_910) 1221 else if (result->modcode <= STV0900_8PSK_910)
1609 i_params->dmd1_rslts.modulation = STV0900_8PSK; 1222 result->modulation = STV0900_8PSK;
1610 else if (i_params->dmd1_rslts.modcode <= STV0900_16APSK_910) 1223 else if (result->modcode <= STV0900_16APSK_910)
1611 i_params->dmd1_rslts.modulation = STV0900_16APSK; 1224 result->modulation = STV0900_16APSK;
1612 else if (i_params->dmd1_rslts.modcode <= STV0900_32APSK_910) 1225 else if (result->modcode <= STV0900_32APSK_910)
1613 i_params->dmd1_rslts.modulation = STV0900_32APSK; 1226 result->modulation = STV0900_32APSK;
1614 else 1227 else
1615 i_params->dmd1_rslts.modulation = STV0900_UNKNOWN; 1228 result->modulation = STV0900_UNKNOWN;
1616 break;
1617 case STV0900_DVBS1_STANDARD:
1618 case STV0900_DSS_STANDARD:
1619 i_params->dmd1_rslts.spectrum = stv0900_get_bits(i_params, F0900_P1_IQINV);
1620 i_params->dmd1_rslts.modulation = STV0900_QPSK;
1621 break;
1622 default:
1623 break;
1624 }
1625
1626 if ((i_params->dmd1_srch_algo == STV0900_BLIND_SEARCH) || (i_params->dmd1_symbol_rate < 10000000)) {
1627 offsetFreq = i_params->dmd1_rslts.frequency - i_params->tuner1_freq;
1628 i_params->tuner1_freq = stv0900_get_tuner_freq(fe);
1629 if (ABS(offsetFreq) <= ((i_params->dmd1_srch_range / 2000) + 500))
1630 range = STV0900_RANGEOK;
1631 else
1632 if (ABS(offsetFreq) <= (stv0900_carrier_width(i_params->dmd1_rslts.symbol_rate, i_params->dmd1_rslts.rolloff) / 2000))
1633 range = STV0900_RANGEOK;
1634 else
1635 range = STV0900_OUTOFRANGE;
1636
1637 } else {
1638 if (ABS(offsetFreq) <= ((i_params->dmd1_srch_range / 2000) + 500))
1639 range = STV0900_RANGEOK;
1640 else
1641 range = STV0900_OUTOFRANGE;
1642 }
1643 break; 1229 break;
1644 case STV0900_DEMOD_2: 1230 case STV0900_DVBS1_STANDARD:
1645 if (i_params->dmd2_srch_algo == STV0900_BLIND_SEARCH) { 1231 case STV0900_DSS_STANDARD:
1646 timing = stv0900_read_reg(i_params, R0900_P2_TMGREG2); 1232 result->spectrum = stv0900_get_bits(intp, IQINV);
1647 i = 0; 1233 result->modulation = STV0900_QPSK;
1648 stv0900_write_reg(i_params, R0900_P2_SFRSTEP, 0x5c); 1234 break;
1649 1235 default:
1650 while ((i <= 50) && (timing != 0) && (timing != 0xff)) { 1236 break;
1651 timing = stv0900_read_reg(i_params, R0900_P2_TMGREG2); 1237 }
1652 msleep(5);
1653 i += 5;
1654 }
1655 }
1656
1657 i_params->dmd2_rslts.standard = stv0900_get_standard(fe, demod);
1658 i_params->dmd2_rslts.frequency = stv0900_get_tuner_freq(fe);
1659 offsetFreq = stv0900_get_carr_freq(i_params, i_params->mclk, demod) / 1000;
1660 i_params->dmd2_rslts.frequency += offsetFreq;
1661 i_params->dmd2_rslts.symbol_rate = stv0900_get_symbol_rate(i_params, i_params->mclk, demod);
1662 srate_offset = stv0900_get_timing_offst(i_params, i_params->dmd2_rslts.symbol_rate, demod);
1663 i_params->dmd2_rslts.symbol_rate += srate_offset;
1664 i_params->dmd2_rslts.fec = stv0900_get_vit_fec(i_params, demod);
1665 i_params->dmd2_rslts.modcode = stv0900_get_bits(i_params, F0900_P2_DEMOD_MODCOD);
1666 i_params->dmd2_rslts.pilot = stv0900_get_bits(i_params, F0900_P2_DEMOD_TYPE) & 0x01;
1667 i_params->dmd2_rslts.frame_length = ((u32)stv0900_get_bits(i_params, F0900_P2_DEMOD_TYPE)) >> 1;
1668 i_params->dmd2_rslts.rolloff = stv0900_get_bits(i_params, F0900_P2_ROLLOFF_STATUS);
1669 switch (i_params->dmd2_rslts.standard) {
1670 case STV0900_DVBS2_STANDARD:
1671 i_params->dmd2_rslts.spectrum = stv0900_get_bits(i_params, F0900_P2_SPECINV_DEMOD);
1672 if (i_params->dmd2_rslts.modcode <= STV0900_QPSK_910)
1673 i_params->dmd2_rslts.modulation = STV0900_QPSK;
1674 else if (i_params->dmd2_rslts.modcode <= STV0900_8PSK_910)
1675 i_params->dmd2_rslts.modulation = STV0900_8PSK;
1676 else if (i_params->dmd2_rslts.modcode <= STV0900_16APSK_910)
1677 i_params->dmd2_rslts.modulation = STV0900_16APSK;
1678 else if (i_params->dmd2_rslts.modcode <= STV0900_32APSK_910)
1679 i_params->dmd2_rslts.modulation = STV0900_32APSK;
1680 else
1681 i_params->dmd2_rslts.modulation = STV0900_UNKNOWN;
1682 break;
1683 case STV0900_DVBS1_STANDARD:
1684 case STV0900_DSS_STANDARD:
1685 i_params->dmd2_rslts.spectrum = stv0900_get_bits(i_params, F0900_P2_IQINV);
1686 i_params->dmd2_rslts.modulation = STV0900_QPSK;
1687 break;
1688 default:
1689 break;
1690 }
1691 1238
1692 if ((i_params->dmd2_srch_algo == STV0900_BLIND_SEARCH) || (i_params->dmd2_symbol_rate < 10000000)) { 1239 if ((intp->srch_algo[d] == STV0900_BLIND_SEARCH) ||
1693 offsetFreq = i_params->dmd2_rslts.frequency - i_params->tuner2_freq; 1240 (intp->symbol_rate[d] < 10000000)) {
1694 i_params->tuner2_freq = stv0900_get_tuner_freq(fe); 1241 offsetFreq = result->frequency - intp->freq[d];
1242 intp->freq[d] = stv0900_get_tuner_freq(fe);
1243 if (ABS(offsetFreq) <= ((intp->srch_range[d] / 2000) + 500))
1244 range = STV0900_RANGEOK;
1245 else if (ABS(offsetFreq) <=
1246 (stv0900_carrier_width(result->symbol_rate,
1247 result->rolloff) / 2000))
1248 range = STV0900_RANGEOK;
1695 1249
1696 if (ABS(offsetFreq) <= ((i_params->dmd2_srch_range / 2000) + 500)) 1250 } else if (ABS(offsetFreq) <= ((intp->srch_range[d] / 2000) + 500))
1697 range = STV0900_RANGEOK; 1251 range = STV0900_RANGEOK;
1698 else
1699 if (ABS(offsetFreq) <= (stv0900_carrier_width(i_params->dmd2_rslts.symbol_rate, i_params->dmd2_rslts.rolloff) / 2000))
1700 range = STV0900_RANGEOK;
1701 else
1702 range = STV0900_OUTOFRANGE;
1703 } else {
1704 if (ABS(offsetFreq) <= ((i_params->dmd2_srch_range / 2000) + 500))
1705 range = STV0900_RANGEOK;
1706 else
1707 range = STV0900_OUTOFRANGE;
1708 }
1709 1252
1710 break; 1253 dprintk("%s: range %d\n", __func__, range);
1711 }
1712 1254
1713 return range; 1255 return range;
1714} 1256}
1715 1257
1716static enum fe_stv0900_signal_type stv0900_dvbs1_acq_workaround(struct dvb_frontend *fe) 1258static enum
1259fe_stv0900_signal_type stv0900_dvbs1_acq_workaround(struct dvb_frontend *fe)
1717{ 1260{
1718 struct stv0900_state *state = fe->demodulator_priv; 1261 struct stv0900_state *state = fe->demodulator_priv;
1719 struct stv0900_internal *i_params = state->internal; 1262 struct stv0900_internal *intp = state->internal;
1720 enum fe_stv0900_demod_num demod = state->demod; 1263 enum fe_stv0900_demod_num demod = state->demod;
1721
1722 s32 srate, demod_timeout,
1723 fec_timeout, freq1, freq0;
1724 enum fe_stv0900_signal_type signal_type = STV0900_NODATA; 1264 enum fe_stv0900_signal_type signal_type = STV0900_NODATA;
1725 1265
1726 switch (demod) { 1266 s32 srate,
1727 case STV0900_DEMOD_1: 1267 demod_timeout,
1728 default: 1268 fec_timeout,
1729 i_params->dmd1_rslts.locked = FALSE; 1269 freq1,
1730 if (stv0900_get_bits(i_params, F0900_P1_HEADER_MODE) == STV0900_DVBS_FOUND) { 1270 freq0;
1731 srate = stv0900_get_symbol_rate(i_params, i_params->mclk, demod); 1271
1732 srate += stv0900_get_timing_offst(i_params, srate, demod); 1272 intp->result[demod].locked = FALSE;
1733 if (i_params->dmd1_srch_algo == STV0900_BLIND_SEARCH) 1273
1734 stv0900_set_symbol_rate(i_params, i_params->mclk, srate, demod); 1274 if (stv0900_get_bits(intp, HEADER_MODE) == STV0900_DVBS_FOUND) {
1735 1275 srate = stv0900_get_symbol_rate(intp, intp->mclk, demod);
1736 stv0900_get_lock_timeout(&demod_timeout, &fec_timeout, srate, STV0900_WARM_START); 1276 srate += stv0900_get_timing_offst(intp, srate, demod);
1737 freq1 = stv0900_read_reg(i_params, R0900_P1_CFR2); 1277 if (intp->srch_algo[demod] == STV0900_BLIND_SEARCH)
1738 freq0 = stv0900_read_reg(i_params, R0900_P1_CFR1); 1278 stv0900_set_symbol_rate(intp, intp->mclk, srate, demod);
1739 stv0900_write_bits(i_params, F0900_P1_CFR_AUTOSCAN, 0); 1279
1740 stv0900_write_bits(i_params, F0900_P1_SPECINV_CONTROL, STV0900_IQ_FORCE_SWAPPED); 1280 stv0900_get_lock_timeout(&demod_timeout, &fec_timeout,
1741 stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1C); 1281 srate, STV0900_WARM_START);
1742 stv0900_write_reg(i_params, R0900_P1_CFRINIT1, freq1); 1282 freq1 = stv0900_read_reg(intp, CFR2);
1743 stv0900_write_reg(i_params, R0900_P1_CFRINIT0, freq0); 1283 freq0 = stv0900_read_reg(intp, CFR1);
1744 stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x18); 1284 stv0900_write_bits(intp, CFR_AUTOSCAN, 0);
1745 if (stv0900_wait_for_lock(i_params, demod, demod_timeout, fec_timeout) == TRUE) { 1285 stv0900_write_bits(intp, SPECINV_CONTROL,
1746 i_params->dmd1_rslts.locked = TRUE; 1286 STV0900_IQ_FORCE_SWAPPED);
1747 signal_type = stv0900_get_signal_params(fe); 1287 stv0900_write_reg(intp, DMDISTATE, 0x1c);
1748 stv0900_track_optimization(fe); 1288 stv0900_write_reg(intp, CFRINIT1, freq1);
1749 } else { 1289 stv0900_write_reg(intp, CFRINIT0, freq0);
1750 stv0900_write_bits(i_params, F0900_P1_SPECINV_CONTROL, STV0900_IQ_FORCE_NORMAL); 1290 stv0900_write_reg(intp, DMDISTATE, 0x18);
1751 stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1c); 1291 if (stv0900_wait_for_lock(intp, demod,
1752 stv0900_write_reg(i_params, R0900_P1_CFRINIT1, freq1); 1292 demod_timeout, fec_timeout) == TRUE) {
1753 stv0900_write_reg(i_params, R0900_P1_CFRINIT0, freq0); 1293 intp->result[demod].locked = TRUE;
1754 stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x18); 1294 signal_type = stv0900_get_signal_params(fe);
1755 if (stv0900_wait_for_lock(i_params, demod, demod_timeout, fec_timeout) == TRUE) { 1295 stv0900_track_optimization(fe);
1756 i_params->dmd1_rslts.locked = TRUE; 1296 } else {
1757 signal_type = stv0900_get_signal_params(fe); 1297 stv0900_write_bits(intp, SPECINV_CONTROL,
1758 stv0900_track_optimization(fe); 1298 STV0900_IQ_FORCE_NORMAL);
1759 } 1299 stv0900_write_reg(intp, DMDISTATE, 0x1c);
1760 1300 stv0900_write_reg(intp, CFRINIT1, freq1);
1761 } 1301 stv0900_write_reg(intp, CFRINIT0, freq0);
1762 1302 stv0900_write_reg(intp, DMDISTATE, 0x18);
1763 } else 1303 if (stv0900_wait_for_lock(intp, demod,
1764 i_params->dmd1_rslts.locked = FALSE; 1304 demod_timeout, fec_timeout) == TRUE) {
1765 1305 intp->result[demod].locked = TRUE;
1766 break;
1767 case STV0900_DEMOD_2:
1768 i_params->dmd2_rslts.locked = FALSE;
1769 if (stv0900_get_bits(i_params, F0900_P2_HEADER_MODE) == STV0900_DVBS_FOUND) {
1770 srate = stv0900_get_symbol_rate(i_params, i_params->mclk, demod);
1771 srate += stv0900_get_timing_offst(i_params, srate, demod);
1772
1773 if (i_params->dmd2_srch_algo == STV0900_BLIND_SEARCH)
1774 stv0900_set_symbol_rate(i_params, i_params->mclk, srate, demod);
1775
1776 stv0900_get_lock_timeout(&demod_timeout, &fec_timeout, srate, STV0900_WARM_START);
1777 freq1 = stv0900_read_reg(i_params, R0900_P2_CFR2);
1778 freq0 = stv0900_read_reg(i_params, R0900_P2_CFR1);
1779 stv0900_write_bits(i_params, F0900_P2_CFR_AUTOSCAN, 0);
1780 stv0900_write_bits(i_params, F0900_P2_SPECINV_CONTROL, STV0900_IQ_FORCE_SWAPPED);
1781 stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1C);
1782 stv0900_write_reg(i_params, R0900_P2_CFRINIT1, freq1);
1783 stv0900_write_reg(i_params, R0900_P2_CFRINIT0, freq0);
1784 stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x18);
1785
1786 if (stv0900_wait_for_lock(i_params, demod, demod_timeout, fec_timeout) == TRUE) {
1787 i_params->dmd2_rslts.locked = TRUE;
1788 signal_type = stv0900_get_signal_params(fe); 1306 signal_type = stv0900_get_signal_params(fe);
1789 stv0900_track_optimization(fe); 1307 stv0900_track_optimization(fe);
1790 } else {
1791 stv0900_write_bits(i_params, F0900_P2_SPECINV_CONTROL, STV0900_IQ_FORCE_NORMAL);
1792 stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1c);
1793 stv0900_write_reg(i_params, R0900_P2_CFRINIT1, freq1);
1794 stv0900_write_reg(i_params, R0900_P2_CFRINIT0, freq0);
1795 stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x18);
1796
1797 if (stv0900_wait_for_lock(i_params, demod, demod_timeout, fec_timeout) == TRUE) {
1798 i_params->dmd2_rslts.locked = TRUE;
1799 signal_type = stv0900_get_signal_params(fe);
1800 stv0900_track_optimization(fe);
1801 }
1802
1803 } 1308 }
1804 1309
1805 } else 1310 }
1806 i_params->dmd1_rslts.locked = FALSE;
1807 1311
1808 break; 1312 } else
1809 } 1313 intp->result[demod].locked = FALSE;
1810 1314
1811 return signal_type; 1315 return signal_type;
1812} 1316}
1813 1317
1814static u16 stv0900_blind_check_agc2_min_level(struct stv0900_internal *i_params, 1318static u16 stv0900_blind_check_agc2_min_level(struct stv0900_internal *intp,
1815 enum fe_stv0900_demod_num demod) 1319 enum fe_stv0900_demod_num demod)
1816{ 1320{
1817 u32 minagc2level = 0xffff, 1321 u32 minagc2level = 0xffff,
@@ -1820,105 +1324,54 @@ static u16 stv0900_blind_check_agc2_min_level(struct stv0900_internal *i_params,
1820 1324
1821 s32 i, j, nb_steps, direction; 1325 s32 i, j, nb_steps, direction;
1822 1326
1823 dprintk(KERN_INFO "%s\n", __func__); 1327 dprintk("%s\n", __func__);
1824
1825 switch (demod) {
1826 case STV0900_DEMOD_1:
1827 default:
1828 stv0900_write_reg(i_params, R0900_P1_AGC2REF, 0x38);
1829 stv0900_write_bits(i_params, F0900_P1_SCAN_ENABLE, 1);
1830 stv0900_write_bits(i_params, F0900_P1_CFR_AUTOSCAN, 1);
1831
1832 stv0900_write_reg(i_params, R0900_P1_SFRUP1, 0x83);
1833 stv0900_write_reg(i_params, R0900_P1_SFRUP0, 0xc0);
1834
1835 stv0900_write_reg(i_params, R0900_P1_SFRLOW1, 0x82);
1836 stv0900_write_reg(i_params, R0900_P1_SFRLOW0, 0xa0);
1837 stv0900_write_reg(i_params, R0900_P1_DMDT0M, 0x0);
1838 1328
1839 stv0900_set_symbol_rate(i_params, i_params->mclk, 1000000, demod); 1329 stv0900_write_reg(intp, AGC2REF, 0x38);
1840 nb_steps = -1 + (i_params->dmd1_srch_range / 1000000); 1330 stv0900_write_bits(intp, SCAN_ENABLE, 0);
1841 nb_steps /= 2; 1331 stv0900_write_bits(intp, CFR_AUTOSCAN, 0);
1842 nb_steps = (2 * nb_steps) + 1;
1843 1332
1844 if (nb_steps < 0) 1333 stv0900_write_bits(intp, AUTO_GUP, 1);
1845 nb_steps = 1; 1334 stv0900_write_bits(intp, AUTO_GLOW, 1);
1846 1335
1847 direction = 1; 1336 stv0900_write_reg(intp, DMDT0M, 0x0);
1848 1337
1849 freq_step = (1000000 << 8) / (i_params->mclk >> 8); 1338 stv0900_set_symbol_rate(intp, intp->mclk, 1000000, demod);
1339 nb_steps = -1 + (intp->srch_range[demod] / 1000000);
1340 nb_steps /= 2;
1341 nb_steps = (2 * nb_steps) + 1;
1850 1342
1851 init_freq = 0; 1343 if (nb_steps < 0)
1344 nb_steps = 1;
1852 1345
1853 for (i = 0; i < nb_steps; i++) { 1346 direction = 1;
1854 if (direction > 0)
1855 init_freq = init_freq + (freq_step * i);
1856 else
1857 init_freq = init_freq - (freq_step * i);
1858 1347
1859 direction *= -1; 1348 freq_step = (1000000 << 8) / (intp->mclk >> 8);
1860 stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x5C);
1861 stv0900_write_reg(i_params, R0900_P1_CFRINIT1, (init_freq >> 8) & 0xff);
1862 stv0900_write_reg(i_params, R0900_P1_CFRINIT0, init_freq & 0xff);
1863 stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x58);
1864 msleep(10);
1865 agc2level = 0;
1866 1349
1867 for (j = 0; j < 10; j++) 1350 init_freq = 0;
1868 agc2level += (stv0900_read_reg(i_params, R0900_P1_AGC2I1) << 8)
1869 | stv0900_read_reg(i_params, R0900_P1_AGC2I0);
1870 1351
1871 agc2level /= 10; 1352 for (i = 0; i < nb_steps; i++) {
1872 1353 if (direction > 0)
1873 if (agc2level < minagc2level) 1354 init_freq = init_freq + (freq_step * i);
1874 minagc2level = agc2level; 1355 else
1875 } 1356 init_freq = init_freq - (freq_step * i);
1876 break;
1877 case STV0900_DEMOD_2:
1878 stv0900_write_reg(i_params, R0900_P2_AGC2REF, 0x38);
1879 stv0900_write_bits(i_params, F0900_P2_SCAN_ENABLE, 1);
1880 stv0900_write_bits(i_params, F0900_P2_CFR_AUTOSCAN, 1);
1881 stv0900_write_reg(i_params, R0900_P2_SFRUP1, 0x83);
1882 stv0900_write_reg(i_params, R0900_P2_SFRUP0, 0xc0);
1883 stv0900_write_reg(i_params, R0900_P2_SFRLOW1, 0x82);
1884 stv0900_write_reg(i_params, R0900_P2_SFRLOW0, 0xa0);
1885 stv0900_write_reg(i_params, R0900_P2_DMDT0M, 0x0);
1886 stv0900_set_symbol_rate(i_params, i_params->mclk, 1000000, demod);
1887 nb_steps = -1 + (i_params->dmd2_srch_range / 1000000);
1888 nb_steps /= 2;
1889 nb_steps = (2 * nb_steps) + 1;
1890
1891 if (nb_steps < 0)
1892 nb_steps = 1;
1893
1894 direction = 1;
1895 freq_step = (1000000 << 8) / (i_params->mclk >> 8);
1896 init_freq = 0;
1897 for (i = 0; i < nb_steps; i++) {
1898 if (direction > 0)
1899 init_freq = init_freq + (freq_step * i);
1900 else
1901 init_freq = init_freq - (freq_step * i);
1902 1357
1903 direction *= -1; 1358 direction *= -1;
1359 stv0900_write_reg(intp, DMDISTATE, 0x5C);
1360 stv0900_write_reg(intp, CFRINIT1, (init_freq >> 8) & 0xff);
1361 stv0900_write_reg(intp, CFRINIT0, init_freq & 0xff);
1362 stv0900_write_reg(intp, DMDISTATE, 0x58);
1363 msleep(10);
1364 agc2level = 0;
1904 1365
1905 stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x5C); 1366 for (j = 0; j < 10; j++)
1906 stv0900_write_reg(i_params, R0900_P2_CFRINIT1, (init_freq >> 8) & 0xff); 1367 agc2level += (stv0900_read_reg(intp, AGC2I1) << 8)
1907 stv0900_write_reg(i_params, R0900_P2_CFRINIT0, init_freq & 0xff); 1368 | stv0900_read_reg(intp, AGC2I0);
1908 stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x58);
1909 1369
1910 msleep(10); 1370 agc2level /= 10;
1911 agc2level = 0;
1912 for (j = 0; j < 10; j++)
1913 agc2level += (stv0900_read_reg(i_params, R0900_P2_AGC2I1) << 8)
1914 | stv0900_read_reg(i_params, R0900_P2_AGC2I0);
1915 1371
1916 agc2level /= 10; 1372 if (agc2level < minagc2level)
1373 minagc2level = agc2level;
1917 1374
1918 if (agc2level < minagc2level)
1919 minagc2level = agc2level;
1920 }
1921 break;
1922 } 1375 }
1923 1376
1924 return (u16)minagc2level; 1377 return (u16)minagc2level;
@@ -1927,336 +1380,192 @@ static u16 stv0900_blind_check_agc2_min_level(struct stv0900_internal *i_params,
1927static u32 stv0900_search_srate_coarse(struct dvb_frontend *fe) 1380static u32 stv0900_search_srate_coarse(struct dvb_frontend *fe)
1928{ 1381{
1929 struct stv0900_state *state = fe->demodulator_priv; 1382 struct stv0900_state *state = fe->demodulator_priv;
1930 struct stv0900_internal *i_params = state->internal; 1383 struct stv0900_internal *intp = state->internal;
1931 enum fe_stv0900_demod_num demod = state->demod; 1384 enum fe_stv0900_demod_num demod = state->demod;
1932 int timingLock = FALSE; 1385 int timing_lck = FALSE;
1933 s32 i, timingcpt = 0, 1386 s32 i, timingcpt = 0,
1934 direction = 1, 1387 direction = 1,
1935 nb_steps, 1388 nb_steps,
1936 current_step = 0, 1389 current_step = 0,
1937 tuner_freq; 1390 tuner_freq;
1391 u32 agc2_th,
1392 coarse_srate = 0,
1393 agc2_integr = 0,
1394 currier_step = 1200;
1938 1395
1939 u32 coarse_srate = 0, agc2_integr = 0, currier_step = 1200; 1396 if (intp->chip_id >= 0x30)
1940 1397 agc2_th = 0x2e00;
1941 switch (demod) { 1398 else
1942 case STV0900_DEMOD_1: 1399 agc2_th = 0x1f00;
1943 default: 1400
1944 stv0900_write_bits(i_params, F0900_P1_I2C_DEMOD_MODE, 0x1F); 1401 stv0900_write_bits(intp, DEMOD_MODE, 0x1f);
1945 stv0900_write_reg(i_params, R0900_P1_TMGCFG, 0x12); 1402 stv0900_write_reg(intp, TMGCFG, 0x12);
1946 stv0900_write_reg(i_params, R0900_P1_TMGTHRISE, 0xf0); 1403 stv0900_write_reg(intp, TMGTHRISE, 0xf0);
1947 stv0900_write_reg(i_params, R0900_P1_TMGTHFALL, 0xe0); 1404 stv0900_write_reg(intp, TMGTHFALL, 0xe0);
1948 stv0900_write_bits(i_params, F0900_P1_SCAN_ENABLE, 1); 1405 stv0900_write_bits(intp, SCAN_ENABLE, 1);
1949 stv0900_write_bits(i_params, F0900_P1_CFR_AUTOSCAN, 1); 1406 stv0900_write_bits(intp, CFR_AUTOSCAN, 1);
1950 stv0900_write_reg(i_params, R0900_P1_SFRUP1, 0x83); 1407 stv0900_write_reg(intp, SFRUP1, 0x83);
1951 stv0900_write_reg(i_params, R0900_P1_SFRUP0, 0xc0); 1408 stv0900_write_reg(intp, SFRUP0, 0xc0);
1952 stv0900_write_reg(i_params, R0900_P1_SFRLOW1, 0x82); 1409 stv0900_write_reg(intp, SFRLOW1, 0x82);
1953 stv0900_write_reg(i_params, R0900_P1_SFRLOW0, 0xa0); 1410 stv0900_write_reg(intp, SFRLOW0, 0xa0);
1954 stv0900_write_reg(i_params, R0900_P1_DMDT0M, 0x0); 1411 stv0900_write_reg(intp, DMDT0M, 0x0);
1955 stv0900_write_reg(i_params, R0900_P1_AGC2REF, 0x50); 1412 stv0900_write_reg(intp, AGC2REF, 0x50);
1956 1413
1957 if (i_params->chip_id >= 0x20) { 1414 if (intp->chip_id >= 0x30) {
1958 stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0x6a); 1415 stv0900_write_reg(intp, CARFREQ, 0x99);
1959 stv0900_write_reg(i_params, R0900_P1_SFRSTEP, 0x95); 1416 stv0900_write_reg(intp, SFRSTEP, 0x98);
1960 } else { 1417 } else if (intp->chip_id >= 0x20) {
1961 stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0xed); 1418 stv0900_write_reg(intp, CARFREQ, 0x6a);
1962 stv0900_write_reg(i_params, R0900_P1_SFRSTEP, 0x73); 1419 stv0900_write_reg(intp, SFRSTEP, 0x95);
1963 } 1420 } else {
1421 stv0900_write_reg(intp, CARFREQ, 0xed);
1422 stv0900_write_reg(intp, SFRSTEP, 0x73);
1423 }
1964 1424
1965 if (i_params->dmd1_symbol_rate <= 2000000) 1425 if (intp->symbol_rate[demod] <= 2000000)
1966 currier_step = 1000; 1426 currier_step = 1000;
1967 else if (i_params->dmd1_symbol_rate <= 5000000) 1427 else if (intp->symbol_rate[demod] <= 5000000)
1968 currier_step = 2000; 1428 currier_step = 2000;
1969 else if (i_params->dmd1_symbol_rate <= 12000000) 1429 else if (intp->symbol_rate[demod] <= 12000000)
1970 currier_step = 3000; 1430 currier_step = 3000;
1971 else 1431 else
1972 currier_step = 5000; 1432 currier_step = 5000;
1973 1433
1974 nb_steps = -1 + ((i_params->dmd1_srch_range / 1000) / currier_step); 1434 nb_steps = -1 + ((intp->srch_range[demod] / 1000) / currier_step);
1975 nb_steps /= 2; 1435 nb_steps /= 2;
1976 nb_steps = (2 * nb_steps) + 1; 1436 nb_steps = (2 * nb_steps) + 1;
1977
1978 if (nb_steps < 0)
1979 nb_steps = 1;
1980
1981 else if (nb_steps > 10) {
1982 nb_steps = 11;
1983 currier_step = (i_params->dmd1_srch_range / 1000) / 10;
1984 }
1985
1986 current_step = 0;
1987
1988 direction = 1;
1989 tuner_freq = i_params->tuner1_freq;
1990
1991 while ((timingLock == FALSE) && (current_step < nb_steps)) {
1992 stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x5F);
1993 stv0900_write_bits(i_params, F0900_P1_I2C_DEMOD_MODE, 0x0);
1994
1995 msleep(50);
1996
1997 for (i = 0; i < 10; i++) {
1998 if (stv0900_get_bits(i_params, F0900_P1_TMGLOCK_QUALITY) >= 2)
1999 timingcpt++;
2000
2001 agc2_integr += (stv0900_read_reg(i_params, R0900_P1_AGC2I1) << 8) | stv0900_read_reg(i_params, R0900_P1_AGC2I0);
2002
2003 }
2004 1437
2005 agc2_integr /= 10; 1438 if (nb_steps < 0)
2006 coarse_srate = stv0900_get_symbol_rate(i_params, i_params->mclk, demod); 1439 nb_steps = 1;
2007 current_step++; 1440 else if (nb_steps > 10) {
2008 direction *= -1; 1441 nb_steps = 11;
1442 currier_step = (intp->srch_range[demod] / 1000) / 10;
1443 }
2009 1444
2010 dprintk("lock: I2C_DEMOD_MODE_FIELD =0. Search started. tuner freq=%d agc2=0x%x srate_coarse=%d tmg_cpt=%d\n", tuner_freq, agc2_integr, coarse_srate, timingcpt); 1445 current_step = 0;
1446 direction = 1;
2011 1447
2012 if ((timingcpt >= 5) && (agc2_integr < 0x1F00) && (coarse_srate < 55000000) && (coarse_srate > 850000)) { 1448 tuner_freq = intp->freq[demod];
2013 timingLock = TRUE;
2014 }
2015 1449
2016 else if (current_step < nb_steps) { 1450 while ((timing_lck == FALSE) && (current_step < nb_steps)) {
2017 if (direction > 0) 1451 stv0900_write_reg(intp, DMDISTATE, 0x5f);
2018 tuner_freq += (current_step * currier_step); 1452 stv0900_write_bits(intp, DEMOD_MODE, 0);
2019 else
2020 tuner_freq -= (current_step * currier_step);
2021 1453
2022 stv0900_set_tuner(fe, tuner_freq, i_params->tuner1_bw); 1454 msleep(50);
2023 }
2024 }
2025 1455
2026 if (timingLock == FALSE) 1456 for (i = 0; i < 10; i++) {
2027 coarse_srate = 0; 1457 if (stv0900_get_bits(intp, TMGLOCK_QUALITY) >= 2)
2028 else 1458 timingcpt++;
2029 coarse_srate = stv0900_get_symbol_rate(i_params, i_params->mclk, demod);
2030 break;
2031 case STV0900_DEMOD_2:
2032 stv0900_write_bits(i_params, F0900_P2_I2C_DEMOD_MODE, 0x1F);
2033 stv0900_write_reg(i_params, R0900_P2_TMGCFG, 0x12);
2034 stv0900_write_reg(i_params, R0900_P2_TMGTHRISE, 0xf0);
2035 stv0900_write_reg(i_params, R0900_P2_TMGTHFALL, 0xe0);
2036 stv0900_write_bits(i_params, F0900_P2_SCAN_ENABLE, 1);
2037 stv0900_write_bits(i_params, F0900_P2_CFR_AUTOSCAN, 1);
2038 stv0900_write_reg(i_params, R0900_P2_SFRUP1, 0x83);
2039 stv0900_write_reg(i_params, R0900_P2_SFRUP0, 0xc0);
2040 stv0900_write_reg(i_params, R0900_P2_SFRLOW1, 0x82);
2041 stv0900_write_reg(i_params, R0900_P2_SFRLOW0, 0xa0);
2042 stv0900_write_reg(i_params, R0900_P2_DMDT0M, 0x0);
2043 stv0900_write_reg(i_params, R0900_P2_AGC2REF, 0x50);
2044
2045 if (i_params->chip_id >= 0x20) {
2046 stv0900_write_reg(i_params, R0900_P2_CARFREQ, 0x6a);
2047 stv0900_write_reg(i_params, R0900_P2_SFRSTEP, 0x95);
2048 } else {
2049 stv0900_write_reg(i_params, R0900_P2_CARFREQ, 0xed);
2050 stv0900_write_reg(i_params, R0900_P2_SFRSTEP, 0x73);
2051 }
2052
2053 if (i_params->dmd2_symbol_rate <= 2000000)
2054 currier_step = 1000;
2055 else if (i_params->dmd2_symbol_rate <= 5000000)
2056 currier_step = 2000;
2057 else if (i_params->dmd2_symbol_rate <= 12000000)
2058 currier_step = 3000;
2059 else
2060 currier_step = 5000;
2061
2062
2063 nb_steps = -1 + ((i_params->dmd2_srch_range / 1000) / currier_step);
2064 nb_steps /= 2;
2065 nb_steps = (2 * nb_steps) + 1;
2066 1459
2067 if (nb_steps < 0) 1460 agc2_integr += (stv0900_read_reg(intp, AGC2I1) << 8) |
2068 nb_steps = 1; 1461 stv0900_read_reg(intp, AGC2I0);
2069 else if (nb_steps > 10) {
2070 nb_steps = 11;
2071 currier_step = (i_params->dmd2_srch_range / 1000) / 10;
2072 } 1462 }
2073 1463
2074 current_step = 0; 1464 agc2_integr /= 10;
2075 direction = 1; 1465 coarse_srate = stv0900_get_symbol_rate(intp, intp->mclk, demod);
2076 tuner_freq = i_params->tuner2_freq; 1466 current_step++;
2077 1467 direction *= -1;
2078 while ((timingLock == FALSE) && (current_step < nb_steps)) { 1468
2079 stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x5F); 1469 dprintk("lock: I2C_DEMOD_MODE_FIELD =0. Search started."
2080 stv0900_write_bits(i_params, F0900_P2_I2C_DEMOD_MODE, 0x0); 1470 " tuner freq=%d agc2=0x%x srate_coarse=%d tmg_cpt=%d\n",
2081 1471 tuner_freq, agc2_integr, coarse_srate, timingcpt);
2082 msleep(50); 1472
2083 timingcpt = 0; 1473 if ((timingcpt >= 5) &&
2084 1474 (agc2_integr < agc2_th) &&
2085 for (i = 0; i < 20; i++) { 1475 (coarse_srate < 55000000) &&
2086 if (stv0900_get_bits(i_params, F0900_P2_TMGLOCK_QUALITY) >= 2) 1476 (coarse_srate > 850000))
2087 timingcpt++; 1477 timing_lck = TRUE;
2088 agc2_integr += (stv0900_read_reg(i_params, R0900_P2_AGC2I1) << 8) 1478 else if (current_step < nb_steps) {
2089 | stv0900_read_reg(i_params, R0900_P2_AGC2I0); 1479 if (direction > 0)
2090 } 1480 tuner_freq += (current_step * currier_step);
2091 1481 else
2092 agc2_integr /= 20; 1482 tuner_freq -= (current_step * currier_step);
2093 coarse_srate = stv0900_get_symbol_rate(i_params, i_params->mclk, demod);
2094 if ((timingcpt >= 10) && (agc2_integr < 0x1F00) && (coarse_srate < 55000000) && (coarse_srate > 850000))
2095 timingLock = TRUE;
2096 else {
2097 current_step++;
2098 direction *= -1;
2099
2100 if (direction > 0)
2101 tuner_freq += (current_step * currier_step);
2102 else
2103 tuner_freq -= (current_step * currier_step);
2104 1483
2105 stv0900_set_tuner(fe, tuner_freq, i_params->tuner2_bw); 1484 stv0900_set_tuner(fe, tuner_freq, intp->bw[demod]);
2106 }
2107 } 1485 }
2108
2109 if (timingLock == FALSE)
2110 coarse_srate = 0;
2111 else
2112 coarse_srate = stv0900_get_symbol_rate(i_params, i_params->mclk, demod);
2113 break;
2114 } 1486 }
2115 1487
1488 if (timing_lck == FALSE)
1489 coarse_srate = 0;
1490 else
1491 coarse_srate = stv0900_get_symbol_rate(intp, intp->mclk, demod);
1492
2116 return coarse_srate; 1493 return coarse_srate;
2117} 1494}
2118 1495
2119static u32 stv0900_search_srate_fine(struct dvb_frontend *fe) 1496static u32 stv0900_search_srate_fine(struct dvb_frontend *fe)
2120{ 1497{
2121 struct stv0900_state *state = fe->demodulator_priv; 1498 struct stv0900_state *state = fe->demodulator_priv;
2122 struct stv0900_internal *i_params = state->internal; 1499 struct stv0900_internal *intp = state->internal;
2123 enum fe_stv0900_demod_num demod = state->demod; 1500 enum fe_stv0900_demod_num demod = state->demod;
2124 u32 coarse_srate, 1501 u32 coarse_srate,
2125 coarse_freq, 1502 coarse_freq,
2126 symb; 1503 symb,
1504 symbmax,
1505 symbmin,
1506 symbcomp;
1507
1508 coarse_srate = stv0900_get_symbol_rate(intp, intp->mclk, demod);
1509
1510 if (coarse_srate > 3000000) {
1511 symbmax = 13 * (coarse_srate / 10);
1512 symbmax = (symbmax / 1000) * 65536;
1513 symbmax /= (intp->mclk / 1000);
1514
1515 symbmin = 10 * (coarse_srate / 13);
1516 symbmin = (symbmin / 1000)*65536;
1517 symbmin /= (intp->mclk / 1000);
1518
1519 symb = (coarse_srate / 1000) * 65536;
1520 symb /= (intp->mclk / 1000);
1521 } else {
1522 symbmax = 13 * (coarse_srate / 10);
1523 symbmax = (symbmax / 100) * 65536;
1524 symbmax /= (intp->mclk / 100);
2127 1525
2128 coarse_srate = stv0900_get_symbol_rate(i_params, i_params->mclk, demod); 1526 symbmin = 10 * (coarse_srate / 14);
1527 symbmin = (symbmin / 100) * 65536;
1528 symbmin /= (intp->mclk / 100);
2129 1529
2130 switch (demod) { 1530 symb = (coarse_srate / 100) * 65536;
2131 case STV0900_DEMOD_1: 1531 symb /= (intp->mclk / 100);
2132 default: 1532 }
2133 coarse_freq = (stv0900_read_reg(i_params, R0900_P1_CFR2) << 8)
2134 | stv0900_read_reg(i_params, R0900_P1_CFR1);
2135 symb = 13 * (coarse_srate / 10);
2136
2137 if (symb < i_params->dmd1_symbol_rate)
2138 coarse_srate = 0;
2139 else {
2140 stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1F);
2141 stv0900_write_reg(i_params, R0900_P1_TMGCFG2, 0x01);
2142 stv0900_write_reg(i_params, R0900_P1_TMGTHRISE, 0x20);
2143 stv0900_write_reg(i_params, R0900_P1_TMGTHFALL, 0x00);
2144 stv0900_write_reg(i_params, R0900_P1_TMGCFG, 0xd2);
2145 stv0900_write_bits(i_params, F0900_P1_CFR_AUTOSCAN, 0);
2146
2147 if (i_params->chip_id >= 0x20)
2148 stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0x49);
2149 else
2150 stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0xed);
2151
2152 if (coarse_srate > 3000000) {
2153 symb = 13 * (coarse_srate / 10);
2154 symb = (symb / 1000) * 65536;
2155 symb /= (i_params->mclk / 1000);
2156 stv0900_write_reg(i_params, R0900_P1_SFRUP1, (symb >> 8) & 0x7F);
2157 stv0900_write_reg(i_params, R0900_P1_SFRUP0, (symb & 0xFF));
2158
2159 symb = 10 * (coarse_srate / 13);
2160 symb = (symb / 1000) * 65536;
2161 symb /= (i_params->mclk / 1000);
2162
2163 stv0900_write_reg(i_params, R0900_P1_SFRLOW1, (symb >> 8) & 0x7F);
2164 stv0900_write_reg(i_params, R0900_P1_SFRLOW0, (symb & 0xFF));
2165
2166 symb = (coarse_srate / 1000) * 65536;
2167 symb /= (i_params->mclk / 1000);
2168 stv0900_write_reg(i_params, R0900_P1_SFRINIT1, (symb >> 8) & 0xFF);
2169 stv0900_write_reg(i_params, R0900_P1_SFRINIT0, (symb & 0xFF));
2170 } else {
2171 symb = 13 * (coarse_srate / 10);
2172 symb = (symb / 100) * 65536;
2173 symb /= (i_params->mclk / 100);
2174 stv0900_write_reg(i_params, R0900_P1_SFRUP1, (symb >> 8) & 0x7F);
2175 stv0900_write_reg(i_params, R0900_P1_SFRUP0, (symb & 0xFF));
2176
2177 symb = 10 * (coarse_srate / 14);
2178 symb = (symb / 100) * 65536;
2179 symb /= (i_params->mclk / 100);
2180 stv0900_write_reg(i_params, R0900_P1_SFRLOW1, (symb >> 8) & 0x7F);
2181 stv0900_write_reg(i_params, R0900_P1_SFRLOW0, (symb & 0xFF));
2182
2183 symb = (coarse_srate / 100) * 65536;
2184 symb /= (i_params->mclk / 100);
2185 stv0900_write_reg(i_params, R0900_P1_SFRINIT1, (symb >> 8) & 0xFF);
2186 stv0900_write_reg(i_params, R0900_P1_SFRINIT0, (symb & 0xFF));
2187 }
2188 1533
2189 stv0900_write_reg(i_params, R0900_P1_DMDT0M, 0x20); 1534 symbcomp = 13 * (coarse_srate / 10);
2190 stv0900_write_reg(i_params, R0900_P1_CFRINIT1, (coarse_freq >> 8) & 0xff); 1535 coarse_freq = (stv0900_read_reg(intp, CFR2) << 8)
2191 stv0900_write_reg(i_params, R0900_P1_CFRINIT0, coarse_freq & 0xff); 1536 | stv0900_read_reg(intp, CFR1);
2192 stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x15); 1537
2193 } 1538 if (symbcomp < intp->symbol_rate[demod])
2194 break; 1539 coarse_srate = 0;
2195 case STV0900_DEMOD_2: 1540 else {
2196 coarse_freq = (stv0900_read_reg(i_params, R0900_P2_CFR2) << 8) 1541 stv0900_write_reg(intp, DMDISTATE, 0x1f);
2197 | stv0900_read_reg(i_params, R0900_P2_CFR1); 1542 stv0900_write_reg(intp, TMGCFG2, 0xc1);
2198 1543 stv0900_write_reg(intp, TMGTHRISE, 0x20);
2199 symb = 13 * (coarse_srate / 10); 1544 stv0900_write_reg(intp, TMGTHFALL, 0x00);
2200 1545 stv0900_write_reg(intp, TMGCFG, 0xd2);
2201 if (symb < i_params->dmd2_symbol_rate) 1546 stv0900_write_bits(intp, CFR_AUTOSCAN, 0);
2202 coarse_srate = 0; 1547 stv0900_write_reg(intp, AGC2REF, 0x38);
2203 else { 1548
2204 stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1F); 1549 if (intp->chip_id >= 0x30)
2205 stv0900_write_reg(i_params, R0900_P2_TMGCFG2, 0x01); 1550 stv0900_write_reg(intp, CARFREQ, 0x79);
2206 stv0900_write_reg(i_params, R0900_P2_TMGTHRISE, 0x20); 1551 else if (intp->chip_id >= 0x20)
2207 stv0900_write_reg(i_params, R0900_P2_TMGTHFALL, 0x00); 1552 stv0900_write_reg(intp, CARFREQ, 0x49);
2208 stv0900_write_reg(i_params, R0900_P2_TMGCFG, 0xd2); 1553 else
2209 stv0900_write_bits(i_params, F0900_P2_CFR_AUTOSCAN, 0); 1554 stv0900_write_reg(intp, CARFREQ, 0xed);
2210
2211 if (i_params->chip_id >= 0x20)
2212 stv0900_write_reg(i_params, R0900_P2_CARFREQ, 0x49);
2213 else
2214 stv0900_write_reg(i_params, R0900_P2_CARFREQ, 0xed);
2215
2216 if (coarse_srate > 3000000) {
2217 symb = 13 * (coarse_srate / 10);
2218 symb = (symb / 1000) * 65536;
2219 symb /= (i_params->mclk / 1000);
2220 stv0900_write_reg(i_params, R0900_P2_SFRUP1, (symb >> 8) & 0x7F);
2221 stv0900_write_reg(i_params, R0900_P2_SFRUP0, (symb & 0xFF));
2222
2223 symb = 10 * (coarse_srate / 13);
2224 symb = (symb / 1000) * 65536;
2225 symb /= (i_params->mclk / 1000);
2226
2227 stv0900_write_reg(i_params, R0900_P2_SFRLOW1, (symb >> 8) & 0x7F);
2228 stv0900_write_reg(i_params, R0900_P2_SFRLOW0, (symb & 0xFF));
2229
2230 symb = (coarse_srate / 1000) * 65536;
2231 symb /= (i_params->mclk / 1000);
2232 stv0900_write_reg(i_params, R0900_P2_SFRINIT1, (symb >> 8) & 0xFF);
2233 stv0900_write_reg(i_params, R0900_P2_SFRINIT0, (symb & 0xFF));
2234 } else {
2235 symb = 13 * (coarse_srate / 10);
2236 symb = (symb / 100) * 65536;
2237 symb /= (i_params->mclk / 100);
2238 stv0900_write_reg(i_params, R0900_P2_SFRUP1, (symb >> 8) & 0x7F);
2239 stv0900_write_reg(i_params, R0900_P2_SFRUP0, (symb & 0xFF));
2240
2241 symb = 10 * (coarse_srate / 14);
2242 symb = (symb / 100) * 65536;
2243 symb /= (i_params->mclk / 100);
2244 stv0900_write_reg(i_params, R0900_P2_SFRLOW1, (symb >> 8) & 0x7F);
2245 stv0900_write_reg(i_params, R0900_P2_SFRLOW0, (symb & 0xFF));
2246
2247 symb = (coarse_srate / 100) * 65536;
2248 symb /= (i_params->mclk / 100);
2249 stv0900_write_reg(i_params, R0900_P2_SFRINIT1, (symb >> 8) & 0xFF);
2250 stv0900_write_reg(i_params, R0900_P2_SFRINIT0, (symb & 0xFF));
2251 }
2252 1555
2253 stv0900_write_reg(i_params, R0900_P2_DMDT0M, 0x20); 1556 stv0900_write_reg(intp, SFRUP1, (symbmax >> 8) & 0x7f);
2254 stv0900_write_reg(i_params, R0900_P2_CFRINIT1, (coarse_freq >> 8) & 0xff); 1557 stv0900_write_reg(intp, SFRUP0, (symbmax & 0xff));
2255 stv0900_write_reg(i_params, R0900_P2_CFRINIT0, coarse_freq & 0xff);
2256 stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x15);
2257 }
2258 1558
2259 break; 1559 stv0900_write_reg(intp, SFRLOW1, (symbmin >> 8) & 0x7f);
1560 stv0900_write_reg(intp, SFRLOW0, (symbmin & 0xff));
1561
1562 stv0900_write_reg(intp, SFRINIT1, (symb >> 8) & 0xff);
1563 stv0900_write_reg(intp, SFRINIT0, (symb & 0xff));
1564
1565 stv0900_write_reg(intp, DMDT0M, 0x20);
1566 stv0900_write_reg(intp, CFRINIT1, (coarse_freq >> 8) & 0xff);
1567 stv0900_write_reg(intp, CFRINIT0, coarse_freq & 0xff);
1568 stv0900_write_reg(intp, DMDISTATE, 0x15);
2260 } 1569 }
2261 1570
2262 return coarse_srate; 1571 return coarse_srate;
@@ -2265,163 +1574,135 @@ static u32 stv0900_search_srate_fine(struct dvb_frontend *fe)
2265static int stv0900_blind_search_algo(struct dvb_frontend *fe) 1574static int stv0900_blind_search_algo(struct dvb_frontend *fe)
2266{ 1575{
2267 struct stv0900_state *state = fe->demodulator_priv; 1576 struct stv0900_state *state = fe->demodulator_priv;
2268 struct stv0900_internal *i_params = state->internal; 1577 struct stv0900_internal *intp = state->internal;
2269 enum fe_stv0900_demod_num demod = state->demod; 1578 enum fe_stv0900_demod_num demod = state->demod;
2270 u8 k_ref_tmg, k_ref_tmg_max, k_ref_tmg_min; 1579 u8 k_ref_tmg,
2271 u32 coarse_srate; 1580 k_ref_tmg_max,
2272 int lock = FALSE, coarse_fail = FALSE; 1581 k_ref_tmg_min;
2273 s32 demod_timeout = 500, fec_timeout = 50, kref_tmg_reg, fail_cpt, i, agc2_overflow; 1582 u32 coarse_srate,
2274 u16 agc2_integr; 1583 agc2_th;
2275 u8 dstatus2; 1584 int lock = FALSE,
2276 1585 coarse_fail = FALSE;
2277 dprintk(KERN_INFO "%s\n", __func__); 1586 s32 demod_timeout = 500,
2278 1587 fec_timeout = 50,
2279 if (i_params->chip_id < 0x20) { 1588 fail_cpt,
1589 i,
1590 agc2_overflow;
1591 u16 agc2_int;
1592 u8 dstatus2;
1593
1594 dprintk("%s\n", __func__);
1595
1596 if (intp->chip_id < 0x20) {
2280 k_ref_tmg_max = 233; 1597 k_ref_tmg_max = 233;
2281 k_ref_tmg_min = 143; 1598 k_ref_tmg_min = 143;
2282 } else { 1599 } else {
2283 k_ref_tmg_max = 120; 1600 k_ref_tmg_max = 110;
2284 k_ref_tmg_min = 30; 1601 k_ref_tmg_min = 10;
2285 } 1602 }
2286 1603
2287 agc2_integr = stv0900_blind_check_agc2_min_level(i_params, demod); 1604 if (intp->chip_id <= 0x20)
2288 1605 agc2_th = STV0900_BLIND_SEARCH_AGC2_TH;
2289 if (agc2_integr > STV0900_BLIND_SEARCH_AGC2_TH) { 1606 else
2290 lock = FALSE; 1607 agc2_th = STV0900_BLIND_SEARCH_AGC2_TH_CUT30;
2291
2292 } else {
2293 switch (demod) {
2294 case STV0900_DEMOD_1:
2295 default:
2296 if (i_params->chip_id == 0x10)
2297 stv0900_write_reg(i_params, R0900_P1_CORRELEXP, 0xAA);
2298
2299 if (i_params->chip_id < 0x20)
2300 stv0900_write_reg(i_params, R0900_P1_CARHDR, 0x55);
2301
2302 stv0900_write_reg(i_params, R0900_P1_CARCFG, 0xC4);
2303 stv0900_write_reg(i_params, R0900_P1_RTCS2, 0x44);
2304
2305 if (i_params->chip_id >= 0x20) {
2306 stv0900_write_reg(i_params, R0900_P1_EQUALCFG, 0x41);
2307 stv0900_write_reg(i_params, R0900_P1_FFECFG, 0x41);
2308 stv0900_write_reg(i_params, R0900_P1_VITSCALE, 0x82);
2309 stv0900_write_reg(i_params, R0900_P1_VAVSRVIT, 0x0);
2310 }
2311
2312 kref_tmg_reg = R0900_P1_KREFTMG;
2313 break;
2314 case STV0900_DEMOD_2:
2315 if (i_params->chip_id == 0x10)
2316 stv0900_write_reg(i_params, R0900_P2_CORRELEXP, 0xAA);
2317
2318 if (i_params->chip_id < 0x20)
2319 stv0900_write_reg(i_params, R0900_P2_CARHDR, 0x55);
2320 1608
2321 stv0900_write_reg(i_params, R0900_P2_CARCFG, 0xC4); 1609 agc2_int = stv0900_blind_check_agc2_min_level(intp, demod);
2322 stv0900_write_reg(i_params, R0900_P2_RTCS2, 0x44);
2323 1610
2324 if (i_params->chip_id >= 0x20) { 1611 if (agc2_int > STV0900_BLIND_SEARCH_AGC2_TH)
2325 stv0900_write_reg(i_params, R0900_P2_EQUALCFG, 0x41); 1612 return FALSE;
2326 stv0900_write_reg(i_params, R0900_P2_FFECFG, 0x41);
2327 stv0900_write_reg(i_params, R0900_P2_VITSCALE, 0x82);
2328 stv0900_write_reg(i_params, R0900_P2_VAVSRVIT, 0x0);
2329 }
2330 1613
2331 kref_tmg_reg = R0900_P2_KREFTMG; 1614 if (intp->chip_id == 0x10)
2332 break; 1615 stv0900_write_reg(intp, CORRELEXP, 0xaa);
2333 }
2334 1616
2335 k_ref_tmg = k_ref_tmg_max; 1617 if (intp->chip_id < 0x20)
1618 stv0900_write_reg(intp, CARHDR, 0x55);
1619 else
1620 stv0900_write_reg(intp, CARHDR, 0x20);
2336 1621
2337 do { 1622 if (intp->chip_id <= 0x20)
2338 stv0900_write_reg(i_params, kref_tmg_reg, k_ref_tmg); 1623 stv0900_write_reg(intp, CARCFG, 0xc4);
2339 if (stv0900_search_srate_coarse(fe) != 0) { 1624 else
2340 coarse_srate = stv0900_search_srate_fine(fe); 1625 stv0900_write_reg(intp, CARCFG, 0x6);
2341 1626
2342 if (coarse_srate != 0) { 1627 stv0900_write_reg(intp, RTCS2, 0x44);
2343 stv0900_get_lock_timeout(&demod_timeout, &fec_timeout, coarse_srate, STV0900_BLIND_SEARCH);
2344 lock = stv0900_get_demod_lock(i_params, demod, demod_timeout);
2345 } else
2346 lock = FALSE;
2347 } else {
2348 fail_cpt = 0;
2349 agc2_overflow = 0;
2350 1628
2351 switch (demod) { 1629 if (intp->chip_id >= 0x20) {
2352 case STV0900_DEMOD_1: 1630 stv0900_write_reg(intp, EQUALCFG, 0x41);
2353 default: 1631 stv0900_write_reg(intp, FFECFG, 0x41);
2354 for (i = 0; i < 10; i++) { 1632 stv0900_write_reg(intp, VITSCALE, 0x82);
2355 agc2_integr = (stv0900_read_reg(i_params, R0900_P1_AGC2I1) << 8) 1633 stv0900_write_reg(intp, VAVSRVIT, 0x0);
2356 | stv0900_read_reg(i_params, R0900_P1_AGC2I0); 1634 }
2357 1635
2358 if (agc2_integr >= 0xff00) 1636 k_ref_tmg = k_ref_tmg_max;
2359 agc2_overflow++;
2360 1637
2361 dstatus2 = stv0900_read_reg(i_params, R0900_P1_DSTATUS2); 1638 do {
1639 stv0900_write_reg(intp, KREFTMG, k_ref_tmg);
1640 if (stv0900_search_srate_coarse(fe) != 0) {
1641 coarse_srate = stv0900_search_srate_fine(fe);
1642
1643 if (coarse_srate != 0) {
1644 stv0900_get_lock_timeout(&demod_timeout,
1645 &fec_timeout,
1646 coarse_srate,
1647 STV0900_BLIND_SEARCH);
1648 lock = stv0900_get_demod_lock(intp,
1649 demod,
1650 demod_timeout);
1651 } else
1652 lock = FALSE;
1653 } else {
1654 fail_cpt = 0;
1655 agc2_overflow = 0;
2362 1656
2363 if (((dstatus2 & 0x1) == 0x1) && ((dstatus2 >> 7) == 1)) 1657 for (i = 0; i < 10; i++) {
2364 fail_cpt++; 1658 agc2_int = (stv0900_read_reg(intp, AGC2I1) << 8)
2365 } 1659 | stv0900_read_reg(intp, AGC2I0);
2366 break;
2367 case STV0900_DEMOD_2:
2368 for (i = 0; i < 10; i++) {
2369 agc2_integr = (stv0900_read_reg(i_params, R0900_P2_AGC2I1) << 8)
2370 | stv0900_read_reg(i_params, R0900_P2_AGC2I0);
2371 1660
2372 if (agc2_integr >= 0xff00) 1661 if (agc2_int >= 0xff00)
2373 agc2_overflow++; 1662 agc2_overflow++;
2374 1663
2375 dstatus2 = stv0900_read_reg(i_params, R0900_P2_DSTATUS2); 1664 dstatus2 = stv0900_read_reg(intp, DSTATUS2);
2376 1665
2377 if (((dstatus2 & 0x1) == 0x1) && ((dstatus2 >> 7) == 1)) 1666 if (((dstatus2 & 0x1) == 0x1) &&
2378 fail_cpt++; 1667 ((dstatus2 >> 7) == 1))
2379 } 1668 fail_cpt++;
2380 break; 1669 }
2381 }
2382 1670
2383 if ((fail_cpt > 7) || (agc2_overflow > 7)) 1671 if ((fail_cpt > 7) || (agc2_overflow > 7))
2384 coarse_fail = TRUE; 1672 coarse_fail = TRUE;
2385 1673
2386 lock = FALSE; 1674 lock = FALSE;
2387 } 1675 }
2388 k_ref_tmg -= 30; 1676 k_ref_tmg -= 30;
2389 } while ((k_ref_tmg >= k_ref_tmg_min) && (lock == FALSE) && (coarse_fail == FALSE)); 1677 } while ((k_ref_tmg >= k_ref_tmg_min) &&
2390 } 1678 (lock == FALSE) &&
1679 (coarse_fail == FALSE));
2391 1680
2392 return lock; 1681 return lock;
2393} 1682}
2394 1683
2395static void stv0900_set_viterbi_acq(struct stv0900_internal *i_params, 1684static void stv0900_set_viterbi_acq(struct stv0900_internal *intp,
2396 enum fe_stv0900_demod_num demod) 1685 enum fe_stv0900_demod_num demod)
2397{ 1686{
2398 s32 vth_reg; 1687 s32 vth_reg = VTH12;
2399 1688
2400 dprintk(KERN_INFO "%s\n", __func__); 1689 dprintk("%s\n", __func__);
2401 1690
2402 dmd_reg(vth_reg, R0900_P1_VTH12, R0900_P2_VTH12); 1691 stv0900_write_reg(intp, vth_reg++, 0x96);
2403 1692 stv0900_write_reg(intp, vth_reg++, 0x64);
2404 stv0900_write_reg(i_params, vth_reg++, 0x96); 1693 stv0900_write_reg(intp, vth_reg++, 0x36);
2405 stv0900_write_reg(i_params, vth_reg++, 0x64); 1694 stv0900_write_reg(intp, vth_reg++, 0x23);
2406 stv0900_write_reg(i_params, vth_reg++, 0x36); 1695 stv0900_write_reg(intp, vth_reg++, 0x1e);
2407 stv0900_write_reg(i_params, vth_reg++, 0x23); 1696 stv0900_write_reg(intp, vth_reg++, 0x19);
2408 stv0900_write_reg(i_params, vth_reg++, 0x1E);
2409 stv0900_write_reg(i_params, vth_reg++, 0x19);
2410} 1697}
2411 1698
2412static void stv0900_set_search_standard(struct stv0900_internal *i_params, 1699static void stv0900_set_search_standard(struct stv0900_internal *intp,
2413 enum fe_stv0900_demod_num demod) 1700 enum fe_stv0900_demod_num demod)
2414{ 1701{
2415 1702
2416 int sstndrd; 1703 dprintk("%s\n", __func__);
2417
2418 dprintk(KERN_INFO "%s\n", __func__);
2419 1704
2420 sstndrd = i_params->dmd1_srch_standard; 1705 switch (intp->srch_standard[demod]) {
2421 if (demod == 1)
2422 sstndrd = i_params->dmd2_srch_stndrd;
2423
2424 switch (sstndrd) {
2425 case STV0900_SEARCH_DVBS1: 1706 case STV0900_SEARCH_DVBS1:
2426 dprintk("Search Standard = DVBS1\n"); 1707 dprintk("Search Standard = DVBS1\n");
2427 break; 1708 break;
@@ -2436,129 +1717,74 @@ static void stv0900_set_search_standard(struct stv0900_internal *i_params,
2436 break; 1717 break;
2437 } 1718 }
2438 1719
2439 switch (demod) { 1720 switch (intp->srch_standard[demod]) {
2440 case STV0900_DEMOD_1: 1721 case STV0900_SEARCH_DVBS1:
2441 default: 1722 case STV0900_SEARCH_DSS:
2442 switch (i_params->dmd1_srch_standard) { 1723 stv0900_write_bits(intp, DVBS1_ENABLE, 1);
2443 case STV0900_SEARCH_DVBS1: 1724 stv0900_write_bits(intp, DVBS2_ENABLE, 0);
2444 case STV0900_SEARCH_DSS: 1725 stv0900_write_bits(intp, STOP_CLKVIT, 0);
2445 stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 1); 1726 stv0900_set_dvbs1_track_car_loop(intp,
2446 stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 0); 1727 demod,
2447 1728 intp->symbol_rate[demod]);
2448 stv0900_write_bits(i_params, F0900_STOP_CLKVIT1, 0); 1729 stv0900_write_reg(intp, CAR2CFG, 0x22);
2449 stv0900_write_reg(i_params, R0900_P1_ACLC, 0x1a); 1730
2450 stv0900_write_reg(i_params, R0900_P1_BCLC, 0x09); 1731 stv0900_set_viterbi_acq(intp, demod);
2451 stv0900_write_reg(i_params, R0900_P1_CAR2CFG, 0x22); 1732 stv0900_set_viterbi_standard(intp,
2452 1733 intp->srch_standard[demod],
2453 stv0900_set_viterbi_acq(i_params, demod); 1734 intp->fec[demod], demod);
2454 stv0900_set_viterbi_standard(i_params,
2455 i_params->dmd1_srch_standard,
2456 i_params->dmd1_fec, demod);
2457
2458 break;
2459 case STV0900_SEARCH_DVBS2:
2460 stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 0);
2461 stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 0);
2462 stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 1);
2463 stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 1);
2464 stv0900_write_bits(i_params, F0900_STOP_CLKVIT1, 1);
2465 stv0900_write_reg(i_params, R0900_P1_ACLC, 0x1a);
2466 stv0900_write_reg(i_params, R0900_P1_BCLC, 0x09);
2467 stv0900_write_reg(i_params, R0900_P1_CAR2CFG, 0x26);
2468 if (i_params->demod_mode != STV0900_SINGLE) {
2469 if (i_params->chip_id <= 0x11)
2470 stv0900_stop_all_s2_modcod(i_params, demod);
2471 else
2472 stv0900_activate_s2_modcode(i_params, demod);
2473
2474 } else
2475 stv0900_activate_s2_modcode_single(i_params, demod);
2476
2477 stv0900_set_viterbi_tracq(i_params, demod);
2478
2479 break;
2480 case STV0900_AUTO_SEARCH:
2481 default:
2482 stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 0);
2483 stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 0);
2484 stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 1);
2485 stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 1);
2486 stv0900_write_bits(i_params, F0900_STOP_CLKVIT1, 0);
2487 stv0900_write_reg(i_params, R0900_P1_ACLC, 0x1a);
2488 stv0900_write_reg(i_params, R0900_P1_BCLC, 0x09);
2489 stv0900_write_reg(i_params, R0900_P1_CAR2CFG, 0x26);
2490 if (i_params->demod_mode != STV0900_SINGLE) {
2491 if (i_params->chip_id <= 0x11)
2492 stv0900_stop_all_s2_modcod(i_params, demod);
2493 else
2494 stv0900_activate_s2_modcode(i_params, demod);
2495 1735
2496 } else 1736 break;
2497 stv0900_activate_s2_modcode_single(i_params, demod); 1737 case STV0900_SEARCH_DVBS2:
1738 stv0900_write_bits(intp, DVBS1_ENABLE, 0);
1739 stv0900_write_bits(intp, DVBS2_ENABLE, 1);
1740 stv0900_write_bits(intp, STOP_CLKVIT, 1);
1741 stv0900_write_reg(intp, ACLC, 0x1a);
1742 stv0900_write_reg(intp, BCLC, 0x09);
1743 if (intp->chip_id <= 0x20) /*cut 1.x and 2.0*/
1744 stv0900_write_reg(intp, CAR2CFG, 0x26);
1745 else
1746 stv0900_write_reg(intp, CAR2CFG, 0x66);
2498 1747
2499 if (i_params->dmd1_symbol_rate >= 2000000) 1748 if (intp->demod_mode != STV0900_SINGLE) {
2500 stv0900_set_viterbi_acq(i_params, demod); 1749 if (intp->chip_id <= 0x11)
1750 stv0900_stop_all_s2_modcod(intp, demod);
2501 else 1751 else
2502 stv0900_set_viterbi_tracq(i_params, demod); 1752 stv0900_activate_s2_modcod(intp, demod);
2503 1753
2504 stv0900_set_viterbi_standard(i_params, i_params->dmd1_srch_standard, i_params->dmd1_fec, demod); 1754 } else
1755 stv0900_activate_s2_modcod_single(intp, demod);
2505 1756
2506 break; 1757 stv0900_set_viterbi_tracq(intp, demod);
2507 }
2508 break;
2509 case STV0900_DEMOD_2:
2510 switch (i_params->dmd2_srch_stndrd) {
2511 case STV0900_SEARCH_DVBS1:
2512 case STV0900_SEARCH_DSS:
2513 stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 1);
2514 stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 0);
2515 stv0900_write_bits(i_params, F0900_STOP_CLKVIT2, 0);
2516 stv0900_write_reg(i_params, R0900_P2_ACLC, 0x1a);
2517 stv0900_write_reg(i_params, R0900_P2_BCLC, 0x09);
2518 stv0900_write_reg(i_params, R0900_P2_CAR2CFG, 0x22);
2519 stv0900_set_viterbi_acq(i_params, demod);
2520 stv0900_set_viterbi_standard(i_params, i_params->dmd2_srch_stndrd, i_params->dmd2_fec, demod);
2521 break;
2522 case STV0900_SEARCH_DVBS2:
2523 stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 0);
2524 stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 0);
2525 stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 1);
2526 stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 1);
2527 stv0900_write_bits(i_params, F0900_STOP_CLKVIT2, 1);
2528 stv0900_write_reg(i_params, R0900_P2_ACLC, 0x1a);
2529 stv0900_write_reg(i_params, R0900_P2_BCLC, 0x09);
2530 stv0900_write_reg(i_params, R0900_P2_CAR2CFG, 0x26);
2531 if (i_params->demod_mode != STV0900_SINGLE)
2532 stv0900_activate_s2_modcode(i_params, demod);
2533 else
2534 stv0900_activate_s2_modcode_single(i_params, demod);
2535 1758
2536 stv0900_set_viterbi_tracq(i_params, demod); 1759 break;
2537 break; 1760 case STV0900_AUTO_SEARCH:
2538 case STV0900_AUTO_SEARCH: 1761 default:
2539 default: 1762 stv0900_write_bits(intp, DVBS1_ENABLE, 1);
2540 stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 0); 1763 stv0900_write_bits(intp, DVBS2_ENABLE, 1);
2541 stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 0); 1764 stv0900_write_bits(intp, STOP_CLKVIT, 0);
2542 stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 1); 1765 stv0900_write_reg(intp, ACLC, 0x1a);
2543 stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 1); 1766 stv0900_write_reg(intp, BCLC, 0x09);
2544 stv0900_write_bits(i_params, F0900_STOP_CLKVIT2, 0); 1767 stv0900_set_dvbs1_track_car_loop(intp,
2545 stv0900_write_reg(i_params, R0900_P2_ACLC, 0x1a); 1768 demod,
2546 stv0900_write_reg(i_params, R0900_P2_BCLC, 0x09); 1769 intp->symbol_rate[demod]);
2547 stv0900_write_reg(i_params, R0900_P2_CAR2CFG, 0x26); 1770 if (intp->chip_id <= 0x20) /*cut 1.x and 2.0*/
2548 if (i_params->demod_mode != STV0900_SINGLE) 1771 stv0900_write_reg(intp, CAR2CFG, 0x26);
2549 stv0900_activate_s2_modcode(i_params, demod); 1772 else
2550 else 1773 stv0900_write_reg(intp, CAR2CFG, 0x66);
2551 stv0900_activate_s2_modcode_single(i_params, demod);
2552 1774
2553 if (i_params->dmd2_symbol_rate >= 2000000) 1775 if (intp->demod_mode != STV0900_SINGLE) {
2554 stv0900_set_viterbi_acq(i_params, demod); 1776 if (intp->chip_id <= 0x11)
1777 stv0900_stop_all_s2_modcod(intp, demod);
2555 else 1778 else
2556 stv0900_set_viterbi_tracq(i_params, demod); 1779 stv0900_activate_s2_modcod(intp, demod);
2557 1780
2558 stv0900_set_viterbi_standard(i_params, i_params->dmd2_srch_stndrd, i_params->dmd2_fec, demod); 1781 } else
1782 stv0900_activate_s2_modcod_single(intp, demod);
2559 1783
2560 break; 1784 stv0900_set_viterbi_tracq(intp, demod);
2561 } 1785 stv0900_set_viterbi_standard(intp,
1786 intp->srch_standard[demod],
1787 intp->fec[demod], demod);
2562 1788
2563 break; 1789 break;
2564 } 1790 }
@@ -2567,10 +1793,11 @@ static void stv0900_set_search_standard(struct stv0900_internal *i_params,
2567enum fe_stv0900_signal_type stv0900_algo(struct dvb_frontend *fe) 1793enum fe_stv0900_signal_type stv0900_algo(struct dvb_frontend *fe)
2568{ 1794{
2569 struct stv0900_state *state = fe->demodulator_priv; 1795 struct stv0900_state *state = fe->demodulator_priv;
2570 struct stv0900_internal *i_params = state->internal; 1796 struct stv0900_internal *intp = state->internal;
2571 enum fe_stv0900_demod_num demod = state->demod; 1797 enum fe_stv0900_demod_num demod = state->demod;
2572 1798
2573 s32 demod_timeout = 500, fec_timeout = 50, stream_merger_field; 1799 s32 demod_timeout = 500, fec_timeout = 50;
1800 s32 aq_power, agc1_power, i;
2574 1801
2575 int lock = FALSE, low_sr = FALSE; 1802 int lock = FALSE, low_sr = FALSE;
2576 1803
@@ -2578,157 +1805,117 @@ enum fe_stv0900_signal_type stv0900_algo(struct dvb_frontend *fe)
2578 enum fe_stv0900_search_algo algo; 1805 enum fe_stv0900_search_algo algo;
2579 int no_signal = FALSE; 1806 int no_signal = FALSE;
2580 1807
2581 dprintk(KERN_INFO "%s\n", __func__); 1808 dprintk("%s\n", __func__);
2582
2583 switch (demod) {
2584 case STV0900_DEMOD_1:
2585 default:
2586 algo = i_params->dmd1_srch_algo;
2587 1809
2588 stv0900_write_bits(i_params, F0900_P1_RST_HWARE, 1); 1810 algo = intp->srch_algo[demod];
2589 stream_merger_field = F0900_P1_RST_HWARE; 1811 stv0900_write_bits(intp, RST_HWARE, 1);
2590 1812 stv0900_write_reg(intp, DMDISTATE, 0x5c);
2591 stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x5C); 1813 if (intp->chip_id >= 0x20) {
2592 1814 if (intp->symbol_rate[demod] > 5000000)
2593 if (i_params->chip_id >= 0x20) 1815 stv0900_write_reg(intp, CORRELABS, 0x9e);
2594 stv0900_write_reg(i_params, R0900_P1_CORRELABS, 0x9e);
2595 else 1816 else
2596 stv0900_write_reg(i_params, R0900_P1_CORRELABS, 0x88); 1817 stv0900_write_reg(intp, CORRELABS, 0x82);
2597 1818 } else
2598 stv0900_get_lock_timeout(&demod_timeout, &fec_timeout, i_params->dmd1_symbol_rate, i_params->dmd1_srch_algo); 1819 stv0900_write_reg(intp, CORRELABS, 0x88);
2599
2600 if (i_params->dmd1_srch_algo == STV0900_BLIND_SEARCH) {
2601 i_params->tuner1_bw = 2 * 36000000;
2602
2603 stv0900_write_reg(i_params, R0900_P1_TMGCFG2, 0x00);
2604 stv0900_write_reg(i_params, R0900_P1_CORRELMANT, 0x70);
2605
2606 stv0900_set_symbol_rate(i_params, i_params->mclk, 1000000, demod);
2607 } else {
2608 stv0900_write_reg(i_params, R0900_P1_DMDT0M, 0x20);
2609 stv0900_write_reg(i_params, R0900_P1_TMGCFG, 0xd2);
2610
2611 if (i_params->dmd1_symbol_rate < 2000000)
2612 stv0900_write_reg(i_params, R0900_P1_CORRELMANT, 0x63);
2613 else
2614 stv0900_write_reg(i_params, R0900_P1_CORRELMANT, 0x70);
2615
2616 stv0900_write_reg(i_params, R0900_P1_AGC2REF, 0x38);
2617 if (i_params->chip_id >= 0x20) {
2618 stv0900_write_reg(i_params, R0900_P1_KREFTMG, 0x5a);
2619
2620 if (i_params->dmd1_srch_algo == STV0900_COLD_START)
2621 i_params->tuner1_bw = (15 * (stv0900_carrier_width(i_params->dmd1_symbol_rate, i_params->rolloff) + 10000000)) / 10;
2622 else if (i_params->dmd1_srch_algo == STV0900_WARM_START)
2623 i_params->tuner1_bw = stv0900_carrier_width(i_params->dmd1_symbol_rate, i_params->rolloff) + 10000000;
2624 } else {
2625 stv0900_write_reg(i_params, R0900_P1_KREFTMG, 0xc1);
2626 i_params->tuner1_bw = (15 * (stv0900_carrier_width(i_params->dmd1_symbol_rate, i_params->rolloff) + 10000000)) / 10;
2627 }
2628
2629 stv0900_write_reg(i_params, R0900_P1_TMGCFG2, 0x01);
2630
2631 stv0900_set_symbol_rate(i_params, i_params->mclk, i_params->dmd1_symbol_rate, demod);
2632 stv0900_set_max_symbol_rate(i_params, i_params->mclk, i_params->dmd1_symbol_rate, demod);
2633 stv0900_set_min_symbol_rate(i_params, i_params->mclk, i_params->dmd1_symbol_rate, demod);
2634 if (i_params->dmd1_symbol_rate >= 10000000)
2635 low_sr = FALSE;
2636 else
2637 low_sr = TRUE;
2638
2639 }
2640
2641 stv0900_set_tuner(fe, i_params->tuner1_freq, i_params->tuner1_bw);
2642
2643 stv0900_write_bits(i_params, F0900_P1_SPECINV_CONTROL, i_params->dmd1_srch_iq_inv);
2644 stv0900_write_bits(i_params, F0900_P1_MANUAL_ROLLOFF, 1);
2645
2646 stv0900_set_search_standard(i_params, demod);
2647 1820
2648 if (i_params->dmd1_srch_algo != STV0900_BLIND_SEARCH) 1821 stv0900_get_lock_timeout(&demod_timeout, &fec_timeout,
2649 stv0900_start_search(i_params, demod); 1822 intp->symbol_rate[demod],
2650 break; 1823 intp->srch_algo[demod]);
2651 case STV0900_DEMOD_2:
2652 algo = i_params->dmd2_srch_algo;
2653 1824
2654 stv0900_write_bits(i_params, F0900_P2_RST_HWARE, 1); 1825 if (intp->srch_algo[demod] == STV0900_BLIND_SEARCH) {
1826 intp->bw[demod] = 2 * 36000000;
2655 1827
2656 stream_merger_field = F0900_P2_RST_HWARE; 1828 stv0900_write_reg(intp, TMGCFG2, 0xc0);
1829 stv0900_write_reg(intp, CORRELMANT, 0x70);
2657 1830
2658 stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x5C); 1831 stv0900_set_symbol_rate(intp, intp->mclk, 1000000, demod);
1832 } else {
1833 stv0900_write_reg(intp, DMDT0M, 0x20);
1834 stv0900_write_reg(intp, TMGCFG, 0xd2);
2659 1835
2660 if (i_params->chip_id >= 0x20) 1836 if (intp->symbol_rate[demod] < 2000000)
2661 stv0900_write_reg(i_params, R0900_P2_CORRELABS, 0x9e); 1837 stv0900_write_reg(intp, CORRELMANT, 0x63);
2662 else 1838 else
2663 stv0900_write_reg(i_params, R0900_P2_CORRELABS, 0x88); 1839 stv0900_write_reg(intp, CORRELMANT, 0x70);
2664 1840
2665 stv0900_get_lock_timeout(&demod_timeout, &fec_timeout, i_params->dmd2_symbol_rate, i_params->dmd2_srch_algo); 1841 stv0900_write_reg(intp, AGC2REF, 0x38);
2666 1842
2667 if (i_params->dmd2_srch_algo == STV0900_BLIND_SEARCH) { 1843 intp->bw[demod] =
2668 i_params->tuner2_bw = 2 * 36000000; 1844 stv0900_carrier_width(intp->symbol_rate[demod],
1845 intp->rolloff);
1846 if (intp->chip_id >= 0x20) {
1847 stv0900_write_reg(intp, KREFTMG, 0x5a);
2669 1848
2670 stv0900_write_reg(i_params, R0900_P2_TMGCFG2, 0x00); 1849 if (intp->srch_algo[demod] == STV0900_COLD_START) {
2671 stv0900_write_reg(i_params, R0900_P2_CORRELMANT, 0x70); 1850 intp->bw[demod] += 10000000;
1851 intp->bw[demod] *= 15;
1852 intp->bw[demod] /= 10;
1853 } else if (intp->srch_algo[demod] == STV0900_WARM_START)
1854 intp->bw[demod] += 10000000;
2672 1855
2673 stv0900_set_symbol_rate(i_params, i_params->mclk, 1000000, demod);
2674 } else { 1856 } else {
2675 stv0900_write_reg(i_params, R0900_P2_DMDT0M, 0x20); 1857 stv0900_write_reg(intp, KREFTMG, 0xc1);
2676 stv0900_write_reg(i_params, R0900_P2_TMGCFG, 0xd2); 1858 intp->bw[demod] += 10000000;
1859 intp->bw[demod] *= 15;
1860 intp->bw[demod] /= 10;
1861 }
2677 1862
2678 if (i_params->dmd2_symbol_rate < 2000000) 1863 stv0900_write_reg(intp, TMGCFG2, 0xc1);
2679 stv0900_write_reg(i_params, R0900_P2_CORRELMANT, 0x63);
2680 else
2681 stv0900_write_reg(i_params, R0900_P2_CORRELMANT, 0x70);
2682 1864
2683 if (i_params->dmd2_symbol_rate >= 10000000) 1865 stv0900_set_symbol_rate(intp, intp->mclk,
2684 stv0900_write_reg(i_params, R0900_P2_AGC2REF, 0x38); 1866 intp->symbol_rate[demod], demod);
2685 else 1867 stv0900_set_max_symbol_rate(intp, intp->mclk,
2686 stv0900_write_reg(i_params, R0900_P2_AGC2REF, 0x60); 1868 intp->symbol_rate[demod], demod);
1869 stv0900_set_min_symbol_rate(intp, intp->mclk,
1870 intp->symbol_rate[demod], demod);
1871 if (intp->symbol_rate[demod] >= 10000000)
1872 low_sr = FALSE;
1873 else
1874 low_sr = TRUE;
2687 1875
2688 if (i_params->chip_id >= 0x20) { 1876 }
2689 stv0900_write_reg(i_params, R0900_P2_KREFTMG, 0x5a);
2690 1877
2691 if (i_params->dmd2_srch_algo == STV0900_COLD_START) 1878 stv0900_set_tuner(fe, intp->freq[demod], intp->bw[demod]);
2692 i_params->tuner2_bw = (15 * (stv0900_carrier_width(i_params->dmd2_symbol_rate,
2693 i_params->rolloff) + 10000000)) / 10;
2694 else if (i_params->dmd2_srch_algo == STV0900_WARM_START)
2695 i_params->tuner2_bw = stv0900_carrier_width(i_params->dmd2_symbol_rate,
2696 i_params->rolloff) + 10000000;
2697 } else {
2698 stv0900_write_reg(i_params, R0900_P2_KREFTMG, 0xc1);
2699 i_params->tuner2_bw = (15 * (stv0900_carrier_width(i_params->dmd2_symbol_rate,
2700 i_params->rolloff) + 10000000)) / 10;
2701 }
2702 1879
2703 stv0900_write_reg(i_params, R0900_P2_TMGCFG2, 0x01); 1880 agc1_power = MAKEWORD(stv0900_get_bits(intp, AGCIQ_VALUE1),
1881 stv0900_get_bits(intp, AGCIQ_VALUE0));
2704 1882
2705 stv0900_set_symbol_rate(i_params, i_params->mclk, i_params->dmd2_symbol_rate, demod); 1883 aq_power = 0;
2706 stv0900_set_max_symbol_rate(i_params, i_params->mclk, i_params->dmd2_symbol_rate, demod);
2707 stv0900_set_min_symbol_rate(i_params, i_params->mclk, i_params->dmd2_symbol_rate, demod);
2708 if (i_params->dmd2_symbol_rate >= 10000000)
2709 low_sr = FALSE;
2710 else
2711 low_sr = TRUE;
2712 1884
2713 } 1885 if (agc1_power == 0) {
1886 for (i = 0; i < 5; i++)
1887 aq_power += (stv0900_get_bits(intp, POWER_I) +
1888 stv0900_get_bits(intp, POWER_Q)) / 2;
2714 1889
2715 stv0900_set_tuner(fe, i_params->tuner2_freq, i_params->tuner2_bw); 1890 aq_power /= 5;
1891 }
2716 1892
2717 stv0900_write_bits(i_params, F0900_P2_SPECINV_CONTROL, i_params->dmd2_srch_iq_inv); 1893 if ((agc1_power == 0) && (aq_power < IQPOWER_THRESHOLD)) {
2718 stv0900_write_bits(i_params, F0900_P2_MANUAL_ROLLOFF, 1); 1894 intp->result[demod].locked = FALSE;
1895 signal_type = STV0900_NOAGC1;
1896 dprintk("%s: NO AGC1, POWERI, POWERQ\n", __func__);
1897 } else {
1898 stv0900_write_bits(intp, SPECINV_CONTROL,
1899 intp->srch_iq_inv[demod]);
1900 if (intp->chip_id <= 0x20) /*cut 2.0*/
1901 stv0900_write_bits(intp, MANUALSX_ROLLOFF, 1);
1902 else /*cut 3.0*/
1903 stv0900_write_bits(intp, MANUALS2_ROLLOFF, 1);
2719 1904
2720 stv0900_set_search_standard(i_params, demod); 1905 stv0900_set_search_standard(intp, demod);
2721 1906
2722 if (i_params->dmd2_srch_algo != STV0900_BLIND_SEARCH) 1907 if (intp->srch_algo[demod] != STV0900_BLIND_SEARCH)
2723 stv0900_start_search(i_params, demod); 1908 stv0900_start_search(intp, demod);
2724 break;
2725 } 1909 }
2726 1910
2727 if (i_params->chip_id == 0x12) { 1911 if (signal_type == STV0900_NOAGC1)
2728 stv0900_write_bits(i_params, stream_merger_field, 0); 1912 return signal_type;
1913
1914 if (intp->chip_id == 0x12) {
1915 stv0900_write_bits(intp, RST_HWARE, 0);
2729 msleep(3); 1916 msleep(3);
2730 stv0900_write_bits(i_params, stream_merger_field, 1); 1917 stv0900_write_bits(intp, RST_HWARE, 1);
2731 stv0900_write_bits(i_params, stream_merger_field, 0); 1918 stv0900_write_bits(intp, RST_HWARE, 0);
2732 } 1919 }
2733 1920
2734 if (algo == STV0900_BLIND_SEARCH) 1921 if (algo == STV0900_BLIND_SEARCH)
@@ -2736,12 +1923,12 @@ enum fe_stv0900_signal_type stv0900_algo(struct dvb_frontend *fe)
2736 else if (algo == STV0900_COLD_START) 1923 else if (algo == STV0900_COLD_START)
2737 lock = stv0900_get_demod_cold_lock(fe, demod_timeout); 1924 lock = stv0900_get_demod_cold_lock(fe, demod_timeout);
2738 else if (algo == STV0900_WARM_START) 1925 else if (algo == STV0900_WARM_START)
2739 lock = stv0900_get_demod_lock(i_params, demod, demod_timeout); 1926 lock = stv0900_get_demod_lock(intp, demod, demod_timeout);
2740 1927
2741 if ((lock == FALSE) && (algo == STV0900_COLD_START)) { 1928 if ((lock == FALSE) && (algo == STV0900_COLD_START)) {
2742 if (low_sr == FALSE) { 1929 if (low_sr == FALSE) {
2743 if (stv0900_check_timing_lock(i_params, demod) == TRUE) 1930 if (stv0900_check_timing_lock(intp, demod) == TRUE)
2744 lock = stv0900_sw_algo(i_params, demod); 1931 lock = stv0900_sw_algo(intp, demod);
2745 } 1932 }
2746 } 1933 }
2747 1934
@@ -2750,98 +1937,64 @@ enum fe_stv0900_signal_type stv0900_algo(struct dvb_frontend *fe)
2750 1937
2751 if ((lock == TRUE) && (signal_type == STV0900_RANGEOK)) { 1938 if ((lock == TRUE) && (signal_type == STV0900_RANGEOK)) {
2752 stv0900_track_optimization(fe); 1939 stv0900_track_optimization(fe);
2753 if (i_params->chip_id <= 0x11) { 1940 if (intp->chip_id <= 0x11) {
2754 if ((stv0900_get_standard(fe, STV0900_DEMOD_1) == STV0900_DVBS1_STANDARD) && (stv0900_get_standard(fe, STV0900_DEMOD_2) == STV0900_DVBS1_STANDARD)) { 1941 if ((stv0900_get_standard(fe, 0) ==
1942 STV0900_DVBS1_STANDARD) &&
1943 (stv0900_get_standard(fe, 1) ==
1944 STV0900_DVBS1_STANDARD)) {
2755 msleep(20); 1945 msleep(20);
2756 stv0900_write_bits(i_params, stream_merger_field, 0); 1946 stv0900_write_bits(intp, RST_HWARE, 0);
2757 } else { 1947 } else {
2758 stv0900_write_bits(i_params, stream_merger_field, 0); 1948 stv0900_write_bits(intp, RST_HWARE, 0);
2759 msleep(3); 1949 msleep(3);
2760 stv0900_write_bits(i_params, stream_merger_field, 1); 1950 stv0900_write_bits(intp, RST_HWARE, 1);
2761 stv0900_write_bits(i_params, stream_merger_field, 0); 1951 stv0900_write_bits(intp, RST_HWARE, 0);
2762 } 1952 }
2763 } else if (i_params->chip_id == 0x20) { 1953
2764 stv0900_write_bits(i_params, stream_merger_field, 0); 1954 } else if (intp->chip_id >= 0x20) {
1955 stv0900_write_bits(intp, RST_HWARE, 0);
2765 msleep(3); 1956 msleep(3);
2766 stv0900_write_bits(i_params, stream_merger_field, 1); 1957 stv0900_write_bits(intp, RST_HWARE, 1);
2767 stv0900_write_bits(i_params, stream_merger_field, 0); 1958 stv0900_write_bits(intp, RST_HWARE, 0);
2768 } 1959 }
2769 1960
2770 if (stv0900_wait_for_lock(i_params, demod, fec_timeout, fec_timeout) == TRUE) { 1961 if (stv0900_wait_for_lock(intp, demod,
1962 fec_timeout, fec_timeout) == TRUE) {
2771 lock = TRUE; 1963 lock = TRUE;
2772 switch (demod) { 1964 intp->result[demod].locked = TRUE;
2773 case STV0900_DEMOD_1: 1965 if (intp->result[demod].standard ==
2774 default: 1966 STV0900_DVBS2_STANDARD) {
2775 i_params->dmd1_rslts.locked = TRUE; 1967 stv0900_set_dvbs2_rolloff(intp, demod);
2776 if (i_params->dmd1_rslts.standard == STV0900_DVBS2_STANDARD) { 1968 stv0900_write_bits(intp, RESET_UPKO_COUNT, 1);
2777 stv0900_set_dvbs2_rolloff(i_params, demod); 1969 stv0900_write_bits(intp, RESET_UPKO_COUNT, 0);
2778 stv0900_write_reg(i_params, R0900_P1_PDELCTRL2, 0x40); 1970 stv0900_write_reg(intp, ERRCTRL1, 0x67);
2779 stv0900_write_reg(i_params, R0900_P1_PDELCTRL2, 0); 1971 } else {
2780 stv0900_write_reg(i_params, R0900_P1_ERRCTRL1, 0x67); 1972 stv0900_write_reg(intp, ERRCTRL1, 0x75);
2781 } else {
2782 stv0900_write_reg(i_params, R0900_P1_ERRCTRL1, 0x75);
2783 }
2784
2785 stv0900_write_reg(i_params, R0900_P1_FBERCPT4, 0);
2786 stv0900_write_reg(i_params, R0900_P1_ERRCTRL2, 0xc1);
2787 break;
2788 case STV0900_DEMOD_2:
2789 i_params->dmd2_rslts.locked = TRUE;
2790
2791 if (i_params->dmd2_rslts.standard == STV0900_DVBS2_STANDARD) {
2792 stv0900_set_dvbs2_rolloff(i_params, demod);
2793 stv0900_write_reg(i_params, R0900_P2_PDELCTRL2, 0x60);
2794 stv0900_write_reg(i_params, R0900_P2_PDELCTRL2, 0x20);
2795 stv0900_write_reg(i_params, R0900_P2_ERRCTRL1, 0x67);
2796 } else {
2797 stv0900_write_reg(i_params, R0900_P2_ERRCTRL1, 0x75);
2798 }
2799
2800 stv0900_write_reg(i_params, R0900_P2_FBERCPT4, 0);
2801
2802 stv0900_write_reg(i_params, R0900_P2_ERRCTRL2, 0xc1);
2803 break;
2804 } 1973 }
1974
1975 stv0900_write_reg(intp, FBERCPT4, 0);
1976 stv0900_write_reg(intp, ERRCTRL2, 0xc1);
2805 } else { 1977 } else {
2806 lock = FALSE; 1978 lock = FALSE;
2807 signal_type = STV0900_NODATA; 1979 signal_type = STV0900_NODATA;
2808 no_signal = stv0900_check_signal_presence(i_params, demod); 1980 no_signal = stv0900_check_signal_presence(intp, demod);
2809 1981
2810 switch (demod) { 1982 intp->result[demod].locked = FALSE;
2811 case STV0900_DEMOD_1:
2812 default:
2813 i_params->dmd1_rslts.locked = FALSE;
2814 break;
2815 case STV0900_DEMOD_2:
2816 i_params->dmd2_rslts.locked = FALSE;
2817 break;
2818 }
2819 } 1983 }
2820 } 1984 }
2821 1985
2822 if ((signal_type == STV0900_NODATA) && (no_signal == FALSE)) { 1986 if ((signal_type != STV0900_NODATA) || (no_signal != FALSE))
2823 switch (demod) { 1987 return signal_type;
2824 case STV0900_DEMOD_1:
2825 default:
2826 if (i_params->chip_id <= 0x11) {
2827 if ((stv0900_get_bits(i_params, F0900_P1_HEADER_MODE) == STV0900_DVBS_FOUND) &&
2828 (i_params->dmd1_srch_iq_inv <= STV0900_IQ_AUTO_NORMAL_FIRST))
2829 signal_type = stv0900_dvbs1_acq_workaround(fe);
2830 } else
2831 i_params->dmd1_rslts.locked = FALSE;
2832 1988
2833 break; 1989 if (intp->chip_id > 0x11) {
2834 case STV0900_DEMOD_2: 1990 intp->result[demod].locked = FALSE;
2835 if (i_params->chip_id <= 0x11) { 1991 return signal_type;
2836 if ((stv0900_get_bits(i_params, F0900_P2_HEADER_MODE) == STV0900_DVBS_FOUND) &&
2837 (i_params->dmd2_srch_iq_inv <= STV0900_IQ_AUTO_NORMAL_FIRST))
2838 signal_type = stv0900_dvbs1_acq_workaround(fe);
2839 } else
2840 i_params->dmd2_rslts.locked = FALSE;
2841 break;
2842 }
2843 } 1992 }
2844 1993
1994 if ((stv0900_get_bits(intp, HEADER_MODE) == STV0900_DVBS_FOUND) &&
1995 (intp->srch_iq_inv[demod] <= STV0900_IQ_AUTO_NORMAL_FIRST))
1996 signal_type = stv0900_dvbs1_acq_workaround(fe);
1997
2845 return signal_type; 1998 return signal_type;
2846} 1999}
2847 2000
diff --git a/drivers/media/dvb/frontends/stv090x.c b/drivers/media/dvb/frontends/stv090x.c
index 488bdfb34fb3..48edd542242e 100644
--- a/drivers/media/dvb/frontends/stv090x.c
+++ b/drivers/media/dvb/frontends/stv090x.c
@@ -825,7 +825,7 @@ static int stv090x_set_min_srate(struct stv090x_state *state, u32 clk, u32 srate
825 sym /= (state->mclk >> 7); 825 sym /= (state->mclk >> 7);
826 } 826 }
827 827
828 if (STV090x_WRITE_DEMOD(state, SFRLOW1, ((sym >> 8) & 0xff)) < 0) /* MSB */ 828 if (STV090x_WRITE_DEMOD(state, SFRLOW1, ((sym >> 8) & 0x7f)) < 0) /* MSB */
829 goto err; 829 goto err;
830 if (STV090x_WRITE_DEMOD(state, SFRLOW0, (sym & 0xff)) < 0) /* LSB */ 830 if (STV090x_WRITE_DEMOD(state, SFRLOW0, (sym & 0xff)) < 0) /* LSB */
831 goto err; 831 goto err;
@@ -1238,6 +1238,8 @@ static int stv090x_delivery_search(struct stv090x_state *state)
1238 goto err; 1238 goto err;
1239 } 1239 }
1240 1240
1241 if (stv090x_set_vit_thtracq(state) < 0)
1242 goto err;
1241 break; 1243 break;
1242 1244
1243 case STV090x_SEARCH_AUTO: 1245 case STV090x_SEARCH_AUTO:
@@ -1278,17 +1280,8 @@ static int stv090x_delivery_search(struct stv090x_state *state)
1278 goto err; 1280 goto err;
1279 } 1281 }
1280 1282
1281 if (state->srate >= 2000000) { 1283 if (stv090x_set_vit_thacq(state) < 0)
1282 /* Srate >= 2MSPS, Viterbi threshold to acquire */ 1284 goto err;
1283 if (stv090x_set_vit_thacq(state) < 0)
1284 goto err;
1285 } else {
1286 /* Srate < 2MSPS, Reset Viterbi thresholdto track
1287 * and then re-acquire
1288 */
1289 if (stv090x_set_vit_thtracq(state) < 0)
1290 goto err;
1291 }
1292 1285
1293 if (stv090x_set_viterbi(state) < 0) 1286 if (stv090x_set_viterbi(state) < 0)
1294 goto err; 1287 goto err;
@@ -1317,7 +1310,7 @@ static int stv090x_start_search(struct stv090x_state *state)
1317 goto err; 1310 goto err;
1318 if (STV090x_WRITE_DEMOD(state, CFRUP1, 0x0f) < 0) 1311 if (STV090x_WRITE_DEMOD(state, CFRUP1, 0x0f) < 0)
1319 goto err; 1312 goto err;
1320 if (STV090x_WRITE_DEMOD(state, CFRUP1, 0xff) < 0) 1313 if (STV090x_WRITE_DEMOD(state, CFRUP0, 0xff) < 0)
1321 goto err; 1314 goto err;
1322 if (STV090x_WRITE_DEMOD(state, CFRLOW1, 0xf0) < 0) 1315 if (STV090x_WRITE_DEMOD(state, CFRLOW1, 0xf0) < 0)
1323 goto err; 1316 goto err;
@@ -1371,7 +1364,7 @@ static int stv090x_start_search(struct stv090x_state *state)
1371 1364
1372 if (STV090x_WRITE_DEMOD(state, CFRUP1, MSB(freq)) < 0) 1365 if (STV090x_WRITE_DEMOD(state, CFRUP1, MSB(freq)) < 0)
1373 goto err; 1366 goto err;
1374 if (STV090x_WRITE_DEMOD(state, CFRUP1, LSB(freq)) < 0) 1367 if (STV090x_WRITE_DEMOD(state, CFRUP0, LSB(freq)) < 0)
1375 goto err; 1368 goto err;
1376 1369
1377 freq *= -1; 1370 freq *= -1;
@@ -1422,6 +1415,9 @@ static int stv090x_start_search(struct stv090x_state *state)
1422 if (STV090x_WRITE_DEMOD(state, DMDCFG2, reg) < 0) 1415 if (STV090x_WRITE_DEMOD(state, DMDCFG2, reg) < 0)
1423 goto err; 1416 goto err;
1424 1417
1418 if (STV090x_WRITE_DEMOD(state, RTC, 0x88) < 0)
1419 goto err;
1420
1425 if (state->dev_ver >= 0x20) { 1421 if (state->dev_ver >= 0x20) {
1426 /*Frequency offset detector setting*/ 1422 /*Frequency offset detector setting*/
1427 if (state->srate < 2000000) { 1423 if (state->srate < 2000000) {
@@ -1430,20 +1426,22 @@ static int stv090x_start_search(struct stv090x_state *state)
1430 if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x39) < 0) 1426 if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x39) < 0)
1431 goto err; 1427 goto err;
1432 } else { 1428 } else {
1433 /* Cut 2 */ 1429 /* Cut 3 */
1434 if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x89) < 0) 1430 if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x89) < 0)
1435 goto err; 1431 goto err;
1436 } 1432 }
1437 if (STV090x_WRITE_DEMOD(state, CARHDR, 0x40) < 0) 1433 if (STV090x_WRITE_DEMOD(state, CARHDR, 0x40) < 0)
1438 goto err; 1434 goto err;
1439 } 1435 } else if (state->srate < 10000000) {
1440
1441 if (state->srate < 10000000) {
1442 if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x4c) < 0) 1436 if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x4c) < 0)
1443 goto err; 1437 goto err;
1438 if (STV090x_WRITE_DEMOD(state, CARHDR, 0x20) < 0)
1439 goto err;
1444 } else { 1440 } else {
1445 if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x4b) < 0) 1441 if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x4b) < 0)
1446 goto err; 1442 goto err;
1443 if (STV090x_WRITE_DEMOD(state, CARHDR, 0x20) < 0)
1444 goto err;
1447 } 1445 }
1448 } else { 1446 } else {
1449 if (state->srate < 10000000) { 1447 if (state->srate < 10000000) {
@@ -1485,14 +1483,14 @@ err:
1485 1483
1486static int stv090x_get_agc2_min_level(struct stv090x_state *state) 1484static int stv090x_get_agc2_min_level(struct stv090x_state *state)
1487{ 1485{
1488 u32 agc2_min = 0, agc2 = 0, freq_init, freq_step, reg; 1486 u32 agc2_min = 0xffff, agc2 = 0, freq_init, freq_step, reg;
1489 s32 i, j, steps, dir; 1487 s32 i, j, steps, dir;
1490 1488
1491 if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x38) < 0) 1489 if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x38) < 0)
1492 goto err; 1490 goto err;
1493 reg = STV090x_READ_DEMOD(state, DMDCFGMD); 1491 reg = STV090x_READ_DEMOD(state, DMDCFGMD);
1494 STV090x_SETFIELD_Px(reg, SCAN_ENABLE_FIELD, 1); 1492 STV090x_SETFIELD_Px(reg, SCAN_ENABLE_FIELD, 0);
1495 STV090x_SETFIELD_Px(reg, CFR_AUTOSCAN_FIELD, 1); 1493 STV090x_SETFIELD_Px(reg, CFR_AUTOSCAN_FIELD, 0);
1496 if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0) 1494 if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)
1497 goto err; 1495 goto err;
1498 1496
@@ -1509,10 +1507,8 @@ static int stv090x_get_agc2_min_level(struct stv090x_state *state)
1509 if (stv090x_set_srate(state, 1000000) < 0) 1507 if (stv090x_set_srate(state, 1000000) < 0)
1510 goto err; 1508 goto err;
1511 1509
1512 steps = -1 + state->search_range / 1000000; 1510 steps = state->search_range / 1000000;
1513 steps /= 2; 1511 if (steps <= 0)
1514 steps = (2 * steps) + 1;
1515 if (steps < 0)
1516 steps = 1; 1512 steps = 1;
1517 1513
1518 dir = 1; 1514 dir = 1;
@@ -1525,7 +1521,7 @@ static int stv090x_get_agc2_min_level(struct stv090x_state *state)
1525 else 1521 else
1526 freq_init = freq_init - (freq_step * i); 1522 freq_init = freq_init - (freq_step * i);
1527 1523
1528 dir = -1; 1524 dir *= -1;
1529 1525
1530 if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x5c) < 0) /* Demod RESET */ 1526 if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x5c) < 0) /* Demod RESET */
1531 goto err; 1527 goto err;
@@ -1536,13 +1532,14 @@ static int stv090x_get_agc2_min_level(struct stv090x_state *state)
1536 if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x58) < 0) /* Demod RESET */ 1532 if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x58) < 0) /* Demod RESET */
1537 goto err; 1533 goto err;
1538 msleep(10); 1534 msleep(10);
1535
1536 agc2 = 0;
1539 for (j = 0; j < 10; j++) { 1537 for (j = 0; j < 10; j++) {
1540 agc2 += STV090x_READ_DEMOD(state, AGC2I1) << 8; 1538 agc2 += (STV090x_READ_DEMOD(state, AGC2I1) << 8) |
1541 agc2 |= STV090x_READ_DEMOD(state, AGC2I0); 1539 STV090x_READ_DEMOD(state, AGC2I0);
1542 } 1540 }
1543 agc2 /= 10; 1541 agc2 /= 10;
1544 agc2_min = 0xffff; 1542 if (agc2 < agc2_min)
1545 if (agc2 < 0xffff)
1546 agc2_min = agc2; 1543 agc2_min = agc2;
1547 } 1544 }
1548 1545
@@ -1584,6 +1581,12 @@ static u32 stv090x_srate_srch_coarse(struct stv090x_state *state)
1584 int tmg_lock = 0, i; 1581 int tmg_lock = 0, i;
1585 s32 tmg_cpt = 0, dir = 1, steps, cur_step = 0, freq; 1582 s32 tmg_cpt = 0, dir = 1, steps, cur_step = 0, freq;
1586 u32 srate_coarse = 0, agc2 = 0, car_step = 1200, reg; 1583 u32 srate_coarse = 0, agc2 = 0, car_step = 1200, reg;
1584 u32 agc2th;
1585
1586 if (state->dev_ver >= 0x30)
1587 agc2th = 0x2e00;
1588 else
1589 agc2th = 0x1f00;
1587 1590
1588 reg = STV090x_READ_DEMOD(state, DMDISTATE); 1591 reg = STV090x_READ_DEMOD(state, DMDISTATE);
1589 STV090x_SETFIELD_Px(reg, I2C_DEMOD_MODE_FIELD, 0x1f); /* Demod RESET */ 1592 STV090x_SETFIELD_Px(reg, I2C_DEMOD_MODE_FIELD, 0x1f); /* Demod RESET */
@@ -1591,13 +1594,15 @@ static u32 stv090x_srate_srch_coarse(struct stv090x_state *state)
1591 goto err; 1594 goto err;
1592 if (STV090x_WRITE_DEMOD(state, TMGCFG, 0x12) < 0) 1595 if (STV090x_WRITE_DEMOD(state, TMGCFG, 0x12) < 0)
1593 goto err; 1596 goto err;
1597 if (STV090x_WRITE_DEMOD(state, TMGCFG2, 0xc0) < 0)
1598 goto err;
1594 if (STV090x_WRITE_DEMOD(state, TMGTHRISE, 0xf0) < 0) 1599 if (STV090x_WRITE_DEMOD(state, TMGTHRISE, 0xf0) < 0)
1595 goto err; 1600 goto err;
1596 if (STV090x_WRITE_DEMOD(state, TMGTHFALL, 0xe0) < 0) 1601 if (STV090x_WRITE_DEMOD(state, TMGTHFALL, 0xe0) < 0)
1597 goto err; 1602 goto err;
1598 reg = STV090x_READ_DEMOD(state, DMDCFGMD); 1603 reg = STV090x_READ_DEMOD(state, DMDCFGMD);
1599 STV090x_SETFIELD_Px(reg, SCAN_ENABLE_FIELD, 1); 1604 STV090x_SETFIELD_Px(reg, SCAN_ENABLE_FIELD, 1);
1600 STV090x_SETFIELD_Px(reg, CFR_AUTOSCAN_FIELD, 1); 1605 STV090x_SETFIELD_Px(reg, CFR_AUTOSCAN_FIELD, 0);
1601 if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0) 1606 if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)
1602 goto err; 1607 goto err;
1603 1608
@@ -1611,13 +1616,13 @@ static u32 stv090x_srate_srch_coarse(struct stv090x_state *state)
1611 goto err; 1616 goto err;
1612 if (STV090x_WRITE_DEMOD(state, DMDTOM, 0x00) < 0) 1617 if (STV090x_WRITE_DEMOD(state, DMDTOM, 0x00) < 0)
1613 goto err; 1618 goto err;
1614 if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x60) < 0) 1619 if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x50) < 0)
1615 goto err; 1620 goto err;
1616 1621
1617 if (state->dev_ver >= 0x30) { 1622 if (state->dev_ver >= 0x30) {
1618 if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x99) < 0) 1623 if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x99) < 0)
1619 goto err; 1624 goto err;
1620 if (STV090x_WRITE_DEMOD(state, SFRSTEP, 0x95) < 0) 1625 if (STV090x_WRITE_DEMOD(state, SFRSTEP, 0x98) < 0)
1621 goto err; 1626 goto err;
1622 1627
1623 } else if (state->dev_ver >= 0x20) { 1628 } else if (state->dev_ver >= 0x20) {
@@ -1652,23 +1657,31 @@ static u32 stv090x_srate_srch_coarse(struct stv090x_state *state)
1652 while ((!tmg_lock) && (cur_step < steps)) { 1657 while ((!tmg_lock) && (cur_step < steps)) {
1653 if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x5f) < 0) /* Demod RESET */ 1658 if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x5f) < 0) /* Demod RESET */
1654 goto err; 1659 goto err;
1655 reg = STV090x_READ_DEMOD(state, DMDISTATE); 1660 if (STV090x_WRITE_DEMOD(state, CFRINIT1, 0x00) < 0)
1656 STV090x_SETFIELD_Px(reg, I2C_DEMOD_MODE_FIELD, 0x00); /* trigger acquisition */ 1661 goto err;
1657 if (STV090x_WRITE_DEMOD(state, DMDISTATE, reg) < 0) 1662 if (STV090x_WRITE_DEMOD(state, CFRINIT0, 0x00) < 0)
1663 goto err;
1664 if (STV090x_WRITE_DEMOD(state, SFRINIT1, 0x00) < 0)
1665 goto err;
1666 if (STV090x_WRITE_DEMOD(state, SFRINIT0, 0x00) < 0)
1667 goto err;
1668 /* trigger acquisition */
1669 if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x40) < 0)
1658 goto err; 1670 goto err;
1659 msleep(50); 1671 msleep(50);
1660 for (i = 0; i < 10; i++) { 1672 for (i = 0; i < 10; i++) {
1661 reg = STV090x_READ_DEMOD(state, DSTATUS); 1673 reg = STV090x_READ_DEMOD(state, DSTATUS);
1662 if (STV090x_GETFIELD_Px(reg, TMGLOCK_QUALITY_FIELD) >= 2) 1674 if (STV090x_GETFIELD_Px(reg, TMGLOCK_QUALITY_FIELD) >= 2)
1663 tmg_cpt++; 1675 tmg_cpt++;
1664 agc2 += STV090x_READ_DEMOD(state, AGC2I1) << 8; 1676 agc2 += (STV090x_READ_DEMOD(state, AGC2I1) << 8) |
1665 agc2 |= STV090x_READ_DEMOD(state, AGC2I0); 1677 STV090x_READ_DEMOD(state, AGC2I0);
1666 } 1678 }
1667 agc2 /= 10; 1679 agc2 /= 10;
1668 srate_coarse = stv090x_get_srate(state, state->mclk); 1680 srate_coarse = stv090x_get_srate(state, state->mclk);
1669 cur_step++; 1681 cur_step++;
1670 dir *= -1; 1682 dir *= -1;
1671 if ((tmg_cpt >= 5) && (agc2 < 0x1f00) && (srate_coarse < 55000000) && (srate_coarse > 850000)) 1683 if ((tmg_cpt >= 5) && (agc2 < agc2th) &&
1684 (srate_coarse < 50000000) && (srate_coarse > 850000))
1672 tmg_lock = 1; 1685 tmg_lock = 1;
1673 else if (cur_step < steps) { 1686 else if (cur_step < steps) {
1674 if (dir > 0) 1687 if (dir > 0)
@@ -1681,7 +1694,7 @@ static u32 stv090x_srate_srch_coarse(struct stv090x_state *state)
1681 goto err; 1694 goto err;
1682 1695
1683 if (state->config->tuner_set_frequency) { 1696 if (state->config->tuner_set_frequency) {
1684 if (state->config->tuner_set_frequency(fe, state->frequency) < 0) 1697 if (state->config->tuner_set_frequency(fe, freq) < 0)
1685 goto err; 1698 goto err;
1686 } 1699 }
1687 1700
@@ -1738,7 +1751,7 @@ static u32 stv090x_srate_srch_fine(struct stv090x_state *state)
1738 else { 1751 else {
1739 if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1f) < 0) /* Demod RESET */ 1752 if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1f) < 0) /* Demod RESET */
1740 goto err; 1753 goto err;
1741 if (STV090x_WRITE_DEMOD(state, TMGCFG2, 0x01) < 0) 1754 if (STV090x_WRITE_DEMOD(state, TMGCFG2, 0xc1) < 0)
1742 goto err; 1755 goto err;
1743 if (STV090x_WRITE_DEMOD(state, TMGTHRISE, 0x20) < 0) 1756 if (STV090x_WRITE_DEMOD(state, TMGTHRISE, 0x20) < 0)
1744 goto err; 1757 goto err;
@@ -1751,6 +1764,9 @@ static u32 stv090x_srate_srch_fine(struct stv090x_state *state)
1751 if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0) 1764 if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)
1752 goto err; 1765 goto err;
1753 1766
1767 if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x38) < 0)
1768 goto err;
1769
1754 if (state->dev_ver >= 0x30) { 1770 if (state->dev_ver >= 0x30) {
1755 if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x79) < 0) 1771 if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x79) < 0)
1756 goto err; 1772 goto err;
@@ -1856,12 +1872,12 @@ static int stv090x_get_dmdlock(struct stv090x_state *state, s32 timeout)
1856static int stv090x_blind_search(struct stv090x_state *state) 1872static int stv090x_blind_search(struct stv090x_state *state)
1857{ 1873{
1858 u32 agc2, reg, srate_coarse; 1874 u32 agc2, reg, srate_coarse;
1859 s32 timeout_dmd = 500, cpt_fail, agc2_ovflw, i; 1875 s32 cpt_fail, agc2_ovflw, i;
1860 u8 k_ref, k_max, k_min; 1876 u8 k_ref, k_max, k_min;
1861 int coarse_fail, lock; 1877 int coarse_fail, lock;
1862 1878
1863 k_max = 120; 1879 k_max = 110;
1864 k_min = 30; 1880 k_min = 10;
1865 1881
1866 agc2 = stv090x_get_agc2_min_level(state); 1882 agc2 = stv090x_get_agc2_min_level(state);
1867 1883
@@ -1900,7 +1916,8 @@ static int stv090x_blind_search(struct stv090x_state *state)
1900 srate_coarse = stv090x_srate_srch_fine(state); 1916 srate_coarse = stv090x_srate_srch_fine(state);
1901 if (srate_coarse != 0) { 1917 if (srate_coarse != 0) {
1902 stv090x_get_lock_tmg(state); 1918 stv090x_get_lock_tmg(state);
1903 lock = stv090x_get_dmdlock(state, timeout_dmd); 1919 lock = stv090x_get_dmdlock(state,
1920 state->DemodTimeout);
1904 } else { 1921 } else {
1905 lock = 0; 1922 lock = 0;
1906 } 1923 }
@@ -1908,8 +1925,8 @@ static int stv090x_blind_search(struct stv090x_state *state)
1908 cpt_fail = 0; 1925 cpt_fail = 0;
1909 agc2_ovflw = 0; 1926 agc2_ovflw = 0;
1910 for (i = 0; i < 10; i++) { 1927 for (i = 0; i < 10; i++) {
1911 agc2 = STV090x_READ_DEMOD(state, AGC2I1) << 8; 1928 agc2 += (STV090x_READ_DEMOD(state, AGC2I1) << 8) |
1912 agc2 |= STV090x_READ_DEMOD(state, AGC2I0); 1929 STV090x_READ_DEMOD(state, AGC2I0);
1913 if (agc2 >= 0xff00) 1930 if (agc2 >= 0xff00)
1914 agc2_ovflw++; 1931 agc2_ovflw++;
1915 reg = STV090x_READ_DEMOD(state, DSTATUS2); 1932 reg = STV090x_READ_DEMOD(state, DSTATUS2);
@@ -1923,7 +1940,7 @@ static int stv090x_blind_search(struct stv090x_state *state)
1923 1940
1924 lock = 0; 1941 lock = 0;
1925 } 1942 }
1926 k_ref -= 30; 1943 k_ref -= 20;
1927 } while ((k_ref >= k_min) && (!lock) && (!coarse_fail)); 1944 } while ((k_ref >= k_min) && (!lock) && (!coarse_fail));
1928 } 1945 }
1929 1946
@@ -2062,7 +2079,7 @@ static int stv090x_get_coldlock(struct stv090x_state *state, s32 timeout_dmd)
2062 goto err; 2079 goto err;
2063 2080
2064 if (state->config->tuner_set_frequency) { 2081 if (state->config->tuner_set_frequency) {
2065 if (state->config->tuner_set_frequency(fe, state->frequency) < 0) 2082 if (state->config->tuner_set_frequency(fe, freq) < 0)
2066 goto err; 2083 goto err;
2067 } 2084 }
2068 2085
@@ -2093,17 +2110,6 @@ static int stv090x_get_coldlock(struct stv090x_state *state, s32 timeout_dmd)
2093 goto err; 2110 goto err;
2094 2111
2095 STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1c); 2112 STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1c);
2096 if (state->delsys == STV090x_DVBS2) {
2097 reg = STV090x_READ_DEMOD(state, DMDCFGMD);
2098 STV090x_SETFIELD_Px(reg, DVBS1_ENABLE_FIELD, 0);
2099 STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 0);
2100 if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)
2101 goto err;
2102 STV090x_SETFIELD_Px(reg, DVBS1_ENABLE_FIELD, 1);
2103 STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 1);
2104 if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)
2105 goto err;
2106 }
2107 if (STV090x_WRITE_DEMOD(state, CFRINIT1, 0x00) < 0) 2113 if (STV090x_WRITE_DEMOD(state, CFRINIT1, 0x00) < 0)
2108 goto err; 2114 goto err;
2109 if (STV090x_WRITE_DEMOD(state, CFRINIT0, 0x00) < 0) 2115 if (STV090x_WRITE_DEMOD(state, CFRINIT0, 0x00) < 0)
@@ -2425,7 +2431,7 @@ static s32 stv090x_get_car_freq(struct stv090x_state *state, u32 mclk)
2425 2431
2426 derot = (int_1 * int_2) + 2432 derot = (int_1 * int_2) +
2427 ((int_1 * tmp_2) >> 12) + 2433 ((int_1 * tmp_2) >> 12) +
2428 ((int_1 * tmp_1) >> 12); 2434 ((int_2 * tmp_1) >> 12);
2429 2435
2430 return derot; 2436 return derot;
2431} 2437}
@@ -2732,7 +2738,7 @@ static int stv090x_optimize_track(struct stv090x_state *state)
2732 switch (state->delsys) { 2738 switch (state->delsys) {
2733 case STV090x_DVBS1: 2739 case STV090x_DVBS1:
2734 case STV090x_DSS: 2740 case STV090x_DSS:
2735 if (state->algo == STV090x_SEARCH_AUTO) { 2741 if (state->search_mode == STV090x_SEARCH_AUTO) {
2736 reg = STV090x_READ_DEMOD(state, DMDCFGMD); 2742 reg = STV090x_READ_DEMOD(state, DMDCFGMD);
2737 STV090x_SETFIELD_Px(reg, DVBS1_ENABLE_FIELD, 1); 2743 STV090x_SETFIELD_Px(reg, DVBS1_ENABLE_FIELD, 1);
2738 STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 0); 2744 STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 0);
@@ -2857,6 +2863,9 @@ static int stv090x_optimize_track(struct stv090x_state *state)
2857 if (stv090x_set_srate(state, srate) < 0) 2863 if (stv090x_set_srate(state, srate) < 0)
2858 goto err; 2864 goto err;
2859 blind_tune = 1; 2865 blind_tune = 1;
2866
2867 if (stv090x_dvbs_track_crl(state) < 0)
2868 goto err;
2860 } 2869 }
2861 2870
2862 if (state->dev_ver >= 0x20) { 2871 if (state->dev_ver >= 0x20) {
@@ -3042,7 +3051,7 @@ static enum stv090x_signal_state stv090x_algo(struct stv090x_state *state)
3042 struct dvb_frontend *fe = &state->frontend; 3051 struct dvb_frontend *fe = &state->frontend;
3043 enum stv090x_signal_state signal_state = STV090x_NOCARRIER; 3052 enum stv090x_signal_state signal_state = STV090x_NOCARRIER;
3044 u32 reg; 3053 u32 reg;
3045 s32 timeout_dmd = 500, timeout_fec = 50, agc1_power, power_iq = 0, i; 3054 s32 agc1_power, power_iq = 0, i;
3046 int lock = 0, low_sr = 0, no_signal = 0; 3055 int lock = 0, low_sr = 0, no_signal = 0;
3047 3056
3048 reg = STV090x_READ_DEMOD(state, TSCFGH); 3057 reg = STV090x_READ_DEMOD(state, TSCFGH);
@@ -3054,8 +3063,13 @@ static enum stv090x_signal_state stv090x_algo(struct stv090x_state *state)
3054 goto err; 3063 goto err;
3055 3064
3056 if (state->dev_ver >= 0x20) { 3065 if (state->dev_ver >= 0x20) {
3057 if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x9e) < 0) /* cut 2.0 */ 3066 if (state->srate > 5000000) {
3058 goto err; 3067 if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x9e) < 0)
3068 goto err;
3069 } else {
3070 if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x82) < 0)
3071 goto err;
3072 }
3059 } 3073 }
3060 3074
3061 stv090x_get_lock_tmg(state); 3075 stv090x_get_lock_tmg(state);
@@ -3175,7 +3189,7 @@ static enum stv090x_signal_state stv090x_algo(struct stv090x_state *state)
3175 if ((agc1_power == 0) && (power_iq < STV090x_IQPOWER_THRESHOLD)) { 3189 if ((agc1_power == 0) && (power_iq < STV090x_IQPOWER_THRESHOLD)) {
3176 dprintk(FE_ERROR, 1, "No Signal: POWER_IQ=0x%02x", power_iq); 3190 dprintk(FE_ERROR, 1, "No Signal: POWER_IQ=0x%02x", power_iq);
3177 lock = 0; 3191 lock = 0;
3178 3192 signal_state = STV090x_NOAGC1;
3179 } else { 3193 } else {
3180 reg = STV090x_READ_DEMOD(state, DEMOD); 3194 reg = STV090x_READ_DEMOD(state, DEMOD);
3181 STV090x_SETFIELD_Px(reg, SPECINV_CONTROL_FIELD, state->inversion); 3195 STV090x_SETFIELD_Px(reg, SPECINV_CONTROL_FIELD, state->inversion);
@@ -3199,18 +3213,17 @@ static enum stv090x_signal_state stv090x_algo(struct stv090x_state *state)
3199 } 3213 }
3200 } 3214 }
3201 3215
3202 /* need to check for AGC1 state */ 3216 if (signal_state == STV090x_NOAGC1)
3203 3217 return signal_state;
3204
3205 3218
3206 if (state->algo == STV090x_BLIND_SEARCH) 3219 if (state->algo == STV090x_BLIND_SEARCH)
3207 lock = stv090x_blind_search(state); 3220 lock = stv090x_blind_search(state);
3208 3221
3209 else if (state->algo == STV090x_COLD_SEARCH) 3222 else if (state->algo == STV090x_COLD_SEARCH)
3210 lock = stv090x_get_coldlock(state, timeout_dmd); 3223 lock = stv090x_get_coldlock(state, state->DemodTimeout);
3211 3224
3212 else if (state->algo == STV090x_WARM_SEARCH) 3225 else if (state->algo == STV090x_WARM_SEARCH)
3213 lock = stv090x_get_dmdlock(state, timeout_dmd); 3226 lock = stv090x_get_dmdlock(state, state->DemodTimeout);
3214 3227
3215 if ((!lock) && (state->algo == STV090x_COLD_SEARCH)) { 3228 if ((!lock) && (state->algo == STV090x_COLD_SEARCH)) {
3216 if (!low_sr) { 3229 if (!low_sr) {
@@ -3245,8 +3258,9 @@ static enum stv090x_signal_state stv090x_algo(struct stv090x_state *state)
3245 goto err; 3258 goto err;
3246 } 3259 }
3247 3260
3248 if (stv090x_get_lock(state, timeout_fec, timeout_fec)) { 3261 lock = stv090x_get_lock(state, state->FecTimeout,
3249 lock = 1; 3262 state->FecTimeout);
3263 if (lock) {
3250 if (state->delsys == STV090x_DVBS2) { 3264 if (state->delsys == STV090x_DVBS2) {
3251 stv090x_set_s2rolloff(state); 3265 stv090x_set_s2rolloff(state);
3252 3266
@@ -3273,7 +3287,6 @@ static enum stv090x_signal_state stv090x_algo(struct stv090x_state *state)
3273 if (STV090x_WRITE_DEMOD(state, ERRCTRL2, 0xc1) < 0) 3287 if (STV090x_WRITE_DEMOD(state, ERRCTRL2, 0xc1) < 0)
3274 goto err; 3288 goto err;
3275 } else { 3289 } else {
3276 lock = 0;
3277 signal_state = STV090x_NODATA; 3290 signal_state = STV090x_NODATA;
3278 no_signal = stv090x_chk_signal(state); 3291 no_signal = stv090x_chk_signal(state);
3279 } 3292 }
@@ -3296,7 +3309,13 @@ static enum dvbfe_search stv090x_search(struct dvb_frontend *fe, struct dvb_fron
3296 state->search_mode = STV090x_SEARCH_AUTO; 3309 state->search_mode = STV090x_SEARCH_AUTO;
3297 state->algo = STV090x_COLD_SEARCH; 3310 state->algo = STV090x_COLD_SEARCH;
3298 state->fec = STV090x_PRERR; 3311 state->fec = STV090x_PRERR;
3299 state->search_range = 2000000; 3312 if (state->srate > 10000000) {
3313 dprintk(FE_DEBUG, 1, "Search range: 10 MHz");
3314 state->search_range = 10000000;
3315 } else {
3316 dprintk(FE_DEBUG, 1, "Search range: 5 MHz");
3317 state->search_range = 5000000;
3318 }
3300 3319
3301 if (stv090x_algo(state) == STV090x_RANGEOK) { 3320 if (stv090x_algo(state) == STV090x_RANGEOK) {
3302 dprintk(FE_DEBUG, 1, "Search success!"); 3321 dprintk(FE_DEBUG, 1, "Search success!");
@@ -3309,7 +3328,6 @@ static enum dvbfe_search stv090x_search(struct dvb_frontend *fe, struct dvb_fron
3309 return DVBFE_ALGO_SEARCH_ERROR; 3328 return DVBFE_ALGO_SEARCH_ERROR;
3310} 3329}
3311 3330
3312/* FIXME! */
3313static int stv090x_read_status(struct dvb_frontend *fe, enum fe_status *status) 3331static int stv090x_read_status(struct dvb_frontend *fe, enum fe_status *status)
3314{ 3332{
3315 struct stv090x_state *state = fe->demodulator_priv; 3333 struct stv090x_state *state = fe->demodulator_priv;
@@ -3331,9 +3349,15 @@ static int stv090x_read_status(struct dvb_frontend *fe, enum fe_status *status)
3331 dprintk(FE_DEBUG, 1, "Delivery system: DVB-S2"); 3349 dprintk(FE_DEBUG, 1, "Delivery system: DVB-S2");
3332 reg = STV090x_READ_DEMOD(state, DSTATUS); 3350 reg = STV090x_READ_DEMOD(state, DSTATUS);
3333 if (STV090x_GETFIELD_Px(reg, LOCK_DEFINITIF_FIELD)) { 3351 if (STV090x_GETFIELD_Px(reg, LOCK_DEFINITIF_FIELD)) {
3334 reg = STV090x_READ_DEMOD(state, TSSTATUS); 3352 reg = STV090x_READ_DEMOD(state, PDELSTATUS1);
3335 if (STV090x_GETFIELD_Px(reg, TSFIFO_LINEOK_FIELD)) { 3353 if (STV090x_GETFIELD_Px(reg, PKTDELIN_LOCK_FIELD)) {
3336 *status = FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK; 3354 reg = STV090x_READ_DEMOD(state, TSSTATUS);
3355 if (STV090x_GETFIELD_Px(reg, TSFIFO_LINEOK_FIELD)) {
3356 *status = FE_HAS_CARRIER |
3357 FE_HAS_VITERBI |
3358 FE_HAS_SYNC |
3359 FE_HAS_LOCK;
3360 }
3337 } 3361 }
3338 } 3362 }
3339 break; 3363 break;
@@ -3412,14 +3436,12 @@ static int stv090x_table_lookup(const struct stv090x_tab *tab, int max, int val)
3412 int res = 0; 3436 int res = 0;
3413 int min = 0, med; 3437 int min = 0, med;
3414 3438
3415 if (val < tab[min].read) 3439 if ((val >= tab[min].read && val < tab[max].read) ||
3416 res = tab[min].real; 3440 (val >= tab[max].read && val < tab[min].read)) {
3417 else if (val >= tab[max].read)
3418 res = tab[max].real;
3419 else {
3420 while ((max - min) > 1) { 3441 while ((max - min) > 1) {
3421 med = (max + min) / 2; 3442 med = (max + min) / 2;
3422 if (val >= tab[min].read && val < tab[med].read) 3443 if ((val >= tab[min].read && val < tab[med].read) ||
3444 (val >= tab[med].read && val < tab[min].read))
3423 max = med; 3445 max = med;
3424 else 3446 else
3425 min = med; 3447 min = med;
@@ -3428,6 +3450,18 @@ static int stv090x_table_lookup(const struct stv090x_tab *tab, int max, int val)
3428 (tab[max].real - tab[min].real) / 3450 (tab[max].real - tab[min].real) /
3429 (tab[max].read - tab[min].read)) + 3451 (tab[max].read - tab[min].read)) +
3430 tab[min].real; 3452 tab[min].real;
3453 } else {
3454 if (tab[min].read < tab[max].read) {
3455 if (val < tab[min].read)
3456 res = tab[min].real;
3457 else if (val >= tab[max].read)
3458 res = tab[max].real;
3459 } else {
3460 if (val >= tab[min].read)
3461 res = tab[min].real;
3462 else if (val < tab[max].read)
3463 res = tab[max].real;
3464 }
3431 } 3465 }
3432 3466
3433 return res; 3467 return res;
@@ -3437,16 +3471,22 @@ static int stv090x_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
3437{ 3471{
3438 struct stv090x_state *state = fe->demodulator_priv; 3472 struct stv090x_state *state = fe->demodulator_priv;
3439 u32 reg; 3473 u32 reg;
3440 s32 agc; 3474 s32 agc_0, agc_1, agc;
3475 s32 str;
3441 3476
3442 reg = STV090x_READ_DEMOD(state, AGCIQIN1); 3477 reg = STV090x_READ_DEMOD(state, AGCIQIN1);
3443 agc = STV090x_GETFIELD_Px(reg, AGCIQ_VALUE_FIELD); 3478 agc_1 = STV090x_GETFIELD_Px(reg, AGCIQ_VALUE_FIELD);
3479 reg = STV090x_READ_DEMOD(state, AGCIQIN0);
3480 agc_0 = STV090x_GETFIELD_Px(reg, AGCIQ_VALUE_FIELD);
3481 agc = MAKEWORD16(agc_1, agc_0);
3444 3482
3445 *strength = stv090x_table_lookup(stv090x_rf_tab, ARRAY_SIZE(stv090x_rf_tab) - 1, agc); 3483 str = stv090x_table_lookup(stv090x_rf_tab,
3484 ARRAY_SIZE(stv090x_rf_tab) - 1, agc);
3446 if (agc > stv090x_rf_tab[0].read) 3485 if (agc > stv090x_rf_tab[0].read)
3447 *strength = 5; 3486 str = 0;
3448 else if (agc < stv090x_rf_tab[ARRAY_SIZE(stv090x_rf_tab) - 1].read) 3487 else if (agc < stv090x_rf_tab[ARRAY_SIZE(stv090x_rf_tab) - 1].read)
3449 *strength = -100; 3488 str = -100;
3489 *strength = (str + 100) * 0xFFFF / 100;
3450 3490
3451 return 0; 3491 return 0;
3452} 3492}
@@ -3457,6 +3497,8 @@ static int stv090x_read_cnr(struct dvb_frontend *fe, u16 *cnr)
3457 u32 reg_0, reg_1, reg, i; 3497 u32 reg_0, reg_1, reg, i;
3458 s32 val_0, val_1, val = 0; 3498 s32 val_0, val_1, val = 0;
3459 u8 lock_f; 3499 u8 lock_f;
3500 s32 div;
3501 u32 last;
3460 3502
3461 switch (state->delsys) { 3503 switch (state->delsys) {
3462 case STV090x_DVBS2: 3504 case STV090x_DVBS2:
@@ -3468,14 +3510,15 @@ static int stv090x_read_cnr(struct dvb_frontend *fe, u16 *cnr)
3468 reg_1 = STV090x_READ_DEMOD(state, NNOSPLHT1); 3510 reg_1 = STV090x_READ_DEMOD(state, NNOSPLHT1);
3469 val_1 = STV090x_GETFIELD_Px(reg_1, NOSPLHT_NORMED_FIELD); 3511 val_1 = STV090x_GETFIELD_Px(reg_1, NOSPLHT_NORMED_FIELD);
3470 reg_0 = STV090x_READ_DEMOD(state, NNOSPLHT0); 3512 reg_0 = STV090x_READ_DEMOD(state, NNOSPLHT0);
3471 val_0 = STV090x_GETFIELD_Px(reg_1, NOSPLHT_NORMED_FIELD); 3513 val_0 = STV090x_GETFIELD_Px(reg_0, NOSPLHT_NORMED_FIELD);
3472 val += MAKEWORD16(val_1, val_0); 3514 val += MAKEWORD16(val_1, val_0);
3473 msleep(1); 3515 msleep(1);
3474 } 3516 }
3475 val /= 16; 3517 val /= 16;
3476 *cnr = stv090x_table_lookup(stv090x_s2cn_tab, ARRAY_SIZE(stv090x_s2cn_tab) - 1, val); 3518 last = ARRAY_SIZE(stv090x_s2cn_tab) - 1;
3477 if (val < stv090x_s2cn_tab[ARRAY_SIZE(stv090x_s2cn_tab) - 1].read) 3519 div = stv090x_s2cn_tab[0].read -
3478 *cnr = 1000; 3520 stv090x_s2cn_tab[last].read;
3521 *cnr = 0xFFFF - ((val * 0xFFFF) / div);
3479 } 3522 }
3480 break; 3523 break;
3481 3524
@@ -3489,14 +3532,15 @@ static int stv090x_read_cnr(struct dvb_frontend *fe, u16 *cnr)
3489 reg_1 = STV090x_READ_DEMOD(state, NOSDATAT1); 3532 reg_1 = STV090x_READ_DEMOD(state, NOSDATAT1);
3490 val_1 = STV090x_GETFIELD_Px(reg_1, NOSDATAT_UNNORMED_FIELD); 3533 val_1 = STV090x_GETFIELD_Px(reg_1, NOSDATAT_UNNORMED_FIELD);
3491 reg_0 = STV090x_READ_DEMOD(state, NOSDATAT0); 3534 reg_0 = STV090x_READ_DEMOD(state, NOSDATAT0);
3492 val_0 = STV090x_GETFIELD_Px(reg_1, NOSDATAT_UNNORMED_FIELD); 3535 val_0 = STV090x_GETFIELD_Px(reg_0, NOSDATAT_UNNORMED_FIELD);
3493 val += MAKEWORD16(val_1, val_0); 3536 val += MAKEWORD16(val_1, val_0);
3494 msleep(1); 3537 msleep(1);
3495 } 3538 }
3496 val /= 16; 3539 val /= 16;
3497 *cnr = stv090x_table_lookup(stv090x_s1cn_tab, ARRAY_SIZE(stv090x_s1cn_tab) - 1, val); 3540 last = ARRAY_SIZE(stv090x_s1cn_tab) - 1;
3498 if (val < stv090x_s2cn_tab[ARRAY_SIZE(stv090x_s1cn_tab) - 1].read) 3541 div = stv090x_s1cn_tab[0].read -
3499 *cnr = 1000; 3542 stv090x_s1cn_tab[last].read;
3543 *cnr = 0xFFFF - ((val * 0xFFFF) / div);
3500 } 3544 }
3501 break; 3545 break;
3502 default: 3546 default:
@@ -3732,6 +3776,8 @@ static int stv090x_ldpc_mode(struct stv090x_state *state, enum stv090x_mode ldpc
3732{ 3776{
3733 u32 reg = 0; 3777 u32 reg = 0;
3734 3778
3779 reg = stv090x_read_reg(state, STV090x_GENCFG);
3780
3735 switch (ldpc_mode) { 3781 switch (ldpc_mode) {
3736 case STV090x_DUAL: 3782 case STV090x_DUAL:
3737 default: 3783 default:
diff --git a/drivers/media/dvb/frontends/stv090x_priv.h b/drivers/media/dvb/frontends/stv090x_priv.h
index 5a4a01740d88..5921a8d6c89f 100644
--- a/drivers/media/dvb/frontends/stv090x_priv.h
+++ b/drivers/media/dvb/frontends/stv090x_priv.h
@@ -83,7 +83,7 @@
83 83
84#define STV090x_IQPOWER_THRESHOLD 30 84#define STV090x_IQPOWER_THRESHOLD 30
85#define STV090x_SEARCH_AGC2_TH_CUT20 700 85#define STV090x_SEARCH_AGC2_TH_CUT20 700
86#define STV090x_SEARCH_AGC2_TH_CUT30 1200 86#define STV090x_SEARCH_AGC2_TH_CUT30 1400
87 87
88#define STV090x_SEARCH_AGC2_TH(__ver) \ 88#define STV090x_SEARCH_AGC2_TH(__ver) \
89 ((__ver <= 0x20) ? \ 89 ((__ver <= 0x20) ? \
@@ -91,6 +91,7 @@
91 STV090x_SEARCH_AGC2_TH_CUT30) 91 STV090x_SEARCH_AGC2_TH_CUT30)
92 92
93enum stv090x_signal_state { 93enum stv090x_signal_state {
94 STV090x_NOAGC1,
94 STV090x_NOCARRIER, 95 STV090x_NOCARRIER,
95 STV090x_NODATA, 96 STV090x_NODATA,
96 STV090x_DATAOK, 97 STV090x_DATAOK,
diff --git a/drivers/media/dvb/frontends/stv090x_reg.h b/drivers/media/dvb/frontends/stv090x_reg.h
index 57b6abbbd32d..2502855dd784 100644
--- a/drivers/media/dvb/frontends/stv090x_reg.h
+++ b/drivers/media/dvb/frontends/stv090x_reg.h
@@ -44,7 +44,7 @@
44#define STV090x_OFFST_OUTSERRS2_HZ_FIELD 5 44#define STV090x_OFFST_OUTSERRS2_HZ_FIELD 5
45#define STV090x_WIDTH_OUTSERRS2_HZ_FIELD 1 45#define STV090x_WIDTH_OUTSERRS2_HZ_FIELD 1
46#define STV090x_OFFST_OUTSERRS3_HZ_FIELD 4 46#define STV090x_OFFST_OUTSERRS3_HZ_FIELD 4
47#define STV090x_WIDTH_OUTPARRS3_HZ_FIELD 1 47#define STV090x_WIDTH_OUTSERRS3_HZ_FIELD 1
48#define STV090x_OFFST_OUTPARRS3_HZ_FIELD 3 48#define STV090x_OFFST_OUTPARRS3_HZ_FIELD 3
49#define STV090x_WIDTH_OUTPARRS3_HZ_FIELD 1 49#define STV090x_WIDTH_OUTPARRS3_HZ_FIELD 1
50 50
@@ -113,24 +113,24 @@
113#define STV090x_IRQMASK3 0xf124 113#define STV090x_IRQMASK3 0xf124
114#define STV090x_OFFST_MPLL_LOCK_FIELD 5 114#define STV090x_OFFST_MPLL_LOCK_FIELD 5
115#define STV090x_WIDTH_MPLL_LOCK_FIELD 1 115#define STV090x_WIDTH_MPLL_LOCK_FIELD 1
116#define STV090x_OFFST_MSTREAM_LCK_3_FIELD 2 116#define STV090x_OFFST_MSTREAM_LCK_3_FIELD 4
117#define STV090x_WIDTH_MSTREAM_LCK_3_FIELD 3 117#define STV090x_WIDTH_MSTREAM_LCK_3_FIELD 1
118#define STV090x_OFFST_MSTREAM_LCK_2_FIELD 2 118#define STV090x_OFFST_MSTREAM_LCK_2_FIELD 3
119#define STV090x_WIDTH_MSTREAM_LCK_2_FIELD 3 119#define STV090x_WIDTH_MSTREAM_LCK_2_FIELD 1
120#define STV090x_OFFST_MSTREAM_LCK_1_FIELD 2 120#define STV090x_OFFST_MSTREAM_LCK_1_FIELD 2
121#define STV090x_WIDTH_MSTREAM_LCK_1_FIELD 3 121#define STV090x_WIDTH_MSTREAM_LCK_1_FIELD 1
122#define STV090x_OFFST_MDVBS1_PRF_2_FIELD 1 122#define STV090x_OFFST_MDVBS1_PRF_2_FIELD 1
123#define STV090x_WIDTH_MDVBS1_PRF_2_FIELD 1 123#define STV090x_WIDTH_MDVBS1_PRF_2_FIELD 1
124#define STV090x_OFFST_MDVBS1_PRF_1_FIELD 0 124#define STV090x_OFFST_MDVBS1_PRF_1_FIELD 0
125#define STV090x_WIDTH_MDVBS1_PRF_1_FIELD 1 125#define STV090x_WIDTH_MDVBS1_PRF_1_FIELD 1
126 126
127#define STV090x_IRQMASK2 0xf125 127#define STV090x_IRQMASK2 0xf125
128#define STV090x_OFFST_MSPY_ENDSIM_3_FIELD 5 128#define STV090x_OFFST_MSPY_ENDSIM_3_FIELD 7
129#define STV090x_WIDTH_MSPY_ENDSIM_3_FIELD 3 129#define STV090x_WIDTH_MSPY_ENDSIM_3_FIELD 1
130#define STV090x_OFFST_MSPY_ENDSIM_2_FIELD 5 130#define STV090x_OFFST_MSPY_ENDSIM_2_FIELD 6
131#define STV090x_WIDTH_MSPY_ENDSIM_2_FIELD 3 131#define STV090x_WIDTH_MSPY_ENDSIM_2_FIELD 1
132#define STV090x_OFFST_MSPY_ENDSIM_1_FIELD 5 132#define STV090x_OFFST_MSPY_ENDSIM_1_FIELD 5
133#define STV090x_WIDTH_MSPY_ENDSIM_1_FIELD 3 133#define STV090x_WIDTH_MSPY_ENDSIM_1_FIELD 1
134#define STV090x_OFFST_MPKTDEL_ERROR_2_FIELD 4 134#define STV090x_OFFST_MPKTDEL_ERROR_2_FIELD 4
135#define STV090x_WIDTH_MPKTDEL_ERROR_2_FIELD 1 135#define STV090x_WIDTH_MPKTDEL_ERROR_2_FIELD 1
136#define STV090x_OFFST_MPKTDEL_LOCKB_2_FIELD 3 136#define STV090x_OFFST_MPKTDEL_LOCKB_2_FIELD 3
@@ -370,7 +370,7 @@
370#define STV090x_OFFST_SELX1RATIO_FIELD 5 370#define STV090x_OFFST_SELX1RATIO_FIELD 5
371#define STV090x_WIDTH_SELX1RATIO_FIELD 1 371#define STV090x_WIDTH_SELX1RATIO_FIELD 1
372#define STV090x_OFFST_STOP_PLL_FIELD 3 372#define STV090x_OFFST_STOP_PLL_FIELD 3
373#define STV090x_WIDTH_SELX1RATIO_FIELD 1 373#define STV090x_WIDTH_STOP_PLL_FIELD 1
374#define STV090x_OFFST_BYPASSPLLFSK_FIELD 2 374#define STV090x_OFFST_BYPASSPLLFSK_FIELD 2
375#define STV090x_WIDTH_BYPASSPLLFSK_FIELD 1 375#define STV090x_WIDTH_BYPASSPLLFSK_FIELD 1
376#define STV090x_OFFST_SELOSCI_FIELD 1 376#define STV090x_OFFST_SELOSCI_FIELD 1
@@ -616,7 +616,7 @@
616#define STV090x_OFFST_Px_CONT_TONE_FIELD 4 616#define STV090x_OFFST_Px_CONT_TONE_FIELD 4
617#define STV090x_WIDTH_Px_CONT_TONE_FIELD 1 617#define STV090x_WIDTH_Px_CONT_TONE_FIELD 1
618#define STV090x_OFFST_Px_FIFO_4BREADY_FIELD 3 618#define STV090x_OFFST_Px_FIFO_4BREADY_FIELD 3
619#define STV090x_WIDTH_Px_FIFO_4BREADY_FIELD 2 619#define STV090x_WIDTH_Px_FIFO_4BREADY_FIELD 1
620#define STV090x_OFFST_Px_FIFO_EMPTY_FIELD 2 620#define STV090x_OFFST_Px_FIFO_EMPTY_FIELD 2
621#define STV090x_WIDTH_Px_FIFO_EMPTY_FIELD 1 621#define STV090x_WIDTH_Px_FIFO_EMPTY_FIELD 1
622#define STV090x_OFFST_Px_ABORT_DISRX_FIELD 0 622#define STV090x_OFFST_Px_ABORT_DISRX_FIELD 0
@@ -847,12 +847,10 @@
847#define STV090x_WIDTH_Px_DVBS2_ENABLE_FIELD 1 847#define STV090x_WIDTH_Px_DVBS2_ENABLE_FIELD 1
848#define STV090x_OFFST_Px_DVBS1_ENABLE_FIELD 6 848#define STV090x_OFFST_Px_DVBS1_ENABLE_FIELD 6
849#define STV090x_WIDTH_Px_DVBS1_ENABLE_FIELD 1 849#define STV090x_WIDTH_Px_DVBS1_ENABLE_FIELD 1
850#define STV090x_OFFST_Px_CFR_AUTOSCAN_FIELD 5 /* check */ 850#define STV090x_OFFST_Px_SCAN_ENABLE_FIELD 4
851#define STV090x_WIDTH_Px_CFR_AUTOSCAN_FIELD 1
852#define STV090x_OFFST_Px_SCAN_ENABLE_FIELD 4 /* check */
853#define STV090x_WIDTH_Px_SCAN_ENABLE_FIELD 1 851#define STV090x_WIDTH_Px_SCAN_ENABLE_FIELD 1
854#define STV090x_OFFST_Px_TUN_AUTOSCAN_FIELD 3 852#define STV090x_OFFST_Px_CFR_AUTOSCAN_FIELD 3
855#define STV090x_WIDTH_Px_TUN_AUTOSCAN_FIELD 1 853#define STV090x_WIDTH_Px_CFR_AUTOSCAN_FIELD 1
856#define STV090x_OFFST_Px_NOFORCE_RELOCK_FIELD 2 854#define STV090x_OFFST_Px_NOFORCE_RELOCK_FIELD 2
857#define STV090x_WIDTH_Px_NOFORCE_RELOCK_FIELD 1 855#define STV090x_WIDTH_Px_NOFORCE_RELOCK_FIELD 1
858#define STV090x_OFFST_Px_TUN_RNG_FIELD 0 856#define STV090x_OFFST_Px_TUN_RNG_FIELD 0
@@ -885,7 +883,7 @@
885#define STV090x_P2_DMDFLYW STV090x_Px_DMDFLYW(2) 883#define STV090x_P2_DMDFLYW STV090x_Px_DMDFLYW(2)
886#define STV090x_OFFST_Px_I2C_IRQVAL_FIELD 4 884#define STV090x_OFFST_Px_I2C_IRQVAL_FIELD 4
887#define STV090x_WIDTH_Px_I2C_IRQVAL_FIELD 4 885#define STV090x_WIDTH_Px_I2C_IRQVAL_FIELD 4
888#define STV090x_OFFST_Px_FLYWHEEL_CPT_FIELD 0 /* check */ 886#define STV090x_OFFST_Px_FLYWHEEL_CPT_FIELD 0
889#define STV090x_WIDTH_Px_FLYWHEEL_CPT_FIELD 4 887#define STV090x_WIDTH_Px_FLYWHEEL_CPT_FIELD 4
890 888
891#define STV090x_Px_DSTATUS3(__x) (0xF41D - (__x - 1) * 0x200) 889#define STV090x_Px_DSTATUS3(__x) (0xF41D - (__x - 1) * 0x200)
@@ -1048,12 +1046,12 @@
1048#define STV090x_P1_CFRINC1 STV090x_Px_CFRINC1(1) 1046#define STV090x_P1_CFRINC1 STV090x_Px_CFRINC1(1)
1049#define STV090x_P2_CFRINC1 STV090x_Px_CFRINC1(2) 1047#define STV090x_P2_CFRINC1 STV090x_Px_CFRINC1(2)
1050#define STV090x_OFFST_Px_CFR_INC1_FIELD 0 1048#define STV090x_OFFST_Px_CFR_INC1_FIELD 0
1051#define STV090x_WIDTH_Px_CFR_INC1_FIELD 7 1049#define STV090x_WIDTH_Px_CFR_INC1_FIELD 7 /* check */
1052 1050
1053#define STV090x_Px_CFRINC0(__x) (0xF44B - (__x - 1) * 0x200) 1051#define STV090x_Px_CFRINC0(__x) (0xF44B - (__x - 1) * 0x200)
1054#define STV090x_P1_CFRINC0 STV090x_Px_CFRINC0(1) 1052#define STV090x_P1_CFRINC0 STV090x_Px_CFRINC0(1)
1055#define STV090x_P2_CFRINC0 STV090x_Px_CFRINC0(2) 1053#define STV090x_P2_CFRINC0 STV090x_Px_CFRINC0(2)
1056#define STV090x_OFFST_Px_CFR_INC0_FIELD 4 1054#define STV090x_OFFST_Px_CFR_INC0_FIELD 4 /* check */
1057#define STV090x_WIDTH_Px_CFR_INC0_FIELD 4 1055#define STV090x_WIDTH_Px_CFR_INC0_FIELD 4
1058 1056
1059#define STV090x_Pn_CFRy(__x, __y) (0xF44E - (__x - 1) * 0x200 - __y * 0x1) 1057#define STV090x_Pn_CFRy(__x, __y) (0xF44E - (__x - 1) * 0x200 - __y * 0x1)
@@ -1145,14 +1143,14 @@
1145#define STV090x_Px_SFRINIT1(__x) (0xF45E - (__x - 1) * 0x200) 1143#define STV090x_Px_SFRINIT1(__x) (0xF45E - (__x - 1) * 0x200)
1146#define STV090x_P1_SFRINIT1 STV090x_Px_SFRINIT1(1) 1144#define STV090x_P1_SFRINIT1 STV090x_Px_SFRINIT1(1)
1147#define STV090x_P2_SFRINIT1 STV090x_Px_SFRINIT1(2) 1145#define STV090x_P2_SFRINIT1 STV090x_Px_SFRINIT1(2)
1148#define STV090x_OFFST_Px_SFR_INIT_FIELD 0 1146#define STV090x_OFFST_Px_SFR_INIT1_FIELD 0
1149#define STV090x_WIDTH_Px_SFR_INIT_FIELD 8 1147#define STV090x_WIDTH_Px_SFR_INIT1_FIELD 7
1150 1148
1151#define STV090x_Px_SFRINIT0(__x) (0xF45F - (__x - 1) * 0x200) 1149#define STV090x_Px_SFRINIT0(__x) (0xF45F - (__x - 1) * 0x200)
1152#define STV090x_P1_SFRINIT0 STV090x_Px_SFRINIT0(1) 1150#define STV090x_P1_SFRINIT0 STV090x_Px_SFRINIT0(1)
1153#define STV090x_P2_SFRINIT0 STV090x_Px_SFRINIT0(2) 1151#define STV090x_P2_SFRINIT0 STV090x_Px_SFRINIT0(2)
1154#define STV090x_OFFST_Px_SFR_INIT_FIELD 0 1152#define STV090x_OFFST_Px_SFR_INIT0_FIELD 0
1155#define STV090x_WIDTH_Px_SFR_INIT_FIELD 8 1153#define STV090x_WIDTH_Px_SFR_INIT0_FIELD 8
1156 1154
1157#define STV090x_Px_SFRUP1(__x) (0xF460 - (__x - 1) * 0x200) 1155#define STV090x_Px_SFRUP1(__x) (0xF460 - (__x - 1) * 0x200)
1158#define STV090x_P1_SFRUP1 STV090x_Px_SFRUP1(1) 1156#define STV090x_P1_SFRUP1 STV090x_Px_SFRUP1(1)
@@ -1178,7 +1176,7 @@
1178#define STV090x_OFFST_Px_SYMB_FREQ_LOW0_FIELD 0 1176#define STV090x_OFFST_Px_SYMB_FREQ_LOW0_FIELD 0
1179#define STV090x_WIDTH_Px_SYMB_FREQ_LOW0_FIELD 8 1177#define STV090x_WIDTH_Px_SYMB_FREQ_LOW0_FIELD 8
1180 1178
1181#define STV090x_Px_SFRy(__x, __y) (0xF464 - (__x-1) * 0x200 + (3 - __y)) 1179#define STV090x_Px_SFRy(__x, __y) (0xF467 - (__x-1) * 0x200 - __y)
1182#define STV090x_P1_SFR0 STV090x_Px_SFRy(1, 0) 1180#define STV090x_P1_SFR0 STV090x_Px_SFRy(1, 0)
1183#define STV090x_P1_SFR1 STV090x_Px_SFRy(1, 1) 1181#define STV090x_P1_SFR1 STV090x_Px_SFRy(1, 1)
1184#define STV090x_P1_SFR2 STV090x_Px_SFRy(1, 2) 1182#define STV090x_P1_SFR2 STV090x_Px_SFRy(1, 2)
@@ -1188,7 +1186,7 @@
1188#define STV090x_P2_SFR2 STV090x_Px_SFRy(2, 2) 1186#define STV090x_P2_SFR2 STV090x_Px_SFRy(2, 2)
1189#define STV090x_P2_SFR3 STV090x_Px_SFRy(2, 3) 1187#define STV090x_P2_SFR3 STV090x_Px_SFRy(2, 3)
1190#define STV090x_OFFST_Px_SYMB_FREQ_FIELD 0 1188#define STV090x_OFFST_Px_SYMB_FREQ_FIELD 0
1191#define STV090x_WIDTH_Px_SYMB_FREQ_FIELD 32 1189#define STV090x_WIDTH_Px_SYMB_FREQ_FIELD 8
1192 1190
1193#define STV090x_Px_TMGREG2(__x) (0xF468 - (__x - 1) * 0x200) 1191#define STV090x_Px_TMGREG2(__x) (0xF468 - (__x - 1) * 0x200)
1194#define STV090x_P1_TMGREG2 STV090x_Px_TMGREG2(1) 1192#define STV090x_P1_TMGREG2 STV090x_Px_TMGREG2(1)
@@ -1198,7 +1196,7 @@
1198 1196
1199#define STV090x_Px_TMGREG1(__x) (0xF469 - (__x - 1) * 0x200) 1197#define STV090x_Px_TMGREG1(__x) (0xF469 - (__x - 1) * 0x200)
1200#define STV090x_P1_TMGREG1 STV090x_Px_TMGREG1(1) 1198#define STV090x_P1_TMGREG1 STV090x_Px_TMGREG1(1)
1201#define STV090x_P2_TMGREG1 STV090x_Px_TMGREG1(2) 1199#define STV090x_P2_TMGREG1 STV090x_Px_TMGREG1(2)
1202#define STV090x_OFFST_Px_TMGREG_FIELD 0 1200#define STV090x_OFFST_Px_TMGREG_FIELD 0
1203#define STV090x_WIDTH_Px_TMGREG_FIELD 8 1201#define STV090x_WIDTH_Px_TMGREG_FIELD 8
1204 1202
@@ -1230,7 +1228,7 @@
1230#define STV090x_OFFST_Px_MU_EQUALDFE_FIELD 0 1228#define STV090x_OFFST_Px_MU_EQUALDFE_FIELD 0
1231#define STV090x_WIDTH_Px_MU_EQUALDFE_FIELD 3 1229#define STV090x_WIDTH_Px_MU_EQUALDFE_FIELD 3
1232 1230
1233#define STV090x_Px_EQUAIy(__x, __y) (0xf470 - (__x - 1) * 0x200 + (__y - 1)) 1231#define STV090x_Px_EQUAIy(__x, __y) (0xf470 - (__x-1) * 0x200 + 2 * (__y-1))
1234#define STV090x_P1_EQUAI1 STV090x_Px_EQUAIy(1, 1) 1232#define STV090x_P1_EQUAI1 STV090x_Px_EQUAIy(1, 1)
1235#define STV090x_P1_EQUAI2 STV090x_Px_EQUAIy(1, 2) 1233#define STV090x_P1_EQUAI2 STV090x_Px_EQUAIy(1, 2)
1236#define STV090x_P1_EQUAI3 STV090x_Px_EQUAIy(1, 3) 1234#define STV090x_P1_EQUAI3 STV090x_Px_EQUAIy(1, 3)
@@ -1251,7 +1249,7 @@
1251#define STV090x_OFFST_Px_EQUA_ACCIy_FIELD 0 1249#define STV090x_OFFST_Px_EQUA_ACCIy_FIELD 0
1252#define STV090x_WIDTH_Px_EQUA_ACCIy_FIELD 8 1250#define STV090x_WIDTH_Px_EQUA_ACCIy_FIELD 8
1253 1251
1254#define STV090x_Px_EQUAQy(__x, __y) (0xf471 - (__x - 1) * 0x200 + (__y - 1)) 1252#define STV090x_Px_EQUAQy(__x, __y) (0xf471 - (__x-1) * 0x200 + 2 * (__y-1))
1255#define STV090x_P1_EQUAQ1 STV090x_Px_EQUAQy(1, 1) 1253#define STV090x_P1_EQUAQ1 STV090x_Px_EQUAQy(1, 1)
1256#define STV090x_P1_EQUAQ2 STV090x_Px_EQUAQy(1, 2) 1254#define STV090x_P1_EQUAQ2 STV090x_Px_EQUAQy(1, 2)
1257#define STV090x_P1_EQUAQ3 STV090x_Px_EQUAQy(1, 3) 1255#define STV090x_P1_EQUAQ3 STV090x_Px_EQUAQy(1, 3)
@@ -1390,7 +1388,7 @@
1390#define STV090x_OFFST_Px_CAR2S2_16A_ALPH_E_FIELD 0 1388#define STV090x_OFFST_Px_CAR2S2_16A_ALPH_E_FIELD 0
1391#define STV090x_WIDTH_Px_CAR2S2_16A_ALPH_E_FIELD 4 1389#define STV090x_WIDTH_Px_CAR2S2_16A_ALPH_E_FIELD 4
1392 1390
1393#define STV090x_Px_ACLC2S232A(__x) (0xf499 - (__x - 1) * 0x200) 1391#define STV090x_Px_ACLC2S232A(__x) (0xf49A - (__x - 1) * 0x200)
1394#define STV090x_P1_ACLC2S232A STV090x_Px_ACLC2S232A(1) 1392#define STV090x_P1_ACLC2S232A STV090x_Px_ACLC2S232A(1)
1395#define STV090x_P2_ACLC2S232A STV090x_Px_ACLC2S232A(2) 1393#define STV090x_P2_ACLC2S232A STV090x_Px_ACLC2S232A(2)
1396#define STV090x_OFFST_Px_CAR2S2_32A_ALPH_M_FIELD 4 1394#define STV090x_OFFST_Px_CAR2S2_32A_ALPH_M_FIELD 4
@@ -1414,7 +1412,7 @@
1414#define STV090x_OFFST_Px_CAR2S2_8_BETA_E_FIELD 0 1412#define STV090x_OFFST_Px_CAR2S2_8_BETA_E_FIELD 0
1415#define STV090x_WIDTH_Px_CAR2S2_8_BETA_E_FIELD 4 1413#define STV090x_WIDTH_Px_CAR2S2_8_BETA_E_FIELD 4
1416 1414
1417#define STV090x_Px_BCLC2S216A(__x) (0xf49d - (__x - 1) * 0x200) 1415#define STV090x_Px_BCLC2S216A(__x) (0xf49e - (__x - 1) * 0x200)
1418#define STV090x_P1_BCLC2S216A STV090x_Px_BCLC2S216A(1) 1416#define STV090x_P1_BCLC2S216A STV090x_Px_BCLC2S216A(1)
1419#define STV090x_P2_BCLC2S216A STV090x_Px_BCLC2S216A(1) 1417#define STV090x_P2_BCLC2S216A STV090x_Px_BCLC2S216A(1)
1420#define STV090x_OFFST_Px_CAR2S2_16A_BETA_M_FIELD 4 1418#define STV090x_OFFST_Px_CAR2S2_16A_BETA_M_FIELD 4
@@ -1422,7 +1420,7 @@
1422#define STV090x_OFFST_Px_CAR2S2_16A_BETA_E_FIELD 0 1420#define STV090x_OFFST_Px_CAR2S2_16A_BETA_E_FIELD 0
1423#define STV090x_WIDTH_Px_CAR2S2_16A_BETA_E_FIELD 4 1421#define STV090x_WIDTH_Px_CAR2S2_16A_BETA_E_FIELD 4
1424 1422
1425#define STV090x_Px_BCLC2S232A(__x) (0xf49d - (__x - 1) * 0x200) 1423#define STV090x_Px_BCLC2S232A(__x) (0xf49f - (__x - 1) * 0x200)
1426#define STV090x_P1_BCLC2S232A STV090x_Px_BCLC2S232A(1) 1424#define STV090x_P1_BCLC2S232A STV090x_Px_BCLC2S232A(1)
1427#define STV090x_P2_BCLC2S232A STV090x_Px_BCLC2S232A(1) 1425#define STV090x_P2_BCLC2S232A STV090x_Px_BCLC2S232A(1)
1428#define STV090x_OFFST_Px_CAR2S2_32A_BETA_M_FIELD 4 1426#define STV090x_OFFST_Px_CAR2S2_32A_BETA_M_FIELD 4
@@ -1458,7 +1456,7 @@
1458#define STV090x_P1_MODCODLST1 STV090x_Px_MODCODLST1(1) 1456#define STV090x_P1_MODCODLST1 STV090x_Px_MODCODLST1(1)
1459#define STV090x_P2_MODCODLST1 STV090x_Px_MODCODLST1(2) 1457#define STV090x_P2_MODCODLST1 STV090x_Px_MODCODLST1(2)
1460#define STV090x_OFFST_Px_DIS_MODCOD29_FIELD 4 1458#define STV090x_OFFST_Px_DIS_MODCOD29_FIELD 4
1461#define STV090x_WIDTH_Px_DIS_MODCOD29T_FIELD 4 1459#define STV090x_WIDTH_Px_DIS_MODCOD29_FIELD 4
1462#define STV090x_OFFST_Px_DIS_32PSK_9_10_FIELD 0 1460#define STV090x_OFFST_Px_DIS_32PSK_9_10_FIELD 0
1463#define STV090x_WIDTH_Px_DIS_32PSK_9_10_FIELD 4 1461#define STV090x_WIDTH_Px_DIS_32PSK_9_10_FIELD 4
1464 1462
@@ -2180,7 +2178,7 @@
2180#define STV090x_WIDTH_Px_TSFIFOSPEED_STORE_FIELD 1 2178#define STV090x_WIDTH_Px_TSFIFOSPEED_STORE_FIELD 1
2181#define STV090x_OFFST_Px_DILXX_RESET_FIELD 5 2179#define STV090x_OFFST_Px_DILXX_RESET_FIELD 5
2182#define STV090x_WIDTH_Px_DILXX_RESET_FIELD 1 2180#define STV090x_WIDTH_Px_DILXX_RESET_FIELD 1
2183#define STV090x_OFFST_Px_TSSERIAL_IMPOS_FIELD 5 2181#define STV090x_OFFST_Px_TSSERIAL_IMPOS_FIELD 4
2184#define STV090x_WIDTH_Px_TSSERIAL_IMPOS_FIELD 1 2182#define STV090x_WIDTH_Px_TSSERIAL_IMPOS_FIELD 1
2185#define STV090x_OFFST_Px_SCRAMBDETECT_FIELD 1 2183#define STV090x_OFFST_Px_SCRAMBDETECT_FIELD 1
2186#define STV090x_WIDTH_Px_SCRAMBDETECT_FIELD 1 2184#define STV090x_WIDTH_Px_SCRAMBDETECT_FIELD 1
@@ -2190,7 +2188,7 @@
2190#define STV090x_P1_TSBITRATE1 STV090x_Px_TSBITRATEy(1, 1) 2188#define STV090x_P1_TSBITRATE1 STV090x_Px_TSBITRATEy(1, 1)
2191#define STV090x_P2_TSBITRATE0 STV090x_Px_TSBITRATEy(2, 0) 2189#define STV090x_P2_TSBITRATE0 STV090x_Px_TSBITRATEy(2, 0)
2192#define STV090x_P2_TSBITRATE1 STV090x_Px_TSBITRATEy(2, 1) 2190#define STV090x_P2_TSBITRATE1 STV090x_Px_TSBITRATEy(2, 1)
2193#define STV090x_OFFST_Px_TSFIFO_BITRATE_FIELD 7 2191#define STV090x_OFFST_Px_TSFIFO_BITRATE_FIELD 0
2194#define STV090x_WIDTH_Px_TSFIFO_BITRATE_FIELD 8 2192#define STV090x_WIDTH_Px_TSFIFO_BITRATE_FIELD 8
2195 2193
2196#define STV090x_Px_ERRCTRL1(__x) (0xF598 - (__x - 1) * 0x200) 2194#define STV090x_Px_ERRCTRL1(__x) (0xF598 - (__x - 1) * 0x200)
diff --git a/drivers/media/dvb/frontends/stv6110.c b/drivers/media/dvb/frontends/stv6110.c
index dcf1b21ea974..bef0cc838471 100644
--- a/drivers/media/dvb/frontends/stv6110.c
+++ b/drivers/media/dvb/frontends/stv6110.c
@@ -37,6 +37,7 @@ struct stv6110_priv {
37 37
38 u32 mclk; 38 u32 mclk;
39 u8 clk_div; 39 u8 clk_div;
40 u8 gain;
40 u8 regs[8]; 41 u8 regs[8];
41}; 42};
42 43
@@ -255,7 +256,7 @@ static int stv6110_set_frequency(struct dvb_frontend *fe, u32 frequency)
255 u8 ret = 0x04; 256 u8 ret = 0x04;
256 u32 divider, ref, p, presc, i, result_freq, vco_freq; 257 u32 divider, ref, p, presc, i, result_freq, vco_freq;
257 s32 p_calc, p_calc_opt = 1000, r_div, r_div_opt = 0, p_val; 258 s32 p_calc, p_calc_opt = 1000, r_div, r_div_opt = 0, p_val;
258 s32 srate; u8 gain; 259 s32 srate;
259 260
260 dprintk("%s, freq=%d kHz, mclk=%d Hz\n", __func__, 261 dprintk("%s, freq=%d kHz, mclk=%d Hz\n", __func__,
261 frequency, priv->mclk); 262 frequency, priv->mclk);
@@ -273,15 +274,8 @@ static int stv6110_set_frequency(struct dvb_frontend *fe, u32 frequency)
273 } else 274 } else
274 srate = 15000000; 275 srate = 15000000;
275 276
276 if (srate >= 15000000)
277 gain = 3; /* +6 dB */
278 else if (srate >= 5000000)
279 gain = 3; /* +6 dB */
280 else
281 gain = 3; /* +6 dB */
282
283 priv->regs[RSTV6110_CTRL2] &= ~0x0f; 277 priv->regs[RSTV6110_CTRL2] &= ~0x0f;
284 priv->regs[RSTV6110_CTRL2] |= (gain & 0x0f); 278 priv->regs[RSTV6110_CTRL2] |= (priv->gain & 0x0f);
285 279
286 if (frequency <= 1023000) { 280 if (frequency <= 1023000) {
287 p = 1; 281 p = 1;
@@ -436,6 +430,7 @@ struct dvb_frontend *stv6110_attach(struct dvb_frontend *fe,
436 priv->i2c = i2c; 430 priv->i2c = i2c;
437 priv->mclk = config->mclk; 431 priv->mclk = config->mclk;
438 priv->clk_div = config->clk_div; 432 priv->clk_div = config->clk_div;
433 priv->gain = config->gain;
439 434
440 memcpy(&priv->regs, &reg0[1], 8); 435 memcpy(&priv->regs, &reg0[1], 8);
441 436
diff --git a/drivers/media/dvb/frontends/stv6110.h b/drivers/media/dvb/frontends/stv6110.h
index 9db2402410f6..fe71bba6a26e 100644
--- a/drivers/media/dvb/frontends/stv6110.h
+++ b/drivers/media/dvb/frontends/stv6110.h
@@ -41,6 +41,7 @@
41struct stv6110_config { 41struct stv6110_config {
42 u8 i2c_address; 42 u8 i2c_address;
43 u32 mclk; 43 u32 mclk;
44 u8 gain;
44 u8 clk_div; /* divisor value for the output clock */ 45 u8 clk_div; /* divisor value for the output clock */
45}; 46};
46 47
diff --git a/drivers/media/dvb/frontends/stv6110x.c b/drivers/media/dvb/frontends/stv6110x.c
index 3d8a2e01c9c4..bcfcb652464c 100644
--- a/drivers/media/dvb/frontends/stv6110x.c
+++ b/drivers/media/dvb/frontends/stv6110x.c
@@ -95,7 +95,7 @@ static int stv6110x_set_frequency(struct dvb_frontend *fe, u32 frequency)
95{ 95{
96 struct stv6110x_state *stv6110x = fe->tuner_priv; 96 struct stv6110x_state *stv6110x = fe->tuner_priv;
97 u32 rDiv, divider; 97 u32 rDiv, divider;
98 s32 pVal, pCalc, rDivOpt = 0; 98 s32 pVal, pCalc, rDivOpt = 0, pCalcOpt = 1000;
99 u8 i; 99 u8 i;
100 100
101 STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL1], CTRL1_K, (REFCLOCK_MHz - 16)); 101 STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL1], CTRL1_K, (REFCLOCK_MHz - 16));
@@ -121,8 +121,10 @@ static int stv6110x_set_frequency(struct dvb_frontend *fe, u32 frequency)
121 for (rDiv = 0; rDiv <= 3; rDiv++) { 121 for (rDiv = 0; rDiv <= 3; rDiv++) {
122 pCalc = (REFCLOCK_kHz / 100) / R_DIV(rDiv); 122 pCalc = (REFCLOCK_kHz / 100) / R_DIV(rDiv);
123 123
124 if ((abs((s32)(pCalc - pVal))) < (abs((s32)(1000 - pVal)))) 124 if ((abs((s32)(pCalc - pVal))) < (abs((s32)(pCalcOpt - pVal))))
125 rDivOpt = rDiv; 125 rDivOpt = rDiv;
126
127 pCalcOpt = (REFCLOCK_kHz / 100) / R_DIV(rDivOpt);
126 } 128 }
127 129
128 divider = (frequency * R_DIV(rDivOpt) * pVal) / REFCLOCK_kHz; 130 divider = (frequency * R_DIV(rDivOpt) * pVal) / REFCLOCK_kHz;
diff --git a/drivers/media/dvb/pt1/pt1.c b/drivers/media/dvb/pt1/pt1.c
index 1fd8306371e2..81e623a90f09 100644
--- a/drivers/media/dvb/pt1/pt1.c
+++ b/drivers/media/dvb/pt1/pt1.c
@@ -27,7 +27,6 @@
27#include <linux/pci.h> 27#include <linux/pci.h>
28#include <linux/kthread.h> 28#include <linux/kthread.h>
29#include <linux/freezer.h> 29#include <linux/freezer.h>
30#include <linux/vmalloc.h>
31 30
32#include "dvbdev.h" 31#include "dvbdev.h"
33#include "dvb_demux.h" 32#include "dvb_demux.h"
diff --git a/drivers/media/dvb/pt1/va1j5jf8007s.c b/drivers/media/dvb/pt1/va1j5jf8007s.c
index 2db940f8635f..fc6594996e79 100644
--- a/drivers/media/dvb/pt1/va1j5jf8007s.c
+++ b/drivers/media/dvb/pt1/va1j5jf8007s.c
@@ -48,6 +48,60 @@ struct va1j5jf8007s_state {
48 enum va1j5jf8007s_tune_state tune_state; 48 enum va1j5jf8007s_tune_state tune_state;
49}; 49};
50 50
51static int va1j5jf8007s_read_snr(struct dvb_frontend *fe, u16 *snr)
52{
53 struct va1j5jf8007s_state *state;
54 u8 addr;
55 int i;
56 u8 write_buf[1], read_buf[1];
57 struct i2c_msg msgs[2];
58 s32 word, x1, x2, x3, x4, x5, y;
59
60 state = fe->demodulator_priv;
61 addr = state->config->demod_address;
62
63 word = 0;
64 for (i = 0; i < 2; i++) {
65 write_buf[0] = 0xbc + i;
66
67 msgs[0].addr = addr;
68 msgs[0].flags = 0;
69 msgs[0].len = sizeof(write_buf);
70 msgs[0].buf = write_buf;
71
72 msgs[1].addr = addr;
73 msgs[1].flags = I2C_M_RD;
74 msgs[1].len = sizeof(read_buf);
75 msgs[1].buf = read_buf;
76
77 if (i2c_transfer(state->adap, msgs, 2) != 2)
78 return -EREMOTEIO;
79
80 word <<= 8;
81 word |= read_buf[0];
82 }
83
84 word -= 3000;
85 if (word < 0)
86 word = 0;
87
88 x1 = int_sqrt(word << 16) * ((15625ll << 21) / 1000000);
89 x2 = (s64)x1 * x1 >> 31;
90 x3 = (s64)x2 * x1 >> 31;
91 x4 = (s64)x2 * x2 >> 31;
92 x5 = (s64)x4 * x1 >> 31;
93
94 y = (58857ll << 23) / 1000;
95 y -= (s64)x1 * ((89565ll << 24) / 1000) >> 30;
96 y += (s64)x2 * ((88977ll << 24) / 1000) >> 28;
97 y -= (s64)x3 * ((50259ll << 25) / 1000) >> 27;
98 y += (s64)x4 * ((14341ll << 27) / 1000) >> 27;
99 y -= (s64)x5 * ((16346ll << 30) / 10000) >> 28;
100
101 *snr = y < 0 ? 0 : y >> 15;
102 return 0;
103}
104
51static int va1j5jf8007s_get_frontend_algo(struct dvb_frontend *fe) 105static int va1j5jf8007s_get_frontend_algo(struct dvb_frontend *fe)
52{ 106{
53 return DVBFE_ALGO_HW; 107 return DVBFE_ALGO_HW;
@@ -337,7 +391,7 @@ va1j5jf8007s_tune(struct dvb_frontend *fe,
337{ 391{
338 struct va1j5jf8007s_state *state; 392 struct va1j5jf8007s_state *state;
339 int ret; 393 int ret;
340 int lock; 394 int lock = 0;
341 395
342 state = fe->demodulator_priv; 396 state = fe->demodulator_priv;
343 397
@@ -536,6 +590,7 @@ static struct dvb_frontend_ops va1j5jf8007s_ops = {
536 FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO, 590 FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO,
537 }, 591 },
538 592
593 .read_snr = va1j5jf8007s_read_snr,
539 .get_frontend_algo = va1j5jf8007s_get_frontend_algo, 594 .get_frontend_algo = va1j5jf8007s_get_frontend_algo,
540 .read_status = va1j5jf8007s_read_status, 595 .read_status = va1j5jf8007s_read_status,
541 .tune = va1j5jf8007s_tune, 596 .tune = va1j5jf8007s_tune,
diff --git a/drivers/media/dvb/pt1/va1j5jf8007t.c b/drivers/media/dvb/pt1/va1j5jf8007t.c
index 71117f4ca7e6..3db4f3e34e8f 100644
--- a/drivers/media/dvb/pt1/va1j5jf8007t.c
+++ b/drivers/media/dvb/pt1/va1j5jf8007t.c
@@ -46,6 +46,52 @@ struct va1j5jf8007t_state {
46 enum va1j5jf8007t_tune_state tune_state; 46 enum va1j5jf8007t_tune_state tune_state;
47}; 47};
48 48
49static int va1j5jf8007t_read_snr(struct dvb_frontend *fe, u16 *snr)
50{
51 struct va1j5jf8007t_state *state;
52 u8 addr;
53 int i;
54 u8 write_buf[1], read_buf[1];
55 struct i2c_msg msgs[2];
56 s32 word, x, y;
57
58 state = fe->demodulator_priv;
59 addr = state->config->demod_address;
60
61 word = 0;
62 for (i = 0; i < 3; i++) {
63 write_buf[0] = 0x8b + i;
64
65 msgs[0].addr = addr;
66 msgs[0].flags = 0;
67 msgs[0].len = sizeof(write_buf);
68 msgs[0].buf = write_buf;
69
70 msgs[1].addr = addr;
71 msgs[1].flags = I2C_M_RD;
72 msgs[1].len = sizeof(read_buf);
73 msgs[1].buf = read_buf;
74
75 if (i2c_transfer(state->adap, msgs, 2) != 2)
76 return -EREMOTEIO;
77
78 word <<= 8;
79 word |= read_buf[0];
80 }
81
82 if (!word)
83 return -EIO;
84
85 x = 10 * (intlog10(0x540000 * 100 / word) - (2 << 24));
86 y = (24ll << 46) / 1000000;
87 y = ((s64)y * x >> 30) - (16ll << 40) / 10000;
88 y = ((s64)y * x >> 29) + (398ll << 35) / 10000;
89 y = ((s64)y * x >> 30) + (5491ll << 29) / 10000;
90 y = ((s64)y * x >> 30) + (30965ll << 23) / 10000;
91 *snr = y >> 15;
92 return 0;
93}
94
49static int va1j5jf8007t_get_frontend_algo(struct dvb_frontend *fe) 95static int va1j5jf8007t_get_frontend_algo(struct dvb_frontend *fe)
50{ 96{
51 return DVBFE_ALGO_HW; 97 return DVBFE_ALGO_HW;
@@ -224,7 +270,7 @@ va1j5jf8007t_tune(struct dvb_frontend *fe,
224{ 270{
225 struct va1j5jf8007t_state *state; 271 struct va1j5jf8007t_state *state;
226 int ret; 272 int ret;
227 int lock, retry; 273 int lock = 0, retry = 0;
228 274
229 state = fe->demodulator_priv; 275 state = fe->demodulator_priv;
230 276
@@ -393,6 +439,7 @@ static struct dvb_frontend_ops va1j5jf8007t_ops = {
393 FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO, 439 FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO,
394 }, 440 },
395 441
442 .read_snr = va1j5jf8007t_read_snr,
396 .get_frontend_algo = va1j5jf8007t_get_frontend_algo, 443 .get_frontend_algo = va1j5jf8007t_get_frontend_algo,
397 .read_status = va1j5jf8007t_read_status, 444 .read_status = va1j5jf8007t_read_status,
398 .tune = va1j5jf8007t_tune, 445 .tune = va1j5jf8007t_tune,
diff --git a/drivers/media/dvb/siano/sms-cards.c b/drivers/media/dvb/siano/sms-cards.c
index 0420e2885e75..1067b22eb0c6 100644
--- a/drivers/media/dvb/siano/sms-cards.c
+++ b/drivers/media/dvb/siano/sms-cards.c
@@ -97,7 +97,7 @@ static struct sms_board sms_boards[] = {
97 }, 97 },
98}; 98};
99 99
100struct sms_board *sms_get_board(int id) 100struct sms_board *sms_get_board(unsigned id)
101{ 101{
102 BUG_ON(id >= ARRAY_SIZE(sms_boards)); 102 BUG_ON(id >= ARRAY_SIZE(sms_boards));
103 103
@@ -294,6 +294,8 @@ int sms_board_load_modules(int id)
294 case SMS1XXX_BOARD_HAUPPAUGE_OKEMO_A: 294 case SMS1XXX_BOARD_HAUPPAUGE_OKEMO_A:
295 case SMS1XXX_BOARD_HAUPPAUGE_OKEMO_B: 295 case SMS1XXX_BOARD_HAUPPAUGE_OKEMO_B:
296 case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM: 296 case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM:
297 case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD:
298 case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2:
297 request_module("smsdvb"); 299 request_module("smsdvb");
298 break; 300 break;
299 default: 301 default:
diff --git a/drivers/media/dvb/siano/sms-cards.h b/drivers/media/dvb/siano/sms-cards.h
index 38f062f6ad68..8f19fc000b46 100644
--- a/drivers/media/dvb/siano/sms-cards.h
+++ b/drivers/media/dvb/siano/sms-cards.h
@@ -81,7 +81,7 @@ struct sms_board {
81 int led_power, led_hi, led_lo, lna_ctrl, rf_switch; 81 int led_power, led_hi, led_lo, lna_ctrl, rf_switch;
82}; 82};
83 83
84struct sms_board *sms_get_board(int id); 84struct sms_board *sms_get_board(unsigned id);
85 85
86extern struct smscore_device_t *coredev; 86extern struct smscore_device_t *coredev;
87 87
diff --git a/drivers/media/dvb/siano/smscoreapi.c b/drivers/media/dvb/siano/smscoreapi.c
index fa6a62369a78..ca758bcb48c9 100644
--- a/drivers/media/dvb/siano/smscoreapi.c
+++ b/drivers/media/dvb/siano/smscoreapi.c
@@ -1373,7 +1373,7 @@ static int GetGpioPinParams(u32 PinNum, u32 *pTranslatedPinNum,
1373 1373
1374 *pGroupCfg = 1; 1374 *pGroupCfg = 1;
1375 1375
1376 if (PinNum >= 0 && PinNum <= 1) { 1376 if (PinNum <= 1) {
1377 *pTranslatedPinNum = 0; 1377 *pTranslatedPinNum = 0;
1378 *pGroupNum = 9; 1378 *pGroupNum = 9;
1379 *pGroupCfg = 2; 1379 *pGroupCfg = 2;
diff --git a/drivers/media/dvb/siano/smssdio.c b/drivers/media/dvb/siano/smssdio.c
index d1d652e7f890..24206cbda264 100644
--- a/drivers/media/dvb/siano/smssdio.c
+++ b/drivers/media/dvb/siano/smssdio.c
@@ -78,7 +78,7 @@ struct smssdio_device {
78 78
79static int smssdio_sendrequest(void *context, void *buffer, size_t size) 79static int smssdio_sendrequest(void *context, void *buffer, size_t size)
80{ 80{
81 int ret; 81 int ret = 0;
82 struct smssdio_device *smsdev; 82 struct smssdio_device *smsdev;
83 83
84 smsdev = context; 84 smsdev = context;
diff --git a/drivers/media/dvb/ttpci/budget-av.c b/drivers/media/dvb/ttpci/budget-av.c
index 8ea915227674..983672aa2450 100644
--- a/drivers/media/dvb/ttpci/budget-av.c
+++ b/drivers/media/dvb/ttpci/budget-av.c
@@ -1055,7 +1055,7 @@ static const struct stb0899_s1_reg knc1_stb0899_s1_init_3[] = {
1055 { STB0899_TSCFGH , 0x0c }, 1055 { STB0899_TSCFGH , 0x0c },
1056 { STB0899_TSCFGM , 0x00 }, 1056 { STB0899_TSCFGM , 0x00 },
1057 { STB0899_TSCFGL , 0x0c }, 1057 { STB0899_TSCFGL , 0x0c },
1058 { STB0899_TSOUT , 0x0d }, /* 0x0d for CAM */ 1058 { STB0899_TSOUT , 0x4d }, /* 0x0d for CAM */
1059 { STB0899_RSSYNCDEL , 0x00 }, 1059 { STB0899_RSSYNCDEL , 0x00 },
1060 { STB0899_TSINHDELH , 0x02 }, 1060 { STB0899_TSINHDELH , 0x02 },
1061 { STB0899_TSINHDELM , 0x00 }, 1061 { STB0899_TSINHDELM , 0x00 },
diff --git a/drivers/media/dvb/ttpci/budget-ci.c b/drivers/media/dvb/ttpci/budget-ci.c
index b5c681372b6c..7d193ebc0aea 100644
--- a/drivers/media/dvb/ttpci/budget-ci.c
+++ b/drivers/media/dvb/ttpci/budget-ci.c
@@ -178,7 +178,7 @@ static void msp430_ir_interrupt(unsigned long data)
178 if (budget_ci->ir.last_raw != raw || !timer_pending(&budget_ci->ir.timer_keyup)) { 178 if (budget_ci->ir.last_raw != raw || !timer_pending(&budget_ci->ir.timer_keyup)) {
179 ir_input_nokey(dev, &budget_ci->ir.state); 179 ir_input_nokey(dev, &budget_ci->ir.state);
180 ir_input_keydown(dev, &budget_ci->ir.state, 180 ir_input_keydown(dev, &budget_ci->ir.state,
181 budget_ci->ir.ir_key, raw); 181 budget_ci->ir.ir_key);
182 budget_ci->ir.last_raw = raw; 182 budget_ci->ir.last_raw = raw;
183 } 183 }
184 184
@@ -224,8 +224,10 @@ static int msp430_ir_init(struct budget_ci *budget_ci)
224 case 0x1011: 224 case 0x1011:
225 case 0x1012: 225 case 0x1012:
226 /* The hauppauge keymap is a superset of these remotes */ 226 /* The hauppauge keymap is a superset of these remotes */
227 ir_input_init(input_dev, &budget_ci->ir.state, 227 error = ir_input_init(input_dev, &budget_ci->ir.state,
228 IR_TYPE_RC5, &ir_codes_hauppauge_new_table); 228 IR_TYPE_RC5, &ir_codes_hauppauge_new_table);
229 if (error < 0)
230 goto out2;
229 231
230 if (rc5_device < 0) 232 if (rc5_device < 0)
231 budget_ci->ir.rc5_device = 0x1f; 233 budget_ci->ir.rc5_device = 0x1f;
@@ -236,8 +238,10 @@ static int msp430_ir_init(struct budget_ci *budget_ci)
236 case 0x1017: 238 case 0x1017:
237 case 0x101a: 239 case 0x101a:
238 /* for the Technotrend 1500 bundled remote */ 240 /* for the Technotrend 1500 bundled remote */
239 ir_input_init(input_dev, &budget_ci->ir.state, 241 error = ir_input_init(input_dev, &budget_ci->ir.state,
240 IR_TYPE_RC5, &ir_codes_tt_1500_table); 242 IR_TYPE_RC5, &ir_codes_tt_1500_table);
243 if (error < 0)
244 goto out2;
241 245
242 if (rc5_device < 0) 246 if (rc5_device < 0)
243 budget_ci->ir.rc5_device = IR_DEVICE_ANY; 247 budget_ci->ir.rc5_device = IR_DEVICE_ANY;
@@ -246,8 +250,10 @@ static int msp430_ir_init(struct budget_ci *budget_ci)
246 break; 250 break;
247 default: 251 default:
248 /* unknown remote */ 252 /* unknown remote */
249 ir_input_init(input_dev, &budget_ci->ir.state, 253 error = ir_input_init(input_dev, &budget_ci->ir.state,
250 IR_TYPE_RC5, &ir_codes_budget_ci_old_table); 254 IR_TYPE_RC5, &ir_codes_budget_ci_old_table);
255 if (error < 0)
256 goto out2;
251 257
252 if (rc5_device < 0) 258 if (rc5_device < 0)
253 budget_ci->ir.rc5_device = IR_DEVICE_ANY; 259 budget_ci->ir.rc5_device = IR_DEVICE_ANY;
@@ -280,6 +286,7 @@ static int msp430_ir_init(struct budget_ci *budget_ci)
280 return 0; 286 return 0;
281 287
282out2: 288out2:
289 ir_input_free(input_dev);
283 input_free_device(input_dev); 290 input_free_device(input_dev);
284out1: 291out1:
285 return error; 292 return error;
@@ -297,6 +304,7 @@ static void msp430_ir_deinit(struct budget_ci *budget_ci)
297 del_timer_sync(&dev->timer); 304 del_timer_sync(&dev->timer);
298 ir_input_nokey(dev, &budget_ci->ir.state); 305 ir_input_nokey(dev, &budget_ci->ir.state);
299 306
307 ir_input_free(dev);
300 input_unregister_device(dev); 308 input_unregister_device(dev);
301} 309}
302 310
@@ -1248,7 +1256,7 @@ static const struct stb0899_s1_reg tt3200_stb0899_s1_init_3[] = {
1248 { STB0899_TSCFGH , 0x0c }, 1256 { STB0899_TSCFGH , 0x0c },
1249 { STB0899_TSCFGM , 0x00 }, 1257 { STB0899_TSCFGM , 0x00 },
1250 { STB0899_TSCFGL , 0x0c }, 1258 { STB0899_TSCFGL , 0x0c },
1251 { STB0899_TSOUT , 0x0d }, /* 0x0d for CAM */ 1259 { STB0899_TSOUT , 0x4d }, /* 0x0d for CAM */
1252 { STB0899_RSSYNCDEL , 0x00 }, 1260 { STB0899_RSSYNCDEL , 0x00 },
1253 { STB0899_TSINHDELH , 0x02 }, 1261 { STB0899_TSINHDELH , 0x02 },
1254 { STB0899_TSINHDELM , 0x00 }, 1262 { STB0899_TSINHDELM , 0x00 },
diff --git a/drivers/media/dvb/ttusb-dec/ttusb_dec.c b/drivers/media/dvb/ttusb-dec/ttusb_dec.c
index d91e0638448f..53baccbab17f 100644
--- a/drivers/media/dvb/ttusb-dec/ttusb_dec.c
+++ b/drivers/media/dvb/ttusb-dec/ttusb_dec.c
@@ -1198,7 +1198,7 @@ static int ttusb_init_rc( struct ttusb_dec *dec)
1198 int err; 1198 int err;
1199 1199
1200 usb_make_path(dec->udev, dec->rc_phys, sizeof(dec->rc_phys)); 1200 usb_make_path(dec->udev, dec->rc_phys, sizeof(dec->rc_phys));
1201 strlcpy(dec->rc_phys, "/input0", sizeof(dec->rc_phys)); 1201 strlcat(dec->rc_phys, "/input0", sizeof(dec->rc_phys));
1202 1202
1203 input_dev = input_allocate_device(); 1203 input_dev = input_allocate_device();
1204 if (!input_dev) 1204 if (!input_dev)
diff --git a/drivers/media/radio/Kconfig b/drivers/media/radio/Kconfig
index b134553eb3b5..d4389963b312 100644
--- a/drivers/media/radio/Kconfig
+++ b/drivers/media/radio/Kconfig
@@ -419,4 +419,16 @@ config RADIO_TEA5764_XTAL
419 Say Y here if TEA5764 have a 32768 Hz crystal in circuit, say N 419 Say Y here if TEA5764 have a 32768 Hz crystal in circuit, say N
420 here if TEA5764 reference frequency is connected in FREQIN. 420 here if TEA5764 reference frequency is connected in FREQIN.
421 421
422config RADIO_TEF6862
423 tristate "TEF6862 Car Radio Enhanced Selectivity Tuner"
424 depends on I2C && VIDEO_V4L2
425 ---help---
426 Say Y here if you want to use the TEF6862 Car Radio Enhanced
427 Selectivity Tuner, found for instance on the Russellville development
428 board. On the russellville the device is connected to internal
429 timberdale I2C bus.
430
431 To compile this driver as a module, choose M here: the
432 module will be called TEF6862.
433
422endif # RADIO_ADAPTERS 434endif # RADIO_ADAPTERS
diff --git a/drivers/media/radio/Makefile b/drivers/media/radio/Makefile
index 8a63d543ae41..01922ada6914 100644
--- a/drivers/media/radio/Makefile
+++ b/drivers/media/radio/Makefile
@@ -23,5 +23,6 @@ obj-$(CONFIG_USB_DSBR) += dsbr100.o
23obj-$(CONFIG_RADIO_SI470X) += si470x/ 23obj-$(CONFIG_RADIO_SI470X) += si470x/
24obj-$(CONFIG_USB_MR800) += radio-mr800.o 24obj-$(CONFIG_USB_MR800) += radio-mr800.o
25obj-$(CONFIG_RADIO_TEA5764) += radio-tea5764.o 25obj-$(CONFIG_RADIO_TEA5764) += radio-tea5764.o
26obj-$(CONFIG_RADIO_TEF6862) += tef6862.o
26 27
27EXTRA_CFLAGS += -Isound 28EXTRA_CFLAGS += -Isound
diff --git a/drivers/media/radio/radio-mr800.c b/drivers/media/radio/radio-mr800.c
index 5f79acb56e48..949f60513d9e 100644
--- a/drivers/media/radio/radio-mr800.c
+++ b/drivers/media/radio/radio-mr800.c
@@ -85,6 +85,9 @@ MODULE_LICENSE("GPL");
85#define amradio_dev_warn(dev, fmt, arg...) \ 85#define amradio_dev_warn(dev, fmt, arg...) \
86 dev_warn(dev, MR800_DRIVER_NAME " - " fmt, ##arg) 86 dev_warn(dev, MR800_DRIVER_NAME " - " fmt, ##arg)
87 87
88#define amradio_dev_err(dev, fmt, arg...) \
89 dev_err(dev, MR800_DRIVER_NAME " - " fmt, ##arg)
90
88/* Probably USB_TIMEOUT should be modified in module parameter */ 91/* Probably USB_TIMEOUT should be modified in module parameter */
89#define BUFFER_LENGTH 8 92#define BUFFER_LENGTH 8
90#define USB_TIMEOUT 500 93#define USB_TIMEOUT 500
@@ -129,18 +132,20 @@ static int usb_amradio_resume(struct usb_interface *intf);
129struct amradio_device { 132struct amradio_device {
130 /* reference to USB and video device */ 133 /* reference to USB and video device */
131 struct usb_device *usbdev; 134 struct usb_device *usbdev;
132 struct video_device *videodev; 135 struct usb_interface *intf;
136 struct video_device videodev;
133 struct v4l2_device v4l2_dev; 137 struct v4l2_device v4l2_dev;
134 138
135 unsigned char *buffer; 139 unsigned char *buffer;
136 struct mutex lock; /* buffer locking */ 140 struct mutex lock; /* buffer locking */
137 int curfreq; 141 int curfreq;
138 int stereo; 142 int stereo;
139 int users;
140 int removed;
141 int muted; 143 int muted;
144 int initialized;
142}; 145};
143 146
147#define vdev_to_amradio(r) container_of(r, struct amradio_device, videodev)
148
144/* USB Device ID List */ 149/* USB Device ID List */
145static struct usb_device_id usb_amradio_device_table[] = { 150static struct usb_device_id usb_amradio_device_table[] = {
146 {USB_DEVICE_AND_INTERFACE_INFO(USB_AMRADIO_VENDOR, USB_AMRADIO_PRODUCT, 151 {USB_DEVICE_AND_INTERFACE_INFO(USB_AMRADIO_VENDOR, USB_AMRADIO_PRODUCT,
@@ -159,7 +164,7 @@ static struct usb_driver usb_amradio_driver = {
159 .resume = usb_amradio_resume, 164 .resume = usb_amradio_resume,
160 .reset_resume = usb_amradio_resume, 165 .reset_resume = usb_amradio_resume,
161 .id_table = usb_amradio_device_table, 166 .id_table = usb_amradio_device_table,
162 .supports_autosuspend = 0, 167 .supports_autosuspend = 1,
163}; 168};
164 169
165/* switch on/off the radio. Send 8 bytes to device */ 170/* switch on/off the radio. Send 8 bytes to device */
@@ -168,11 +173,7 @@ static int amradio_set_mute(struct amradio_device *radio, char argument)
168 int retval; 173 int retval;
169 int size; 174 int size;
170 175
171 /* safety check */ 176 BUG_ON(!mutex_is_locked(&radio->lock));
172 if (radio->removed)
173 return -EIO;
174
175 mutex_lock(&radio->lock);
176 177
177 radio->buffer[0] = 0x00; 178 radio->buffer[0] = 0x00;
178 radio->buffer[1] = 0x55; 179 radio->buffer[1] = 0x55;
@@ -187,14 +188,12 @@ static int amradio_set_mute(struct amradio_device *radio, char argument)
187 (void *) (radio->buffer), BUFFER_LENGTH, &size, USB_TIMEOUT); 188 (void *) (radio->buffer), BUFFER_LENGTH, &size, USB_TIMEOUT);
188 189
189 if (retval < 0 || size != BUFFER_LENGTH) { 190 if (retval < 0 || size != BUFFER_LENGTH) {
190 mutex_unlock(&radio->lock); 191 amradio_dev_warn(&radio->videodev.dev, "set mute failed\n");
191 return retval; 192 return retval;
192 } 193 }
193 194
194 radio->muted = argument; 195 radio->muted = argument;
195 196
196 mutex_unlock(&radio->lock);
197
198 return retval; 197 return retval;
199} 198}
200 199
@@ -205,11 +204,7 @@ static int amradio_setfreq(struct amradio_device *radio, int freq)
205 int size; 204 int size;
206 unsigned short freq_send = 0x10 + (freq >> 3) / 25; 205 unsigned short freq_send = 0x10 + (freq >> 3) / 25;
207 206
208 /* safety check */ 207 BUG_ON(!mutex_is_locked(&radio->lock));
209 if (radio->removed)
210 return -EIO;
211
212 mutex_lock(&radio->lock);
213 208
214 radio->buffer[0] = 0x00; 209 radio->buffer[0] = 0x00;
215 radio->buffer[1] = 0x55; 210 radio->buffer[1] = 0x55;
@@ -223,10 +218,8 @@ static int amradio_setfreq(struct amradio_device *radio, int freq)
223 retval = usb_bulk_msg(radio->usbdev, usb_sndintpipe(radio->usbdev, 2), 218 retval = usb_bulk_msg(radio->usbdev, usb_sndintpipe(radio->usbdev, 2),
224 (void *) (radio->buffer), BUFFER_LENGTH, &size, USB_TIMEOUT); 219 (void *) (radio->buffer), BUFFER_LENGTH, &size, USB_TIMEOUT);
225 220
226 if (retval < 0 || size != BUFFER_LENGTH) { 221 if (retval < 0 || size != BUFFER_LENGTH)
227 mutex_unlock(&radio->lock); 222 goto out_err;
228 return retval;
229 }
230 223
231 /* frequency is calculated from freq_send and placed in first 2 bytes */ 224 /* frequency is calculated from freq_send and placed in first 2 bytes */
232 radio->buffer[0] = (freq_send >> 8) & 0xff; 225 radio->buffer[0] = (freq_send >> 8) & 0xff;
@@ -240,13 +233,15 @@ static int amradio_setfreq(struct amradio_device *radio, int freq)
240 retval = usb_bulk_msg(radio->usbdev, usb_sndintpipe(radio->usbdev, 2), 233 retval = usb_bulk_msg(radio->usbdev, usb_sndintpipe(radio->usbdev, 2),
241 (void *) (radio->buffer), BUFFER_LENGTH, &size, USB_TIMEOUT); 234 (void *) (radio->buffer), BUFFER_LENGTH, &size, USB_TIMEOUT);
242 235
243 if (retval < 0 || size != BUFFER_LENGTH) { 236 if (retval < 0 || size != BUFFER_LENGTH)
244 mutex_unlock(&radio->lock); 237 goto out_err;
245 return retval;
246 }
247 238
248 mutex_unlock(&radio->lock); 239 radio->curfreq = freq;
240 goto out;
249 241
242out_err:
243 amradio_dev_warn(&radio->videodev.dev, "set frequency failed\n");
244out:
250 return retval; 245 return retval;
251} 246}
252 247
@@ -255,11 +250,7 @@ static int amradio_set_stereo(struct amradio_device *radio, char argument)
255 int retval; 250 int retval;
256 int size; 251 int size;
257 252
258 /* safety check */ 253 BUG_ON(!mutex_is_locked(&radio->lock));
259 if (radio->removed)
260 return -EIO;
261
262 mutex_lock(&radio->lock);
263 254
264 radio->buffer[0] = 0x00; 255 radio->buffer[0] = 0x00;
265 radio->buffer[1] = 0x55; 256 radio->buffer[1] = 0x55;
@@ -274,14 +265,14 @@ static int amradio_set_stereo(struct amradio_device *radio, char argument)
274 (void *) (radio->buffer), BUFFER_LENGTH, &size, USB_TIMEOUT); 265 (void *) (radio->buffer), BUFFER_LENGTH, &size, USB_TIMEOUT);
275 266
276 if (retval < 0 || size != BUFFER_LENGTH) { 267 if (retval < 0 || size != BUFFER_LENGTH) {
277 radio->stereo = -1; 268 amradio_dev_warn(&radio->videodev.dev, "set stereo failed\n");
278 mutex_unlock(&radio->lock);
279 return retval; 269 return retval;
280 } 270 }
281 271
282 radio->stereo = 1; 272 if (argument == WANT_STEREO)
283 273 radio->stereo = 1;
284 mutex_unlock(&radio->lock); 274 else
275 radio->stereo = 0;
285 276
286 return retval; 277 return retval;
287} 278}
@@ -296,19 +287,19 @@ static void usb_amradio_disconnect(struct usb_interface *intf)
296 struct amradio_device *radio = usb_get_intfdata(intf); 287 struct amradio_device *radio = usb_get_intfdata(intf);
297 288
298 mutex_lock(&radio->lock); 289 mutex_lock(&radio->lock);
299 radio->removed = 1; 290 radio->usbdev = NULL;
300 mutex_unlock(&radio->lock); 291 mutex_unlock(&radio->lock);
301 292
302 usb_set_intfdata(intf, NULL); 293 usb_set_intfdata(intf, NULL);
303 video_unregister_device(radio->videodev);
304 v4l2_device_disconnect(&radio->v4l2_dev); 294 v4l2_device_disconnect(&radio->v4l2_dev);
295 video_unregister_device(&radio->videodev);
305} 296}
306 297
307/* vidioc_querycap - query device capabilities */ 298/* vidioc_querycap - query device capabilities */
308static int vidioc_querycap(struct file *file, void *priv, 299static int vidioc_querycap(struct file *file, void *priv,
309 struct v4l2_capability *v) 300 struct v4l2_capability *v)
310{ 301{
311 struct amradio_device *radio = video_drvdata(file); 302 struct amradio_device *radio = file->private_data;
312 303
313 strlcpy(v->driver, "radio-mr800", sizeof(v->driver)); 304 strlcpy(v->driver, "radio-mr800", sizeof(v->driver));
314 strlcpy(v->card, "AverMedia MR 800 USB FM Radio", sizeof(v->card)); 305 strlcpy(v->card, "AverMedia MR 800 USB FM Radio", sizeof(v->card));
@@ -322,13 +313,9 @@ static int vidioc_querycap(struct file *file, void *priv,
322static int vidioc_g_tuner(struct file *file, void *priv, 313static int vidioc_g_tuner(struct file *file, void *priv,
323 struct v4l2_tuner *v) 314 struct v4l2_tuner *v)
324{ 315{
325 struct amradio_device *radio = video_get_drvdata(video_devdata(file)); 316 struct amradio_device *radio = file->private_data;
326 int retval; 317 int retval;
327 318
328 /* safety check */
329 if (radio->removed)
330 return -EIO;
331
332 if (v->index > 0) 319 if (v->index > 0)
333 return -EINVAL; 320 return -EINVAL;
334 321
@@ -341,9 +328,6 @@ static int vidioc_g_tuner(struct file *file, void *priv,
341 * amradio_set_stereo shouldn't be here 328 * amradio_set_stereo shouldn't be here
342 */ 329 */
343 retval = amradio_set_stereo(radio, WANT_STEREO); 330 retval = amradio_set_stereo(radio, WANT_STEREO);
344 if (retval < 0)
345 amradio_dev_warn(&radio->videodev->dev,
346 "set stereo failed\n");
347 331
348 strcpy(v->name, "FM"); 332 strcpy(v->name, "FM");
349 v->type = V4L2_TUNER_RADIO; 333 v->type = V4L2_TUNER_RADIO;
@@ -357,19 +341,16 @@ static int vidioc_g_tuner(struct file *file, void *priv,
357 v->audmode = V4L2_TUNER_MODE_MONO; 341 v->audmode = V4L2_TUNER_MODE_MONO;
358 v->signal = 0xffff; /* Can't get the signal strength, sad.. */ 342 v->signal = 0xffff; /* Can't get the signal strength, sad.. */
359 v->afc = 0; /* Don't know what is this */ 343 v->afc = 0; /* Don't know what is this */
360 return 0; 344
345 return retval;
361} 346}
362 347
363/* vidioc_s_tuner - set tuner attributes */ 348/* vidioc_s_tuner - set tuner attributes */
364static int vidioc_s_tuner(struct file *file, void *priv, 349static int vidioc_s_tuner(struct file *file, void *priv,
365 struct v4l2_tuner *v) 350 struct v4l2_tuner *v)
366{ 351{
367 struct amradio_device *radio = video_get_drvdata(video_devdata(file)); 352 struct amradio_device *radio = file->private_data;
368 int retval; 353 int retval = -EINVAL;
369
370 /* safety check */
371 if (radio->removed)
372 return -EIO;
373 354
374 if (v->index > 0) 355 if (v->index > 0)
375 return -EINVAL; 356 return -EINVAL;
@@ -378,57 +359,33 @@ static int vidioc_s_tuner(struct file *file, void *priv,
378 switch (v->audmode) { 359 switch (v->audmode) {
379 case V4L2_TUNER_MODE_MONO: 360 case V4L2_TUNER_MODE_MONO:
380 retval = amradio_set_stereo(radio, WANT_MONO); 361 retval = amradio_set_stereo(radio, WANT_MONO);
381 if (retval < 0)
382 amradio_dev_warn(&radio->videodev->dev,
383 "set mono failed\n");
384 break; 362 break;
385 case V4L2_TUNER_MODE_STEREO: 363 case V4L2_TUNER_MODE_STEREO:
386 retval = amradio_set_stereo(radio, WANT_STEREO); 364 retval = amradio_set_stereo(radio, WANT_STEREO);
387 if (retval < 0)
388 amradio_dev_warn(&radio->videodev->dev,
389 "set stereo failed\n");
390 break; 365 break;
391 default:
392 return -EINVAL;
393 } 366 }
394 367
395 return 0; 368 return retval;
396} 369}
397 370
398/* vidioc_s_frequency - set tuner radio frequency */ 371/* vidioc_s_frequency - set tuner radio frequency */
399static int vidioc_s_frequency(struct file *file, void *priv, 372static int vidioc_s_frequency(struct file *file, void *priv,
400 struct v4l2_frequency *f) 373 struct v4l2_frequency *f)
401{ 374{
402 struct amradio_device *radio = video_get_drvdata(video_devdata(file)); 375 struct amradio_device *radio = file->private_data;
403 int retval;
404 376
405 /* safety check */ 377 return amradio_setfreq(radio, f->frequency);
406 if (radio->removed)
407 return -EIO;
408
409 mutex_lock(&radio->lock);
410 radio->curfreq = f->frequency;
411 mutex_unlock(&radio->lock);
412
413 retval = amradio_setfreq(radio, radio->curfreq);
414 if (retval < 0)
415 amradio_dev_warn(&radio->videodev->dev,
416 "set frequency failed\n");
417 return 0;
418} 378}
419 379
420/* vidioc_g_frequency - get tuner radio frequency */ 380/* vidioc_g_frequency - get tuner radio frequency */
421static int vidioc_g_frequency(struct file *file, void *priv, 381static int vidioc_g_frequency(struct file *file, void *priv,
422 struct v4l2_frequency *f) 382 struct v4l2_frequency *f)
423{ 383{
424 struct amradio_device *radio = video_get_drvdata(video_devdata(file)); 384 struct amradio_device *radio = file->private_data;
425
426 /* safety check */
427 if (radio->removed)
428 return -EIO;
429 385
430 f->type = V4L2_TUNER_RADIO; 386 f->type = V4L2_TUNER_RADIO;
431 f->frequency = radio->curfreq; 387 f->frequency = radio->curfreq;
388
432 return 0; 389 return 0;
433} 390}
434 391
@@ -448,17 +405,14 @@ static int vidioc_queryctrl(struct file *file, void *priv,
448static int vidioc_g_ctrl(struct file *file, void *priv, 405static int vidioc_g_ctrl(struct file *file, void *priv,
449 struct v4l2_control *ctrl) 406 struct v4l2_control *ctrl)
450{ 407{
451 struct amradio_device *radio = video_get_drvdata(video_devdata(file)); 408 struct amradio_device *radio = file->private_data;
452
453 /* safety check */
454 if (radio->removed)
455 return -EIO;
456 409
457 switch (ctrl->id) { 410 switch (ctrl->id) {
458 case V4L2_CID_AUDIO_MUTE: 411 case V4L2_CID_AUDIO_MUTE:
459 ctrl->value = radio->muted; 412 ctrl->value = radio->muted;
460 return 0; 413 return 0;
461 } 414 }
415
462 return -EINVAL; 416 return -EINVAL;
463} 417}
464 418
@@ -466,33 +420,20 @@ static int vidioc_g_ctrl(struct file *file, void *priv,
466static int vidioc_s_ctrl(struct file *file, void *priv, 420static int vidioc_s_ctrl(struct file *file, void *priv,
467 struct v4l2_control *ctrl) 421 struct v4l2_control *ctrl)
468{ 422{
469 struct amradio_device *radio = video_get_drvdata(video_devdata(file)); 423 struct amradio_device *radio = file->private_data;
470 int retval; 424 int retval = -EINVAL;
471
472 /* safety check */
473 if (radio->removed)
474 return -EIO;
475 425
476 switch (ctrl->id) { 426 switch (ctrl->id) {
477 case V4L2_CID_AUDIO_MUTE: 427 case V4L2_CID_AUDIO_MUTE:
478 if (ctrl->value) { 428 if (ctrl->value)
479 retval = amradio_set_mute(radio, AMRADIO_STOP); 429 retval = amradio_set_mute(radio, AMRADIO_STOP);
480 if (retval < 0) { 430 else
481 amradio_dev_warn(&radio->videodev->dev,
482 "amradio_stop failed\n");
483 return -1;
484 }
485 } else {
486 retval = amradio_set_mute(radio, AMRADIO_START); 431 retval = amradio_set_mute(radio, AMRADIO_START);
487 if (retval < 0) { 432
488 amradio_dev_warn(&radio->videodev->dev, 433 break;
489 "amradio_start failed\n");
490 return -1;
491 }
492 }
493 return 0;
494 } 434 }
495 return -EINVAL; 435
436 return retval;
496} 437}
497 438
498/* vidioc_g_audio - get audio attributes */ 439/* vidioc_g_audio - get audio attributes */
@@ -531,75 +472,108 @@ static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
531 return 0; 472 return 0;
532} 473}
533 474
534/* open device - amradio_start() and amradio_setfreq() */ 475static int usb_amradio_init(struct amradio_device *radio)
535static int usb_amradio_open(struct file *file)
536{ 476{
537 struct amradio_device *radio = video_get_drvdata(video_devdata(file));
538 int retval; 477 int retval;
539 478
540 lock_kernel(); 479 retval = amradio_set_mute(radio, AMRADIO_STOP);
480 if (retval)
481 goto out_err;
541 482
542 radio->users = 1; 483 retval = amradio_set_stereo(radio, WANT_STEREO);
543 radio->muted = 1; 484 if (retval)
485 goto out_err;
544 486
545 retval = amradio_set_mute(radio, AMRADIO_START); 487 radio->initialized = 1;
546 if (retval < 0) { 488 goto out;
547 amradio_dev_warn(&radio->videodev->dev, 489
548 "radio did not start up properly\n"); 490out_err:
549 radio->users = 0; 491 amradio_dev_err(&radio->videodev.dev, "initialization failed\n");
550 unlock_kernel(); 492out:
551 return -EIO; 493 return retval;
494}
495
496/* open device - amradio_start() and amradio_setfreq() */
497static int usb_amradio_open(struct file *file)
498{
499 struct amradio_device *radio = vdev_to_amradio(video_devdata(file));
500 int retval = 0;
501
502 mutex_lock(&radio->lock);
503
504 if (!radio->usbdev) {
505 retval = -EIO;
506 goto unlock;
552 } 507 }
553 508
554 retval = amradio_set_stereo(radio, WANT_STEREO); 509 file->private_data = radio;
555 if (retval < 0) 510 retval = usb_autopm_get_interface(radio->intf);
556 amradio_dev_warn(&radio->videodev->dev, 511 if (retval)
557 "set stereo failed\n"); 512 goto unlock;
558 513
559 retval = amradio_setfreq(radio, radio->curfreq); 514 if (unlikely(!radio->initialized)) {
560 if (retval < 0) 515 retval = usb_amradio_init(radio);
561 amradio_dev_warn(&radio->videodev->dev, 516 if (retval)
562 "set frequency failed\n"); 517 usb_autopm_put_interface(radio->intf);
518 }
563 519
564 unlock_kernel(); 520unlock:
565 return 0; 521 mutex_unlock(&radio->lock);
522 return retval;
566} 523}
567 524
568/*close device */ 525/*close device */
569static int usb_amradio_close(struct file *file) 526static int usb_amradio_close(struct file *file)
570{ 527{
571 struct amradio_device *radio = video_get_drvdata(video_devdata(file)); 528 struct amradio_device *radio = file->private_data;
572 int retval; 529 int retval = 0;
573
574 if (!radio)
575 return -ENODEV;
576 530
577 mutex_lock(&radio->lock); 531 mutex_lock(&radio->lock);
578 radio->users = 0; 532
533 if (!radio->usbdev)
534 retval = -EIO;
535 else
536 usb_autopm_put_interface(radio->intf);
537
579 mutex_unlock(&radio->lock); 538 mutex_unlock(&radio->lock);
539 return retval;
540}
580 541
581 if (!radio->removed) { 542static long usb_amradio_ioctl(struct file *file, unsigned int cmd,
582 retval = amradio_set_mute(radio, AMRADIO_STOP); 543 unsigned long arg)
583 if (retval < 0) 544{
584 amradio_dev_warn(&radio->videodev->dev, 545 struct amradio_device *radio = file->private_data;
585 "amradio_stop failed\n"); 546 long retval = 0;
547
548 mutex_lock(&radio->lock);
549
550 if (!radio->usbdev) {
551 retval = -EIO;
552 goto unlock;
586 } 553 }
587 554
588 return 0; 555 retval = video_ioctl2(file, cmd, arg);
556
557unlock:
558 mutex_unlock(&radio->lock);
559 return retval;
589} 560}
590 561
591/* Suspend device - stop device. Need to be checked and fixed */ 562/* Suspend device - stop device. Need to be checked and fixed */
592static int usb_amradio_suspend(struct usb_interface *intf, pm_message_t message) 563static int usb_amradio_suspend(struct usb_interface *intf, pm_message_t message)
593{ 564{
594 struct amradio_device *radio = usb_get_intfdata(intf); 565 struct amradio_device *radio = usb_get_intfdata(intf);
595 int retval;
596 566
597 retval = amradio_set_mute(radio, AMRADIO_STOP); 567 mutex_lock(&radio->lock);
598 if (retval < 0) 568
599 dev_warn(&intf->dev, "amradio_stop failed\n"); 569 if (!radio->muted && radio->initialized) {
570 amradio_set_mute(radio, AMRADIO_STOP);
571 radio->muted = 0;
572 }
600 573
601 dev_info(&intf->dev, "going into suspend..\n"); 574 dev_info(&intf->dev, "going into suspend..\n");
602 575
576 mutex_unlock(&radio->lock);
603 return 0; 577 return 0;
604} 578}
605 579
@@ -607,14 +581,26 @@ static int usb_amradio_suspend(struct usb_interface *intf, pm_message_t message)
607static int usb_amradio_resume(struct usb_interface *intf) 581static int usb_amradio_resume(struct usb_interface *intf)
608{ 582{
609 struct amradio_device *radio = usb_get_intfdata(intf); 583 struct amradio_device *radio = usb_get_intfdata(intf);
610 int retval;
611 584
612 retval = amradio_set_mute(radio, AMRADIO_START); 585 mutex_lock(&radio->lock);
613 if (retval < 0) 586
614 dev_warn(&intf->dev, "amradio_start failed\n"); 587 if (unlikely(!radio->initialized))
588 goto unlock;
589
590 if (radio->stereo)
591 amradio_set_stereo(radio, WANT_STEREO);
592 else
593 amradio_set_stereo(radio, WANT_MONO);
594
595 amradio_setfreq(radio, radio->curfreq);
615 596
597 if (!radio->muted)
598 amradio_set_mute(radio, AMRADIO_START);
599
600unlock:
616 dev_info(&intf->dev, "coming out of suspend..\n"); 601 dev_info(&intf->dev, "coming out of suspend..\n");
617 602
603 mutex_unlock(&radio->lock);
618 return 0; 604 return 0;
619} 605}
620 606
@@ -623,7 +609,7 @@ static const struct v4l2_file_operations usb_amradio_fops = {
623 .owner = THIS_MODULE, 609 .owner = THIS_MODULE,
624 .open = usb_amradio_open, 610 .open = usb_amradio_open,
625 .release = usb_amradio_close, 611 .release = usb_amradio_close,
626 .ioctl = video_ioctl2, 612 .ioctl = usb_amradio_ioctl,
627}; 613};
628 614
629static const struct v4l2_ioctl_ops usb_amradio_ioctl_ops = { 615static const struct v4l2_ioctl_ops usb_amradio_ioctl_ops = {
@@ -643,10 +629,7 @@ static const struct v4l2_ioctl_ops usb_amradio_ioctl_ops = {
643 629
644static void usb_amradio_video_device_release(struct video_device *videodev) 630static void usb_amradio_video_device_release(struct video_device *videodev)
645{ 631{
646 struct amradio_device *radio = video_get_drvdata(videodev); 632 struct amradio_device *radio = vdev_to_amradio(videodev);
647
648 /* we call v4l to free radio->videodev */
649 video_device_release(videodev);
650 633
651 v4l2_device_unregister(&radio->v4l2_dev); 634 v4l2_device_unregister(&radio->v4l2_dev);
652 635
@@ -660,70 +643,63 @@ static int usb_amradio_probe(struct usb_interface *intf,
660 const struct usb_device_id *id) 643 const struct usb_device_id *id)
661{ 644{
662 struct amradio_device *radio; 645 struct amradio_device *radio;
663 struct v4l2_device *v4l2_dev; 646 int retval = 0;
664 int retval;
665 647
666 radio = kzalloc(sizeof(struct amradio_device), GFP_KERNEL); 648 radio = kzalloc(sizeof(struct amradio_device), GFP_KERNEL);
667 649
668 if (!radio) { 650 if (!radio) {
669 dev_err(&intf->dev, "kmalloc for amradio_device failed\n"); 651 dev_err(&intf->dev, "kmalloc for amradio_device failed\n");
670 return -ENOMEM; 652 retval = -ENOMEM;
653 goto err;
671 } 654 }
672 655
673 radio->buffer = kmalloc(BUFFER_LENGTH, GFP_KERNEL); 656 radio->buffer = kmalloc(BUFFER_LENGTH, GFP_KERNEL);
674 657
675 if (!radio->buffer) { 658 if (!radio->buffer) {
676 dev_err(&intf->dev, "kmalloc for radio->buffer failed\n"); 659 dev_err(&intf->dev, "kmalloc for radio->buffer failed\n");
677 kfree(radio); 660 retval = -ENOMEM;
678 return -ENOMEM; 661 goto err_nobuf;
679 } 662 }
680 663
681 v4l2_dev = &radio->v4l2_dev; 664 retval = v4l2_device_register(&intf->dev, &radio->v4l2_dev);
682 retval = v4l2_device_register(&intf->dev, v4l2_dev);
683 if (retval < 0) { 665 if (retval < 0) {
684 dev_err(&intf->dev, "couldn't register v4l2_device\n"); 666 dev_err(&intf->dev, "couldn't register v4l2_device\n");
685 kfree(radio->buffer); 667 goto err_v4l2;
686 kfree(radio);
687 return retval;
688 } 668 }
689 669
690 radio->videodev = video_device_alloc(); 670 strlcpy(radio->videodev.name, radio->v4l2_dev.name,
691 671 sizeof(radio->videodev.name));
692 if (!radio->videodev) { 672 radio->videodev.v4l2_dev = &radio->v4l2_dev;
693 dev_err(&intf->dev, "video_device_alloc failed\n"); 673 radio->videodev.fops = &usb_amradio_fops;
694 kfree(radio->buffer); 674 radio->videodev.ioctl_ops = &usb_amradio_ioctl_ops;
695 kfree(radio); 675 radio->videodev.release = usb_amradio_video_device_release;
696 return -ENOMEM;
697 }
698 676
699 strlcpy(radio->videodev->name, v4l2_dev->name, sizeof(radio->videodev->name));
700 radio->videodev->v4l2_dev = v4l2_dev;
701 radio->videodev->fops = &usb_amradio_fops;
702 radio->videodev->ioctl_ops = &usb_amradio_ioctl_ops;
703 radio->videodev->release = usb_amradio_video_device_release;
704
705 radio->removed = 0;
706 radio->users = 0;
707 radio->usbdev = interface_to_usbdev(intf); 677 radio->usbdev = interface_to_usbdev(intf);
678 radio->intf = intf;
708 radio->curfreq = 95.16 * FREQ_MUL; 679 radio->curfreq = 95.16 * FREQ_MUL;
709 radio->stereo = -1;
710 680
711 mutex_init(&radio->lock); 681 mutex_init(&radio->lock);
712 682
713 video_set_drvdata(radio->videodev, radio); 683 video_set_drvdata(&radio->videodev, radio);
714 684
715 retval = video_register_device(radio->videodev, VFL_TYPE_RADIO, radio_nr); 685 retval = video_register_device(&radio->videodev, VFL_TYPE_RADIO,
686 radio_nr);
716 if (retval < 0) { 687 if (retval < 0) {
717 dev_err(&intf->dev, "could not register video device\n"); 688 dev_err(&intf->dev, "could not register video device\n");
718 video_device_release(radio->videodev); 689 goto err_vdev;
719 v4l2_device_unregister(v4l2_dev);
720 kfree(radio->buffer);
721 kfree(radio);
722 return -EIO;
723 } 690 }
724 691
725 usb_set_intfdata(intf, radio); 692 usb_set_intfdata(intf, radio);
726 return 0; 693 return 0;
694
695err_vdev:
696 v4l2_device_unregister(&radio->v4l2_dev);
697err_v4l2:
698 kfree(radio->buffer);
699err_nobuf:
700 kfree(radio);
701err:
702 return retval;
727} 703}
728 704
729static int __init amradio_init(void) 705static int __init amradio_init(void)
diff --git a/drivers/media/radio/tef6862.c b/drivers/media/radio/tef6862.c
new file mode 100644
index 000000000000..6e607ff0c169
--- /dev/null
+++ b/drivers/media/radio/tef6862.c
@@ -0,0 +1,232 @@
1/*
2 * tef6862.c Philips TEF6862 Car Radio Enhanced Selectivity Tuner
3 * Copyright (c) 2009 Intel Corporation
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 */
18
19#include <linux/module.h>
20#include <linux/init.h>
21#include <linux/errno.h>
22#include <linux/kernel.h>
23#include <linux/interrupt.h>
24#include <linux/i2c.h>
25#include <linux/i2c-id.h>
26#include <media/v4l2-ioctl.h>
27#include <media/v4l2-device.h>
28#include <media/v4l2-chip-ident.h>
29
30#define DRIVER_NAME "tef6862"
31
32#define FREQ_MUL 16000
33
34#define TEF6862_LO_FREQ (875 * FREQ_MUL / 10)
35#define TEF6862_HI_FREQ (108 * FREQ_MUL)
36
37/* Write mode sub addresses */
38#define WM_SUB_BANDWIDTH 0x0
39#define WM_SUB_PLLM 0x1
40#define WM_SUB_PLLL 0x2
41#define WM_SUB_DAA 0x3
42#define WM_SUB_AGC 0x4
43#define WM_SUB_BAND 0x5
44#define WM_SUB_CONTROL 0x6
45#define WM_SUB_LEVEL 0x7
46#define WM_SUB_IFCF 0x8
47#define WM_SUB_IFCAP 0x9
48#define WM_SUB_ACD 0xA
49#define WM_SUB_TEST 0xF
50
51/* Different modes of the MSA register */
52#define MODE_BUFFER 0x0
53#define MODE_PRESET 0x1
54#define MODE_SEARCH 0x2
55#define MODE_AF_UPDATE 0x3
56#define MODE_JUMP 0x4
57#define MODE_CHECK 0x5
58#define MODE_LOAD 0x6
59#define MODE_END 0x7
60#define MODE_SHIFT 5
61
62struct tef6862_state {
63 struct v4l2_subdev sd;
64 unsigned long freq;
65};
66
67static inline struct tef6862_state *to_state(struct v4l2_subdev *sd)
68{
69 return container_of(sd, struct tef6862_state, sd);
70}
71
72static u16 tef6862_sigstr(struct i2c_client *client)
73{
74 u8 buf[4];
75 int err = i2c_master_recv(client, buf, sizeof(buf));
76 if (err == sizeof(buf))
77 return buf[3] << 8;
78 return 0;
79}
80
81static int tef6862_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *v)
82{
83 if (v->index > 0)
84 return -EINVAL;
85
86 /* only support FM for now */
87 strlcpy(v->name, "FM", sizeof(v->name));
88 v->type = V4L2_TUNER_RADIO;
89 v->rangelow = TEF6862_LO_FREQ;
90 v->rangehigh = TEF6862_HI_FREQ;
91 v->rxsubchans = V4L2_TUNER_SUB_MONO;
92 v->capability = V4L2_TUNER_CAP_LOW;
93 v->audmode = V4L2_TUNER_MODE_STEREO;
94 v->signal = tef6862_sigstr(v4l2_get_subdevdata(sd));
95
96 return 0;
97}
98
99static int tef6862_s_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *v)
100{
101 return v->index ? -EINVAL : 0;
102}
103
104static int tef6862_s_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *f)
105{
106 struct tef6862_state *state = to_state(sd);
107 struct i2c_client *client = v4l2_get_subdevdata(sd);
108 u16 pll;
109 u8 i2cmsg[3];
110 int err;
111
112 if (f->tuner != 0)
113 return -EINVAL;
114
115 pll = 1964 + ((f->frequency - TEF6862_LO_FREQ) * 20) / FREQ_MUL;
116 i2cmsg[0] = (MODE_PRESET << MODE_SHIFT) | WM_SUB_PLLM;
117 i2cmsg[1] = (pll >> 8) & 0xff;
118 i2cmsg[2] = pll & 0xff;
119
120 err = i2c_master_send(client, i2cmsg, sizeof(i2cmsg));
121 if (!err)
122 state->freq = f->frequency;
123 return err;
124}
125
126static int tef6862_g_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *f)
127{
128 struct tef6862_state *state = to_state(sd);
129
130 if (f->tuner != 0)
131 return -EINVAL;
132 f->type = V4L2_TUNER_RADIO;
133 f->frequency = state->freq;
134 return 0;
135}
136
137static int tef6862_g_chip_ident(struct v4l2_subdev *sd,
138 struct v4l2_dbg_chip_ident *chip)
139{
140 struct i2c_client *client = v4l2_get_subdevdata(sd);
141
142 return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_TEF6862, 0);
143}
144
145static const struct v4l2_subdev_tuner_ops tef6862_tuner_ops = {
146 .g_tuner = tef6862_g_tuner,
147 .s_tuner = tef6862_s_tuner,
148 .s_frequency = tef6862_s_frequency,
149 .g_frequency = tef6862_g_frequency,
150};
151
152static const struct v4l2_subdev_core_ops tef6862_core_ops = {
153 .g_chip_ident = tef6862_g_chip_ident,
154};
155
156static const struct v4l2_subdev_ops tef6862_ops = {
157 .core = &tef6862_core_ops,
158 .tuner = &tef6862_tuner_ops,
159};
160
161/*
162 * Generic i2c probe
163 * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
164 */
165
166static int __devinit tef6862_probe(struct i2c_client *client,
167 const struct i2c_device_id *id)
168{
169 struct tef6862_state *state;
170 struct v4l2_subdev *sd;
171
172 /* Check if the adapter supports the needed features */
173 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
174 return -EIO;
175
176 v4l_info(client, "chip found @ 0x%02x (%s)\n",
177 client->addr << 1, client->adapter->name);
178
179 state = kmalloc(sizeof(struct tef6862_state), GFP_KERNEL);
180 if (state == NULL)
181 return -ENOMEM;
182 state->freq = TEF6862_LO_FREQ;
183
184 sd = &state->sd;
185 v4l2_i2c_subdev_init(sd, client, &tef6862_ops);
186
187 return 0;
188}
189
190static int __devexit tef6862_remove(struct i2c_client *client)
191{
192 struct v4l2_subdev *sd = i2c_get_clientdata(client);
193
194 v4l2_device_unregister_subdev(sd);
195 kfree(to_state(sd));
196 return 0;
197}
198
199static const struct i2c_device_id tef6862_id[] = {
200 {DRIVER_NAME, 0},
201 {},
202};
203
204MODULE_DEVICE_TABLE(i2c, tef6862_id);
205
206static struct i2c_driver tef6862_driver = {
207 .driver = {
208 .owner = THIS_MODULE,
209 .name = DRIVER_NAME,
210 },
211 .probe = tef6862_probe,
212 .remove = tef6862_remove,
213 .id_table = tef6862_id,
214};
215
216static __init int tef6862_init(void)
217{
218 return i2c_add_driver(&tef6862_driver);
219}
220
221static __exit void tef6862_exit(void)
222{
223 i2c_del_driver(&tef6862_driver);
224}
225
226module_init(tef6862_init);
227module_exit(tef6862_exit);
228
229MODULE_DESCRIPTION("TEF6862 Car Radio Enhanced Selectivity Tuner");
230MODULE_AUTHOR("Mocean Laboratories");
231MODULE_LICENSE("GPL v2");
232
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index e6186b338a12..9dc74c93bf24 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -600,7 +600,7 @@ source "drivers/media/video/bt8xx/Kconfig"
600 600
601config VIDEO_PMS 601config VIDEO_PMS
602 tristate "Mediavision Pro Movie Studio Video For Linux" 602 tristate "Mediavision Pro Movie Studio Video For Linux"
603 depends on ISA && VIDEO_V4L1 603 depends on ISA && VIDEO_V4L2
604 help 604 help
605 Say Y if you have such a thing. 605 Say Y if you have such a thing.
606 606
@@ -847,6 +847,12 @@ config SOC_CAMERA_MT9V022
847 help 847 help
848 This driver supports MT9V022 cameras from Micron 848 This driver supports MT9V022 cameras from Micron
849 849
850config SOC_CAMERA_RJ54N1
851 tristate "rj54n1cb0c support"
852 depends on SOC_CAMERA && I2C
853 help
854 This is a rj54n1cb0c video driver
855
850config SOC_CAMERA_TW9910 856config SOC_CAMERA_TW9910
851 tristate "tw9910 support" 857 tristate "tw9910 support"
852 depends on SOC_CAMERA && I2C 858 depends on SOC_CAMERA && I2C
@@ -865,6 +871,12 @@ config SOC_CAMERA_OV772X
865 help 871 help
866 This is a ov772x camera driver 872 This is a ov772x camera driver
867 873
874config SOC_CAMERA_OV9640
875 tristate "ov9640 camera support"
876 depends on SOC_CAMERA && I2C
877 help
878 This is a ov9640 camera driver
879
868config MX1_VIDEO 880config MX1_VIDEO
869 bool 881 bool
870 882
@@ -939,9 +951,14 @@ source "drivers/media/video/usbvideo/Kconfig"
939source "drivers/media/video/et61x251/Kconfig" 951source "drivers/media/video/et61x251/Kconfig"
940 952
941config VIDEO_OVCAMCHIP 953config VIDEO_OVCAMCHIP
942 tristate "OmniVision Camera Chip support" 954 tristate "OmniVision Camera Chip support (DEPRECATED)"
943 depends on I2C && VIDEO_V4L1 955 depends on I2C && VIDEO_V4L1
944 ---help--- 956 ---help---
957 This driver is DEPRECATED please use the gspca ov519 module
958 instead. Note that for the ov511 / ov518 support of the gspca module
959 you need atleast version 0.6.0 of libv4l and for the w9968cf
960 atleast version 0.6.3 of libv4l.
961
945 Support for the OmniVision OV6xxx and OV7xxx series of camera chips. 962 Support for the OmniVision OV6xxx and OV7xxx series of camera chips.
946 This driver is intended to be used with the ov511 and w9968cf USB 963 This driver is intended to be used with the ov511 and w9968cf USB
947 camera drivers. 964 camera drivers.
@@ -950,9 +967,13 @@ config VIDEO_OVCAMCHIP
950 module will be called ovcamchip. 967 module will be called ovcamchip.
951 968
952config USB_W9968CF 969config USB_W9968CF
953 tristate "USB W996[87]CF JPEG Dual Mode Camera support" 970 tristate "USB W996[87]CF JPEG Dual Mode Camera support (DEPRECATED)"
954 depends on VIDEO_V4L1 && I2C && VIDEO_OVCAMCHIP 971 depends on VIDEO_V4L1 && I2C && VIDEO_OVCAMCHIP
955 ---help--- 972 ---help---
973 This driver is DEPRECATED please use the gspca ov519 module
974 instead. Note that for the w9968cf support of the gspca module
975 you need atleast version 0.6.3 of libv4l.
976
956 Say Y here if you want support for cameras based on OV681 or 977 Say Y here if you want support for cameras based on OV681 or
957 Winbond W9967CF/W9968CF JPEG USB Dual Mode Camera Chips. 978 Winbond W9967CF/W9968CF JPEG USB Dual Mode Camera Chips.
958 979
@@ -995,9 +1016,13 @@ config USB_SE401
995source "drivers/media/video/sn9c102/Kconfig" 1016source "drivers/media/video/sn9c102/Kconfig"
996 1017
997config USB_STV680 1018config USB_STV680
998 tristate "USB STV680 (Pencam) Camera support" 1019 tristate "USB STV680 (Pencam) Camera support (DEPRECATED)"
999 depends on VIDEO_V4L1 1020 depends on VIDEO_V4L1
1000 ---help--- 1021 ---help---
1022 This driver is DEPRECATED please use the gspca stv0680 module
1023 instead. Note that for the gspca stv0680 module you need
1024 atleast version 0.6.3 of libv4l.
1025
1001 Say Y here if you want to connect this type of camera to your 1026 Say Y here if you want to connect this type of camera to your
1002 computer's USB port. This includes the Pencam line of cameras. 1027 computer's USB port. This includes the Pencam line of cameras.
1003 See <file:Documentation/video4linux/stv680.txt> for more information 1028 See <file:Documentation/video4linux/stv680.txt> for more information
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
index e541932a789b..7a2dcc34111c 100644
--- a/drivers/media/video/Makefile
+++ b/drivers/media/video/Makefile
@@ -77,6 +77,8 @@ obj-$(CONFIG_SOC_CAMERA_MT9M111) += mt9m111.o
77obj-$(CONFIG_SOC_CAMERA_MT9T031) += mt9t031.o 77obj-$(CONFIG_SOC_CAMERA_MT9T031) += mt9t031.o
78obj-$(CONFIG_SOC_CAMERA_MT9V022) += mt9v022.o 78obj-$(CONFIG_SOC_CAMERA_MT9V022) += mt9v022.o
79obj-$(CONFIG_SOC_CAMERA_OV772X) += ov772x.o 79obj-$(CONFIG_SOC_CAMERA_OV772X) += ov772x.o
80obj-$(CONFIG_SOC_CAMERA_OV9640) += ov9640.o
81obj-$(CONFIG_SOC_CAMERA_RJ54N1) += rj54n1cb0c.o
80obj-$(CONFIG_SOC_CAMERA_TW9910) += tw9910.o 82obj-$(CONFIG_SOC_CAMERA_TW9910) += tw9910.o
81 83
82# And now the v4l2 drivers: 84# And now the v4l2 drivers:
diff --git a/drivers/media/video/adv7180.c b/drivers/media/video/adv7180.c
index 1b3cbd02a7fd..0826f0dabc17 100644
--- a/drivers/media/video/adv7180.c
+++ b/drivers/media/video/adv7180.c
@@ -27,17 +27,40 @@
27#include <linux/videodev2.h> 27#include <linux/videodev2.h>
28#include <media/v4l2-device.h> 28#include <media/v4l2-device.h>
29#include <media/v4l2-chip-ident.h> 29#include <media/v4l2-chip-ident.h>
30#include <linux/mutex.h>
30 31
31#define DRIVER_NAME "adv7180" 32#define DRIVER_NAME "adv7180"
32 33
33#define ADV7180_INPUT_CONTROL_REG 0x00 34#define ADV7180_INPUT_CONTROL_REG 0x00
34#define ADV7180_INPUT_CONTROL_PAL_BG_NTSC_J_SECAM 0x00 35#define ADV7180_INPUT_CONTROL_AD_PAL_BG_NTSC_J_SECAM 0x00
35#define ADV7180_AUTODETECT_ENABLE_REG 0x07 36#define ADV7180_INPUT_CONTROL_AD_PAL_BG_NTSC_J_SECAM_PED 0x10
36#define ADV7180_AUTODETECT_DEFAULT 0x7f 37#define ADV7180_INPUT_CONTROL_AD_PAL_N_NTSC_J_SECAM 0x20
37 38#define ADV7180_INPUT_CONTROL_AD_PAL_N_NTSC_M_SECAM 0x30
38 39#define ADV7180_INPUT_CONTROL_NTSC_J 0x40
39#define ADV7180_STATUS1_REG 0x10 40#define ADV7180_INPUT_CONTROL_NTSC_M 0x50
40#define ADV7180_STATUS1_AUTOD_MASK 0x70 41#define ADV7180_INPUT_CONTROL_PAL60 0x60
42#define ADV7180_INPUT_CONTROL_NTSC_443 0x70
43#define ADV7180_INPUT_CONTROL_PAL_BG 0x80
44#define ADV7180_INPUT_CONTROL_PAL_N 0x90
45#define ADV7180_INPUT_CONTROL_PAL_M 0xa0
46#define ADV7180_INPUT_CONTROL_PAL_M_PED 0xb0
47#define ADV7180_INPUT_CONTROL_PAL_COMB_N 0xc0
48#define ADV7180_INPUT_CONTROL_PAL_COMB_N_PED 0xd0
49#define ADV7180_INPUT_CONTROL_PAL_SECAM 0xe0
50#define ADV7180_INPUT_CONTROL_PAL_SECAM_PED 0xf0
51
52#define ADV7180_EXTENDED_OUTPUT_CONTROL_REG 0x04
53#define ADV7180_EXTENDED_OUTPUT_CONTROL_NTSCDIS 0xC5
54
55#define ADV7180_AUTODETECT_ENABLE_REG 0x07
56#define ADV7180_AUTODETECT_DEFAULT 0x7f
57
58#define ADV7180_ADI_CTRL_REG 0x0e
59#define ADV7180_ADI_CTRL_IRQ_SPACE 0x20
60
61#define ADV7180_STATUS1_REG 0x10
62#define ADV7180_STATUS1_IN_LOCK 0x01
63#define ADV7180_STATUS1_AUTOD_MASK 0x70
41#define ADV7180_STATUS1_AUTOD_NTSM_M_J 0x00 64#define ADV7180_STATUS1_AUTOD_NTSM_M_J 0x00
42#define ADV7180_STATUS1_AUTOD_NTSC_4_43 0x10 65#define ADV7180_STATUS1_AUTOD_NTSC_4_43 0x10
43#define ADV7180_STATUS1_AUTOD_PAL_M 0x20 66#define ADV7180_STATUS1_AUTOD_PAL_M 0x20
@@ -50,18 +73,37 @@
50#define ADV7180_IDENT_REG 0x11 73#define ADV7180_IDENT_REG 0x11
51#define ADV7180_ID_7180 0x18 74#define ADV7180_ID_7180 0x18
52 75
76#define ADV7180_ICONF1_ADI 0x40
77#define ADV7180_ICONF1_ACTIVE_LOW 0x01
78#define ADV7180_ICONF1_PSYNC_ONLY 0x10
79#define ADV7180_ICONF1_ACTIVE_TO_CLR 0xC0
80
81#define ADV7180_IRQ1_LOCK 0x01
82#define ADV7180_IRQ1_UNLOCK 0x02
83#define ADV7180_ISR1_ADI 0x42
84#define ADV7180_ICR1_ADI 0x43
85#define ADV7180_IMR1_ADI 0x44
86#define ADV7180_IMR2_ADI 0x48
87#define ADV7180_IRQ3_AD_CHANGE 0x08
88#define ADV7180_ISR3_ADI 0x4A
89#define ADV7180_ICR3_ADI 0x4B
90#define ADV7180_IMR3_ADI 0x4C
91#define ADV7180_IMR4_ADI 0x50
53 92
54struct adv7180_state { 93struct adv7180_state {
55 struct v4l2_subdev sd; 94 struct v4l2_subdev sd;
95 struct work_struct work;
96 struct mutex mutex; /* mutual excl. when accessing chip */
97 int irq;
98 v4l2_std_id curr_norm;
99 bool autodetect;
56}; 100};
57 101
58static v4l2_std_id determine_norm(struct i2c_client *client) 102static v4l2_std_id adv7180_std_to_v4l2(u8 status1)
59{ 103{
60 u8 status1 = i2c_smbus_read_byte_data(client, ADV7180_STATUS1_REG);
61
62 switch (status1 & ADV7180_STATUS1_AUTOD_MASK) { 104 switch (status1 & ADV7180_STATUS1_AUTOD_MASK) {
63 case ADV7180_STATUS1_AUTOD_NTSM_M_J: 105 case ADV7180_STATUS1_AUTOD_NTSM_M_J:
64 return V4L2_STD_NTSC_M_JP; 106 return V4L2_STD_NTSC;
65 case ADV7180_STATUS1_AUTOD_NTSC_4_43: 107 case ADV7180_STATUS1_AUTOD_NTSC_4_43:
66 return V4L2_STD_NTSC_443; 108 return V4L2_STD_NTSC_443;
67 case ADV7180_STATUS1_AUTOD_PAL_M: 109 case ADV7180_STATUS1_AUTOD_PAL_M:
@@ -81,6 +123,53 @@ static v4l2_std_id determine_norm(struct i2c_client *client)
81 } 123 }
82} 124}
83 125
126static int v4l2_std_to_adv7180(v4l2_std_id std)
127{
128 if (std == V4L2_STD_PAL_60)
129 return ADV7180_INPUT_CONTROL_PAL60;
130 if (std == V4L2_STD_NTSC_443)
131 return ADV7180_INPUT_CONTROL_NTSC_443;
132 if (std == V4L2_STD_PAL_N)
133 return ADV7180_INPUT_CONTROL_PAL_N;
134 if (std == V4L2_STD_PAL_M)
135 return ADV7180_INPUT_CONTROL_PAL_M;
136 if (std == V4L2_STD_PAL_Nc)
137 return ADV7180_INPUT_CONTROL_PAL_COMB_N;
138
139 if (std & V4L2_STD_PAL)
140 return ADV7180_INPUT_CONTROL_PAL_BG;
141 if (std & V4L2_STD_NTSC)
142 return ADV7180_INPUT_CONTROL_NTSC_M;
143 if (std & V4L2_STD_SECAM)
144 return ADV7180_INPUT_CONTROL_PAL_SECAM;
145
146 return -EINVAL;
147}
148
149static u32 adv7180_status_to_v4l2(u8 status1)
150{
151 if (!(status1 & ADV7180_STATUS1_IN_LOCK))
152 return V4L2_IN_ST_NO_SIGNAL;
153
154 return 0;
155}
156
157static int __adv7180_status(struct i2c_client *client, u32 *status,
158 v4l2_std_id *std)
159{
160 int status1 = i2c_smbus_read_byte_data(client, ADV7180_STATUS1_REG);
161
162 if (status1 < 0)
163 return status1;
164
165 if (status)
166 *status = adv7180_status_to_v4l2(status1);
167 if (std)
168 *std = adv7180_std_to_v4l2(status1);
169
170 return 0;
171}
172
84static inline struct adv7180_state *to_state(struct v4l2_subdev *sd) 173static inline struct adv7180_state *to_state(struct v4l2_subdev *sd)
85{ 174{
86 return container_of(sd, struct adv7180_state, sd); 175 return container_of(sd, struct adv7180_state, sd);
@@ -88,10 +177,31 @@ static inline struct adv7180_state *to_state(struct v4l2_subdev *sd)
88 177
89static int adv7180_querystd(struct v4l2_subdev *sd, v4l2_std_id *std) 178static int adv7180_querystd(struct v4l2_subdev *sd, v4l2_std_id *std)
90{ 179{
91 struct i2c_client *client = v4l2_get_subdevdata(sd); 180 struct adv7180_state *state = to_state(sd);
181 int err = mutex_lock_interruptible(&state->mutex);
182 if (err)
183 return err;
184
185 /* when we are interrupt driven we know the state */
186 if (!state->autodetect || state->irq > 0)
187 *std = state->curr_norm;
188 else
189 err = __adv7180_status(v4l2_get_subdevdata(sd), NULL, std);
190
191 mutex_unlock(&state->mutex);
192 return err;
193}
92 194
93 *std = determine_norm(client); 195static int adv7180_g_input_status(struct v4l2_subdev *sd, u32 *status)
94 return 0; 196{
197 struct adv7180_state *state = to_state(sd);
198 int ret = mutex_lock_interruptible(&state->mutex);
199 if (ret)
200 return ret;
201
202 ret = __adv7180_status(v4l2_get_subdevdata(sd), status, NULL);
203 mutex_unlock(&state->mutex);
204 return ret;
95} 205}
96 206
97static int adv7180_g_chip_ident(struct v4l2_subdev *sd, 207static int adv7180_g_chip_ident(struct v4l2_subdev *sd,
@@ -102,12 +212,51 @@ static int adv7180_g_chip_ident(struct v4l2_subdev *sd,
102 return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_ADV7180, 0); 212 return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_ADV7180, 0);
103} 213}
104 214
215static int adv7180_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
216{
217 struct adv7180_state *state = to_state(sd);
218 struct i2c_client *client = v4l2_get_subdevdata(sd);
219 int ret = mutex_lock_interruptible(&state->mutex);
220 if (ret)
221 return ret;
222
223 /* all standards -> autodetect */
224 if (std == V4L2_STD_ALL) {
225 ret = i2c_smbus_write_byte_data(client,
226 ADV7180_INPUT_CONTROL_REG,
227 ADV7180_INPUT_CONTROL_AD_PAL_BG_NTSC_J_SECAM);
228 if (ret < 0)
229 goto out;
230
231 __adv7180_status(client, NULL, &state->curr_norm);
232 state->autodetect = true;
233 } else {
234 ret = v4l2_std_to_adv7180(std);
235 if (ret < 0)
236 goto out;
237
238 ret = i2c_smbus_write_byte_data(client,
239 ADV7180_INPUT_CONTROL_REG, ret);
240 if (ret < 0)
241 goto out;
242
243 state->curr_norm = std;
244 state->autodetect = false;
245 }
246 ret = 0;
247out:
248 mutex_unlock(&state->mutex);
249 return ret;
250}
251
105static const struct v4l2_subdev_video_ops adv7180_video_ops = { 252static const struct v4l2_subdev_video_ops adv7180_video_ops = {
106 .querystd = adv7180_querystd, 253 .querystd = adv7180_querystd,
254 .g_input_status = adv7180_g_input_status,
107}; 255};
108 256
109static const struct v4l2_subdev_core_ops adv7180_core_ops = { 257static const struct v4l2_subdev_core_ops adv7180_core_ops = {
110 .g_chip_ident = adv7180_g_chip_ident, 258 .g_chip_ident = adv7180_g_chip_ident,
259 .s_std = adv7180_s_std,
111}; 260};
112 261
113static const struct v4l2_subdev_ops adv7180_ops = { 262static const struct v4l2_subdev_ops adv7180_ops = {
@@ -115,12 +264,45 @@ static const struct v4l2_subdev_ops adv7180_ops = {
115 .video = &adv7180_video_ops, 264 .video = &adv7180_video_ops,
116}; 265};
117 266
267static void adv7180_work(struct work_struct *work)
268{
269 struct adv7180_state *state = container_of(work, struct adv7180_state,
270 work);
271 struct i2c_client *client = v4l2_get_subdevdata(&state->sd);
272 u8 isr3;
273
274 mutex_lock(&state->mutex);
275 i2c_smbus_write_byte_data(client, ADV7180_ADI_CTRL_REG,
276 ADV7180_ADI_CTRL_IRQ_SPACE);
277 isr3 = i2c_smbus_read_byte_data(client, ADV7180_ISR3_ADI);
278 /* clear */
279 i2c_smbus_write_byte_data(client, ADV7180_ICR3_ADI, isr3);
280 i2c_smbus_write_byte_data(client, ADV7180_ADI_CTRL_REG, 0);
281
282 if (isr3 & ADV7180_IRQ3_AD_CHANGE && state->autodetect)
283 __adv7180_status(client, NULL, &state->curr_norm);
284 mutex_unlock(&state->mutex);
285
286 enable_irq(state->irq);
287}
288
289static irqreturn_t adv7180_irq(int irq, void *devid)
290{
291 struct adv7180_state *state = devid;
292
293 schedule_work(&state->work);
294
295 disable_irq_nosync(state->irq);
296
297 return IRQ_HANDLED;
298}
299
118/* 300/*
119 * Generic i2c probe 301 * Generic i2c probe
120 * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1' 302 * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
121 */ 303 */
122 304
123static int adv7180_probe(struct i2c_client *client, 305static __devinit int adv7180_probe(struct i2c_client *client,
124 const struct i2c_device_id *id) 306 const struct i2c_device_id *id)
125{ 307{
126 struct adv7180_state *state; 308 struct adv7180_state *state;
@@ -135,32 +317,111 @@ static int adv7180_probe(struct i2c_client *client,
135 client->addr << 1, client->adapter->name); 317 client->addr << 1, client->adapter->name);
136 318
137 state = kzalloc(sizeof(struct adv7180_state), GFP_KERNEL); 319 state = kzalloc(sizeof(struct adv7180_state), GFP_KERNEL);
138 if (state == NULL) 320 if (state == NULL) {
139 return -ENOMEM; 321 ret = -ENOMEM;
322 goto err;
323 }
324
325 state->irq = client->irq;
326 INIT_WORK(&state->work, adv7180_work);
327 mutex_init(&state->mutex);
328 state->autodetect = true;
140 sd = &state->sd; 329 sd = &state->sd;
141 v4l2_i2c_subdev_init(sd, client, &adv7180_ops); 330 v4l2_i2c_subdev_init(sd, client, &adv7180_ops);
142 331
143 /* Initialize adv7180 */ 332 /* Initialize adv7180 */
144 /* enable autodetection */ 333 /* Enable autodetection */
145 ret = i2c_smbus_write_byte_data(client, ADV7180_INPUT_CONTROL_REG, 334 ret = i2c_smbus_write_byte_data(client, ADV7180_INPUT_CONTROL_REG,
146 ADV7180_INPUT_CONTROL_PAL_BG_NTSC_J_SECAM); 335 ADV7180_INPUT_CONTROL_AD_PAL_BG_NTSC_J_SECAM);
147 if (ret > 0) 336 if (ret < 0)
148 ret = i2c_smbus_write_byte_data(client, 337 goto err_unreg_subdev;
149 ADV7180_AUTODETECT_ENABLE_REG, 338
150 ADV7180_AUTODETECT_DEFAULT); 339 ret = i2c_smbus_write_byte_data(client, ADV7180_AUTODETECT_ENABLE_REG,
151 if (ret < 0) { 340 ADV7180_AUTODETECT_DEFAULT);
152 printk(KERN_ERR DRIVER_NAME 341 if (ret < 0)
153 ": Failed to communicate to chip: %d\n", ret); 342 goto err_unreg_subdev;
154 return ret; 343
344 /* ITU-R BT.656-4 compatible */
345 ret = i2c_smbus_write_byte_data(client,
346 ADV7180_EXTENDED_OUTPUT_CONTROL_REG,
347 ADV7180_EXTENDED_OUTPUT_CONTROL_NTSCDIS);
348 if (ret < 0)
349 goto err_unreg_subdev;
350
351 /* read current norm */
352 __adv7180_status(client, NULL, &state->curr_norm);
353
354 /* register for interrupts */
355 if (state->irq > 0) {
356 ret = request_irq(state->irq, adv7180_irq, 0, DRIVER_NAME,
357 state);
358 if (ret)
359 goto err_unreg_subdev;
360
361 ret = i2c_smbus_write_byte_data(client, ADV7180_ADI_CTRL_REG,
362 ADV7180_ADI_CTRL_IRQ_SPACE);
363 if (ret < 0)
364 goto err_unreg_subdev;
365
366 /* config the Interrupt pin to be active low */
367 ret = i2c_smbus_write_byte_data(client, ADV7180_ICONF1_ADI,
368 ADV7180_ICONF1_ACTIVE_LOW | ADV7180_ICONF1_PSYNC_ONLY);
369 if (ret < 0)
370 goto err_unreg_subdev;
371
372 ret = i2c_smbus_write_byte_data(client, ADV7180_IMR1_ADI, 0);
373 if (ret < 0)
374 goto err_unreg_subdev;
375
376 ret = i2c_smbus_write_byte_data(client, ADV7180_IMR2_ADI, 0);
377 if (ret < 0)
378 goto err_unreg_subdev;
379
380 /* enable AD change interrupts interrupts */
381 ret = i2c_smbus_write_byte_data(client, ADV7180_IMR3_ADI,
382 ADV7180_IRQ3_AD_CHANGE);
383 if (ret < 0)
384 goto err_unreg_subdev;
385
386 ret = i2c_smbus_write_byte_data(client, ADV7180_IMR4_ADI, 0);
387 if (ret < 0)
388 goto err_unreg_subdev;
389
390 ret = i2c_smbus_write_byte_data(client, ADV7180_ADI_CTRL_REG,
391 0);
392 if (ret < 0)
393 goto err_unreg_subdev;
155 } 394 }
156 395
157 return 0; 396 return 0;
397
398err_unreg_subdev:
399 mutex_destroy(&state->mutex);
400 v4l2_device_unregister_subdev(sd);
401 kfree(state);
402err:
403 printk(KERN_ERR DRIVER_NAME ": Failed to probe: %d\n", ret);
404 return ret;
158} 405}
159 406
160static int adv7180_remove(struct i2c_client *client) 407static __devexit int adv7180_remove(struct i2c_client *client)
161{ 408{
162 struct v4l2_subdev *sd = i2c_get_clientdata(client); 409 struct v4l2_subdev *sd = i2c_get_clientdata(client);
410 struct adv7180_state *state = to_state(sd);
411
412 if (state->irq > 0) {
413 free_irq(client->irq, state);
414 if (cancel_work_sync(&state->work)) {
415 /*
416 * Work was pending, therefore we need to enable
417 * IRQ here to balance the disable_irq() done in the
418 * interrupt handler.
419 */
420 enable_irq(state->irq);
421 }
422 }
163 423
424 mutex_destroy(&state->mutex);
164 v4l2_device_unregister_subdev(sd); 425 v4l2_device_unregister_subdev(sd);
165 kfree(to_state(sd)); 426 kfree(to_state(sd));
166 return 0; 427 return 0;
@@ -179,7 +440,7 @@ static struct i2c_driver adv7180_driver = {
179 .name = DRIVER_NAME, 440 .name = DRIVER_NAME,
180 }, 441 },
181 .probe = adv7180_probe, 442 .probe = adv7180_probe,
182 .remove = adv7180_remove, 443 .remove = __devexit_p(adv7180_remove),
183 .id_table = adv7180_id, 444 .id_table = adv7180_id,
184}; 445};
185 446
diff --git a/drivers/media/video/au0828/au0828-video.c b/drivers/media/video/au0828/au0828-video.c
index 51527d7b55a7..1485aee18d58 100644
--- a/drivers/media/video/au0828/au0828-video.c
+++ b/drivers/media/video/au0828/au0828-video.c
@@ -830,7 +830,7 @@ static int au0828_v4l2_close(struct file *filp)
830 au0828_uninit_isoc(dev); 830 au0828_uninit_isoc(dev);
831 831
832 /* Save some power by putting tuner to sleep */ 832 /* Save some power by putting tuner to sleep */
833 v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_standby); 833 v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_power, 0);
834 834
835 /* When close the device, set the usb intf0 into alt0 to free 835 /* When close the device, set the usb intf0 into alt0 to free
836 USB bandwidth */ 836 USB bandwidth */
diff --git a/drivers/media/video/bt819.c b/drivers/media/video/bt819.c
index f9330e3529c3..5bb0f9e71583 100644
--- a/drivers/media/video/bt819.c
+++ b/drivers/media/video/bt819.c
@@ -299,7 +299,7 @@ static int bt819_s_routing(struct v4l2_subdev *sd,
299 299
300 v4l2_dbg(1, debug, sd, "set input %x\n", input); 300 v4l2_dbg(1, debug, sd, "set input %x\n", input);
301 301
302 if (input < 0 || input > 7) 302 if (input > 7)
303 return -EINVAL; 303 return -EINVAL;
304 304
305 if (sd->v4l2_dev == NULL || sd->v4l2_dev->notify == NULL) 305 if (sd->v4l2_dev == NULL || sd->v4l2_dev->notify == NULL)
diff --git a/drivers/media/video/bt8xx/bttv-input.c b/drivers/media/video/bt8xx/bttv-input.c
index ebd51afe8761..84a957e52c4b 100644
--- a/drivers/media/video/bt8xx/bttv-input.c
+++ b/drivers/media/video/bt8xx/bttv-input.c
@@ -73,12 +73,12 @@ static void ir_handle_key(struct bttv *btv)
73 73
74 if ((ir->mask_keydown && (0 != (gpio & ir->mask_keydown))) || 74 if ((ir->mask_keydown && (0 != (gpio & ir->mask_keydown))) ||
75 (ir->mask_keyup && (0 == (gpio & ir->mask_keyup)))) { 75 (ir->mask_keyup && (0 == (gpio & ir->mask_keyup)))) {
76 ir_input_keydown(ir->dev,&ir->ir,data,data); 76 ir_input_keydown(ir->dev, &ir->ir, data);
77 } else { 77 } else {
78 /* HACK: Probably, ir->mask_keydown is missing 78 /* HACK: Probably, ir->mask_keydown is missing
79 for this board */ 79 for this board */
80 if (btv->c.type == BTTV_BOARD_WINFAST2000) 80 if (btv->c.type == BTTV_BOARD_WINFAST2000)
81 ir_input_keydown(ir->dev, &ir->ir, data, data); 81 ir_input_keydown(ir->dev, &ir->ir, data);
82 82
83 ir_input_nokey(ir->dev,&ir->ir); 83 ir_input_nokey(ir->dev,&ir->ir);
84 } 84 }
@@ -104,7 +104,7 @@ static void ir_enltv_handle_key(struct bttv *btv)
104 gpio, data, 104 gpio, data,
105 (gpio & ir->mask_keyup) ? " up" : "up/down"); 105 (gpio & ir->mask_keyup) ? " up" : "up/down");
106 106
107 ir_input_keydown(ir->dev, &ir->ir, data, data); 107 ir_input_keydown(ir->dev, &ir->ir, data);
108 if (keyup) 108 if (keyup)
109 ir_input_nokey(ir->dev, &ir->ir); 109 ir_input_nokey(ir->dev, &ir->ir);
110 } else { 110 } else {
@@ -118,7 +118,7 @@ static void ir_enltv_handle_key(struct bttv *btv)
118 if (keyup) 118 if (keyup)
119 ir_input_nokey(ir->dev, &ir->ir); 119 ir_input_nokey(ir->dev, &ir->ir);
120 else 120 else
121 ir_input_keydown(ir->dev, &ir->ir, data, data); 121 ir_input_keydown(ir->dev, &ir->ir, data);
122 } 122 }
123 123
124 ir->last_gpio = data | keyup; 124 ir->last_gpio = data | keyup;
@@ -368,7 +368,10 @@ int bttv_input_init(struct bttv *btv)
368 snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0", 368 snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0",
369 pci_name(btv->c.pci)); 369 pci_name(btv->c.pci));
370 370
371 ir_input_init(input_dev, &ir->ir, ir_type, ir_codes); 371 err = ir_input_init(input_dev, &ir->ir, ir_type, ir_codes);
372 if (err < 0)
373 goto err_out_free;
374
372 input_dev->name = ir->name; 375 input_dev->name = ir->name;
373 input_dev->phys = ir->phys; 376 input_dev->phys = ir->phys;
374 input_dev->id.bustype = BUS_PCI; 377 input_dev->id.bustype = BUS_PCI;
@@ -400,6 +403,7 @@ int bttv_input_init(struct bttv *btv)
400 bttv_ir_stop(btv); 403 bttv_ir_stop(btv);
401 btv->remote = NULL; 404 btv->remote = NULL;
402 err_out_free: 405 err_out_free:
406 ir_input_free(input_dev);
403 input_free_device(input_dev); 407 input_free_device(input_dev);
404 kfree(ir); 408 kfree(ir);
405 return err; 409 return err;
@@ -411,6 +415,7 @@ void bttv_input_fini(struct bttv *btv)
411 return; 415 return;
412 416
413 bttv_ir_stop(btv); 417 bttv_ir_stop(btv);
418 ir_input_free(btv->remote->dev);
414 input_unregister_device(btv->remote->dev); 419 input_unregister_device(btv->remote->dev);
415 kfree(btv->remote); 420 kfree(btv->remote);
416 btv->remote = NULL; 421 btv->remote = NULL;
diff --git a/drivers/media/video/cx18/cx18-av-core.c b/drivers/media/video/cx18/cx18-av-core.c
index 536dedb23ba3..4392c76af5df 100644
--- a/drivers/media/video/cx18/cx18-av-core.c
+++ b/drivers/media/video/cx18/cx18-av-core.c
@@ -99,10 +99,8 @@ int cx18_av_and_or4(struct cx18 *cx, u16 addr, u32 and_mask,
99 or_value); 99 or_value);
100} 100}
101 101
102static int cx18_av_init(struct v4l2_subdev *sd, u32 val) 102static void cx18_av_init(struct cx18 *cx)
103{ 103{
104 struct cx18 *cx = v4l2_get_subdevdata(sd);
105
106 /* 104 /*
107 * The crystal freq used in calculations in this driver will be 105 * The crystal freq used in calculations in this driver will be
108 * 28.636360 MHz. 106 * 28.636360 MHz.
@@ -125,7 +123,6 @@ static int cx18_av_init(struct v4l2_subdev *sd, u32 val)
125 123
126 /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x16 */ 124 /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x16 */
127 cx18_av_write(cx, CXADEC_I2S_MCLK, 0x56); 125 cx18_av_write(cx, CXADEC_I2S_MCLK, 0x56);
128 return 0;
129} 126}
130 127
131static void cx18_av_initialize(struct v4l2_subdev *sd) 128static void cx18_av_initialize(struct v4l2_subdev *sd)
@@ -198,7 +195,7 @@ static void cx18_av_initialize(struct v4l2_subdev *sd)
198 cx18_av_and_or4(cx, CXADEC_CHIP_CTRL, 0xFFFBFFFF, 0x00120000); 195 cx18_av_and_or4(cx, CXADEC_CHIP_CTRL, 0xFFFBFFFF, 0x00120000);
199 196
200 /* Setup the Video and and Aux/Audio PLLs */ 197 /* Setup the Video and and Aux/Audio PLLs */
201 cx18_av_init(sd, 0); 198 cx18_av_init(cx);
202 199
203 /* set video to auto-detect */ 200 /* set video to auto-detect */
204 /* Clear bits 11-12 to enable slow locking mode. Set autodetect mode */ 201 /* Clear bits 11-12 to enable slow locking mode. Set autodetect mode */
@@ -1355,7 +1352,6 @@ static int cx18_av_s_register(struct v4l2_subdev *sd,
1355static const struct v4l2_subdev_core_ops cx18_av_general_ops = { 1352static const struct v4l2_subdev_core_ops cx18_av_general_ops = {
1356 .g_chip_ident = cx18_av_g_chip_ident, 1353 .g_chip_ident = cx18_av_g_chip_ident,
1357 .log_status = cx18_av_log_status, 1354 .log_status = cx18_av_log_status,
1358 .init = cx18_av_init,
1359 .load_fw = cx18_av_load_fw, 1355 .load_fw = cx18_av_load_fw,
1360 .reset = cx18_av_reset, 1356 .reset = cx18_av_reset,
1361 .queryctrl = cx18_av_queryctrl, 1357 .queryctrl = cx18_av_queryctrl,
@@ -1399,6 +1395,7 @@ int cx18_av_probe(struct cx18 *cx)
1399{ 1395{
1400 struct cx18_av_state *state = &cx->av_state; 1396 struct cx18_av_state *state = &cx->av_state;
1401 struct v4l2_subdev *sd; 1397 struct v4l2_subdev *sd;
1398 int err;
1402 1399
1403 state->rev = cx18_av_read4(cx, CXADEC_CHIP_CTRL) & 0xffff; 1400 state->rev = cx18_av_read4(cx, CXADEC_CHIP_CTRL) & 0xffff;
1404 state->id = ((state->rev >> 4) == CXADEC_CHIP_TYPE_MAKO) 1401 state->id = ((state->rev >> 4) == CXADEC_CHIP_TYPE_MAKO)
@@ -1417,5 +1414,8 @@ int cx18_av_probe(struct cx18 *cx)
1417 snprintf(sd->name, sizeof(sd->name), 1414 snprintf(sd->name, sizeof(sd->name),
1418 "%s %03x", cx->v4l2_dev.name, (state->rev >> 4)); 1415 "%s %03x", cx->v4l2_dev.name, (state->rev >> 4));
1419 sd->grp_id = CX18_HW_418_AV; 1416 sd->grp_id = CX18_HW_418_AV;
1420 return v4l2_device_register_subdev(&cx->v4l2_dev, sd); 1417 err = v4l2_device_register_subdev(&cx->v4l2_dev, sd);
1418 if (!err)
1419 cx18_av_init(cx);
1420 return err;
1421} 1421}
diff --git a/drivers/media/video/cx18/cx18-cards.h b/drivers/media/video/cx18/cx18-cards.h
index 444e3c7c563e..af3d71607dc9 100644
--- a/drivers/media/video/cx18/cx18-cards.h
+++ b/drivers/media/video/cx18/cx18-cards.h
@@ -34,6 +34,9 @@
34#define CX18_HW_Z8F0811_IR_HAUP (CX18_HW_Z8F0811_IR_RX_HAUP | \ 34#define CX18_HW_Z8F0811_IR_HAUP (CX18_HW_Z8F0811_IR_RX_HAUP | \
35 CX18_HW_Z8F0811_IR_TX_HAUP) 35 CX18_HW_Z8F0811_IR_TX_HAUP)
36 36
37#define CX18_HW_IR_ANY (CX18_HW_Z8F0811_IR_RX_HAUP | \
38 CX18_HW_Z8F0811_IR_TX_HAUP)
39
37/* video inputs */ 40/* video inputs */
38#define CX18_CARD_INPUT_VID_TUNER 1 41#define CX18_CARD_INPUT_VID_TUNER 1
39#define CX18_CARD_INPUT_SVIDEO1 2 42#define CX18_CARD_INPUT_SVIDEO1 2
diff --git a/drivers/media/video/cx18/cx18-driver.c b/drivers/media/video/cx18/cx18-driver.c
index e12082b8a08d..7f65a47f12e1 100644
--- a/drivers/media/video/cx18/cx18-driver.c
+++ b/drivers/media/video/cx18/cx18-driver.c
@@ -87,7 +87,6 @@ static int enc_ts_bufsize = CX18_DEFAULT_ENC_TS_BUFSIZE;
87static int enc_mpg_bufsize = CX18_DEFAULT_ENC_MPG_BUFSIZE; 87static int enc_mpg_bufsize = CX18_DEFAULT_ENC_MPG_BUFSIZE;
88static int enc_idx_bufsize = CX18_DEFAULT_ENC_IDX_BUFSIZE; 88static int enc_idx_bufsize = CX18_DEFAULT_ENC_IDX_BUFSIZE;
89static int enc_yuv_bufsize = CX18_DEFAULT_ENC_YUV_BUFSIZE; 89static int enc_yuv_bufsize = CX18_DEFAULT_ENC_YUV_BUFSIZE;
90/* VBI bufsize based on standards supported by card tuner for now */
91static int enc_pcm_bufsize = CX18_DEFAULT_ENC_PCM_BUFSIZE; 90static int enc_pcm_bufsize = CX18_DEFAULT_ENC_PCM_BUFSIZE;
92 91
93static int enc_ts_bufs = -1; 92static int enc_ts_bufs = -1;
@@ -128,7 +127,6 @@ module_param(enc_ts_bufsize, int, 0644);
128module_param(enc_mpg_bufsize, int, 0644); 127module_param(enc_mpg_bufsize, int, 0644);
129module_param(enc_idx_bufsize, int, 0644); 128module_param(enc_idx_bufsize, int, 0644);
130module_param(enc_yuv_bufsize, int, 0644); 129module_param(enc_yuv_bufsize, int, 0644);
131/* VBI bufsize based on standards supported by card tuner for now */
132module_param(enc_pcm_bufsize, int, 0644); 130module_param(enc_pcm_bufsize, int, 0644);
133 131
134module_param(enc_ts_bufs, int, 0644); 132module_param(enc_ts_bufs, int, 0644);
@@ -211,7 +209,9 @@ MODULE_PARM_DESC(enc_yuv_buffers,
211 "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_YUV_BUFFERS)); 209 "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_YUV_BUFFERS));
212MODULE_PARM_DESC(enc_yuv_bufsize, 210MODULE_PARM_DESC(enc_yuv_bufsize,
213 "Size of an encoder YUV buffer (kB)\n" 211 "Size of an encoder YUV buffer (kB)\n"
214 "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_YUV_BUFSIZE)); 212 "\t\t\tAllowed values are multiples of 33.75 kB rounded up\n"
213 "\t\t\t(multiples of size required for 32 screen lines)\n"
214 "\t\t\tDefault: 102");
215MODULE_PARM_DESC(enc_yuv_bufs, 215MODULE_PARM_DESC(enc_yuv_bufs,
216 "Number of encoder YUV buffers\n" 216 "Number of encoder YUV buffers\n"
217 "\t\t\tDefault is computed from other enc_yuv_* parameters"); 217 "\t\t\tDefault is computed from other enc_yuv_* parameters");
@@ -220,7 +220,7 @@ MODULE_PARM_DESC(enc_vbi_buffers,
220 "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_VBI_BUFFERS)); 220 "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_VBI_BUFFERS));
221MODULE_PARM_DESC(enc_vbi_bufs, 221MODULE_PARM_DESC(enc_vbi_bufs,
222 "Number of encoder VBI buffers\n" 222 "Number of encoder VBI buffers\n"
223 "\t\t\tDefault is computed from enc_vbi_buffers & tuner std"); 223 "\t\t\tDefault is computed from enc_vbi_buffers");
224MODULE_PARM_DESC(enc_pcm_buffers, 224MODULE_PARM_DESC(enc_pcm_buffers,
225 "Encoder PCM buffer memory (MB). (enc_pcm_bufs can override)\n" 225 "Encoder PCM buffer memory (MB). (enc_pcm_bufs can override)\n"
226 "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_PCM_BUFFERS)); 226 "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_PCM_BUFFERS));
@@ -499,10 +499,27 @@ static void cx18_process_options(struct cx18 *cx)
499 continue; 499 continue;
500 } 500 }
501 /* 501 /*
502 * YUV is a special case where the stream_buf_size needs to be
503 * an integral multiple of 33.75 kB (storage for 32 screens
504 * lines to maintain alignment in case of lost buffers
505 */
506 if (i == CX18_ENC_STREAM_TYPE_YUV) {
507 cx->stream_buf_size[i] *= 1024;
508 cx->stream_buf_size[i] -=
509 (cx->stream_buf_size[i] % CX18_UNIT_ENC_YUV_BUFSIZE);
510
511 if (cx->stream_buf_size[i] < CX18_UNIT_ENC_YUV_BUFSIZE)
512 cx->stream_buf_size[i] =
513 CX18_UNIT_ENC_YUV_BUFSIZE;
514 }
515 /*
516 * YUV is a special case where the stream_buf_size is
517 * now in bytes.
502 * VBI is a special case where the stream_buf_size is fixed 518 * VBI is a special case where the stream_buf_size is fixed
503 * and already in bytes 519 * and already in bytes
504 */ 520 */
505 if (i == CX18_ENC_STREAM_TYPE_VBI) { 521 if (i == CX18_ENC_STREAM_TYPE_VBI ||
522 i == CX18_ENC_STREAM_TYPE_YUV) {
506 if (cx->stream_buffers[i] < 0) { 523 if (cx->stream_buffers[i] < 0) {
507 cx->stream_buffers[i] = 524 cx->stream_buffers[i] =
508 cx->options.megabytes[i] * 1024 * 1024 525 cx->options.megabytes[i] * 1024 * 1024
@@ -513,18 +530,24 @@ static void cx18_process_options(struct cx18 *cx)
513 cx->stream_buffers[i] 530 cx->stream_buffers[i]
514 * cx->stream_buf_size[i]/(1024 * 1024); 531 * cx->stream_buf_size[i]/(1024 * 1024);
515 } 532 }
516 continue;
517 }
518 /* All other streams have stream_buf_size in kB at this point */
519 if (cx->stream_buffers[i] < 0) {
520 cx->stream_buffers[i] = cx->options.megabytes[i] * 1024
521 / cx->stream_buf_size[i];
522 } else { 533 } else {
523 /* N.B. This might round down to 0 */ 534 /* All other streams have stream_buf_size in kB here */
524 cx->options.megabytes[i] = 535 if (cx->stream_buffers[i] < 0) {
525 cx->stream_buffers[i] * cx->stream_buf_size[i] / 1024; 536 cx->stream_buffers[i] =
537 cx->options.megabytes[i] * 1024
538 / cx->stream_buf_size[i];
539 } else {
540 /* N.B. This might round down to 0 */
541 cx->options.megabytes[i] =
542 cx->stream_buffers[i]
543 * cx->stream_buf_size[i] / 1024;
544 }
545 /* convert from kB to bytes */
546 cx->stream_buf_size[i] *= 1024;
526 } 547 }
527 cx->stream_buf_size[i] *= 1024; /* convert from kB to bytes */ 548 CX18_DEBUG_INFO("Stream type %d options: %d MB, %d buffers, "
549 "%d bytes\n", i, cx->options.megabytes[i],
550 cx->stream_buffers[i], cx->stream_buf_size[i]);
528 } 551 }
529 552
530 cx->options.cardtype = cardtype[cx->instance]; 553 cx->options.cardtype = cardtype[cx->instance];
@@ -669,6 +692,12 @@ static int __devinit cx18_init_struct1(struct cx18 *cx)
669 cx->vbi.in.type = V4L2_BUF_TYPE_VBI_CAPTURE; 692 cx->vbi.in.type = V4L2_BUF_TYPE_VBI_CAPTURE;
670 cx->vbi.sliced_in = &cx->vbi.in.fmt.sliced; 693 cx->vbi.sliced_in = &cx->vbi.in.fmt.sliced;
671 694
695 /* IVTV style VBI insertion into MPEG streams */
696 INIT_LIST_HEAD(&cx->vbi.sliced_mpeg_buf.list);
697 INIT_LIST_HEAD(&cx->vbi.sliced_mpeg_mdl.list);
698 INIT_LIST_HEAD(&cx->vbi.sliced_mpeg_mdl.buf_list);
699 list_add(&cx->vbi.sliced_mpeg_buf.list,
700 &cx->vbi.sliced_mpeg_mdl.buf_list);
672 return 0; 701 return 0;
673} 702}
674 703
@@ -883,7 +912,6 @@ static int __devinit cx18_probe(struct pci_dev *pci_dev,
883 CX18_ERR("Could not register A/V decoder subdevice\n"); 912 CX18_ERR("Could not register A/V decoder subdevice\n");
884 goto free_map; 913 goto free_map;
885 } 914 }
886 cx18_call_hw(cx, CX18_HW_418_AV, core, init, 0);
887 915
888 /* Initialize GPIO Reset Controller to do chip resets during i2c init */ 916 /* Initialize GPIO Reset Controller to do chip resets during i2c init */
889 if (cx->card->hw_all & CX18_HW_GPIO_RESET_CTRL) { 917 if (cx->card->hw_all & CX18_HW_GPIO_RESET_CTRL) {
diff --git a/drivers/media/video/cx18/cx18-driver.h b/drivers/media/video/cx18/cx18-driver.h
index c6a1e907f63a..e3f7911a7385 100644
--- a/drivers/media/video/cx18/cx18-driver.h
+++ b/drivers/media/video/cx18/cx18-driver.h
@@ -50,6 +50,7 @@
50#include <media/v4l2-ioctl.h> 50#include <media/v4l2-ioctl.h>
51#include <media/v4l2-device.h> 51#include <media/v4l2-device.h>
52#include <media/tuner.h> 52#include <media/tuner.h>
53#include <media/ir-kbd-i2c.h>
53#include "cx18-mailbox.h" 54#include "cx18-mailbox.h"
54#include "cx18-av-core.h" 55#include "cx18-av-core.h"
55#include "cx23418.h" 56#include "cx23418.h"
@@ -120,12 +121,16 @@
120/* Maximum firmware DMA buffers per stream */ 121/* Maximum firmware DMA buffers per stream */
121#define CX18_MAX_FW_MDLS_PER_STREAM 63 122#define CX18_MAX_FW_MDLS_PER_STREAM 63
122 123
124/* YUV buffer sizes in bytes to ensure integer # of frames per buffer */
125#define CX18_UNIT_ENC_YUV_BUFSIZE (720 * 32 * 3 / 2) /* bytes */
126#define CX18_625_LINE_ENC_YUV_BUFSIZE (CX18_UNIT_ENC_YUV_BUFSIZE * 576/32)
127#define CX18_525_LINE_ENC_YUV_BUFSIZE (CX18_UNIT_ENC_YUV_BUFSIZE * 480/32)
128
123/* DMA buffer, default size in kB allocated */ 129/* DMA buffer, default size in kB allocated */
124#define CX18_DEFAULT_ENC_TS_BUFSIZE 32 130#define CX18_DEFAULT_ENC_TS_BUFSIZE 32
125#define CX18_DEFAULT_ENC_MPG_BUFSIZE 32 131#define CX18_DEFAULT_ENC_MPG_BUFSIZE 32
126#define CX18_DEFAULT_ENC_IDX_BUFSIZE 32 132#define CX18_DEFAULT_ENC_IDX_BUFSIZE 32
127#define CX18_DEFAULT_ENC_YUV_BUFSIZE 128 133#define CX18_DEFAULT_ENC_YUV_BUFSIZE (CX18_UNIT_ENC_YUV_BUFSIZE * 3 / 1024 + 1)
128/* Default VBI bufsize based on standards supported by card tuner for now */
129#define CX18_DEFAULT_ENC_PCM_BUFSIZE 4 134#define CX18_DEFAULT_ENC_PCM_BUFSIZE 4
130 135
131/* i2c stuff */ 136/* i2c stuff */
@@ -246,8 +251,8 @@ struct cx18_options {
246 int radio; /* enable/disable radio */ 251 int radio; /* enable/disable radio */
247}; 252};
248 253
249/* per-buffer bit flags */ 254/* per-mdl bit flags */
250#define CX18_F_B_NEED_BUF_SWAP 0 /* this buffer should be byte swapped */ 255#define CX18_F_M_NEED_SWAP 0 /* mdl buffer data must be endianess swapped */
251 256
252/* per-stream, s_flags */ 257/* per-stream, s_flags */
253#define CX18_F_S_CLAIMED 3 /* this stream is claimed */ 258#define CX18_F_S_CLAIMED 3 /* this stream is claimed */
@@ -274,18 +279,29 @@ struct cx18_options {
274struct cx18_buffer { 279struct cx18_buffer {
275 struct list_head list; 280 struct list_head list;
276 dma_addr_t dma_handle; 281 dma_addr_t dma_handle;
277 u32 id;
278 unsigned long b_flags;
279 unsigned skipped;
280 char *buf; 282 char *buf;
281 283
282 u32 bytesused; 284 u32 bytesused;
283 u32 readpos; 285 u32 readpos;
284}; 286};
285 287
288struct cx18_mdl {
289 struct list_head list;
290 u32 id; /* index into cx->scb->cpu_mdl[] of 1st cx18_mdl_ent */
291
292 unsigned int skipped;
293 unsigned long m_flags;
294
295 struct list_head buf_list;
296 struct cx18_buffer *curr_buf; /* current buffer in list for reading */
297
298 u32 bytesused;
299 u32 readpos;
300};
301
286struct cx18_queue { 302struct cx18_queue {
287 struct list_head list; 303 struct list_head list;
288 atomic_t buffers; 304 atomic_t depth;
289 u32 bytesused; 305 u32 bytesused;
290 spinlock_t lock; 306 spinlock_t lock;
291}; 307};
@@ -337,7 +353,7 @@ struct cx18_stream {
337 const char *name; /* name of the stream */ 353 const char *name; /* name of the stream */
338 int type; /* stream type */ 354 int type; /* stream type */
339 u32 handle; /* task handle */ 355 u32 handle; /* task handle */
340 unsigned mdl_offset; 356 unsigned int mdl_base_idx;
341 357
342 u32 id; 358 u32 id;
343 unsigned long s_flags; /* status flags, see above */ 359 unsigned long s_flags; /* status flags, see above */
@@ -346,14 +362,20 @@ struct cx18_stream {
346 PCI_DMA_NONE */ 362 PCI_DMA_NONE */
347 wait_queue_head_t waitq; 363 wait_queue_head_t waitq;
348 364
349 /* Buffer Stats */ 365 /* Buffers */
350 u32 buffers; 366 struct list_head buf_pool; /* buffers not attached to an MDL */
351 u32 buf_size; 367 u32 buffers; /* total buffers owned by this stream */
368 u32 buf_size; /* size in bytes of a single buffer */
369
370 /* MDL sizes - all stream MDLs are the same size */
371 u32 bufs_per_mdl;
372 u32 mdl_size; /* total bytes in all buffers in a mdl */
352 373
353 /* Buffer Queues */ 374 /* MDL Queues */
354 struct cx18_queue q_free; /* free buffers */ 375 struct cx18_queue q_free; /* free - in rotation, not committed */
355 struct cx18_queue q_busy; /* busy buffers - in use by firmware */ 376 struct cx18_queue q_busy; /* busy - in use by firmware */
356 struct cx18_queue q_full; /* full buffers - data for user apps */ 377 struct cx18_queue q_full; /* full - data for user apps */
378 struct cx18_queue q_idle; /* idle - not in rotation */
357 379
358 struct work_struct out_work_order; 380 struct work_struct out_work_order;
359 381
@@ -481,10 +503,11 @@ struct vbi_info {
481 u32 inserted_frame; 503 u32 inserted_frame;
482 504
483 /* 505 /*
484 * A dummy driver stream transfer buffer with a copy of the next 506 * A dummy driver stream transfer mdl & buffer with a copy of the next
485 * sliced_mpeg_data[] buffer for output to userland apps. 507 * sliced_mpeg_data[] buffer for output to userland apps.
486 * Only used in cx18-fileops.c, but its state needs to persist at times. 508 * Only used in cx18-fileops.c, but its state needs to persist at times.
487 */ 509 */
510 struct cx18_mdl sliced_mpeg_mdl;
488 struct cx18_buffer sliced_mpeg_buf; 511 struct cx18_buffer sliced_mpeg_buf;
489}; 512};
490 513
@@ -511,10 +534,9 @@ struct cx18 {
511 u8 is_60hz; 534 u8 is_60hz;
512 u8 nof_inputs; /* number of video inputs */ 535 u8 nof_inputs; /* number of video inputs */
513 u8 nof_audio_inputs; /* number of audio inputs */ 536 u8 nof_audio_inputs; /* number of audio inputs */
514 u16 buffer_id; /* buffer ID counter */
515 u32 v4l2_cap; /* V4L2 capabilities of card */ 537 u32 v4l2_cap; /* V4L2 capabilities of card */
516 u32 hw_flags; /* Hardware description of the board */ 538 u32 hw_flags; /* Hardware description of the board */
517 unsigned mdl_offset; 539 unsigned int free_mdl_idx;
518 struct cx18_scb __iomem *scb; /* pointer to SCB */ 540 struct cx18_scb __iomem *scb; /* pointer to SCB */
519 struct mutex epu2apu_mb_lock; /* protect driver to chip mailbox in SCB*/ 541 struct mutex epu2apu_mb_lock; /* protect driver to chip mailbox in SCB*/
520 struct mutex epu2cpu_mb_lock; /* protect driver to chip mailbox in SCB*/ 542 struct mutex epu2cpu_mb_lock; /* protect driver to chip mailbox in SCB*/
@@ -585,6 +607,8 @@ struct cx18 {
585 struct i2c_algo_bit_data i2c_algo[2]; 607 struct i2c_algo_bit_data i2c_algo[2];
586 struct cx18_i2c_algo_callback_data i2c_algo_cb_data[2]; 608 struct cx18_i2c_algo_callback_data i2c_algo_cb_data[2];
587 609
610 struct IR_i2c_init_data ir_i2c_init_data;
611
588 /* gpio */ 612 /* gpio */
589 u32 gpio_dir; 613 u32 gpio_dir;
590 u32 gpio_val; 614 u32 gpio_val;
diff --git a/drivers/media/video/cx18/cx18-dvb.c b/drivers/media/video/cx18/cx18-dvb.c
index 51a0c33b25b7..71ad2d1b4c2c 100644
--- a/drivers/media/video/cx18/cx18-dvb.c
+++ b/drivers/media/video/cx18/cx18-dvb.c
@@ -61,6 +61,7 @@ static struct mxl5005s_config hauppauge_hvr1600_tuner = {
61 .top = MXL5005S_TOP_25P2, 61 .top = MXL5005S_TOP_25P2,
62 .mod_mode = MXL_DIGITAL_MODE, 62 .mod_mode = MXL_DIGITAL_MODE,
63 .if_mode = MXL_ZERO_IF, 63 .if_mode = MXL_ZERO_IF,
64 .qam_gain = 0x02,
64 .AgcMasterByte = 0x00, 65 .AgcMasterByte = 0x00,
65}; 66};
66 67
@@ -71,7 +72,8 @@ static struct s5h1409_config hauppauge_hvr1600_config = {
71 .qam_if = 44000, 72 .qam_if = 44000,
72 .inversion = S5H1409_INVERSION_OFF, 73 .inversion = S5H1409_INVERSION_OFF,
73 .status_mode = S5H1409_DEMODLOCKING, 74 .status_mode = S5H1409_DEMODLOCKING,
74 .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK 75 .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK,
76 .hvr1600_opt = S5H1409_HVR1600_OPTIMIZE
75}; 77};
76 78
77/* 79/*
@@ -360,9 +362,10 @@ int cx18_dvb_register(struct cx18_stream *stream)
360 dvb_net_init(dvb_adapter, &dvb->dvbnet, dmx); 362 dvb_net_init(dvb_adapter, &dvb->dvbnet, dmx);
361 363
362 CX18_INFO("DVB Frontend registered\n"); 364 CX18_INFO("DVB Frontend registered\n");
363 CX18_INFO("Registered DVB adapter%d for %s (%d x %d kB)\n", 365 CX18_INFO("Registered DVB adapter%d for %s (%d x %d.%02d kB)\n",
364 stream->dvb.dvb_adapter.num, stream->name, 366 stream->dvb.dvb_adapter.num, stream->name,
365 stream->buffers, stream->buf_size/1024); 367 stream->buffers, stream->buf_size/1024,
368 (stream->buf_size * 100 / 1024) % 100);
366 369
367 mutex_init(&dvb->feedlock); 370 mutex_init(&dvb->feedlock);
368 dvb->enabled = 1; 371 dvb->enabled = 1;
diff --git a/drivers/media/video/cx18/cx18-fileops.c b/drivers/media/video/cx18/cx18-fileops.c
index 04d9c2508b86..4e278db31cc9 100644
--- a/drivers/media/video/cx18/cx18-fileops.c
+++ b/drivers/media/video/cx18/cx18-fileops.c
@@ -166,11 +166,12 @@ static void cx18_dualwatch(struct cx18 *cx)
166} 166}
167 167
168 168
169static struct cx18_buffer *cx18_get_buffer(struct cx18_stream *s, int non_block, int *err) 169static struct cx18_mdl *cx18_get_mdl(struct cx18_stream *s, int non_block,
170 int *err)
170{ 171{
171 struct cx18 *cx = s->cx; 172 struct cx18 *cx = s->cx;
172 struct cx18_stream *s_vbi = &cx->streams[CX18_ENC_STREAM_TYPE_VBI]; 173 struct cx18_stream *s_vbi = &cx->streams[CX18_ENC_STREAM_TYPE_VBI];
173 struct cx18_buffer *buf; 174 struct cx18_mdl *mdl;
174 DEFINE_WAIT(wait); 175 DEFINE_WAIT(wait);
175 176
176 *err = 0; 177 *err = 0;
@@ -185,32 +186,33 @@ static struct cx18_buffer *cx18_get_buffer(struct cx18_stream *s, int non_block,
185 } 186 }
186 if (test_bit(CX18_F_S_INTERNAL_USE, &s_vbi->s_flags) && 187 if (test_bit(CX18_F_S_INTERNAL_USE, &s_vbi->s_flags) &&
187 !test_bit(CX18_F_S_APPL_IO, &s_vbi->s_flags)) { 188 !test_bit(CX18_F_S_APPL_IO, &s_vbi->s_flags)) {
188 while ((buf = cx18_dequeue(s_vbi, &s_vbi->q_full))) { 189 while ((mdl = cx18_dequeue(s_vbi,
190 &s_vbi->q_full))) {
189 /* byteswap and process VBI data */ 191 /* byteswap and process VBI data */
190 cx18_process_vbi_data(cx, buf, 192 cx18_process_vbi_data(cx, mdl,
191 s_vbi->type); 193 s_vbi->type);
192 cx18_stream_put_buf_fw(s_vbi, buf); 194 cx18_stream_put_mdl_fw(s_vbi, mdl);
193 } 195 }
194 } 196 }
195 buf = &cx->vbi.sliced_mpeg_buf; 197 mdl = &cx->vbi.sliced_mpeg_mdl;
196 if (buf->readpos != buf->bytesused) 198 if (mdl->readpos != mdl->bytesused)
197 return buf; 199 return mdl;
198 } 200 }
199 201
200 /* do we have new data? */ 202 /* do we have new data? */
201 buf = cx18_dequeue(s, &s->q_full); 203 mdl = cx18_dequeue(s, &s->q_full);
202 if (buf) { 204 if (mdl) {
203 if (!test_and_clear_bit(CX18_F_B_NEED_BUF_SWAP, 205 if (!test_and_clear_bit(CX18_F_M_NEED_SWAP,
204 &buf->b_flags)) 206 &mdl->m_flags))
205 return buf; 207 return mdl;
206 if (s->type == CX18_ENC_STREAM_TYPE_MPG) 208 if (s->type == CX18_ENC_STREAM_TYPE_MPG)
207 /* byteswap MPG data */ 209 /* byteswap MPG data */
208 cx18_buf_swap(buf); 210 cx18_mdl_swap(mdl);
209 else { 211 else {
210 /* byteswap and process VBI data */ 212 /* byteswap and process VBI data */
211 cx18_process_vbi_data(cx, buf, s->type); 213 cx18_process_vbi_data(cx, mdl, s->type);
212 } 214 }
213 return buf; 215 return mdl;
214 } 216 }
215 217
216 /* return if end of stream */ 218 /* return if end of stream */
@@ -229,7 +231,7 @@ static struct cx18_buffer *cx18_get_buffer(struct cx18_stream *s, int non_block,
229 prepare_to_wait(&s->waitq, &wait, TASK_INTERRUPTIBLE); 231 prepare_to_wait(&s->waitq, &wait, TASK_INTERRUPTIBLE);
230 /* New buffers might have become available before we were added 232 /* New buffers might have become available before we were added
231 to the waitqueue */ 233 to the waitqueue */
232 if (!atomic_read(&s->q_full.buffers)) 234 if (!atomic_read(&s->q_full.depth))
233 schedule(); 235 schedule();
234 finish_wait(&s->waitq, &wait); 236 finish_wait(&s->waitq, &wait);
235 if (signal_pending(current)) { 237 if (signal_pending(current)) {
@@ -241,21 +243,28 @@ static struct cx18_buffer *cx18_get_buffer(struct cx18_stream *s, int non_block,
241 } 243 }
242} 244}
243 245
244static void cx18_setup_sliced_vbi_buf(struct cx18 *cx) 246static void cx18_setup_sliced_vbi_mdl(struct cx18 *cx)
245{ 247{
248 struct cx18_mdl *mdl = &cx->vbi.sliced_mpeg_mdl;
249 struct cx18_buffer *buf = &cx->vbi.sliced_mpeg_buf;
246 int idx = cx->vbi.inserted_frame % CX18_VBI_FRAMES; 250 int idx = cx->vbi.inserted_frame % CX18_VBI_FRAMES;
247 251
248 cx->vbi.sliced_mpeg_buf.buf = cx->vbi.sliced_mpeg_data[idx]; 252 buf->buf = cx->vbi.sliced_mpeg_data[idx];
249 cx->vbi.sliced_mpeg_buf.bytesused = cx->vbi.sliced_mpeg_size[idx]; 253 buf->bytesused = cx->vbi.sliced_mpeg_size[idx];
250 cx->vbi.sliced_mpeg_buf.readpos = 0; 254 buf->readpos = 0;
255
256 mdl->curr_buf = NULL;
257 mdl->bytesused = cx->vbi.sliced_mpeg_size[idx];
258 mdl->readpos = 0;
251} 259}
252 260
253static size_t cx18_copy_buf_to_user(struct cx18_stream *s, 261static size_t cx18_copy_buf_to_user(struct cx18_stream *s,
254 struct cx18_buffer *buf, char __user *ubuf, size_t ucount) 262 struct cx18_buffer *buf, char __user *ubuf, size_t ucount, bool *stop)
255{ 263{
256 struct cx18 *cx = s->cx; 264 struct cx18 *cx = s->cx;
257 size_t len = buf->bytesused - buf->readpos; 265 size_t len = buf->bytesused - buf->readpos;
258 266
267 *stop = false;
259 if (len > ucount) 268 if (len > ucount)
260 len = ucount; 269 len = ucount;
261 if (cx->vbi.insert_mpeg && s->type == CX18_ENC_STREAM_TYPE_MPG && 270 if (cx->vbi.insert_mpeg && s->type == CX18_ENC_STREAM_TYPE_MPG &&
@@ -335,7 +344,8 @@ static size_t cx18_copy_buf_to_user(struct cx18_stream *s,
335 /* We declare we actually found a Program Pack*/ 344 /* We declare we actually found a Program Pack*/
336 cx->search_pack_header = 0; /* expect vid PES */ 345 cx->search_pack_header = 0; /* expect vid PES */
337 len = (char *)q - start; 346 len = (char *)q - start;
338 cx18_setup_sliced_vbi_buf(cx); 347 cx18_setup_sliced_vbi_mdl(cx);
348 *stop = true;
339 break; 349 break;
340 } 350 }
341 } 351 }
@@ -352,6 +362,60 @@ static size_t cx18_copy_buf_to_user(struct cx18_stream *s,
352 return len; 362 return len;
353} 363}
354 364
365/**
366 * list_entry_is_past_end - check if a previous loop cursor is off list end
367 * @pos: the type * previously used as a loop cursor.
368 * @head: the head for your list.
369 * @member: the name of the list_struct within the struct.
370 *
371 * Check if the entry's list_head is the head of the list, thus it's not a
372 * real entry but was the loop cursor that walked past the end
373 */
374#define list_entry_is_past_end(pos, head, member) \
375 (&pos->member == (head))
376
377static size_t cx18_copy_mdl_to_user(struct cx18_stream *s,
378 struct cx18_mdl *mdl, char __user *ubuf, size_t ucount)
379{
380 size_t tot_written = 0;
381 int rc;
382 bool stop = false;
383
384 if (mdl->curr_buf == NULL)
385 mdl->curr_buf = list_first_entry(&mdl->buf_list,
386 struct cx18_buffer, list);
387
388 if (list_entry_is_past_end(mdl->curr_buf, &mdl->buf_list, list)) {
389 /*
390 * For some reason we've exhausted the buffers, but the MDL
391 * object still said some data was unread.
392 * Fix that and bail out.
393 */
394 mdl->readpos = mdl->bytesused;
395 return 0;
396 }
397
398 list_for_each_entry_from(mdl->curr_buf, &mdl->buf_list, list) {
399
400 if (mdl->curr_buf->readpos >= mdl->curr_buf->bytesused)
401 continue;
402
403 rc = cx18_copy_buf_to_user(s, mdl->curr_buf, ubuf + tot_written,
404 ucount - tot_written, &stop);
405 if (rc < 0)
406 return rc;
407 mdl->readpos += rc;
408 tot_written += rc;
409
410 if (stop || /* Forced stopping point for VBI insertion */
411 tot_written >= ucount || /* Reader request statisfied */
412 mdl->curr_buf->readpos < mdl->curr_buf->bytesused ||
413 mdl->readpos >= mdl->bytesused) /* MDL buffers drained */
414 break;
415 }
416 return tot_written;
417}
418
355static ssize_t cx18_read(struct cx18_stream *s, char __user *ubuf, 419static ssize_t cx18_read(struct cx18_stream *s, char __user *ubuf,
356 size_t tot_count, int non_block) 420 size_t tot_count, int non_block)
357{ 421{
@@ -373,12 +437,12 @@ static ssize_t cx18_read(struct cx18_stream *s, char __user *ubuf,
373 single_frame = 1; 437 single_frame = 1;
374 438
375 for (;;) { 439 for (;;) {
376 struct cx18_buffer *buf; 440 struct cx18_mdl *mdl;
377 int rc; 441 int rc;
378 442
379 buf = cx18_get_buffer(s, non_block, &rc); 443 mdl = cx18_get_mdl(s, non_block, &rc);
380 /* if there is no data available... */ 444 /* if there is no data available... */
381 if (buf == NULL) { 445 if (mdl == NULL) {
382 /* if we got data, then return that regardless */ 446 /* if we got data, then return that regardless */
383 if (tot_written) 447 if (tot_written)
384 break; 448 break;
@@ -392,20 +456,20 @@ static ssize_t cx18_read(struct cx18_stream *s, char __user *ubuf,
392 return rc; 456 return rc;
393 } 457 }
394 458
395 rc = cx18_copy_buf_to_user(s, buf, ubuf + tot_written, 459 rc = cx18_copy_mdl_to_user(s, mdl, ubuf + tot_written,
396 tot_count - tot_written); 460 tot_count - tot_written);
397 461
398 if (buf != &cx->vbi.sliced_mpeg_buf) { 462 if (mdl != &cx->vbi.sliced_mpeg_mdl) {
399 if (buf->readpos == buf->bytesused) 463 if (mdl->readpos == mdl->bytesused)
400 cx18_stream_put_buf_fw(s, buf); 464 cx18_stream_put_mdl_fw(s, mdl);
401 else 465 else
402 cx18_push(s, buf, &s->q_full); 466 cx18_push(s, mdl, &s->q_full);
403 } else if (buf->readpos == buf->bytesused) { 467 } else if (mdl->readpos == mdl->bytesused) {
404 int idx = cx->vbi.inserted_frame % CX18_VBI_FRAMES; 468 int idx = cx->vbi.inserted_frame % CX18_VBI_FRAMES;
405 469
406 cx->vbi.sliced_mpeg_size[idx] = 0; 470 cx->vbi.sliced_mpeg_size[idx] = 0;
407 cx->vbi.inserted_frame++; 471 cx->vbi.inserted_frame++;
408 cx->vbi_data_inserted += buf->bytesused; 472 cx->vbi_data_inserted += mdl->bytesused;
409 } 473 }
410 if (rc < 0) 474 if (rc < 0)
411 return rc; 475 return rc;
@@ -543,7 +607,7 @@ unsigned int cx18_v4l2_enc_poll(struct file *filp, poll_table *wait)
543 CX18_DEBUG_HI_FILE("Encoder poll\n"); 607 CX18_DEBUG_HI_FILE("Encoder poll\n");
544 poll_wait(filp, &s->waitq, wait); 608 poll_wait(filp, &s->waitq, wait);
545 609
546 if (atomic_read(&s->q_full.buffers)) 610 if (atomic_read(&s->q_full.depth))
547 return POLLIN | POLLRDNORM; 611 return POLLIN | POLLRDNORM;
548 if (eof) 612 if (eof)
549 return POLLHUP; 613 return POLLHUP;
diff --git a/drivers/media/video/cx18/cx18-i2c.c b/drivers/media/video/cx18/cx18-i2c.c
index 2477461e84d7..eecf29af916c 100644
--- a/drivers/media/video/cx18/cx18-i2c.c
+++ b/drivers/media/video/cx18/cx18-i2c.c
@@ -28,7 +28,6 @@
28#include "cx18-gpio.h" 28#include "cx18-gpio.h"
29#include "cx18-i2c.h" 29#include "cx18-i2c.h"
30#include "cx18-irq.h" 30#include "cx18-irq.h"
31#include <media/ir-kbd-i2c.h>
32 31
33#define CX18_REG_I2C_1_WR 0xf15000 32#define CX18_REG_I2C_1_WR 0xf15000
34#define CX18_REG_I2C_1_RD 0xf15008 33#define CX18_REG_I2C_1_RD 0xf15008
@@ -97,17 +96,11 @@ static const char * const hw_devicenames[] = {
97 "ir_rx_z8f0811_haup", 96 "ir_rx_z8f0811_haup",
98}; 97};
99 98
100static const struct IR_i2c_init_data z8f0811_ir_init_data = { 99static int cx18_i2c_new_ir(struct cx18 *cx, struct i2c_adapter *adap, u32 hw,
101 .ir_codes = &ir_codes_hauppauge_new_table, 100 const char *type, u8 addr)
102 .internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR,
103 .type = IR_TYPE_RC5,
104 .name = "CX23418 Z8F0811 Hauppauge",
105};
106
107static int cx18_i2c_new_ir(struct i2c_adapter *adap, u32 hw, const char *type,
108 u8 addr)
109{ 101{
110 struct i2c_board_info info; 102 struct i2c_board_info info;
103 struct IR_i2c_init_data *init_data = &cx->ir_i2c_init_data;
111 unsigned short addr_list[2] = { addr, I2C_CLIENT_END }; 104 unsigned short addr_list[2] = { addr, I2C_CLIENT_END };
112 105
113 memset(&info, 0, sizeof(struct i2c_board_info)); 106 memset(&info, 0, sizeof(struct i2c_board_info));
@@ -116,9 +109,11 @@ static int cx18_i2c_new_ir(struct i2c_adapter *adap, u32 hw, const char *type,
116 /* Our default information for ir-kbd-i2c.c to use */ 109 /* Our default information for ir-kbd-i2c.c to use */
117 switch (hw) { 110 switch (hw) {
118 case CX18_HW_Z8F0811_IR_RX_HAUP: 111 case CX18_HW_Z8F0811_IR_RX_HAUP:
119 info.platform_data = (void *) &z8f0811_ir_init_data; 112 init_data->ir_codes = &ir_codes_hauppauge_new_table;
120 break; 113 init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR;
121 default: 114 init_data->type = IR_TYPE_RC5;
115 init_data->name = cx->card_name;
116 info.platform_data = init_data;
122 break; 117 break;
123 } 118 }
124 119
@@ -154,8 +149,8 @@ int cx18_i2c_register(struct cx18 *cx, unsigned idx)
154 return sd != NULL ? 0 : -1; 149 return sd != NULL ? 0 : -1;
155 } 150 }
156 151
157 if (hw & CX18_HW_Z8F0811_IR_HAUP) 152 if (hw & CX18_HW_IR_ANY)
158 return cx18_i2c_new_ir(adap, hw, type, hw_addrs[idx]); 153 return cx18_i2c_new_ir(cx, adap, hw, type, hw_addrs[idx]);
159 154
160 /* Is it not an I2C device or one we do not wish to register? */ 155 /* Is it not an I2C device or one we do not wish to register? */
161 if (!hw_addrs[idx]) 156 if (!hw_addrs[idx])
diff --git a/drivers/media/video/cx18/cx18-ioctl.c b/drivers/media/video/cx18/cx18-ioctl.c
index fc76e4d6ffa7..3e4fc192fdec 100644
--- a/drivers/media/video/cx18/cx18-ioctl.c
+++ b/drivers/media/video/cx18/cx18-ioctl.c
@@ -910,7 +910,8 @@ static int cx18_log_status(struct file *file, void *fh)
910 continue; 910 continue;
911 CX18_INFO("Stream %s: status 0x%04lx, %d%% of %d KiB (%d buffers) in use\n", 911 CX18_INFO("Stream %s: status 0x%04lx, %d%% of %d KiB (%d buffers) in use\n",
912 s->name, s->s_flags, 912 s->name, s->s_flags,
913 atomic_read(&s->q_full.buffers) * 100 / s->buffers, 913 atomic_read(&s->q_full.depth) * s->bufs_per_mdl * 100
914 / s->buffers,
914 (s->buffers * s->buf_size) / 1024, s->buffers); 915 (s->buffers * s->buf_size) / 1024, s->buffers);
915 } 916 }
916 CX18_INFO("Read MPEG/VBI: %lld/%lld bytes\n", 917 CX18_INFO("Read MPEG/VBI: %lld/%lld bytes\n",
diff --git a/drivers/media/video/cx18/cx18-mailbox.c b/drivers/media/video/cx18/cx18-mailbox.c
index afe46c3d4057..f231dd09c720 100644
--- a/drivers/media/video/cx18/cx18-mailbox.c
+++ b/drivers/media/video/cx18/cx18-mailbox.c
@@ -131,13 +131,39 @@ static void dump_mb(struct cx18 *cx, struct cx18_mailbox *mb, char *name)
131 * Functions that run in a work_queue work handling context 131 * Functions that run in a work_queue work handling context
132 */ 132 */
133 133
134static void cx18_mdl_send_to_dvb(struct cx18_stream *s, struct cx18_mdl *mdl)
135{
136 struct cx18_buffer *buf;
137
138 if (!s->dvb.enabled || mdl->bytesused == 0)
139 return;
140
141 /* We ignore mdl and buf readpos accounting here - it doesn't matter */
142
143 /* The likely case */
144 if (list_is_singular(&mdl->buf_list)) {
145 buf = list_first_entry(&mdl->buf_list, struct cx18_buffer,
146 list);
147 if (buf->bytesused)
148 dvb_dmx_swfilter(&s->dvb.demux,
149 buf->buf, buf->bytesused);
150 return;
151 }
152
153 list_for_each_entry(buf, &mdl->buf_list, list) {
154 if (buf->bytesused == 0)
155 break;
156 dvb_dmx_swfilter(&s->dvb.demux, buf->buf, buf->bytesused);
157 }
158}
159
134static void epu_dma_done(struct cx18 *cx, struct cx18_in_work_order *order) 160static void epu_dma_done(struct cx18 *cx, struct cx18_in_work_order *order)
135{ 161{
136 u32 handle, mdl_ack_count, id; 162 u32 handle, mdl_ack_count, id;
137 struct cx18_mailbox *mb; 163 struct cx18_mailbox *mb;
138 struct cx18_mdl_ack *mdl_ack; 164 struct cx18_mdl_ack *mdl_ack;
139 struct cx18_stream *s; 165 struct cx18_stream *s;
140 struct cx18_buffer *buf; 166 struct cx18_mdl *mdl;
141 int i; 167 int i;
142 168
143 mb = &order->mb; 169 mb = &order->mb;
@@ -158,7 +184,7 @@ static void epu_dma_done(struct cx18 *cx, struct cx18_in_work_order *order)
158 id = mdl_ack->id; 184 id = mdl_ack->id;
159 /* 185 /*
160 * Simple integrity check for processing a stale (and possibly 186 * Simple integrity check for processing a stale (and possibly
161 * inconsistent mailbox): make sure the buffer id is in the 187 * inconsistent mailbox): make sure the MDL id is in the
162 * valid range for the stream. 188 * valid range for the stream.
163 * 189 *
164 * We go through the trouble of dealing with stale mailboxes 190 * We go through the trouble of dealing with stale mailboxes
@@ -169,44 +195,42 @@ static void epu_dma_done(struct cx18 *cx, struct cx18_in_work_order *order)
169 * There are occasions when we get a half changed mailbox, 195 * There are occasions when we get a half changed mailbox,
170 * which this check catches for a handle & id mismatch. If the 196 * which this check catches for a handle & id mismatch. If the
171 * handle and id do correspond, the worst case is that we 197 * handle and id do correspond, the worst case is that we
172 * completely lost the old buffer, but pick up the new buffer 198 * completely lost the old MDL, but pick up the new MDL
173 * early (but the new mdl_ack is guaranteed to be good in this 199 * early (but the new mdl_ack is guaranteed to be good in this
174 * case as the firmware wouldn't point us to a new mdl_ack until 200 * case as the firmware wouldn't point us to a new mdl_ack until
175 * it's filled in). 201 * it's filled in).
176 * 202 *
177 * cx18_queue_get buf() will detect the lost buffers 203 * cx18_queue_get_mdl() will detect the lost MDLs
178 * and send them back to q_free for fw rotation eventually. 204 * and send them back to q_free for fw rotation eventually.
179 */ 205 */
180 if ((order->flags & CX18_F_EWO_MB_STALE_UPON_RECEIPT) && 206 if ((order->flags & CX18_F_EWO_MB_STALE_UPON_RECEIPT) &&
181 !(id >= s->mdl_offset && 207 !(id >= s->mdl_base_idx &&
182 id < (s->mdl_offset + s->buffers))) { 208 id < (s->mdl_base_idx + s->buffers))) {
183 CX18_WARN("Fell behind! Ignoring stale mailbox with " 209 CX18_WARN("Fell behind! Ignoring stale mailbox with "
184 " inconsistent data. Lost buffer for mailbox " 210 " inconsistent data. Lost MDL for mailbox "
185 "seq no %d\n", mb->request); 211 "seq no %d\n", mb->request);
186 break; 212 break;
187 } 213 }
188 buf = cx18_queue_get_buf(s, id, mdl_ack->data_used); 214 mdl = cx18_queue_get_mdl(s, id, mdl_ack->data_used);
189 215
190 CX18_DEBUG_HI_DMA("DMA DONE for %s (buffer %d)\n", s->name, id); 216 CX18_DEBUG_HI_DMA("DMA DONE for %s (MDL %d)\n", s->name, id);
191 if (buf == NULL) { 217 if (mdl == NULL) {
192 CX18_WARN("Could not find buf %d for stream %s\n", 218 CX18_WARN("Could not find MDL %d for stream %s\n",
193 id, s->name); 219 id, s->name);
194 continue; 220 continue;
195 } 221 }
196 222
197 CX18_DEBUG_HI_DMA("%s recv bytesused = %d\n", 223 CX18_DEBUG_HI_DMA("%s recv bytesused = %d\n",
198 s->name, buf->bytesused); 224 s->name, mdl->bytesused);
199 225
200 if (s->type != CX18_ENC_STREAM_TYPE_TS) 226 if (s->type != CX18_ENC_STREAM_TYPE_TS)
201 cx18_enqueue(s, buf, &s->q_full); 227 cx18_enqueue(s, mdl, &s->q_full);
202 else { 228 else {
203 if (s->dvb.enabled) 229 cx18_mdl_send_to_dvb(s, mdl);
204 dvb_dmx_swfilter(&s->dvb.demux, buf->buf, 230 cx18_enqueue(s, mdl, &s->q_free);
205 buf->bytesused);
206 cx18_enqueue(s, buf, &s->q_free);
207 } 231 }
208 } 232 }
209 /* Put as many buffers as possible back into fw use */ 233 /* Put as many MDLs as possible back into fw use */
210 cx18_stream_load_fw_queue(s); 234 cx18_stream_load_fw_queue(s);
211 235
212 wake_up(&cx->dma_waitq); 236 wake_up(&cx->dma_waitq);
@@ -616,7 +640,7 @@ static int cx18_api_call(struct cx18 *cx, u32 cmd, int args, u32 data[])
616 640
617 /* 641 /*
618 * Wait for XPU to perform extra actions for the caller in some cases. 642 * Wait for XPU to perform extra actions for the caller in some cases.
619 * e.g. CX18_CPU_DE_RELEASE_MDL will cause the CPU to send all buffers 643 * e.g. CX18_CPU_DE_RELEASE_MDL will cause the CPU to send all MDLs
620 * back in a burst shortly thereafter 644 * back in a burst shortly thereafter
621 */ 645 */
622 if (info->flags & API_SLOW) 646 if (info->flags & API_SLOW)
diff --git a/drivers/media/video/cx18/cx18-mailbox.h b/drivers/media/video/cx18/cx18-mailbox.h
index 522ad534034c..33a3491c4537 100644
--- a/drivers/media/video/cx18/cx18-mailbox.h
+++ b/drivers/media/video/cx18/cx18-mailbox.h
@@ -39,14 +39,14 @@
39struct cx18; 39struct cx18;
40 40
41/* 41/*
42 * This structure is used by CPU to provide completed buffers information 42 * This structure is used by CPU to provide completed MDL & buffers information.
43 * Its structure is dictrated by the layout of the SCB, required by the 43 * Its structure is dictated by the layout of the SCB, required by the
44 * firmware, but its definition needs to be here, instead of in cx18-scb.h, 44 * firmware, but its definition needs to be here, instead of in cx18-scb.h,
45 * for mailbox work order scheduling 45 * for mailbox work order scheduling
46 */ 46 */
47struct cx18_mdl_ack { 47struct cx18_mdl_ack {
48 u32 id; /* ID of a completed MDL */ 48 u32 id; /* ID of a completed MDL */
49 u32 data_used; /* Total data filled in the MDL for buffer 'id' */ 49 u32 data_used; /* Total data filled in the MDL with 'id' */
50}; 50};
51 51
52/* The cx18_mailbox struct is the mailbox structure which is used for passing 52/* The cx18_mailbox struct is the mailbox structure which is used for passing
diff --git a/drivers/media/video/cx18/cx18-queue.c b/drivers/media/video/cx18/cx18-queue.c
index fa1ed7897d97..63304823cef5 100644
--- a/drivers/media/video/cx18/cx18-queue.c
+++ b/drivers/media/video/cx18/cx18-queue.c
@@ -26,6 +26,7 @@
26#include "cx18-queue.h" 26#include "cx18-queue.h"
27#include "cx18-streams.h" 27#include "cx18-streams.h"
28#include "cx18-scb.h" 28#include "cx18-scb.h"
29#include "cx18-io.h"
29 30
30void cx18_buf_swap(struct cx18_buffer *buf) 31void cx18_buf_swap(struct cx18_buffer *buf)
31{ 32{
@@ -35,151 +36,312 @@ void cx18_buf_swap(struct cx18_buffer *buf)
35 swab32s((u32 *)(buf->buf + i)); 36 swab32s((u32 *)(buf->buf + i));
36} 37}
37 38
39void _cx18_mdl_swap(struct cx18_mdl *mdl)
40{
41 struct cx18_buffer *buf;
42
43 list_for_each_entry(buf, &mdl->buf_list, list) {
44 if (buf->bytesused == 0)
45 break;
46 cx18_buf_swap(buf);
47 }
48}
49
38void cx18_queue_init(struct cx18_queue *q) 50void cx18_queue_init(struct cx18_queue *q)
39{ 51{
40 INIT_LIST_HEAD(&q->list); 52 INIT_LIST_HEAD(&q->list);
41 atomic_set(&q->buffers, 0); 53 atomic_set(&q->depth, 0);
42 q->bytesused = 0; 54 q->bytesused = 0;
43} 55}
44 56
45struct cx18_queue *_cx18_enqueue(struct cx18_stream *s, struct cx18_buffer *buf, 57struct cx18_queue *_cx18_enqueue(struct cx18_stream *s, struct cx18_mdl *mdl,
46 struct cx18_queue *q, int to_front) 58 struct cx18_queue *q, int to_front)
47{ 59{
48 /* clear the buffer if it is not to be enqueued to the full queue */ 60 /* clear the mdl if it is not to be enqueued to the full queue */
49 if (q != &s->q_full) { 61 if (q != &s->q_full) {
50 buf->bytesused = 0; 62 mdl->bytesused = 0;
51 buf->readpos = 0; 63 mdl->readpos = 0;
52 buf->b_flags = 0; 64 mdl->m_flags = 0;
53 buf->skipped = 0; 65 mdl->skipped = 0;
66 mdl->curr_buf = NULL;
54 } 67 }
55 68
56 /* q_busy is restricted to a max buffer count imposed by firmware */ 69 /* q_busy is restricted to a max buffer count imposed by firmware */
57 if (q == &s->q_busy && 70 if (q == &s->q_busy &&
58 atomic_read(&q->buffers) >= CX18_MAX_FW_MDLS_PER_STREAM) 71 atomic_read(&q->depth) >= CX18_MAX_FW_MDLS_PER_STREAM)
59 q = &s->q_free; 72 q = &s->q_free;
60 73
61 spin_lock(&q->lock); 74 spin_lock(&q->lock);
62 75
63 if (to_front) 76 if (to_front)
64 list_add(&buf->list, &q->list); /* LIFO */ 77 list_add(&mdl->list, &q->list); /* LIFO */
65 else 78 else
66 list_add_tail(&buf->list, &q->list); /* FIFO */ 79 list_add_tail(&mdl->list, &q->list); /* FIFO */
67 q->bytesused += buf->bytesused - buf->readpos; 80 q->bytesused += mdl->bytesused - mdl->readpos;
68 atomic_inc(&q->buffers); 81 atomic_inc(&q->depth);
69 82
70 spin_unlock(&q->lock); 83 spin_unlock(&q->lock);
71 return q; 84 return q;
72} 85}
73 86
74struct cx18_buffer *cx18_dequeue(struct cx18_stream *s, struct cx18_queue *q) 87struct cx18_mdl *cx18_dequeue(struct cx18_stream *s, struct cx18_queue *q)
75{ 88{
76 struct cx18_buffer *buf = NULL; 89 struct cx18_mdl *mdl = NULL;
77 90
78 spin_lock(&q->lock); 91 spin_lock(&q->lock);
79 if (!list_empty(&q->list)) { 92 if (!list_empty(&q->list)) {
80 buf = list_first_entry(&q->list, struct cx18_buffer, list); 93 mdl = list_first_entry(&q->list, struct cx18_mdl, list);
81 list_del_init(&buf->list); 94 list_del_init(&mdl->list);
82 q->bytesused -= buf->bytesused - buf->readpos; 95 q->bytesused -= mdl->bytesused - mdl->readpos;
83 buf->skipped = 0; 96 mdl->skipped = 0;
84 atomic_dec(&q->buffers); 97 atomic_dec(&q->depth);
85 } 98 }
86 spin_unlock(&q->lock); 99 spin_unlock(&q->lock);
87 return buf; 100 return mdl;
101}
102
103static void _cx18_mdl_update_bufs_for_cpu(struct cx18_stream *s,
104 struct cx18_mdl *mdl)
105{
106 struct cx18_buffer *buf;
107 u32 buf_size = s->buf_size;
108 u32 bytesused = mdl->bytesused;
109
110 list_for_each_entry(buf, &mdl->buf_list, list) {
111 buf->readpos = 0;
112 if (bytesused >= buf_size) {
113 buf->bytesused = buf_size;
114 bytesused -= buf_size;
115 } else {
116 buf->bytesused = bytesused;
117 bytesused = 0;
118 }
119 cx18_buf_sync_for_cpu(s, buf);
120 }
121}
122
123static inline void cx18_mdl_update_bufs_for_cpu(struct cx18_stream *s,
124 struct cx18_mdl *mdl)
125{
126 struct cx18_buffer *buf;
127
128 if (list_is_singular(&mdl->buf_list)) {
129 buf = list_first_entry(&mdl->buf_list, struct cx18_buffer,
130 list);
131 buf->bytesused = mdl->bytesused;
132 buf->readpos = 0;
133 cx18_buf_sync_for_cpu(s, buf);
134 } else {
135 _cx18_mdl_update_bufs_for_cpu(s, mdl);
136 }
88} 137}
89 138
90struct cx18_buffer *cx18_queue_get_buf(struct cx18_stream *s, u32 id, 139struct cx18_mdl *cx18_queue_get_mdl(struct cx18_stream *s, u32 id,
91 u32 bytesused) 140 u32 bytesused)
92{ 141{
93 struct cx18 *cx = s->cx; 142 struct cx18 *cx = s->cx;
94 struct cx18_buffer *buf; 143 struct cx18_mdl *mdl;
95 struct cx18_buffer *tmp; 144 struct cx18_mdl *tmp;
96 struct cx18_buffer *ret = NULL; 145 struct cx18_mdl *ret = NULL;
97 LIST_HEAD(sweep_up); 146 LIST_HEAD(sweep_up);
98 147
99 /* 148 /*
100 * We don't have to acquire multiple q locks here, because we are 149 * We don't have to acquire multiple q locks here, because we are
101 * serialized by the single threaded work handler. 150 * serialized by the single threaded work handler.
102 * Buffers from the firmware will thus remain in order as 151 * MDLs from the firmware will thus remain in order as
103 * they are moved from q_busy to q_full or to the dvb ring buffer. 152 * they are moved from q_busy to q_full or to the dvb ring buffer.
104 */ 153 */
105 spin_lock(&s->q_busy.lock); 154 spin_lock(&s->q_busy.lock);
106 list_for_each_entry_safe(buf, tmp, &s->q_busy.list, list) { 155 list_for_each_entry_safe(mdl, tmp, &s->q_busy.list, list) {
107 /* 156 /*
108 * We should find what the firmware told us is done, 157 * We should find what the firmware told us is done,
109 * right at the front of the queue. If we don't, we likely have 158 * right at the front of the queue. If we don't, we likely have
110 * missed a buffer done message from the firmware. 159 * missed an mdl done message from the firmware.
111 * Once we skip a buffer repeatedly, relative to the size of 160 * Once we skip an mdl repeatedly, relative to the size of
112 * q_busy, we have high confidence we've missed it. 161 * q_busy, we have high confidence we've missed it.
113 */ 162 */
114 if (buf->id != id) { 163 if (mdl->id != id) {
115 buf->skipped++; 164 mdl->skipped++;
116 if (buf->skipped >= atomic_read(&s->q_busy.buffers)-1) { 165 if (mdl->skipped >= atomic_read(&s->q_busy.depth)-1) {
117 /* buffer must have fallen out of rotation */ 166 /* mdl must have fallen out of rotation */
118 CX18_WARN("Skipped %s, buffer %d, %d " 167 CX18_WARN("Skipped %s, MDL %d, %d "
119 "times - it must have dropped out of " 168 "times - it must have dropped out of "
120 "rotation\n", s->name, buf->id, 169 "rotation\n", s->name, mdl->id,
121 buf->skipped); 170 mdl->skipped);
122 /* Sweep it up to put it back into rotation */ 171 /* Sweep it up to put it back into rotation */
123 list_move_tail(&buf->list, &sweep_up); 172 list_move_tail(&mdl->list, &sweep_up);
124 atomic_dec(&s->q_busy.buffers); 173 atomic_dec(&s->q_busy.depth);
125 } 174 }
126 continue; 175 continue;
127 } 176 }
128 /* 177 /*
129 * We pull the desired buffer off of the queue here. Something 178 * We pull the desired mdl off of the queue here. Something
130 * will have to put it back on a queue later. 179 * will have to put it back on a queue later.
131 */ 180 */
132 list_del_init(&buf->list); 181 list_del_init(&mdl->list);
133 atomic_dec(&s->q_busy.buffers); 182 atomic_dec(&s->q_busy.depth);
134 ret = buf; 183 ret = mdl;
135 break; 184 break;
136 } 185 }
137 spin_unlock(&s->q_busy.lock); 186 spin_unlock(&s->q_busy.lock);
138 187
139 /* 188 /*
140 * We found the buffer for which we were looking. Get it ready for 189 * We found the mdl for which we were looking. Get it ready for
141 * the caller to put on q_full or in the dvb ring buffer. 190 * the caller to put on q_full or in the dvb ring buffer.
142 */ 191 */
143 if (ret != NULL) { 192 if (ret != NULL) {
144 ret->bytesused = bytesused; 193 ret->bytesused = bytesused;
145 ret->skipped = 0; 194 ret->skipped = 0;
146 /* readpos and b_flags were 0'ed when the buf went on q_busy */ 195 /* 0'ed readpos, m_flags & curr_buf when mdl went on q_busy */
147 cx18_buf_sync_for_cpu(s, ret); 196 cx18_mdl_update_bufs_for_cpu(s, ret);
148 if (s->type != CX18_ENC_STREAM_TYPE_TS) 197 if (s->type != CX18_ENC_STREAM_TYPE_TS)
149 set_bit(CX18_F_B_NEED_BUF_SWAP, &ret->b_flags); 198 set_bit(CX18_F_M_NEED_SWAP, &ret->m_flags);
150 } 199 }
151 200
152 /* Put any buffers the firmware is ignoring back into normal rotation */ 201 /* Put any mdls the firmware is ignoring back into normal rotation */
153 list_for_each_entry_safe(buf, tmp, &sweep_up, list) { 202 list_for_each_entry_safe(mdl, tmp, &sweep_up, list) {
154 list_del_init(&buf->list); 203 list_del_init(&mdl->list);
155 cx18_enqueue(s, buf, &s->q_free); 204 cx18_enqueue(s, mdl, &s->q_free);
156 } 205 }
157 return ret; 206 return ret;
158} 207}
159 208
160/* Move all buffers of a queue to q_free, while flushing the buffers */ 209/* Move all mdls of a queue, while flushing the mdl */
161static void cx18_queue_flush(struct cx18_stream *s, struct cx18_queue *q) 210static void cx18_queue_flush(struct cx18_stream *s,
211 struct cx18_queue *q_src, struct cx18_queue *q_dst)
162{ 212{
163 struct cx18_buffer *buf; 213 struct cx18_mdl *mdl;
164 214
165 if (q == &s->q_free) 215 /* It only makes sense to flush to q_free or q_idle */
216 if (q_src == q_dst || q_dst == &s->q_full || q_dst == &s->q_busy)
166 return; 217 return;
167 218
168 spin_lock(&q->lock); 219 spin_lock(&q_src->lock);
169 while (!list_empty(&q->list)) { 220 spin_lock(&q_dst->lock);
170 buf = list_first_entry(&q->list, struct cx18_buffer, list); 221 while (!list_empty(&q_src->list)) {
171 list_move_tail(&buf->list, &s->q_free.list); 222 mdl = list_first_entry(&q_src->list, struct cx18_mdl, list);
172 buf->bytesused = buf->readpos = buf->b_flags = buf->skipped = 0; 223 list_move_tail(&mdl->list, &q_dst->list);
173 atomic_inc(&s->q_free.buffers); 224 mdl->bytesused = 0;
225 mdl->readpos = 0;
226 mdl->m_flags = 0;
227 mdl->skipped = 0;
228 mdl->curr_buf = NULL;
229 atomic_inc(&q_dst->depth);
174 } 230 }
175 cx18_queue_init(q); 231 cx18_queue_init(q_src);
176 spin_unlock(&q->lock); 232 spin_unlock(&q_src->lock);
233 spin_unlock(&q_dst->lock);
177} 234}
178 235
179void cx18_flush_queues(struct cx18_stream *s) 236void cx18_flush_queues(struct cx18_stream *s)
180{ 237{
181 cx18_queue_flush(s, &s->q_busy); 238 cx18_queue_flush(s, &s->q_busy, &s->q_free);
182 cx18_queue_flush(s, &s->q_full); 239 cx18_queue_flush(s, &s->q_full, &s->q_free);
240}
241
242/*
243 * Note, s->buf_pool is not protected by a lock,
244 * the stream better not have *anything* going on when calling this
245 */
246void cx18_unload_queues(struct cx18_stream *s)
247{
248 struct cx18_queue *q_idle = &s->q_idle;
249 struct cx18_mdl *mdl;
250 struct cx18_buffer *buf;
251
252 /* Move all MDLS to q_idle */
253 cx18_queue_flush(s, &s->q_busy, q_idle);
254 cx18_queue_flush(s, &s->q_full, q_idle);
255 cx18_queue_flush(s, &s->q_free, q_idle);
256
257 /* Reset MDL id's and move all buffers back to the stream's buf_pool */
258 spin_lock(&q_idle->lock);
259 list_for_each_entry(mdl, &q_idle->list, list) {
260 while (!list_empty(&mdl->buf_list)) {
261 buf = list_first_entry(&mdl->buf_list,
262 struct cx18_buffer, list);
263 list_move_tail(&buf->list, &s->buf_pool);
264 buf->bytesused = 0;
265 buf->readpos = 0;
266 }
267 mdl->id = s->mdl_base_idx; /* reset id to a "safe" value */
268 /* all other mdl fields were cleared by cx18_queue_flush() */
269 }
270 spin_unlock(&q_idle->lock);
271}
272
273/*
274 * Note, s->buf_pool is not protected by a lock,
275 * the stream better not have *anything* going on when calling this
276 */
277void cx18_load_queues(struct cx18_stream *s)
278{
279 struct cx18 *cx = s->cx;
280 struct cx18_mdl *mdl;
281 struct cx18_buffer *buf;
282 int mdl_id;
283 int i;
284 u32 partial_buf_size;
285
286 /*
287 * Attach buffers to MDLs, give the MDLs ids, and add MDLs to q_free
288 * Excess MDLs are left on q_idle
289 * Excess buffers are left in buf_pool and/or on an MDL in q_idle
290 */
291 mdl_id = s->mdl_base_idx;
292 for (mdl = cx18_dequeue(s, &s->q_idle), i = s->bufs_per_mdl;
293 mdl != NULL && i == s->bufs_per_mdl;
294 mdl = cx18_dequeue(s, &s->q_idle)) {
295
296 mdl->id = mdl_id;
297
298 for (i = 0; i < s->bufs_per_mdl; i++) {
299 if (list_empty(&s->buf_pool))
300 break;
301
302 buf = list_first_entry(&s->buf_pool, struct cx18_buffer,
303 list);
304 list_move_tail(&buf->list, &mdl->buf_list);
305
306 /* update the firmware's MDL array with this buffer */
307 cx18_writel(cx, buf->dma_handle,
308 &cx->scb->cpu_mdl[mdl_id + i].paddr);
309 cx18_writel(cx, s->buf_size,
310 &cx->scb->cpu_mdl[mdl_id + i].length);
311 }
312
313 if (i == s->bufs_per_mdl) {
314 /*
315 * The encoder doesn't honor s->mdl_size. So in the
316 * case of a non-integral number of buffers to meet
317 * mdl_size, we lie about the size of the last buffer
318 * in the MDL to get the encoder to really only send
319 * us mdl_size bytes per MDL transfer.
320 */
321 partial_buf_size = s->mdl_size % s->buf_size;
322 if (partial_buf_size) {
323 cx18_writel(cx, partial_buf_size,
324 &cx->scb->cpu_mdl[mdl_id + i - 1].length);
325 }
326 cx18_enqueue(s, mdl, &s->q_free);
327 } else {
328 /* Not enough buffers for this MDL; we won't use it */
329 cx18_push(s, mdl, &s->q_idle);
330 }
331 mdl_id += i;
332 }
333}
334
335void _cx18_mdl_sync_for_device(struct cx18_stream *s, struct cx18_mdl *mdl)
336{
337 int dma = s->dma;
338 u32 buf_size = s->buf_size;
339 struct pci_dev *pci_dev = s->cx->pci_dev;
340 struct cx18_buffer *buf;
341
342 list_for_each_entry(buf, &mdl->buf_list, list)
343 pci_dma_sync_single_for_device(pci_dev, buf->dma_handle,
344 buf_size, dma);
183} 345}
184 346
185int cx18_stream_alloc(struct cx18_stream *s) 347int cx18_stream_alloc(struct cx18_stream *s)
@@ -190,44 +352,62 @@ int cx18_stream_alloc(struct cx18_stream *s)
190 if (s->buffers == 0) 352 if (s->buffers == 0)
191 return 0; 353 return 0;
192 354
193 CX18_DEBUG_INFO("Allocate %s stream: %d x %d buffers (%dkB total)\n", 355 CX18_DEBUG_INFO("Allocate %s stream: %d x %d buffers "
356 "(%d.%02d kB total)\n",
194 s->name, s->buffers, s->buf_size, 357 s->name, s->buffers, s->buf_size,
195 s->buffers * s->buf_size / 1024); 358 s->buffers * s->buf_size / 1024,
359 (s->buffers * s->buf_size * 100 / 1024) % 100);
196 360
197 if (((char __iomem *)&cx->scb->cpu_mdl[cx->mdl_offset + s->buffers] - 361 if (((char __iomem *)&cx->scb->cpu_mdl[cx->free_mdl_idx + s->buffers] -
198 (char __iomem *)cx->scb) > SCB_RESERVED_SIZE) { 362 (char __iomem *)cx->scb) > SCB_RESERVED_SIZE) {
199 unsigned bufsz = (((char __iomem *)cx->scb) + SCB_RESERVED_SIZE - 363 unsigned bufsz = (((char __iomem *)cx->scb) + SCB_RESERVED_SIZE -
200 ((char __iomem *)cx->scb->cpu_mdl)); 364 ((char __iomem *)cx->scb->cpu_mdl));
201 365
202 CX18_ERR("Too many buffers, cannot fit in SCB area\n"); 366 CX18_ERR("Too many buffers, cannot fit in SCB area\n");
203 CX18_ERR("Max buffers = %zd\n", 367 CX18_ERR("Max buffers = %zd\n",
204 bufsz / sizeof(struct cx18_mdl)); 368 bufsz / sizeof(struct cx18_mdl_ent));
205 return -ENOMEM; 369 return -ENOMEM;
206 } 370 }
207 371
208 s->mdl_offset = cx->mdl_offset; 372 s->mdl_base_idx = cx->free_mdl_idx;
209 373
210 /* allocate stream buffers. Initially all buffers are in q_free. */ 374 /* allocate stream buffers and MDLs */
211 for (i = 0; i < s->buffers; i++) { 375 for (i = 0; i < s->buffers; i++) {
212 struct cx18_buffer *buf = kzalloc(sizeof(struct cx18_buffer), 376 struct cx18_mdl *mdl;
213 GFP_KERNEL|__GFP_NOWARN); 377 struct cx18_buffer *buf;
214 378
215 if (buf == NULL) 379 /* 1 MDL per buffer to handle the worst & also default case */
380 mdl = kzalloc(sizeof(struct cx18_mdl), GFP_KERNEL|__GFP_NOWARN);
381 if (mdl == NULL)
216 break; 382 break;
383
384 buf = kzalloc(sizeof(struct cx18_buffer),
385 GFP_KERNEL|__GFP_NOWARN);
386 if (buf == NULL) {
387 kfree(mdl);
388 break;
389 }
390
217 buf->buf = kmalloc(s->buf_size, GFP_KERNEL|__GFP_NOWARN); 391 buf->buf = kmalloc(s->buf_size, GFP_KERNEL|__GFP_NOWARN);
218 if (buf->buf == NULL) { 392 if (buf->buf == NULL) {
393 kfree(mdl);
219 kfree(buf); 394 kfree(buf);
220 break; 395 break;
221 } 396 }
222 buf->id = cx->buffer_id++; 397
398 INIT_LIST_HEAD(&mdl->list);
399 INIT_LIST_HEAD(&mdl->buf_list);
400 mdl->id = s->mdl_base_idx; /* a somewhat safe value */
401 cx18_enqueue(s, mdl, &s->q_idle);
402
223 INIT_LIST_HEAD(&buf->list); 403 INIT_LIST_HEAD(&buf->list);
224 buf->dma_handle = pci_map_single(s->cx->pci_dev, 404 buf->dma_handle = pci_map_single(s->cx->pci_dev,
225 buf->buf, s->buf_size, s->dma); 405 buf->buf, s->buf_size, s->dma);
226 cx18_buf_sync_for_cpu(s, buf); 406 cx18_buf_sync_for_cpu(s, buf);
227 cx18_enqueue(s, buf, &s->q_free); 407 list_add_tail(&buf->list, &s->buf_pool);
228 } 408 }
229 if (i == s->buffers) { 409 if (i == s->buffers) {
230 cx->mdl_offset += s->buffers; 410 cx->free_mdl_idx += s->buffers;
231 return 0; 411 return 0;
232 } 412 }
233 CX18_ERR("Couldn't allocate buffers for %s stream\n", s->name); 413 CX18_ERR("Couldn't allocate buffers for %s stream\n", s->name);
@@ -237,13 +417,21 @@ int cx18_stream_alloc(struct cx18_stream *s)
237 417
238void cx18_stream_free(struct cx18_stream *s) 418void cx18_stream_free(struct cx18_stream *s)
239{ 419{
420 struct cx18_mdl *mdl;
240 struct cx18_buffer *buf; 421 struct cx18_buffer *buf;
241 422
242 /* move all buffers to q_free */ 423 /* move all buffers to buf_pool and all MDLs to q_idle */
243 cx18_flush_queues(s); 424 cx18_unload_queues(s);
425
426 /* empty q_idle */
427 while ((mdl = cx18_dequeue(s, &s->q_idle)))
428 kfree(mdl);
429
430 /* empty buf_pool */
431 while (!list_empty(&s->buf_pool)) {
432 buf = list_first_entry(&s->buf_pool, struct cx18_buffer, list);
433 list_del_init(&buf->list);
244 434
245 /* empty q_free */
246 while ((buf = cx18_dequeue(s, &s->q_free))) {
247 pci_unmap_single(s->cx->pci_dev, buf->dma_handle, 435 pci_unmap_single(s->cx->pci_dev, buf->dma_handle,
248 s->buf_size, s->dma); 436 s->buf_size, s->dma);
249 kfree(buf->buf); 437 kfree(buf->buf);
diff --git a/drivers/media/video/cx18/cx18-queue.h b/drivers/media/video/cx18/cx18-queue.h
index 4de06269d88f..88a6d34ad3bb 100644
--- a/drivers/media/video/cx18/cx18-queue.h
+++ b/drivers/media/video/cx18/cx18-queue.h
@@ -40,32 +40,59 @@ static inline void cx18_buf_sync_for_device(struct cx18_stream *s,
40 s->buf_size, s->dma); 40 s->buf_size, s->dma);
41} 41}
42 42
43void _cx18_mdl_sync_for_device(struct cx18_stream *s, struct cx18_mdl *mdl);
44
45static inline void cx18_mdl_sync_for_device(struct cx18_stream *s,
46 struct cx18_mdl *mdl)
47{
48 if (list_is_singular(&mdl->buf_list))
49 cx18_buf_sync_for_device(s, list_first_entry(&mdl->buf_list,
50 struct cx18_buffer,
51 list));
52 else
53 _cx18_mdl_sync_for_device(s, mdl);
54}
55
43void cx18_buf_swap(struct cx18_buffer *buf); 56void cx18_buf_swap(struct cx18_buffer *buf);
57void _cx18_mdl_swap(struct cx18_mdl *mdl);
58
59static inline void cx18_mdl_swap(struct cx18_mdl *mdl)
60{
61 if (list_is_singular(&mdl->buf_list))
62 cx18_buf_swap(list_first_entry(&mdl->buf_list,
63 struct cx18_buffer, list));
64 else
65 _cx18_mdl_swap(mdl);
66}
44 67
45/* cx18_queue utility functions */ 68/* cx18_queue utility functions */
46struct cx18_queue *_cx18_enqueue(struct cx18_stream *s, struct cx18_buffer *buf, 69struct cx18_queue *_cx18_enqueue(struct cx18_stream *s, struct cx18_mdl *mdl,
47 struct cx18_queue *q, int to_front); 70 struct cx18_queue *q, int to_front);
48 71
49static inline 72static inline
50struct cx18_queue *cx18_enqueue(struct cx18_stream *s, struct cx18_buffer *buf, 73struct cx18_queue *cx18_enqueue(struct cx18_stream *s, struct cx18_mdl *mdl,
51 struct cx18_queue *q) 74 struct cx18_queue *q)
52{ 75{
53 return _cx18_enqueue(s, buf, q, 0); /* FIFO */ 76 return _cx18_enqueue(s, mdl, q, 0); /* FIFO */
54} 77}
55 78
56static inline 79static inline
57struct cx18_queue *cx18_push(struct cx18_stream *s, struct cx18_buffer *buf, 80struct cx18_queue *cx18_push(struct cx18_stream *s, struct cx18_mdl *mdl,
58 struct cx18_queue *q) 81 struct cx18_queue *q)
59{ 82{
60 return _cx18_enqueue(s, buf, q, 1); /* LIFO */ 83 return _cx18_enqueue(s, mdl, q, 1); /* LIFO */
61} 84}
62 85
63void cx18_queue_init(struct cx18_queue *q); 86void cx18_queue_init(struct cx18_queue *q);
64struct cx18_buffer *cx18_dequeue(struct cx18_stream *s, struct cx18_queue *q); 87struct cx18_mdl *cx18_dequeue(struct cx18_stream *s, struct cx18_queue *q);
65struct cx18_buffer *cx18_queue_get_buf(struct cx18_stream *s, u32 id, 88struct cx18_mdl *cx18_queue_get_mdl(struct cx18_stream *s, u32 id,
66 u32 bytesused); 89 u32 bytesused);
67void cx18_flush_queues(struct cx18_stream *s); 90void cx18_flush_queues(struct cx18_stream *s);
68 91
92/* queue MDL reconfiguration helpers */
93void cx18_unload_queues(struct cx18_stream *s);
94void cx18_load_queues(struct cx18_stream *s);
95
69/* cx18_stream utility functions */ 96/* cx18_stream utility functions */
70int cx18_stream_alloc(struct cx18_stream *s); 97int cx18_stream_alloc(struct cx18_stream *s);
71void cx18_stream_free(struct cx18_stream *s); 98void cx18_stream_free(struct cx18_stream *s);
diff --git a/drivers/media/video/cx18/cx18-scb.h b/drivers/media/video/cx18/cx18-scb.h
index 1dc1c431f5a1..368f23d08709 100644
--- a/drivers/media/video/cx18/cx18-scb.h
+++ b/drivers/media/video/cx18/cx18-scb.h
@@ -81,7 +81,7 @@
81 81
82 82
83/* This structure is used by EPU to provide memory descriptors in its memory */ 83/* This structure is used by EPU to provide memory descriptors in its memory */
84struct cx18_mdl { 84struct cx18_mdl_ent {
85 u32 paddr; /* Physical address of a buffer segment */ 85 u32 paddr; /* Physical address of a buffer segment */
86 u32 length; /* Length of the buffer segment */ 86 u32 length; /* Length of the buffer segment */
87}; 87};
@@ -272,7 +272,7 @@ struct cx18_scb {
272 struct cx18_mailbox ppu2epu_mb; 272 struct cx18_mailbox ppu2epu_mb;
273 273
274 struct cx18_mdl_ack cpu_mdl_ack[CX18_MAX_STREAMS][CX18_MAX_MDL_ACKS]; 274 struct cx18_mdl_ack cpu_mdl_ack[CX18_MAX_STREAMS][CX18_MAX_MDL_ACKS];
275 struct cx18_mdl cpu_mdl[1]; 275 struct cx18_mdl_ent cpu_mdl[1];
276}; 276};
277 277
278void cx18_init_scb(struct cx18 *cx); 278void cx18_init_scb(struct cx18 *cx);
diff --git a/drivers/media/video/cx18/cx18-streams.c b/drivers/media/video/cx18/cx18-streams.c
index 7df513a2dba8..c398651dd74c 100644
--- a/drivers/media/video/cx18/cx18-streams.c
+++ b/drivers/media/video/cx18/cx18-streams.c
@@ -115,6 +115,9 @@ static void cx18_stream_init(struct cx18 *cx, int type)
115 s->dma = cx18_stream_info[type].dma; 115 s->dma = cx18_stream_info[type].dma;
116 s->buffers = cx->stream_buffers[type]; 116 s->buffers = cx->stream_buffers[type];
117 s->buf_size = cx->stream_buf_size[type]; 117 s->buf_size = cx->stream_buf_size[type];
118 INIT_LIST_HEAD(&s->buf_pool);
119 s->bufs_per_mdl = 1;
120 s->mdl_size = s->buf_size * s->bufs_per_mdl;
118 121
119 init_waitqueue_head(&s->waitq); 122 init_waitqueue_head(&s->waitq);
120 s->id = -1; 123 s->id = -1;
@@ -124,6 +127,8 @@ static void cx18_stream_init(struct cx18 *cx, int type)
124 cx18_queue_init(&s->q_busy); 127 cx18_queue_init(&s->q_busy);
125 spin_lock_init(&s->q_full.lock); 128 spin_lock_init(&s->q_full.lock);
126 cx18_queue_init(&s->q_full); 129 cx18_queue_init(&s->q_full);
130 spin_lock_init(&s->q_idle.lock);
131 cx18_queue_init(&s->q_idle);
127 132
128 INIT_WORK(&s->out_work_order, cx18_out_work_handler); 133 INIT_WORK(&s->out_work_order, cx18_out_work_handler);
129} 134}
@@ -257,9 +262,11 @@ static int cx18_reg_dev(struct cx18 *cx, int type)
257 262
258 switch (vfl_type) { 263 switch (vfl_type) {
259 case VFL_TYPE_GRABBER: 264 case VFL_TYPE_GRABBER:
260 CX18_INFO("Registered device video%d for %s (%d x %d kB)\n", 265 CX18_INFO("Registered device video%d for %s "
266 "(%d x %d.%02d kB)\n",
261 num, s->name, cx->stream_buffers[type], 267 num, s->name, cx->stream_buffers[type],
262 cx->stream_buf_size[type]/1024); 268 cx->stream_buf_size[type] / 1024,
269 (cx->stream_buf_size[type] * 100 / 1024) % 100);
263 break; 270 break;
264 271
265 case VFL_TYPE_RADIO: 272 case VFL_TYPE_RADIO:
@@ -441,8 +448,8 @@ static void cx18_vbi_setup(struct cx18_stream *s)
441} 448}
442 449
443static 450static
444struct cx18_queue *_cx18_stream_put_buf_fw(struct cx18_stream *s, 451struct cx18_queue *_cx18_stream_put_mdl_fw(struct cx18_stream *s,
445 struct cx18_buffer *buf) 452 struct cx18_mdl *mdl)
446{ 453{
447 struct cx18 *cx = s->cx; 454 struct cx18 *cx = s->cx;
448 struct cx18_queue *q; 455 struct cx18_queue *q;
@@ -451,16 +458,16 @@ struct cx18_queue *_cx18_stream_put_buf_fw(struct cx18_stream *s,
451 if (s->handle == CX18_INVALID_TASK_HANDLE || 458 if (s->handle == CX18_INVALID_TASK_HANDLE ||
452 test_bit(CX18_F_S_STOPPING, &s->s_flags) || 459 test_bit(CX18_F_S_STOPPING, &s->s_flags) ||
453 !test_bit(CX18_F_S_STREAMING, &s->s_flags)) 460 !test_bit(CX18_F_S_STREAMING, &s->s_flags))
454 return cx18_enqueue(s, buf, &s->q_free); 461 return cx18_enqueue(s, mdl, &s->q_free);
455 462
456 q = cx18_enqueue(s, buf, &s->q_busy); 463 q = cx18_enqueue(s, mdl, &s->q_busy);
457 if (q != &s->q_busy) 464 if (q != &s->q_busy)
458 return q; /* The firmware has the max buffers it can handle */ 465 return q; /* The firmware has the max MDLs it can handle */
459 466
460 cx18_buf_sync_for_device(s, buf); 467 cx18_mdl_sync_for_device(s, mdl);
461 cx18_vapi(cx, CX18_CPU_DE_SET_MDL, 5, s->handle, 468 cx18_vapi(cx, CX18_CPU_DE_SET_MDL, 5, s->handle,
462 (void __iomem *) &cx->scb->cpu_mdl[buf->id] - cx->enc_mem, 469 (void __iomem *) &cx->scb->cpu_mdl[mdl->id] - cx->enc_mem,
463 1, buf->id, s->buf_size); 470 s->bufs_per_mdl, mdl->id, s->mdl_size);
464 return q; 471 return q;
465} 472}
466 473
@@ -468,19 +475,19 @@ static
468void _cx18_stream_load_fw_queue(struct cx18_stream *s) 475void _cx18_stream_load_fw_queue(struct cx18_stream *s)
469{ 476{
470 struct cx18_queue *q; 477 struct cx18_queue *q;
471 struct cx18_buffer *buf; 478 struct cx18_mdl *mdl;
472 479
473 if (atomic_read(&s->q_free.buffers) == 0 || 480 if (atomic_read(&s->q_free.depth) == 0 ||
474 atomic_read(&s->q_busy.buffers) >= CX18_MAX_FW_MDLS_PER_STREAM) 481 atomic_read(&s->q_busy.depth) >= CX18_MAX_FW_MDLS_PER_STREAM)
475 return; 482 return;
476 483
477 /* Move from q_free to q_busy notifying the firmware, until the limit */ 484 /* Move from q_free to q_busy notifying the firmware, until the limit */
478 do { 485 do {
479 buf = cx18_dequeue(s, &s->q_free); 486 mdl = cx18_dequeue(s, &s->q_free);
480 if (buf == NULL) 487 if (mdl == NULL)
481 break; 488 break;
482 q = _cx18_stream_put_buf_fw(s, buf); 489 q = _cx18_stream_put_mdl_fw(s, mdl);
483 } while (atomic_read(&s->q_busy.buffers) < CX18_MAX_FW_MDLS_PER_STREAM 490 } while (atomic_read(&s->q_busy.depth) < CX18_MAX_FW_MDLS_PER_STREAM
484 && q == &s->q_busy); 491 && q == &s->q_busy);
485} 492}
486 493
@@ -492,11 +499,51 @@ void cx18_out_work_handler(struct work_struct *work)
492 _cx18_stream_load_fw_queue(s); 499 _cx18_stream_load_fw_queue(s);
493} 500}
494 501
502static void cx18_stream_configure_mdls(struct cx18_stream *s)
503{
504 cx18_unload_queues(s);
505
506 switch (s->type) {
507 case CX18_ENC_STREAM_TYPE_YUV:
508 /*
509 * Height should be a multiple of 32 lines.
510 * Set the MDL size to the exact size needed for one frame.
511 * Use enough buffers per MDL to cover the MDL size
512 */
513 s->mdl_size = 720 * s->cx->params.height * 3 / 2;
514 s->bufs_per_mdl = s->mdl_size / s->buf_size;
515 if (s->mdl_size % s->buf_size)
516 s->bufs_per_mdl++;
517 break;
518 case CX18_ENC_STREAM_TYPE_VBI:
519 s->bufs_per_mdl = 1;
520 if (cx18_raw_vbi(s->cx)) {
521 s->mdl_size = (s->cx->is_60hz ? 12 : 18)
522 * 2 * vbi_active_samples;
523 } else {
524 /*
525 * See comment in cx18_vbi_setup() below about the
526 * extra lines we capture in sliced VBI mode due to
527 * the lines on which EAV RP codes toggle.
528 */
529 s->mdl_size = s->cx->is_60hz
530 ? (21 - 4 + 1) * 2 * vbi_hblank_samples_60Hz
531 : (23 - 2 + 1) * 2 * vbi_hblank_samples_50Hz;
532 }
533 break;
534 default:
535 s->bufs_per_mdl = 1;
536 s->mdl_size = s->buf_size * s->bufs_per_mdl;
537 break;
538 }
539
540 cx18_load_queues(s);
541}
542
495int cx18_start_v4l2_encode_stream(struct cx18_stream *s) 543int cx18_start_v4l2_encode_stream(struct cx18_stream *s)
496{ 544{
497 u32 data[MAX_MB_ARGUMENTS]; 545 u32 data[MAX_MB_ARGUMENTS];
498 struct cx18 *cx = s->cx; 546 struct cx18 *cx = s->cx;
499 struct cx18_buffer *buf;
500 int captype = 0; 547 int captype = 0;
501 struct cx18_api_func_private priv; 548 struct cx18_api_func_private priv;
502 549
@@ -619,14 +666,7 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s)
619 (void __iomem *)&cx->scb->cpu_mdl_ack[s->type][1] - cx->enc_mem); 666 (void __iomem *)&cx->scb->cpu_mdl_ack[s->type][1] - cx->enc_mem);
620 667
621 /* Init all the cpu_mdls for this stream */ 668 /* Init all the cpu_mdls for this stream */
622 cx18_flush_queues(s); 669 cx18_stream_configure_mdls(s);
623 spin_lock(&s->q_free.lock);
624 list_for_each_entry(buf, &s->q_free.list, list) {
625 cx18_writel(cx, buf->dma_handle,
626 &cx->scb->cpu_mdl[buf->id].paddr);
627 cx18_writel(cx, s->buf_size, &cx->scb->cpu_mdl[buf->id].length);
628 }
629 spin_unlock(&s->q_free.lock);
630 _cx18_stream_load_fw_queue(s); 670 _cx18_stream_load_fw_queue(s);
631 671
632 /* begin_capture */ 672 /* begin_capture */
diff --git a/drivers/media/video/cx18/cx18-streams.h b/drivers/media/video/cx18/cx18-streams.h
index 1afc3fd9d822..4a01db5e5a35 100644
--- a/drivers/media/video/cx18/cx18-streams.h
+++ b/drivers/media/video/cx18/cx18-streams.h
@@ -28,18 +28,18 @@ int cx18_streams_setup(struct cx18 *cx);
28int cx18_streams_register(struct cx18 *cx); 28int cx18_streams_register(struct cx18 *cx);
29void cx18_streams_cleanup(struct cx18 *cx, int unregister); 29void cx18_streams_cleanup(struct cx18 *cx, int unregister);
30 30
31/* Related to submission of buffers to firmware */ 31/* Related to submission of mdls to firmware */
32static inline void cx18_stream_load_fw_queue(struct cx18_stream *s) 32static inline void cx18_stream_load_fw_queue(struct cx18_stream *s)
33{ 33{
34 struct cx18 *cx = s->cx; 34 struct cx18 *cx = s->cx;
35 queue_work(cx->out_work_queue, &s->out_work_order); 35 queue_work(cx->out_work_queue, &s->out_work_order);
36} 36}
37 37
38static inline void cx18_stream_put_buf_fw(struct cx18_stream *s, 38static inline void cx18_stream_put_mdl_fw(struct cx18_stream *s,
39 struct cx18_buffer *buf) 39 struct cx18_mdl *mdl)
40{ 40{
41 /* Put buf on q_free; the out work handler will move buf(s) to q_busy */ 41 /* Put mdl on q_free; the out work handler will move mdl(s) to q_busy */
42 cx18_enqueue(s, buf, &s->q_free); 42 cx18_enqueue(s, mdl, &s->q_free);
43 cx18_stream_load_fw_queue(s); 43 cx18_stream_load_fw_queue(s);
44} 44}
45 45
diff --git a/drivers/media/video/cx18/cx18-vbi.c b/drivers/media/video/cx18/cx18-vbi.c
index c2aef4add31d..574c1c6974f8 100644
--- a/drivers/media/video/cx18/cx18-vbi.c
+++ b/drivers/media/video/cx18/cx18-vbi.c
@@ -105,6 +105,7 @@ static void copy_vbi_data(struct cx18 *cx, int lines, u32 pts_stamp)
105 105
106/* Compress raw VBI format, removes leading SAV codes and surplus space 106/* Compress raw VBI format, removes leading SAV codes and surplus space
107 after the frame. Returns new compressed size. */ 107 after the frame. Returns new compressed size. */
108/* FIXME - this function ignores the input size. */
108static u32 compress_raw_buf(struct cx18 *cx, u8 *buf, u32 size, u32 hdr_size) 109static u32 compress_raw_buf(struct cx18 *cx, u8 *buf, u32 size, u32 hdr_size)
109{ 110{
110 u32 line_size = vbi_active_samples; 111 u32 line_size = vbi_active_samples;
@@ -185,8 +186,7 @@ static u32 compress_sliced_buf(struct cx18 *cx, u8 *buf, u32 size,
185 return line; 186 return line;
186} 187}
187 188
188void cx18_process_vbi_data(struct cx18 *cx, struct cx18_buffer *buf, 189static void _cx18_process_vbi_data(struct cx18 *cx, struct cx18_buffer *buf)
189 int streamtype)
190{ 190{
191 /* 191 /*
192 * The CX23418 provides a 12 byte header in its raw VBI buffers to us: 192 * The CX23418 provides a 12 byte header in its raw VBI buffers to us:
@@ -203,9 +203,6 @@ void cx18_process_vbi_data(struct cx18 *cx, struct cx18_buffer *buf,
203 u32 pts; 203 u32 pts;
204 int lines; 204 int lines;
205 205
206 if (streamtype != CX18_ENC_STREAM_TYPE_VBI)
207 return;
208
209 /* 206 /*
210 * The CX23418 sends us data that is 32 bit little-endian swapped, 207 * The CX23418 sends us data that is 32 bit little-endian swapped,
211 * but we want the raw VBI bytes in the order they were in the raster 208 * but we want the raw VBI bytes in the order they were in the raster
@@ -250,3 +247,31 @@ void cx18_process_vbi_data(struct cx18 *cx, struct cx18_buffer *buf,
250 copy_vbi_data(cx, lines, pts); 247 copy_vbi_data(cx, lines, pts);
251 cx->vbi.frame++; 248 cx->vbi.frame++;
252} 249}
250
251void cx18_process_vbi_data(struct cx18 *cx, struct cx18_mdl *mdl,
252 int streamtype)
253{
254 struct cx18_buffer *buf;
255 u32 orig_used;
256
257 if (streamtype != CX18_ENC_STREAM_TYPE_VBI)
258 return;
259
260 /*
261 * Big assumption here:
262 * Every buffer hooked to the MDL's buf_list is a complete VBI frame
263 * that ends at the end of the buffer.
264 *
265 * To assume anything else would make the code in this file
266 * more complex, or require extra memcpy()'s to make the
267 * buffers satisfy the above assumption. It's just simpler to set
268 * up the encoder buffer transfers to make the assumption true.
269 */
270 list_for_each_entry(buf, &mdl->buf_list, list) {
271 orig_used = buf->bytesused;
272 if (orig_used == 0)
273 break;
274 _cx18_process_vbi_data(cx, buf);
275 mdl->bytesused -= (orig_used - buf->bytesused);
276 }
277}
diff --git a/drivers/media/video/cx18/cx18-vbi.h b/drivers/media/video/cx18/cx18-vbi.h
index e7e1ae427f34..b365cf4b4668 100644
--- a/drivers/media/video/cx18/cx18-vbi.h
+++ b/drivers/media/video/cx18/cx18-vbi.h
@@ -21,6 +21,6 @@
21 * 02111-1307 USA 21 * 02111-1307 USA
22 */ 22 */
23 23
24void cx18_process_vbi_data(struct cx18 *cx, struct cx18_buffer *buf, 24void cx18_process_vbi_data(struct cx18 *cx, struct cx18_mdl *mdl,
25 int streamtype); 25 int streamtype);
26int cx18_used_line(struct cx18 *cx, int line, int field); 26int cx18_used_line(struct cx18 *cx, int line, int field);
diff --git a/drivers/media/video/cx18/cx18-version.h b/drivers/media/video/cx18/cx18-version.h
index 45494b094e7f..9c0b5bb1b019 100644
--- a/drivers/media/video/cx18/cx18-version.h
+++ b/drivers/media/video/cx18/cx18-version.h
@@ -24,7 +24,7 @@
24 24
25#define CX18_DRIVER_NAME "cx18" 25#define CX18_DRIVER_NAME "cx18"
26#define CX18_DRIVER_VERSION_MAJOR 1 26#define CX18_DRIVER_VERSION_MAJOR 1
27#define CX18_DRIVER_VERSION_MINOR 2 27#define CX18_DRIVER_VERSION_MINOR 3
28#define CX18_DRIVER_VERSION_PATCHLEVEL 0 28#define CX18_DRIVER_VERSION_PATCHLEVEL 0
29 29
30#define CX18_VERSION __stringify(CX18_DRIVER_VERSION_MAJOR) "." __stringify(CX18_DRIVER_VERSION_MINOR) "." __stringify(CX18_DRIVER_VERSION_PATCHLEVEL) 30#define CX18_VERSION __stringify(CX18_DRIVER_VERSION_MAJOR) "." __stringify(CX18_DRIVER_VERSION_MINOR) "." __stringify(CX18_DRIVER_VERSION_PATCHLEVEL)
diff --git a/drivers/media/video/cx18/cx23418.h b/drivers/media/video/cx18/cx23418.h
index 9956abf576c5..868806effdcf 100644
--- a/drivers/media/video/cx18/cx23418.h
+++ b/drivers/media/video/cx18/cx23418.h
@@ -363,7 +363,7 @@
363/* Description: This command provides the offset to a Memory Descriptor List 363/* Description: This command provides the offset to a Memory Descriptor List
364 IN[0] - Task handle. Handle of the task to start 364 IN[0] - Task handle. Handle of the task to start
365 IN[1] - Offset of the MDL from the beginning of the local DDR. 365 IN[1] - Offset of the MDL from the beginning of the local DDR.
366 IN[2] - Number of cx18_mdl structures in the array pointed to by IN[1] 366 IN[2] - Number of cx18_mdl_ent structures in the array pointed to by IN[1]
367 IN[3] - Buffer ID 367 IN[3] - Buffer ID
368 IN[4] - Total buffer length 368 IN[4] - Total buffer length
369 ReturnCode - One of the ERR_DE_... */ 369 ReturnCode - One of the ERR_DE_... */
diff --git a/drivers/media/video/cx231xx/cx231xx-input.c b/drivers/media/video/cx231xx/cx231xx-input.c
index 48f22fa38e6c..cd135f01b9c1 100644
--- a/drivers/media/video/cx231xx/cx231xx-input.c
+++ b/drivers/media/video/cx231xx/cx231xx-input.c
@@ -126,8 +126,7 @@ static void cx231xx_ir_handle_key(struct cx231xx_IR *ir)
126 126
127 if (do_sendkey) { 127 if (do_sendkey) {
128 dprintk("sending keypress\n"); 128 dprintk("sending keypress\n");
129 ir_input_keydown(ir->input, &ir->ir, poll_result.rc_data[0], 129 ir_input_keydown(ir->input, &ir->ir, poll_result.rc_data[0]);
130 poll_result.rc_data[0]);
131 ir_input_nokey(ir->input, &ir->ir); 130 ir_input_nokey(ir->input, &ir->ir);
132 } 131 }
133 132
@@ -198,7 +197,11 @@ int cx231xx_ir_init(struct cx231xx *dev)
198 usb_make_path(dev->udev, ir->phys, sizeof(ir->phys)); 197 usb_make_path(dev->udev, ir->phys, sizeof(ir->phys));
199 strlcat(ir->phys, "/input0", sizeof(ir->phys)); 198 strlcat(ir->phys, "/input0", sizeof(ir->phys));
200 199
201 ir_input_init(input_dev, &ir->ir, IR_TYPE_OTHER, dev->board.ir_codes); 200 err = ir_input_init(input_dev, &ir->ir, IR_TYPE_OTHER,
201 dev->board.ir_codes);
202 if (err < 0)
203 goto err_out_free;
204
202 input_dev->name = ir->name; 205 input_dev->name = ir->name;
203 input_dev->phys = ir->phys; 206 input_dev->phys = ir->phys;
204 input_dev->id.bustype = BUS_USB; 207 input_dev->id.bustype = BUS_USB;
@@ -223,6 +226,7 @@ err_out_stop:
223 cx231xx_ir_stop(ir); 226 cx231xx_ir_stop(ir);
224 dev->ir = NULL; 227 dev->ir = NULL;
225err_out_free: 228err_out_free:
229 ir_input_free(input_dev);
226 input_free_device(input_dev); 230 input_free_device(input_dev);
227 kfree(ir); 231 kfree(ir);
228 return err; 232 return err;
@@ -237,6 +241,7 @@ int cx231xx_ir_fini(struct cx231xx *dev)
237 return 0; 241 return 0;
238 242
239 cx231xx_ir_stop(ir); 243 cx231xx_ir_stop(ir);
244 ir_input_free(ir->input);
240 input_unregister_device(ir->input); 245 input_unregister_device(ir->input);
241 kfree(ir); 246 kfree(ir);
242 247
diff --git a/drivers/media/video/cx231xx/cx231xx-video.c b/drivers/media/video/cx231xx/cx231xx-video.c
index 36503725d973..d095aa0d6d19 100644
--- a/drivers/media/video/cx231xx/cx231xx-video.c
+++ b/drivers/media/video/cx231xx/cx231xx-video.c
@@ -2106,7 +2106,7 @@ static int cx231xx_v4l2_close(struct file *filp)
2106 } 2106 }
2107 2107
2108 /* Save some power by putting tuner to sleep */ 2108 /* Save some power by putting tuner to sleep */
2109 call_all(dev, tuner, s_standby); 2109 call_all(dev, core, s_power, 0);
2110 2110
2111 /* do this before setting alternate! */ 2111 /* do this before setting alternate! */
2112 cx231xx_uninit_isoc(dev); 2112 cx231xx_uninit_isoc(dev);
diff --git a/drivers/media/video/cx23885/Kconfig b/drivers/media/video/cx23885/Kconfig
index fd3fc3e3198a..bcdda9a9aa96 100644
--- a/drivers/media/video/cx23885/Kconfig
+++ b/drivers/media/video/cx23885/Kconfig
@@ -18,7 +18,9 @@ config VIDEO_CX23885
18 select DVB_TDA10048 if !DVB_FE_CUSTOMISE 18 select DVB_TDA10048 if !DVB_FE_CUSTOMISE
19 select DVB_LNBP21 if !DVB_FE_CUSTOMISE 19 select DVB_LNBP21 if !DVB_FE_CUSTOMISE
20 select DVB_STV6110 if !DVB_FE_CUSTOMISE 20 select DVB_STV6110 if !DVB_FE_CUSTOMISE
21 select DVB_CX24116 if !DVB_FE_CUSTOMISE
21 select DVB_STV0900 if !DVB_FE_CUSTOMISE 22 select DVB_STV0900 if !DVB_FE_CUSTOMISE
23 select DVB_DS3000 if !DVB_FE_CUSTOMISE
22 select MEDIA_TUNER_MT2131 if !MEDIA_TUNER_CUSTOMISE 24 select MEDIA_TUNER_MT2131 if !MEDIA_TUNER_CUSTOMISE
23 select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMISE 25 select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMISE
24 select MEDIA_TUNER_TDA8290 if !MEDIA_TUNER_CUSTOMISE 26 select MEDIA_TUNER_TDA8290 if !MEDIA_TUNER_CUSTOMISE
diff --git a/drivers/media/video/cx23885/Makefile b/drivers/media/video/cx23885/Makefile
index ab8ea35c9bfb..5787ae243631 100644
--- a/drivers/media/video/cx23885/Makefile
+++ b/drivers/media/video/cx23885/Makefile
@@ -1,6 +1,7 @@
1cx23885-objs := cx23885-cards.o cx23885-video.o cx23885-vbi.o \ 1cx23885-objs := cx23885-cards.o cx23885-video.o cx23885-vbi.o \
2 cx23885-core.o cx23885-i2c.o cx23885-dvb.o cx23885-417.o \ 2 cx23885-core.o cx23885-i2c.o cx23885-dvb.o cx23885-417.o \
3 netup-init.o cimax2.o netup-eeprom.o 3 cx23885-ioctl.o cx23885-ir.o cx23885-input.o cx23888-ir.o \
4 netup-init.o cimax2.o netup-eeprom.o cx23885-f300.o
4 5
5obj-$(CONFIG_VIDEO_CX23885) += cx23885.o 6obj-$(CONFIG_VIDEO_CX23885) += cx23885.o
6 7
diff --git a/drivers/media/video/cx23885/cx23885-417.c b/drivers/media/video/cx23885/cx23885-417.c
index 6c3b51ce3372..0eed852c61e9 100644
--- a/drivers/media/video/cx23885/cx23885-417.c
+++ b/drivers/media/video/cx23885/cx23885-417.c
@@ -37,6 +37,7 @@
37#include <media/cx2341x.h> 37#include <media/cx2341x.h>
38 38
39#include "cx23885.h" 39#include "cx23885.h"
40#include "cx23885-ioctl.h"
40 41
41#define CX23885_FIRM_IMAGE_SIZE 376836 42#define CX23885_FIRM_IMAGE_SIZE 376836
42#define CX23885_FIRM_IMAGE_NAME "v4l-cx23885-enc.fw" 43#define CX23885_FIRM_IMAGE_NAME "v4l-cx23885-enc.fw"
@@ -318,7 +319,7 @@ static int mc417_wait_ready(struct cx23885_dev *dev)
318 } 319 }
319} 320}
320 321
321static int mc417_register_write(struct cx23885_dev *dev, u16 address, u32 value) 322int mc417_register_write(struct cx23885_dev *dev, u16 address, u32 value)
322{ 323{
323 u32 regval; 324 u32 regval;
324 325
@@ -382,7 +383,7 @@ static int mc417_register_write(struct cx23885_dev *dev, u16 address, u32 value)
382 return mc417_wait_ready(dev); 383 return mc417_wait_ready(dev);
383} 384}
384 385
385static int mc417_register_read(struct cx23885_dev *dev, u16 address, u32 *value) 386int mc417_register_read(struct cx23885_dev *dev, u16 address, u32 *value)
386{ 387{
387 int retval; 388 int retval;
388 u32 regval; 389 u32 regval;
@@ -1724,6 +1725,11 @@ static const struct v4l2_ioctl_ops mpeg_ioctl_ops = {
1724 .vidioc_log_status = vidioc_log_status, 1725 .vidioc_log_status = vidioc_log_status,
1725 .vidioc_querymenu = vidioc_querymenu, 1726 .vidioc_querymenu = vidioc_querymenu,
1726 .vidioc_queryctrl = vidioc_queryctrl, 1727 .vidioc_queryctrl = vidioc_queryctrl,
1728 .vidioc_g_chip_ident = cx23885_g_chip_ident,
1729#ifdef CONFIG_VIDEO_ADV_DEBUG
1730 .vidioc_g_register = cx23885_g_register,
1731 .vidioc_s_register = cx23885_s_register,
1732#endif
1727}; 1733};
1728 1734
1729static struct video_device cx23885_mpeg_template = { 1735static struct video_device cx23885_mpeg_template = {
diff --git a/drivers/media/video/cx23885/cx23885-cards.c b/drivers/media/video/cx23885/cx23885-cards.c
index bfdf79f1033c..1ec48169277d 100644
--- a/drivers/media/video/cx23885/cx23885-cards.c
+++ b/drivers/media/video/cx23885/cx23885-cards.c
@@ -28,6 +28,7 @@
28#include "cx23885.h" 28#include "cx23885.h"
29#include "tuner-xc2028.h" 29#include "tuner-xc2028.h"
30#include "netup-init.h" 30#include "netup-init.h"
31#include "cx23888-ir.h"
31 32
32/* ------------------------------------------------------------------ */ 33/* ------------------------------------------------------------------ */
33/* board config info */ 34/* board config info */
@@ -199,11 +200,61 @@ struct cx23885_board cx23885_boards[] = {
199 }, 200 },
200 [CX23885_BOARD_MYGICA_X8506] = { 201 [CX23885_BOARD_MYGICA_X8506] = {
201 .name = "Mygica X8506 DMB-TH", 202 .name = "Mygica X8506 DMB-TH",
203 .tuner_type = TUNER_XC5000,
204 .tuner_addr = 0x61,
205 .porta = CX23885_ANALOG_VIDEO,
202 .portb = CX23885_MPEG_DVB, 206 .portb = CX23885_MPEG_DVB,
207 .input = {
208 {
209 .type = CX23885_VMUX_TELEVISION,
210 .vmux = CX25840_COMPOSITE2,
211 },
212 {
213 .type = CX23885_VMUX_COMPOSITE1,
214 .vmux = CX25840_COMPOSITE8,
215 },
216 {
217 .type = CX23885_VMUX_SVIDEO,
218 .vmux = CX25840_SVIDEO_LUMA3 |
219 CX25840_SVIDEO_CHROMA4,
220 },
221 {
222 .type = CX23885_VMUX_COMPONENT,
223 .vmux = CX25840_COMPONENT_ON |
224 CX25840_VIN1_CH1 |
225 CX25840_VIN6_CH2 |
226 CX25840_VIN7_CH3,
227 },
228 },
203 }, 229 },
204 [CX23885_BOARD_MAGICPRO_PROHDTVE2] = { 230 [CX23885_BOARD_MAGICPRO_PROHDTVE2] = {
205 .name = "Magic-Pro ProHDTV Extreme 2", 231 .name = "Magic-Pro ProHDTV Extreme 2",
232 .tuner_type = TUNER_XC5000,
233 .tuner_addr = 0x61,
234 .porta = CX23885_ANALOG_VIDEO,
206 .portb = CX23885_MPEG_DVB, 235 .portb = CX23885_MPEG_DVB,
236 .input = {
237 {
238 .type = CX23885_VMUX_TELEVISION,
239 .vmux = CX25840_COMPOSITE2,
240 },
241 {
242 .type = CX23885_VMUX_COMPOSITE1,
243 .vmux = CX25840_COMPOSITE8,
244 },
245 {
246 .type = CX23885_VMUX_SVIDEO,
247 .vmux = CX25840_SVIDEO_LUMA3 |
248 CX25840_SVIDEO_CHROMA4,
249 },
250 {
251 .type = CX23885_VMUX_COMPONENT,
252 .vmux = CX25840_COMPONENT_ON |
253 CX25840_VIN1_CH1 |
254 CX25840_VIN6_CH2 |
255 CX25840_VIN7_CH3,
256 },
257 },
207 }, 258 },
208 [CX23885_BOARD_HAUPPAUGE_HVR1850] = { 259 [CX23885_BOARD_HAUPPAUGE_HVR1850] = {
209 .name = "Hauppauge WinTV-HVR1850", 260 .name = "Hauppauge WinTV-HVR1850",
@@ -214,6 +265,15 @@ struct cx23885_board cx23885_boards[] = {
214 .name = "Compro VideoMate E800", 265 .name = "Compro VideoMate E800",
215 .portc = CX23885_MPEG_DVB, 266 .portc = CX23885_MPEG_DVB,
216 }, 267 },
268 [CX23885_BOARD_HAUPPAUGE_HVR1290] = {
269 .name = "Hauppauge WinTV-HVR1290",
270 .portc = CX23885_MPEG_DVB,
271 },
272 [CX23885_BOARD_MYGICA_X8558PRO] = {
273 .name = "Mygica X8558 PRO DMB-TH",
274 .portb = CX23885_MPEG_DVB,
275 .portc = CX23885_MPEG_DVB,
276 },
217}; 277};
218const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards); 278const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards);
219 279
@@ -349,6 +409,14 @@ struct cx23885_subid cx23885_subids[] = {
349 .subvendor = 0x1858, 409 .subvendor = 0x1858,
350 .subdevice = 0xe800, 410 .subdevice = 0xe800,
351 .card = CX23885_BOARD_COMPRO_VIDEOMATE_E800, 411 .card = CX23885_BOARD_COMPRO_VIDEOMATE_E800,
412 }, {
413 .subvendor = 0x0070,
414 .subdevice = 0x8551,
415 .card = CX23885_BOARD_HAUPPAUGE_HVR1290,
416 }, {
417 .subvendor = 0x14f1,
418 .subdevice = 0x8578,
419 .card = CX23885_BOARD_MYGICA_X8558PRO,
352 }, 420 },
353}; 421};
354const unsigned int cx23885_idcount = ARRAY_SIZE(cx23885_subids); 422const unsigned int cx23885_idcount = ARRAY_SIZE(cx23885_subids);
@@ -509,9 +577,13 @@ static void hauppauge_eeprom(struct cx23885_dev *dev, u8 *eeprom_data)
509 * DVB-T and MPEG2 HW Encoder */ 577 * DVB-T and MPEG2 HW Encoder */
510 break; 578 break;
511 case 85021: 579 case 85021:
512 /* WinTV-HVR1850 (PCIe, OEM, RCA in, IR, FM, 580 /* WinTV-HVR1850 (PCIe, Retail, 3.5mm in, IR, FM,
513 Dual channel ATSC and MPEG2 HW Encoder */ 581 Dual channel ATSC and MPEG2 HW Encoder */
514 break; 582 break;
583 case 85721:
584 /* WinTV-HVR1290 (PCIe, OEM, RCA in, IR,
585 Dual channel ATSC and Basic analog */
586 break;
515 default: 587 default:
516 printk(KERN_WARNING "%s: warning: " 588 printk(KERN_WARNING "%s: warning: "
517 "unknown hauppauge model #%d\n", 589 "unknown hauppauge model #%d\n",
@@ -710,10 +782,14 @@ void cx23885_gpio_setup(struct cx23885_dev *dev)
710 cx_set(GP0_IO, 0x00040004); 782 cx_set(GP0_IO, 0x00040004);
711 break; 783 break;
712 case CX23885_BOARD_TBS_6920: 784 case CX23885_BOARD_TBS_6920:
713 case CX23885_BOARD_TEVII_S470:
714 cx_write(MC417_CTL, 0x00000036); 785 cx_write(MC417_CTL, 0x00000036);
715 cx_write(MC417_OEN, 0x00001000); 786 cx_write(MC417_OEN, 0x00001000);
716 cx_write(MC417_RWD, 0x00001800); 787 cx_set(MC417_RWD, 0x00000002);
788 mdelay(200);
789 cx_clear(MC417_RWD, 0x00000800);
790 mdelay(200);
791 cx_set(MC417_RWD, 0x00000800);
792 mdelay(200);
717 break; 793 break;
718 case CX23885_BOARD_NETUP_DUAL_DVBS2_CI: 794 case CX23885_BOARD_NETUP_DUAL_DVBS2_CI:
719 /* GPIO-0 INTA from CiMax1 795 /* GPIO-0 INTA from CiMax1
@@ -758,15 +834,26 @@ void cx23885_gpio_setup(struct cx23885_dev *dev)
758 break; 834 break;
759 case CX23885_BOARD_MYGICA_X8506: 835 case CX23885_BOARD_MYGICA_X8506:
760 case CX23885_BOARD_MAGICPRO_PROHDTVE2: 836 case CX23885_BOARD_MAGICPRO_PROHDTVE2:
837 /* GPIO-0 (0)Analog / (1)Digital TV */
761 /* GPIO-1 reset XC5000 */ 838 /* GPIO-1 reset XC5000 */
762 /* GPIO-2 reset LGS8GL5 / LGS8G75 */ 839 /* GPIO-2 reset LGS8GL5 / LGS8G75 */
763 cx_set(GP0_IO, 0x00060000); 840 cx23885_gpio_enable(dev, GPIO_0 | GPIO_1 | GPIO_2, 1);
764 cx_clear(GP0_IO, 0x00000006); 841 cx23885_gpio_clear(dev, GPIO_1 | GPIO_2);
765 mdelay(100); 842 mdelay(100);
766 cx_set(GP0_IO, 0x00060006); 843 cx23885_gpio_set(dev, GPIO_0 | GPIO_1 | GPIO_2);
844 mdelay(100);
845 break;
846 case CX23885_BOARD_MYGICA_X8558PRO:
847 /* GPIO-0 reset first ATBM8830 */
848 /* GPIO-1 reset second ATBM8830 */
849 cx23885_gpio_enable(dev, GPIO_0 | GPIO_1, 1);
850 cx23885_gpio_clear(dev, GPIO_0 | GPIO_1);
851 mdelay(100);
852 cx23885_gpio_set(dev, GPIO_0 | GPIO_1);
767 mdelay(100); 853 mdelay(100);
768 break; 854 break;
769 case CX23885_BOARD_HAUPPAUGE_HVR1850: 855 case CX23885_BOARD_HAUPPAUGE_HVR1850:
856 case CX23885_BOARD_HAUPPAUGE_HVR1290:
770 /* GPIO-0 656_CLK */ 857 /* GPIO-0 656_CLK */
771 /* GPIO-1 656_D0 */ 858 /* GPIO-1 656_D0 */
772 /* GPIO-2 Wake# */ 859 /* GPIO-2 Wake# */
@@ -801,6 +888,7 @@ void cx23885_gpio_setup(struct cx23885_dev *dev)
801 888
802int cx23885_ir_init(struct cx23885_dev *dev) 889int cx23885_ir_init(struct cx23885_dev *dev)
803{ 890{
891 int ret = 0;
804 switch (dev->board) { 892 switch (dev->board) {
805 case CX23885_BOARD_HAUPPAUGE_HVR1250: 893 case CX23885_BOARD_HAUPPAUGE_HVR1250:
806 case CX23885_BOARD_HAUPPAUGE_HVR1500: 894 case CX23885_BOARD_HAUPPAUGE_HVR1500:
@@ -812,15 +900,46 @@ int cx23885_ir_init(struct cx23885_dev *dev)
812 case CX23885_BOARD_HAUPPAUGE_HVR1275: 900 case CX23885_BOARD_HAUPPAUGE_HVR1275:
813 case CX23885_BOARD_HAUPPAUGE_HVR1255: 901 case CX23885_BOARD_HAUPPAUGE_HVR1255:
814 case CX23885_BOARD_HAUPPAUGE_HVR1210: 902 case CX23885_BOARD_HAUPPAUGE_HVR1210:
815 case CX23885_BOARD_HAUPPAUGE_HVR1850:
816 /* FIXME: Implement me */ 903 /* FIXME: Implement me */
817 break; 904 break;
905 case CX23885_BOARD_HAUPPAUGE_HVR1850:
906 case CX23885_BOARD_HAUPPAUGE_HVR1290:
907 ret = cx23888_ir_probe(dev);
908 if (ret)
909 break;
910 dev->sd_ir = cx23885_find_hw(dev, CX23885_HW_888_IR);
911 dev->pci_irqmask |= PCI_MSK_IR;
912 break;
818 case CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP: 913 case CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP:
819 request_module("ir-kbd-i2c"); 914 request_module("ir-kbd-i2c");
820 break; 915 break;
821 } 916 }
822 917
823 return 0; 918 return ret;
919}
920
921void cx23885_ir_fini(struct cx23885_dev *dev)
922{
923 switch (dev->board) {
924 case CX23885_BOARD_HAUPPAUGE_HVR1850:
925 case CX23885_BOARD_HAUPPAUGE_HVR1290:
926 dev->pci_irqmask &= ~PCI_MSK_IR;
927 cx_clear(PCI_INT_MSK, PCI_MSK_IR);
928 cx23888_ir_remove(dev);
929 dev->sd_ir = NULL;
930 break;
931 }
932}
933
934void cx23885_ir_pci_int_enable(struct cx23885_dev *dev)
935{
936 switch (dev->board) {
937 case CX23885_BOARD_HAUPPAUGE_HVR1850:
938 case CX23885_BOARD_HAUPPAUGE_HVR1290:
939 if (dev->sd_ir && (dev->pci_irqmask & PCI_MSK_IR))
940 cx_set(PCI_INT_MSK, PCI_MSK_IR);
941 break;
942 }
824} 943}
825 944
826void cx23885_card_setup(struct cx23885_dev *dev) 945void cx23885_card_setup(struct cx23885_dev *dev)
@@ -853,6 +972,7 @@ void cx23885_card_setup(struct cx23885_dev *dev)
853 case CX23885_BOARD_HAUPPAUGE_HVR1255: 972 case CX23885_BOARD_HAUPPAUGE_HVR1255:
854 case CX23885_BOARD_HAUPPAUGE_HVR1210: 973 case CX23885_BOARD_HAUPPAUGE_HVR1210:
855 case CX23885_BOARD_HAUPPAUGE_HVR1850: 974 case CX23885_BOARD_HAUPPAUGE_HVR1850:
975 case CX23885_BOARD_HAUPPAUGE_HVR1290:
856 if (dev->i2c_bus[0].i2c_rc == 0) 976 if (dev->i2c_bus[0].i2c_rc == 0)
857 hauppauge_eeprom(dev, eeprom+0xc0); 977 hauppauge_eeprom(dev, eeprom+0xc0);
858 break; 978 break;
@@ -886,8 +1006,12 @@ void cx23885_card_setup(struct cx23885_dev *dev)
886 ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */ 1006 ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */
887 ts2->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; 1007 ts2->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO;
888 break; 1008 break;
889 case CX23885_BOARD_TEVII_S470:
890 case CX23885_BOARD_TBS_6920: 1009 case CX23885_BOARD_TBS_6920:
1010 ts1->gen_ctrl_val = 0x4; /* Parallel */
1011 ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */
1012 ts1->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO;
1013 break;
1014 case CX23885_BOARD_TEVII_S470:
891 case CX23885_BOARD_DVBWORLD_2005: 1015 case CX23885_BOARD_DVBWORLD_2005:
892 ts1->gen_ctrl_val = 0x5; /* Parallel */ 1016 ts1->gen_ctrl_val = 0x5; /* Parallel */
893 ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */ 1017 ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */
@@ -907,6 +1031,14 @@ void cx23885_card_setup(struct cx23885_dev *dev)
907 ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */ 1031 ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */
908 ts1->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; 1032 ts1->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO;
909 break; 1033 break;
1034 case CX23885_BOARD_MYGICA_X8558PRO:
1035 ts1->gen_ctrl_val = 0x5; /* Parallel */
1036 ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */
1037 ts1->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO;
1038 ts2->gen_ctrl_val = 0xc; /* Serial bus + punctured clock */
1039 ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */
1040 ts2->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO;
1041 break;
910 case CX23885_BOARD_HAUPPAUGE_HVR1250: 1042 case CX23885_BOARD_HAUPPAUGE_HVR1250:
911 case CX23885_BOARD_HAUPPAUGE_HVR1500: 1043 case CX23885_BOARD_HAUPPAUGE_HVR1500:
912 case CX23885_BOARD_HAUPPAUGE_HVR1500Q: 1044 case CX23885_BOARD_HAUPPAUGE_HVR1500Q:
@@ -922,6 +1054,7 @@ void cx23885_card_setup(struct cx23885_dev *dev)
922 case CX23885_BOARD_HAUPPAUGE_HVR1210: 1054 case CX23885_BOARD_HAUPPAUGE_HVR1210:
923 case CX23885_BOARD_HAUPPAUGE_HVR1850: 1055 case CX23885_BOARD_HAUPPAUGE_HVR1850:
924 case CX23885_BOARD_COMPRO_VIDEOMATE_E800: 1056 case CX23885_BOARD_COMPRO_VIDEOMATE_E800:
1057 case CX23885_BOARD_HAUPPAUGE_HVR1290:
925 default: 1058 default:
926 ts2->gen_ctrl_val = 0xc; /* Serial bus + punctured clock */ 1059 ts2->gen_ctrl_val = 0xc; /* Serial bus + punctured clock */
927 ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */ 1060 ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */
@@ -939,6 +1072,10 @@ void cx23885_card_setup(struct cx23885_dev *dev)
939 case CX23885_BOARD_COMPRO_VIDEOMATE_E650F: 1072 case CX23885_BOARD_COMPRO_VIDEOMATE_E650F:
940 case CX23885_BOARD_NETUP_DUAL_DVBS2_CI: 1073 case CX23885_BOARD_NETUP_DUAL_DVBS2_CI:
941 case CX23885_BOARD_COMPRO_VIDEOMATE_E800: 1074 case CX23885_BOARD_COMPRO_VIDEOMATE_E800:
1075 case CX23885_BOARD_HAUPPAUGE_HVR1850:
1076 case CX23885_BOARD_MYGICA_X8506:
1077 case CX23885_BOARD_MAGICPRO_PROHDTVE2:
1078 case CX23885_BOARD_HAUPPAUGE_HVR1290:
942 dev->sd_cx25840 = v4l2_i2c_new_subdev(&dev->v4l2_dev, 1079 dev->sd_cx25840 = v4l2_i2c_new_subdev(&dev->v4l2_dev,
943 &dev->i2c_bus[2].i2c_adap, 1080 &dev->i2c_bus[2].i2c_adap,
944 "cx25840", "cx25840", 0x88 >> 1, NULL); 1081 "cx25840", "cx25840", 0x88 >> 1, NULL);
diff --git a/drivers/media/video/cx23885/cx23885-core.c b/drivers/media/video/cx23885/cx23885-core.c
index fa2d350e20fd..04b12d27bc13 100644
--- a/drivers/media/video/cx23885/cx23885-core.c
+++ b/drivers/media/video/cx23885/cx23885-core.c
@@ -32,6 +32,9 @@
32 32
33#include "cx23885.h" 33#include "cx23885.h"
34#include "cimax2.h" 34#include "cimax2.h"
35#include "cx23888-ir.h"
36#include "cx23885-ir.h"
37#include "cx23885-input.h"
35 38
36MODULE_DESCRIPTION("Driver for cx23885 based TV cards"); 39MODULE_DESCRIPTION("Driver for cx23885 based TV cards");
37MODULE_AUTHOR("Steven Toth <stoth@linuxtv.org>"); 40MODULE_AUTHOR("Steven Toth <stoth@linuxtv.org>");
@@ -753,6 +756,23 @@ static void cx23885_dev_checkrevision(struct cx23885_dev *dev)
753 __func__, dev->hwrevision); 756 __func__, dev->hwrevision);
754} 757}
755 758
759/* Find the first v4l2_subdev member of the group id in hw */
760struct v4l2_subdev *cx23885_find_hw(struct cx23885_dev *dev, u32 hw)
761{
762 struct v4l2_subdev *result = NULL;
763 struct v4l2_subdev *sd;
764
765 spin_lock(&dev->v4l2_dev.lock);
766 v4l2_device_for_each_subdev(sd, &dev->v4l2_dev) {
767 if (sd->grp_id == hw) {
768 result = sd;
769 break;
770 }
771 }
772 spin_unlock(&dev->v4l2_dev.lock);
773 return result;
774}
775
756static int cx23885_dev_setup(struct cx23885_dev *dev) 776static int cx23885_dev_setup(struct cx23885_dev *dev)
757{ 777{
758 int i; 778 int i;
@@ -899,7 +919,7 @@ static int cx23885_dev_setup(struct cx23885_dev *dev)
899 cx23885_i2c_register(&dev->i2c_bus[1]); 919 cx23885_i2c_register(&dev->i2c_bus[1]);
900 cx23885_i2c_register(&dev->i2c_bus[2]); 920 cx23885_i2c_register(&dev->i2c_bus[2]);
901 cx23885_card_setup(dev); 921 cx23885_card_setup(dev);
902 call_all(dev, tuner, s_standby); 922 call_all(dev, core, s_power, 0);
903 cx23885_ir_init(dev); 923 cx23885_ir_init(dev);
904 924
905 if (cx23885_boards[dev->board].porta == CX23885_ANALOG_VIDEO) { 925 if (cx23885_boards[dev->board].porta == CX23885_ANALOG_VIDEO) {
@@ -1637,6 +1657,7 @@ static irqreturn_t cx23885_irq(int irq, void *dev_id)
1637 u32 ts1_status, ts1_mask; 1657 u32 ts1_status, ts1_mask;
1638 u32 ts2_status, ts2_mask; 1658 u32 ts2_status, ts2_mask;
1639 int vida_count = 0, ts1_count = 0, ts2_count = 0, handled = 0; 1659 int vida_count = 0, ts1_count = 0, ts2_count = 0, handled = 0;
1660 bool ir_handled = false;
1640 1661
1641 pci_status = cx_read(PCI_INT_STAT); 1662 pci_status = cx_read(PCI_INT_STAT);
1642 pci_mask = cx_read(PCI_INT_MSK); 1663 pci_mask = cx_read(PCI_INT_MSK);
@@ -1662,18 +1683,12 @@ static irqreturn_t cx23885_irq(int irq, void *dev_id)
1662 dprintk(7, "ts2_status: 0x%08x ts2_mask: 0x%08x count: 0x%x\n", 1683 dprintk(7, "ts2_status: 0x%08x ts2_mask: 0x%08x count: 0x%x\n",
1663 ts2_status, ts2_mask, ts2_count); 1684 ts2_status, ts2_mask, ts2_count);
1664 1685
1665 if ((pci_status & PCI_MSK_RISC_RD) || 1686 if (pci_status & (PCI_MSK_RISC_RD | PCI_MSK_RISC_WR |
1666 (pci_status & PCI_MSK_RISC_WR) || 1687 PCI_MSK_AL_RD | PCI_MSK_AL_WR | PCI_MSK_APB_DMA |
1667 (pci_status & PCI_MSK_AL_RD) || 1688 PCI_MSK_VID_C | PCI_MSK_VID_B | PCI_MSK_VID_A |
1668 (pci_status & PCI_MSK_AL_WR) || 1689 PCI_MSK_AUD_INT | PCI_MSK_AUD_EXT |
1669 (pci_status & PCI_MSK_APB_DMA) || 1690 PCI_MSK_GPIO0 | PCI_MSK_GPIO1 |
1670 (pci_status & PCI_MSK_VID_C) || 1691 PCI_MSK_IR)) {
1671 (pci_status & PCI_MSK_VID_B) ||
1672 (pci_status & PCI_MSK_VID_A) ||
1673 (pci_status & PCI_MSK_AUD_INT) ||
1674 (pci_status & PCI_MSK_AUD_EXT) ||
1675 (pci_status & PCI_MSK_GPIO0) ||
1676 (pci_status & PCI_MSK_GPIO1)) {
1677 1692
1678 if (pci_status & PCI_MSK_RISC_RD) 1693 if (pci_status & PCI_MSK_RISC_RD)
1679 dprintk(7, " (PCI_MSK_RISC_RD 0x%08x)\n", 1694 dprintk(7, " (PCI_MSK_RISC_RD 0x%08x)\n",
@@ -1722,6 +1737,10 @@ static irqreturn_t cx23885_irq(int irq, void *dev_id)
1722 if (pci_status & PCI_MSK_GPIO1) 1737 if (pci_status & PCI_MSK_GPIO1)
1723 dprintk(7, " (PCI_MSK_GPIO1 0x%08x)\n", 1738 dprintk(7, " (PCI_MSK_GPIO1 0x%08x)\n",
1724 PCI_MSK_GPIO1); 1739 PCI_MSK_GPIO1);
1740
1741 if (pci_status & PCI_MSK_IR)
1742 dprintk(7, " (PCI_MSK_IR 0x%08x)\n",
1743 PCI_MSK_IR);
1725 } 1744 }
1726 1745
1727 if (cx23885_boards[dev->board].cimax > 0 && 1746 if (cx23885_boards[dev->board].cimax > 0 &&
@@ -1752,12 +1771,48 @@ static irqreturn_t cx23885_irq(int irq, void *dev_id)
1752 if (vida_status) 1771 if (vida_status)
1753 handled += cx23885_video_irq(dev, vida_status); 1772 handled += cx23885_video_irq(dev, vida_status);
1754 1773
1774 if (pci_status & PCI_MSK_IR) {
1775 v4l2_subdev_call(dev->sd_ir, ir, interrupt_service_routine,
1776 pci_status, &ir_handled);
1777 if (ir_handled)
1778 handled++;
1779 }
1780
1755 if (handled) 1781 if (handled)
1756 cx_write(PCI_INT_STAT, pci_status); 1782 cx_write(PCI_INT_STAT, pci_status);
1757out: 1783out:
1758 return IRQ_RETVAL(handled); 1784 return IRQ_RETVAL(handled);
1759} 1785}
1760 1786
1787static void cx23885_v4l2_dev_notify(struct v4l2_subdev *sd,
1788 unsigned int notification, void *arg)
1789{
1790 struct cx23885_dev *dev;
1791
1792 if (sd == NULL)
1793 return;
1794
1795 dev = to_cx23885(sd->v4l2_dev);
1796
1797 switch (notification) {
1798 case V4L2_SUBDEV_IR_RX_NOTIFY: /* Called in an IRQ context */
1799 if (sd == dev->sd_ir)
1800 cx23885_ir_rx_v4l2_dev_notify(sd, *(u32 *)arg);
1801 break;
1802 case V4L2_SUBDEV_IR_TX_NOTIFY: /* Called in an IRQ context */
1803 if (sd == dev->sd_ir)
1804 cx23885_ir_tx_v4l2_dev_notify(sd, *(u32 *)arg);
1805 break;
1806 }
1807}
1808
1809static void cx23885_v4l2_dev_notify_init(struct cx23885_dev *dev)
1810{
1811 INIT_WORK(&dev->ir_rx_work, cx23885_ir_rx_work_handler);
1812 INIT_WORK(&dev->ir_tx_work, cx23885_ir_tx_work_handler);
1813 dev->v4l2_dev.notify = cx23885_v4l2_dev_notify;
1814}
1815
1761static inline int encoder_on_portb(struct cx23885_dev *dev) 1816static inline int encoder_on_portb(struct cx23885_dev *dev)
1762{ 1817{
1763 return cx23885_boards[dev->board].portb == CX23885_MPEG_ENCODER; 1818 return cx23885_boards[dev->board].portb == CX23885_MPEG_ENCODER;
@@ -1816,6 +1871,26 @@ void cx23885_gpio_clear(struct cx23885_dev *dev, u32 mask)
1816 printk(KERN_INFO "%s: Unsupported\n", dev->name); 1871 printk(KERN_INFO "%s: Unsupported\n", dev->name);
1817} 1872}
1818 1873
1874u32 cx23885_gpio_get(struct cx23885_dev *dev, u32 mask)
1875{
1876 if (mask & 0x00000007)
1877 return (cx_read(GP0_IO) >> 8) & mask & 0x7;
1878
1879 if (mask & 0x0007fff8) {
1880 if (encoder_on_portb(dev) || encoder_on_portc(dev))
1881 printk(KERN_ERR
1882 "%s: Reading GPIO moving on encoder ports\n",
1883 dev->name);
1884 return (cx_read(MC417_RWD) & ((mask & 0x7fff8) >> 3)) << 3;
1885 }
1886
1887 /* TODO: 23-19 */
1888 if (mask & 0x00f80000)
1889 printk(KERN_INFO "%s: Unsupported\n", dev->name);
1890
1891 return 0;
1892}
1893
1819void cx23885_gpio_enable(struct cx23885_dev *dev, u32 mask, int asoutput) 1894void cx23885_gpio_enable(struct cx23885_dev *dev, u32 mask, int asoutput)
1820{ 1895{
1821 if ((mask & 0x00000007) && asoutput) 1896 if ((mask & 0x00000007) && asoutput)
@@ -1854,6 +1929,9 @@ static int __devinit cx23885_initdev(struct pci_dev *pci_dev,
1854 if (err < 0) 1929 if (err < 0)
1855 goto fail_free; 1930 goto fail_free;
1856 1931
1932 /* Prepare to handle notifications from subdevices */
1933 cx23885_v4l2_dev_notify_init(dev);
1934
1857 /* pci init */ 1935 /* pci init */
1858 dev->pci = pci_dev; 1936 dev->pci = pci_dev;
1859 if (pci_enable_device(pci_dev)) { 1937 if (pci_enable_device(pci_dev)) {
@@ -1896,6 +1974,14 @@ static int __devinit cx23885_initdev(struct pci_dev *pci_dev,
1896 break; 1974 break;
1897 } 1975 }
1898 1976
1977 /*
1978 * The CX2388[58] IR controller can start firing interrupts when
1979 * enabled, so these have to take place after the cx23885_irq() handler
1980 * is hooked up by the call to request_irq() above.
1981 */
1982 cx23885_ir_pci_int_enable(dev);
1983 cx23885_input_init(dev);
1984
1899 return 0; 1985 return 0;
1900 1986
1901fail_irq: 1987fail_irq:
@@ -1912,6 +1998,9 @@ static void __devexit cx23885_finidev(struct pci_dev *pci_dev)
1912 struct v4l2_device *v4l2_dev = pci_get_drvdata(pci_dev); 1998 struct v4l2_device *v4l2_dev = pci_get_drvdata(pci_dev);
1913 struct cx23885_dev *dev = to_cx23885(v4l2_dev); 1999 struct cx23885_dev *dev = to_cx23885(v4l2_dev);
1914 2000
2001 cx23885_input_fini(dev);
2002 cx23885_ir_fini(dev);
2003
1915 cx23885_shutdown(dev); 2004 cx23885_shutdown(dev);
1916 2005
1917 pci_disable_device(pci_dev); 2006 pci_disable_device(pci_dev);
diff --git a/drivers/media/video/cx23885/cx23885-dvb.c b/drivers/media/video/cx23885/cx23885-dvb.c
index 16c6a921f40b..e45d2df08138 100644
--- a/drivers/media/video/cx23885/cx23885-dvb.c
+++ b/drivers/media/video/cx23885/cx23885-dvb.c
@@ -38,6 +38,7 @@
38#include "tda18271.h" 38#include "tda18271.h"
39#include "lgdt330x.h" 39#include "lgdt330x.h"
40#include "xc5000.h" 40#include "xc5000.h"
41#include "max2165.h"
41#include "tda10048.h" 42#include "tda10048.h"
42#include "tuner-xc2028.h" 43#include "tuner-xc2028.h"
43#include "tuner-simple.h" 44#include "tuner-simple.h"
@@ -54,6 +55,9 @@
54#include "netup-eeprom.h" 55#include "netup-eeprom.h"
55#include "netup-init.h" 56#include "netup-init.h"
56#include "lgdt3305.h" 57#include "lgdt3305.h"
58#include "atbm8830.h"
59#include "ds3000.h"
60#include "cx23885-f300.h"
57 61
58static unsigned int debug; 62static unsigned int debug;
59 63
@@ -400,6 +404,7 @@ static struct stv0900_reg stv0900_ts_regs[] = {
400 404
401static struct stv0900_config netup_stv0900_config = { 405static struct stv0900_config netup_stv0900_config = {
402 .demod_address = 0x68, 406 .demod_address = 0x68,
407 .demod_mode = 1, /* dual */
403 .xtal = 8000000, 408 .xtal = 8000000,
404 .clkmode = 3,/* 0-CLKI, 2-XTALI, else AUTO */ 409 .clkmode = 3,/* 0-CLKI, 2-XTALI, else AUTO */
405 .diseqc_mode = 2,/* 2/3 PWM */ 410 .diseqc_mode = 2,/* 2/3 PWM */
@@ -414,34 +419,22 @@ static struct stv6110_config netup_stv6110_tunerconfig_a = {
414 .i2c_address = 0x60, 419 .i2c_address = 0x60,
415 .mclk = 16000000, 420 .mclk = 16000000,
416 .clk_div = 1, 421 .clk_div = 1,
422 .gain = 8, /* +16 dB - maximum gain */
417}; 423};
418 424
419static struct stv6110_config netup_stv6110_tunerconfig_b = { 425static struct stv6110_config netup_stv6110_tunerconfig_b = {
420 .i2c_address = 0x63, 426 .i2c_address = 0x63,
421 .mclk = 16000000, 427 .mclk = 16000000,
422 .clk_div = 1, 428 .clk_div = 1,
429 .gain = 8, /* +16 dB - maximum gain */
423}; 430};
424 431
425static int tbs_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
426{
427 struct cx23885_tsport *port = fe->dvb->priv;
428 struct cx23885_dev *dev = port->dev;
429
430 if (voltage == SEC_VOLTAGE_18)
431 cx_write(MC417_RWD, 0x00001e00);/* GPIO-13 high */
432 else if (voltage == SEC_VOLTAGE_13)
433 cx_write(MC417_RWD, 0x00001a00);/* GPIO-13 low */
434 else
435 cx_write(MC417_RWD, 0x00001800);/* GPIO-12 low */
436 return 0;
437}
438
439static struct cx24116_config tbs_cx24116_config = { 432static struct cx24116_config tbs_cx24116_config = {
440 .demod_address = 0x05, 433 .demod_address = 0x55,
441}; 434};
442 435
443static struct cx24116_config tevii_cx24116_config = { 436static struct ds3000_config tevii_ds3000_config = {
444 .demod_address = 0x55, 437 .demod_address = 0x68,
445}; 438};
446 439
447static struct cx24116_config dvbworld_cx24116_config = { 440static struct cx24116_config dvbworld_cx24116_config = {
@@ -486,11 +479,40 @@ static int cx23885_dvb_set_frontend(struct dvb_frontend *fe,
486 break; 479 break;
487 } 480 }
488 break; 481 break;
482 case CX23885_BOARD_MYGICA_X8506:
483 case CX23885_BOARD_MAGICPRO_PROHDTVE2:
484 /* Select Digital TV */
485 cx23885_gpio_set(dev, GPIO_0);
486 break;
489 } 487 }
490 return (port->set_frontend_save) ? 488 return 0;
491 port->set_frontend_save(fe, param) : -ENODEV;
492} 489}
493 490
491static int cx23885_dvb_fe_ioctl_override(struct dvb_frontend *fe,
492 unsigned int cmd, void *parg,
493 unsigned int stage)
494{
495 int err = 0;
496
497 switch (stage) {
498 case DVB_FE_IOCTL_PRE:
499
500 switch (cmd) {
501 case FE_SET_FRONTEND:
502 err = cx23885_dvb_set_frontend(fe,
503 (struct dvb_frontend_parameters *) parg);
504 break;
505 }
506 break;
507
508 case DVB_FE_IOCTL_POST:
509 /* no post-ioctl handling required */
510 break;
511 }
512 return err;
513};
514
515
494static struct lgs8gxx_config magicpro_prohdtve2_lgs8g75_config = { 516static struct lgs8gxx_config magicpro_prohdtve2_lgs8g75_config = {
495 .prod = LGS8GXX_PROD_LGS8G75, 517 .prod = LGS8GXX_PROD_LGS8G75,
496 .demod_address = 0x19, 518 .demod_address = 0x19,
@@ -511,6 +533,38 @@ static struct xc5000_config magicpro_prohdtve2_xc5000_config = {
511 .if_khz = 6500, 533 .if_khz = 6500,
512}; 534};
513 535
536static struct atbm8830_config mygica_x8558pro_atbm8830_cfg1 = {
537 .prod = ATBM8830_PROD_8830,
538 .demod_address = 0x44,
539 .serial_ts = 0,
540 .ts_sampling_edge = 1,
541 .ts_clk_gated = 0,
542 .osc_clk_freq = 30400, /* in kHz */
543 .if_freq = 0, /* zero IF */
544 .zif_swap_iq = 1,
545};
546
547static struct max2165_config mygic_x8558pro_max2165_cfg1 = {
548 .i2c_address = 0x60,
549 .osc_clk = 20
550};
551
552static struct atbm8830_config mygica_x8558pro_atbm8830_cfg2 = {
553 .prod = ATBM8830_PROD_8830,
554 .demod_address = 0x44,
555 .serial_ts = 1,
556 .ts_sampling_edge = 1,
557 .ts_clk_gated = 0,
558 .osc_clk_freq = 30400, /* in kHz */
559 .if_freq = 0, /* zero IF */
560 .zif_swap_iq = 1,
561};
562
563static struct max2165_config mygic_x8558pro_max2165_cfg2 = {
564 .i2c_address = 0x60,
565 .osc_clk = 20
566};
567
514static int dvb_register(struct cx23885_tsport *port) 568static int dvb_register(struct cx23885_tsport *port)
515{ 569{
516 struct cx23885_dev *dev = port->dev; 570 struct cx23885_dev *dev = port->dev;
@@ -550,12 +604,6 @@ static int dvb_register(struct cx23885_tsport *port)
550 0x60, &dev->i2c_bus[1].i2c_adap, 604 0x60, &dev->i2c_bus[1].i2c_adap,
551 &hauppauge_hvr127x_config); 605 &hauppauge_hvr127x_config);
552 } 606 }
553
554 /* FIXME: temporary hack */
555 /* define bridge override to set_frontend */
556 port->set_frontend_save = fe0->dvb.frontend->ops.set_frontend;
557 fe0->dvb.frontend->ops.set_frontend = cx23885_dvb_set_frontend;
558
559 break; 607 break;
560 case CX23885_BOARD_HAUPPAUGE_HVR1255: 608 case CX23885_BOARD_HAUPPAUGE_HVR1255:
561 i2c_bus = &dev->i2c_bus[0]; 609 i2c_bus = &dev->i2c_bus[0];
@@ -772,23 +820,23 @@ static int dvb_register(struct cx23885_tsport *port)
772 } 820 }
773 break; 821 break;
774 case CX23885_BOARD_TBS_6920: 822 case CX23885_BOARD_TBS_6920:
775 i2c_bus = &dev->i2c_bus[0]; 823 i2c_bus = &dev->i2c_bus[1];
776 824
777 fe0->dvb.frontend = dvb_attach(cx24116_attach, 825 fe0->dvb.frontend = dvb_attach(cx24116_attach,
778 &tbs_cx24116_config, 826 &tbs_cx24116_config,
779 &i2c_bus->i2c_adap); 827 &i2c_bus->i2c_adap);
780 if (fe0->dvb.frontend != NULL) 828 if (fe0->dvb.frontend != NULL)
781 fe0->dvb.frontend->ops.set_voltage = tbs_set_voltage; 829 fe0->dvb.frontend->ops.set_voltage = f300_set_voltage;
782 830
783 break; 831 break;
784 case CX23885_BOARD_TEVII_S470: 832 case CX23885_BOARD_TEVII_S470:
785 i2c_bus = &dev->i2c_bus[1]; 833 i2c_bus = &dev->i2c_bus[1];
786 834
787 fe0->dvb.frontend = dvb_attach(cx24116_attach, 835 fe0->dvb.frontend = dvb_attach(ds3000_attach,
788 &tevii_cx24116_config, 836 &tevii_ds3000_config,
789 &i2c_bus->i2c_adap); 837 &i2c_bus->i2c_adap);
790 if (fe0->dvb.frontend != NULL) 838 if (fe0->dvb.frontend != NULL)
791 fe0->dvb.frontend->ops.set_voltage = tbs_set_voltage; 839 fe0->dvb.frontend->ops.set_voltage = f300_set_voltage;
792 840
793 break; 841 break;
794 case CX23885_BOARD_DVBWORLD_2005: 842 case CX23885_BOARD_DVBWORLD_2005:
@@ -814,8 +862,8 @@ static int dvb_register(struct cx23885_tsport *port)
814 if (!dvb_attach(lnbh24_attach, 862 if (!dvb_attach(lnbh24_attach,
815 fe0->dvb.frontend, 863 fe0->dvb.frontend,
816 &i2c_bus->i2c_adap, 864 &i2c_bus->i2c_adap,
817 LNBH24_PCL, 865 LNBH24_PCL | LNBH24_TTX,
818 LNBH24_TTX, 0x09)) 866 LNBH24_TEN, 0x09))
819 printk(KERN_ERR 867 printk(KERN_ERR
820 "No LNBH24 found!\n"); 868 "No LNBH24 found!\n");
821 869
@@ -835,8 +883,8 @@ static int dvb_register(struct cx23885_tsport *port)
835 if (!dvb_attach(lnbh24_attach, 883 if (!dvb_attach(lnbh24_attach,
836 fe0->dvb.frontend, 884 fe0->dvb.frontend,
837 &i2c_bus->i2c_adap, 885 &i2c_bus->i2c_adap,
838 LNBH24_PCL, 886 LNBH24_PCL | LNBH24_TTX,
839 LNBH24_TTX, 0x0a)) 887 LNBH24_TEN, 0x0a))
840 printk(KERN_ERR 888 printk(KERN_ERR
841 "No LNBH24 found!\n"); 889 "No LNBH24 found!\n");
842 890
@@ -872,6 +920,7 @@ static int dvb_register(struct cx23885_tsport *port)
872 } 920 }
873 break; 921 break;
874 case CX23885_BOARD_HAUPPAUGE_HVR1850: 922 case CX23885_BOARD_HAUPPAUGE_HVR1850:
923 case CX23885_BOARD_HAUPPAUGE_HVR1290:
875 i2c_bus = &dev->i2c_bus[0]; 924 i2c_bus = &dev->i2c_bus[0];
876 fe0->dvb.frontend = dvb_attach(s5h1411_attach, 925 fe0->dvb.frontend = dvb_attach(s5h1411_attach,
877 &hcw_s5h1411_config, 926 &hcw_s5h1411_config,
@@ -881,6 +930,36 @@ static int dvb_register(struct cx23885_tsport *port)
881 0x60, &dev->i2c_bus[0].i2c_adap, 930 0x60, &dev->i2c_bus[0].i2c_adap,
882 &hauppauge_tda18271_config); 931 &hauppauge_tda18271_config);
883 break; 932 break;
933 case CX23885_BOARD_MYGICA_X8558PRO:
934 switch (port->nr) {
935 /* port B */
936 case 1:
937 i2c_bus = &dev->i2c_bus[0];
938 fe0->dvb.frontend = dvb_attach(atbm8830_attach,
939 &mygica_x8558pro_atbm8830_cfg1,
940 &i2c_bus->i2c_adap);
941 if (fe0->dvb.frontend != NULL) {
942 dvb_attach(max2165_attach,
943 fe0->dvb.frontend,
944 &i2c_bus->i2c_adap,
945 &mygic_x8558pro_max2165_cfg1);
946 }
947 break;
948 /* port C */
949 case 2:
950 i2c_bus = &dev->i2c_bus[1];
951 fe0->dvb.frontend = dvb_attach(atbm8830_attach,
952 &mygica_x8558pro_atbm8830_cfg2,
953 &i2c_bus->i2c_adap);
954 if (fe0->dvb.frontend != NULL) {
955 dvb_attach(max2165_attach,
956 fe0->dvb.frontend,
957 &i2c_bus->i2c_adap,
958 &mygic_x8558pro_max2165_cfg2);
959 }
960 break;
961 }
962 break;
884 963
885 default: 964 default:
886 printk(KERN_INFO "%s: The frontend of your DVB/ATSC card " 965 printk(KERN_INFO "%s: The frontend of your DVB/ATSC card "
@@ -897,14 +976,15 @@ static int dvb_register(struct cx23885_tsport *port)
897 fe0->dvb.frontend->callback = cx23885_tuner_callback; 976 fe0->dvb.frontend->callback = cx23885_tuner_callback;
898 977
899 /* Put the analog decoder in standby to keep it quiet */ 978 /* Put the analog decoder in standby to keep it quiet */
900 call_all(dev, tuner, s_standby); 979 call_all(dev, core, s_power, 0);
901 980
902 if (fe0->dvb.frontend->ops.analog_ops.standby) 981 if (fe0->dvb.frontend->ops.analog_ops.standby)
903 fe0->dvb.frontend->ops.analog_ops.standby(fe0->dvb.frontend); 982 fe0->dvb.frontend->ops.analog_ops.standby(fe0->dvb.frontend);
904 983
905 /* register everything */ 984 /* register everything */
906 ret = videobuf_dvb_register_bus(&port->frontends, THIS_MODULE, port, 985 ret = videobuf_dvb_register_bus(&port->frontends, THIS_MODULE, port,
907 &dev->pci->dev, adapter_nr, 0); 986 &dev->pci->dev, adapter_nr, 0,
987 cx23885_dvb_fe_ioctl_override);
908 988
909 /* init CI & MAC */ 989 /* init CI & MAC */
910 switch (dev->board) { 990 switch (dev->board) {
diff --git a/drivers/media/video/cx23885/cx23885-f300.c b/drivers/media/video/cx23885/cx23885-f300.c
new file mode 100644
index 000000000000..93998f220986
--- /dev/null
+++ b/drivers/media/video/cx23885/cx23885-f300.c
@@ -0,0 +1,177 @@
1/*
2 * Driver for Silicon Labs C8051F300 microcontroller.
3 *
4 * It is used for LNB power control in TeVii S470,
5 * TBS 6920 PCIe DVB-S2 cards.
6 *
7 * Microcontroller connected to cx23885 GPIO pins:
8 * GPIO0 - data - P0.3 F300
9 * GPIO1 - reset - P0.2 F300
10 * GPIO2 - clk - P0.1 F300
11 * GPIO3 - busy - P0.0 F300
12 *
13 * Copyright (C) 2009 Igor M. Liplianin <liplianin@me.by>
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 *
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29 */
30
31#include "cx23885.h"
32
33#define F300_DATA GPIO_0
34#define F300_RESET GPIO_1
35#define F300_CLK GPIO_2
36#define F300_BUSY GPIO_3
37
38static void f300_set_line(struct cx23885_dev *dev, u32 line, u8 lvl)
39{
40 cx23885_gpio_enable(dev, line, 1);
41 if (lvl == 1)
42 cx23885_gpio_set(dev, line);
43 else
44 cx23885_gpio_clear(dev, line);
45}
46
47static u8 f300_get_line(struct cx23885_dev *dev, u32 line)
48{
49 cx23885_gpio_enable(dev, line, 0);
50
51 return cx23885_gpio_get(dev, line);
52}
53
54static void f300_send_byte(struct cx23885_dev *dev, u8 dta)
55{
56 u8 i;
57
58 for (i = 0; i < 8; i++) {
59 f300_set_line(dev, F300_CLK, 0);
60 udelay(30);
61 f300_set_line(dev, F300_DATA, (dta & 0x80) >> 7);/* msb first */
62 udelay(30);
63 dta <<= 1;
64 f300_set_line(dev, F300_CLK, 1);
65 udelay(30);
66 }
67}
68
69static u8 f300_get_byte(struct cx23885_dev *dev)
70{
71 u8 i, dta = 0;
72
73 for (i = 0; i < 8; i++) {
74 f300_set_line(dev, F300_CLK, 0);
75 udelay(30);
76 dta <<= 1;
77 f300_set_line(dev, F300_CLK, 1);
78 udelay(30);
79 dta |= f300_get_line(dev, F300_DATA);/* msb first */
80
81 }
82
83 return dta;
84}
85
86static u8 f300_xfer(struct dvb_frontend *fe, u8 *buf)
87{
88 struct cx23885_tsport *port = fe->dvb->priv;
89 struct cx23885_dev *dev = port->dev;
90 u8 i, temp, ret = 0;
91
92 temp = buf[0];
93 for (i = 0; i < buf[0]; i++)
94 temp += buf[i + 1];
95 temp = (~temp + 1);/* get check sum */
96 buf[1 + buf[0]] = temp;
97
98 f300_set_line(dev, F300_RESET, 1);
99 f300_set_line(dev, F300_CLK, 1);
100 udelay(30);
101 f300_set_line(dev, F300_DATA, 1);
102 msleep(1);
103
104 /* question: */
105 f300_set_line(dev, F300_RESET, 0);/* begin to send data */
106 msleep(1);
107
108 f300_send_byte(dev, 0xe0);/* the slave address is 0xe0, write */
109 msleep(1);
110
111 temp = buf[0];
112 temp += 2;
113 for (i = 0; i < temp; i++)
114 f300_send_byte(dev, buf[i]);
115
116 f300_set_line(dev, F300_RESET, 1);/* sent data over */
117 f300_set_line(dev, F300_DATA, 1);
118
119 /* answer: */
120 temp = 0;
121 for (i = 0; ((i < 8) & (temp == 0)); i++) {
122 msleep(1);
123 if (f300_get_line(dev, F300_BUSY) == 0)
124 temp = 1;
125 }
126
127 if (i > 7) {
128 printk(KERN_ERR "%s: timeout, the slave no response\n",
129 __func__);
130 ret = 1; /* timeout, the slave no response */
131 } else { /* the slave not busy, prepare for getting data */
132 f300_set_line(dev, F300_RESET, 0);/*ready...*/
133 msleep(1);
134 f300_send_byte(dev, 0xe1);/* 0xe1 is Read */
135 msleep(1);
136 temp = f300_get_byte(dev);/*get the data length */
137 if (temp > 14)
138 temp = 14;
139
140 for (i = 0; i < (temp + 1); i++)
141 f300_get_byte(dev);/* get data to empty buffer */
142
143 f300_set_line(dev, F300_RESET, 1);/* received data over */
144 f300_set_line(dev, F300_DATA, 1);
145 }
146
147 return ret;
148}
149
150int f300_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
151{
152 u8 buf[16];
153
154 buf[0] = 0x05;
155 buf[1] = 0x38;/* write port */
156 buf[2] = 0x01;/* A port, lnb power */
157
158 switch (voltage) {
159 case SEC_VOLTAGE_13:
160 buf[3] = 0x01;/* power on */
161 buf[4] = 0x02;/* B port, H/V */
162 buf[5] = 0x00;/*13V v*/
163 break;
164 case SEC_VOLTAGE_18:
165 buf[3] = 0x01;
166 buf[4] = 0x02;
167 buf[5] = 0x01;/* 18V h*/
168 break;
169 case SEC_VOLTAGE_OFF:
170 buf[3] = 0x00;/* power off */
171 buf[4] = 0x00;
172 buf[5] = 0x00;
173 break;
174 }
175
176 return f300_xfer(fe, buf);
177}
diff --git a/drivers/media/video/cx23885/cx23885-f300.h b/drivers/media/video/cx23885/cx23885-f300.h
new file mode 100644
index 000000000000..e73344c94963
--- /dev/null
+++ b/drivers/media/video/cx23885/cx23885-f300.h
@@ -0,0 +1,2 @@
1extern int f300_set_voltage(struct dvb_frontend *fe,
2 fe_sec_voltage_t voltage);
diff --git a/drivers/media/video/cx23885/cx23885-input.c b/drivers/media/video/cx23885/cx23885-input.c
new file mode 100644
index 000000000000..469e083dd5f8
--- /dev/null
+++ b/drivers/media/video/cx23885/cx23885-input.c
@@ -0,0 +1,427 @@
1/*
2 * Driver for the Conexant CX23885/7/8 PCIe bridge
3 *
4 * Infrared remote control input device
5 *
6 * Most of this file is
7 *
8 * Copyright (C) 2009 Andy Walls <awalls@radix.net>
9 *
10 * However, the cx23885_input_{init,fini} functions contained herein are
11 * derived from Linux kernel files linux/media/video/.../...-input.c marked as:
12 *
13 * Copyright (C) 2008 <srinivasa.deevi at conexant dot com>
14 * Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it>
15 * Markus Rechberger <mrechberger@gmail.com>
16 * Mauro Carvalho Chehab <mchehab@infradead.org>
17 * Sascha Sommer <saschasommer@freenet.de>
18 * Copyright (C) 2004, 2005 Chris Pascoe
19 * Copyright (C) 2003, 2004 Gerd Knorr
20 * Copyright (C) 2003 Pavel Machek
21 *
22 * This program is free software; you can redistribute it and/or
23 * modify it under the terms of the GNU General Public License
24 * as published by the Free Software Foundation; either version 2
25 * of the License, or (at your option) any later version.
26 *
27 * This program is distributed in the hope that it will be useful,
28 * but WITHOUT ANY WARRANTY; without even the implied warranty of
29 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30 * GNU General Public License for more details.
31 *
32 * You should have received a copy of the GNU General Public License
33 * along with this program; if not, write to the Free Software
34 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
35 * 02110-1301, USA.
36 */
37
38#include <linux/input.h>
39#include <media/ir-common.h>
40#include <media/v4l2-subdev.h>
41
42#include "cx23885.h"
43
44#define RC5_BITS 14
45#define RC5_HALF_BITS (2*RC5_BITS)
46#define RC5_HALF_BITS_MASK ((1 << RC5_HALF_BITS) - 1)
47
48#define RC5_START_BITS_NORMAL 0x3 /* Command range 0 - 63 */
49#define RC5_START_BITS_EXTENDED 0x2 /* Command range 64 - 127 */
50
51#define RC5_EXTENDED_COMMAND_OFFSET 64
52
53static inline unsigned int rc5_command(u32 rc5_baseband)
54{
55 return RC5_INSTR(rc5_baseband) +
56 ((RC5_START(rc5_baseband) == RC5_START_BITS_EXTENDED)
57 ? RC5_EXTENDED_COMMAND_OFFSET : 0);
58}
59
60static void cx23885_input_process_raw_rc5(struct cx23885_dev *dev)
61{
62 struct card_ir *ir_input = dev->ir_input;
63 unsigned int code, command;
64 u32 rc5;
65
66 /* Ignore codes that are too short to be valid RC-5 */
67 if (ir_input->last_bit < (RC5_HALF_BITS - 1))
68 return;
69
70 /* The library has the manchester coding backwards; XOR to adapt. */
71 code = (ir_input->code & RC5_HALF_BITS_MASK) ^ RC5_HALF_BITS_MASK;
72 rc5 = ir_rc5_decode(code);
73
74 switch (RC5_START(rc5)) {
75 case RC5_START_BITS_NORMAL:
76 break;
77 case RC5_START_BITS_EXTENDED:
78 /* Don't allow if the remote only emits standard commands */
79 if (ir_input->start == RC5_START_BITS_NORMAL)
80 return;
81 break;
82 default:
83 return;
84 }
85
86 if (ir_input->addr != RC5_ADDR(rc5))
87 return;
88
89 /* Don't generate a keypress for RC-5 auto-repeated keypresses */
90 command = rc5_command(rc5);
91 if (RC5_TOGGLE(rc5) != RC5_TOGGLE(ir_input->last_rc5) ||
92 command != rc5_command(ir_input->last_rc5) ||
93 /* Catch T == 0, CMD == 0 (e.g. '0') as first keypress after init */
94 RC5_START(ir_input->last_rc5) == 0) {
95 /* This keypress is differnet: not an auto repeat */
96 ir_input_nokey(ir_input->dev, &ir_input->ir);
97 ir_input_keydown(ir_input->dev, &ir_input->ir, command);
98 }
99 ir_input->last_rc5 = rc5;
100
101 /* Schedule when we should do the key up event: ir_input_nokey() */
102 mod_timer(&ir_input->timer_keyup,
103 jiffies + msecs_to_jiffies(ir_input->rc5_key_timeout));
104}
105
106static void cx23885_input_next_pulse_width_rc5(struct cx23885_dev *dev,
107 u32 ns_pulse)
108{
109 const int rc5_quarterbit_ns = 444444; /* 32 cycles/36 kHz/2 = 444 us */
110 struct card_ir *ir_input = dev->ir_input;
111 int i, level, quarterbits, halfbits;
112
113 if (!ir_input->active) {
114 ir_input->active = 1;
115 /* assume an initial space that we may not detect or measure */
116 ir_input->code = 0;
117 ir_input->last_bit = 0;
118 }
119
120 if (ns_pulse == V4L2_SUBDEV_IR_PULSE_RX_SEQ_END) {
121 ir_input->last_bit++; /* Account for the final space */
122 ir_input->active = 0;
123 cx23885_input_process_raw_rc5(dev);
124 return;
125 }
126
127 level = (ns_pulse & V4L2_SUBDEV_IR_PULSE_LEVEL_MASK) ? 1 : 0;
128
129 /* Skip any leading space to sync to the start bit */
130 if (ir_input->last_bit == 0 && level == 0)
131 return;
132
133 /*
134 * With valid RC-5 we can get up to two consecutive half-bits in a
135 * single pulse measurment. Experiments have shown that the duration
136 * of a half-bit can vary. Make sure we always end up with an even
137 * number of quarter bits at the same level (mark or space).
138 */
139 ns_pulse &= V4L2_SUBDEV_IR_PULSE_MAX_WIDTH_NS;
140 quarterbits = ns_pulse / rc5_quarterbit_ns;
141 if (quarterbits & 1)
142 quarterbits++;
143 halfbits = quarterbits / 2;
144
145 for (i = 0; i < halfbits; i++) {
146 ir_input->last_bit++;
147 ir_input->code |= (level << ir_input->last_bit);
148
149 if (ir_input->last_bit >= RC5_HALF_BITS-1) {
150 ir_input->active = 0;
151 cx23885_input_process_raw_rc5(dev);
152 /*
153 * If level is 1, a leading mark is invalid for RC5.
154 * If level is 0, we scan past extra intial space.
155 * Either way we don't want to reactivate collecting
156 * marks or spaces here with any left over half-bits.
157 */
158 break;
159 }
160 }
161}
162
163static void cx23885_input_process_pulse_widths_rc5(struct cx23885_dev *dev,
164 bool add_eom)
165{
166 struct card_ir *ir_input = dev->ir_input;
167 struct ir_input_state *ir_input_state = &ir_input->ir;
168
169 u32 ns_pulse[RC5_HALF_BITS+1];
170 ssize_t num = 0;
171 int count, i;
172
173 do {
174 v4l2_subdev_call(dev->sd_ir, ir, rx_read, (u8 *) ns_pulse,
175 sizeof(ns_pulse), &num);
176
177 count = num / sizeof(u32);
178
179 /* Append an end of Rx seq, if the caller requested */
180 if (add_eom && count < ARRAY_SIZE(ns_pulse)) {
181 ns_pulse[count] = V4L2_SUBDEV_IR_PULSE_RX_SEQ_END;
182 count++;
183 }
184
185 /* Just drain the Rx FIFO, if we're called, but not RC-5 */
186 if (ir_input_state->ir_type != IR_TYPE_RC5)
187 continue;
188
189 for (i = 0; i < count; i++)
190 cx23885_input_next_pulse_width_rc5(dev, ns_pulse[i]);
191 } while (num != 0);
192}
193
194void cx23885_input_rx_work_handler(struct cx23885_dev *dev, u32 events)
195{
196 struct v4l2_subdev_ir_parameters params;
197 int overrun, data_available;
198
199 if (dev->sd_ir == NULL || events == 0)
200 return;
201
202 switch (dev->board) {
203 case CX23885_BOARD_HAUPPAUGE_HVR1850:
204 case CX23885_BOARD_HAUPPAUGE_HVR1290:
205 /*
206 * The only board we handle right now. However other boards
207 * using the CX2388x integrated IR controller should be similar
208 */
209 break;
210 default:
211 return;
212 }
213
214 overrun = events & (V4L2_SUBDEV_IR_RX_SW_FIFO_OVERRUN |
215 V4L2_SUBDEV_IR_RX_HW_FIFO_OVERRUN);
216
217 data_available = events & (V4L2_SUBDEV_IR_RX_END_OF_RX_DETECTED |
218 V4L2_SUBDEV_IR_RX_FIFO_SERVICE_REQ);
219
220 if (overrun) {
221 /* If there was a FIFO overrun, stop the device */
222 v4l2_subdev_call(dev->sd_ir, ir, rx_g_parameters, &params);
223 params.enable = false;
224 /* Mitigate race with cx23885_input_ir_stop() */
225 params.shutdown = atomic_read(&dev->ir_input_stopping);
226 v4l2_subdev_call(dev->sd_ir, ir, rx_s_parameters, &params);
227 }
228
229 if (data_available)
230 cx23885_input_process_pulse_widths_rc5(dev, overrun);
231
232 if (overrun) {
233 /* If there was a FIFO overrun, clear & restart the device */
234 params.enable = true;
235 /* Mitigate race with cx23885_input_ir_stop() */
236 params.shutdown = atomic_read(&dev->ir_input_stopping);
237 v4l2_subdev_call(dev->sd_ir, ir, rx_s_parameters, &params);
238 }
239}
240
241static void cx23885_input_ir_start(struct cx23885_dev *dev)
242{
243 struct card_ir *ir_input = dev->ir_input;
244 struct ir_input_state *ir_input_state = &ir_input->ir;
245 struct v4l2_subdev_ir_parameters params;
246
247 if (dev->sd_ir == NULL)
248 return;
249
250 atomic_set(&dev->ir_input_stopping, 0);
251
252 /* keyup timer set up, if needed */
253 switch (dev->board) {
254 case CX23885_BOARD_HAUPPAUGE_HVR1850:
255 case CX23885_BOARD_HAUPPAUGE_HVR1290:
256 setup_timer(&ir_input->timer_keyup,
257 ir_rc5_timer_keyup, /* Not actually RC-5 specific */
258 (unsigned long) ir_input);
259 if (ir_input_state->ir_type == IR_TYPE_RC5) {
260 /*
261 * RC-5 repeats a held key every
262 * 64 bits * (2 * 32/36000) sec/bit = 113.778 ms
263 */
264 ir_input->rc5_key_timeout = 115;
265 }
266 break;
267 }
268
269 v4l2_subdev_call(dev->sd_ir, ir, rx_g_parameters, &params);
270 switch (dev->board) {
271 case CX23885_BOARD_HAUPPAUGE_HVR1850:
272 case CX23885_BOARD_HAUPPAUGE_HVR1290:
273 /*
274 * The IR controller on this board only returns pulse widths.
275 * Any other mode setting will fail to set up the device.
276 */
277 params.mode = V4L2_SUBDEV_IR_MODE_PULSE_WIDTH;
278 params.enable = true;
279 params.interrupt_enable = true;
280 params.shutdown = false;
281
282 /* Setup for baseband compatible with both RC-5 and RC-6A */
283 params.modulation = false;
284 /* RC-5: 2,222,222 ns = 1/36 kHz * 32 cycles * 2 marks * 1.25*/
285 /* RC-6A: 3,333,333 ns = 1/36 kHz * 16 cycles * 6 marks * 1.25*/
286 params.max_pulse_width = 3333333; /* ns */
287 /* RC-5: 666,667 ns = 1/36 kHz * 32 cycles * 1 mark * 0.75 */
288 /* RC-6A: 333,333 ns = 1/36 kHz * 16 cycles * 1 mark * 0.75 */
289 params.noise_filter_min_width = 333333; /* ns */
290 /*
291 * This board has inverted receive sense:
292 * mark is received as low logic level;
293 * falling edges are detected as rising edges; etc.
294 */
295 params.invert = true;
296 break;
297 }
298 v4l2_subdev_call(dev->sd_ir, ir, rx_s_parameters, &params);
299}
300
301static void cx23885_input_ir_stop(struct cx23885_dev *dev)
302{
303 struct card_ir *ir_input = dev->ir_input;
304 struct v4l2_subdev_ir_parameters params;
305
306 if (dev->sd_ir == NULL)
307 return;
308
309 /*
310 * Stop the sd_ir subdevice from generating notifications and
311 * scheduling work.
312 * It is shutdown this way in order to mitigate a race with
313 * cx23885_input_rx_work_handler() in the overrun case, which could
314 * re-enable the subdevice.
315 */
316 atomic_set(&dev->ir_input_stopping, 1);
317 v4l2_subdev_call(dev->sd_ir, ir, rx_g_parameters, &params);
318 while (params.shutdown == false) {
319 params.enable = false;
320 params.interrupt_enable = false;
321 params.shutdown = true;
322 v4l2_subdev_call(dev->sd_ir, ir, rx_s_parameters, &params);
323 v4l2_subdev_call(dev->sd_ir, ir, rx_g_parameters, &params);
324 }
325
326 flush_scheduled_work();
327
328 switch (dev->board) {
329 case CX23885_BOARD_HAUPPAUGE_HVR1850:
330 case CX23885_BOARD_HAUPPAUGE_HVR1290:
331 del_timer_sync(&ir_input->timer_keyup);
332 break;
333 }
334}
335
336int cx23885_input_init(struct cx23885_dev *dev)
337{
338 struct card_ir *ir;
339 struct input_dev *input_dev;
340 struct ir_scancode_table *ir_codes = NULL;
341 int ir_type, ir_addr, ir_start;
342 int ret;
343
344 /*
345 * If the IR device (hardware registers, chip, GPIO lines, etc.) isn't
346 * encapsulated in a v4l2_subdev, then I'm not going to deal with it.
347 */
348 if (dev->sd_ir == NULL)
349 return -ENODEV;
350
351 switch (dev->board) {
352 case CX23885_BOARD_HAUPPAUGE_HVR1850:
353 case CX23885_BOARD_HAUPPAUGE_HVR1290:
354 /* Parameters for the grey Hauppauge remote for the HVR-1850 */
355 ir_codes = &ir_codes_hauppauge_new_table;
356 ir_type = IR_TYPE_RC5;
357 ir_addr = 0x1e; /* RC-5 system bits emitted by the remote */
358 ir_start = RC5_START_BITS_NORMAL; /* A basic RC-5 remote */
359 break;
360 }
361 if (ir_codes == NULL)
362 return -ENODEV;
363
364 ir = kzalloc(sizeof(*ir), GFP_KERNEL);
365 input_dev = input_allocate_device();
366 if (!ir || !input_dev) {
367 ret = -ENOMEM;
368 goto err_out_free;
369 }
370
371 ir->dev = input_dev;
372 ir->addr = ir_addr;
373 ir->start = ir_start;
374
375 /* init input device */
376 snprintf(ir->name, sizeof(ir->name), "cx23885 IR (%s)",
377 cx23885_boards[dev->board].name);
378 snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0", pci_name(dev->pci));
379
380 ret = ir_input_init(input_dev, &ir->ir, ir_type, ir_codes);
381 if (ret < 0)
382 goto err_out_free;
383
384 input_dev->name = ir->name;
385 input_dev->phys = ir->phys;
386 input_dev->id.bustype = BUS_PCI;
387 input_dev->id.version = 1;
388 if (dev->pci->subsystem_vendor) {
389 input_dev->id.vendor = dev->pci->subsystem_vendor;
390 input_dev->id.product = dev->pci->subsystem_device;
391 } else {
392 input_dev->id.vendor = dev->pci->vendor;
393 input_dev->id.product = dev->pci->device;
394 }
395 input_dev->dev.parent = &dev->pci->dev;
396
397 dev->ir_input = ir;
398 cx23885_input_ir_start(dev);
399
400 ret = input_register_device(ir->dev);
401 if (ret)
402 goto err_out_stop;
403
404 return 0;
405
406err_out_stop:
407 cx23885_input_ir_stop(dev);
408 dev->ir_input = NULL;
409err_out_free:
410 ir_input_free(input_dev);
411 input_free_device(input_dev);
412 kfree(ir);
413 return ret;
414}
415
416void cx23885_input_fini(struct cx23885_dev *dev)
417{
418 /* Always stop the IR hardware from generating interrupts */
419 cx23885_input_ir_stop(dev);
420
421 if (dev->ir_input == NULL)
422 return;
423 ir_input_free(dev->ir_input->dev);
424 input_unregister_device(dev->ir_input->dev);
425 kfree(dev->ir_input);
426 dev->ir_input = NULL;
427}
diff --git a/drivers/media/video/cx23885/cx23885-input.h b/drivers/media/video/cx23885/cx23885-input.h
new file mode 100644
index 000000000000..3572cb1ecfc2
--- /dev/null
+++ b/drivers/media/video/cx23885/cx23885-input.h
@@ -0,0 +1,30 @@
1/*
2 * Driver for the Conexant CX23885/7/8 PCIe bridge
3 *
4 * Infrared remote control input device
5 *
6 * Copyright (C) 2009 Andy Walls <awalls@radix.net>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 * 02110-1301, USA.
22 */
23
24#ifndef _CX23885_INPUT_H_
25#define _CX23885_INPUT_H_
26int cx23885_input_rx_work_handler(struct cx23885_dev *dev, u32 events);
27
28int cx23885_input_init(struct cx23885_dev *dev);
29void cx23885_input_fini(struct cx23885_dev *dev);
30#endif
diff --git a/drivers/media/video/cx23885/cx23885-ioctl.c b/drivers/media/video/cx23885/cx23885-ioctl.c
new file mode 100644
index 000000000000..dfb4627fb340
--- /dev/null
+++ b/drivers/media/video/cx23885/cx23885-ioctl.c
@@ -0,0 +1,208 @@
1/*
2 * Driver for the Conexant CX23885/7/8 PCIe bridge
3 *
4 * Various common ioctl() support functions
5 *
6 * Copyright (c) 2009 Andy Walls <awalls@radix.net>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 *
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24#include "cx23885.h"
25#include <media/v4l2-chip-ident.h>
26
27int cx23885_g_chip_ident(struct file *file, void *fh,
28 struct v4l2_dbg_chip_ident *chip)
29{
30 struct cx23885_dev *dev = ((struct cx23885_fh *)fh)->dev;
31 int err = 0;
32 u8 rev;
33
34 chip->ident = V4L2_IDENT_NONE;
35 chip->revision = 0;
36 switch (chip->match.type) {
37 case V4L2_CHIP_MATCH_HOST:
38 switch (chip->match.addr) {
39 case 0:
40 rev = cx_read(RDR_CFG2) & 0xff;
41 switch (dev->pci->device) {
42 case 0x8852:
43 /* rev 0x04 could be '885 or '888. Pick '888. */
44 if (rev == 0x04)
45 chip->ident = V4L2_IDENT_CX23888;
46 else
47 chip->ident = V4L2_IDENT_CX23885;
48 break;
49 case 0x8880:
50 if (rev == 0x0e || rev == 0x0f)
51 chip->ident = V4L2_IDENT_CX23887;
52 else
53 chip->ident = V4L2_IDENT_CX23888;
54 break;
55 default:
56 chip->ident = V4L2_IDENT_UNKNOWN;
57 break;
58 }
59 chip->revision = (dev->pci->device << 16) | (rev << 8) |
60 (dev->hwrevision & 0xff);
61 break;
62 case 1:
63 if (dev->v4l_device != NULL) {
64 chip->ident = V4L2_IDENT_CX23417;
65 chip->revision = 0;
66 }
67 break;
68 case 2:
69 /*
70 * The integrated IR controller on the CX23888 is
71 * host chip 2. It may not be used/initialized or sd_ir
72 * may be pointing at the cx25840 subdevice for the
73 * IR controller on the CX23885. Thus we find it
74 * without using the dev->sd_ir pointer.
75 */
76 call_hw(dev, CX23885_HW_888_IR, core, g_chip_ident,
77 chip);
78 break;
79 default:
80 err = -EINVAL; /* per V4L2 spec */
81 break;
82 }
83 break;
84 case V4L2_CHIP_MATCH_I2C_DRIVER:
85 /* If needed, returns V4L2_IDENT_AMBIGUOUS without extra work */
86 call_all(dev, core, g_chip_ident, chip);
87 break;
88 case V4L2_CHIP_MATCH_I2C_ADDR:
89 /*
90 * We could return V4L2_IDENT_UNKNOWN, but we don't do the work
91 * to look if a chip is at the address with no driver. That's a
92 * dangerous thing to do with EEPROMs anyway.
93 */
94 call_all(dev, core, g_chip_ident, chip);
95 break;
96 default:
97 err = -EINVAL;
98 break;
99 }
100 return err;
101}
102
103#ifdef CONFIG_VIDEO_ADV_DEBUG
104static int cx23885_g_host_register(struct cx23885_dev *dev,
105 struct v4l2_dbg_register *reg)
106{
107 if ((reg->reg & 0x3) != 0 || reg->reg >= pci_resource_len(dev->pci, 0))
108 return -EINVAL;
109
110 reg->size = 4;
111 reg->val = cx_read(reg->reg);
112 return 0;
113}
114
115static int cx23417_g_register(struct cx23885_dev *dev,
116 struct v4l2_dbg_register *reg)
117{
118 u32 value;
119
120 if (dev->v4l_device == NULL)
121 return -EINVAL;
122
123 if ((reg->reg & 0x3) != 0 || reg->reg >= 0x10000)
124 return -EINVAL;
125
126 if (mc417_register_read(dev, (u16) reg->reg, &value))
127 return -EINVAL; /* V4L2 spec, but -EREMOTEIO really */
128
129 reg->size = 4;
130 reg->val = value;
131 return 0;
132}
133
134int cx23885_g_register(struct file *file, void *fh,
135 struct v4l2_dbg_register *reg)
136{
137 struct cx23885_dev *dev = ((struct cx23885_fh *)fh)->dev;
138
139 if (!capable(CAP_SYS_ADMIN))
140 return -EPERM;
141
142 if (reg->match.type == V4L2_CHIP_MATCH_HOST) {
143 switch (reg->match.addr) {
144 case 0:
145 return cx23885_g_host_register(dev, reg);
146 case 1:
147 return cx23417_g_register(dev, reg);
148 default:
149 break;
150 }
151 }
152
153 /* FIXME - any error returns should not be ignored */
154 call_all(dev, core, g_register, reg);
155 return 0;
156}
157
158static int cx23885_s_host_register(struct cx23885_dev *dev,
159 struct v4l2_dbg_register *reg)
160{
161 if ((reg->reg & 0x3) != 0 || reg->reg >= pci_resource_len(dev->pci, 0))
162 return -EINVAL;
163
164 reg->size = 4;
165 cx_write(reg->reg, reg->val);
166 return 0;
167}
168
169static int cx23417_s_register(struct cx23885_dev *dev,
170 struct v4l2_dbg_register *reg)
171{
172 if (dev->v4l_device == NULL)
173 return -EINVAL;
174
175 if ((reg->reg & 0x3) != 0 || reg->reg >= 0x10000)
176 return -EINVAL;
177
178 if (mc417_register_write(dev, (u16) reg->reg, (u32) reg->val))
179 return -EINVAL; /* V4L2 spec, but -EREMOTEIO really */
180
181 reg->size = 4;
182 return 0;
183}
184
185int cx23885_s_register(struct file *file, void *fh,
186 struct v4l2_dbg_register *reg)
187{
188 struct cx23885_dev *dev = ((struct cx23885_fh *)fh)->dev;
189
190 if (!capable(CAP_SYS_ADMIN))
191 return -EPERM;
192
193 if (reg->match.type == V4L2_CHIP_MATCH_HOST) {
194 switch (reg->match.addr) {
195 case 0:
196 return cx23885_s_host_register(dev, reg);
197 case 1:
198 return cx23417_s_register(dev, reg);
199 default:
200 break;
201 }
202 }
203
204 /* FIXME - any error returns should not be ignored */
205 call_all(dev, core, s_register, reg);
206 return 0;
207}
208#endif
diff --git a/drivers/media/video/cx23885/cx23885-ioctl.h b/drivers/media/video/cx23885/cx23885-ioctl.h
new file mode 100644
index 000000000000..80b0f4923c6a
--- /dev/null
+++ b/drivers/media/video/cx23885/cx23885-ioctl.h
@@ -0,0 +1,39 @@
1/*
2 * Driver for the Conexant CX23885/7/8 PCIe bridge
3 *
4 * Various common ioctl() support functions
5 *
6 * Copyright (c) 2009 Andy Walls <awalls@radix.net>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 *
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24#ifndef _CX23885_IOCTL_H_
25#define _CX23885_IOCTL_H_
26
27int cx23885_g_chip_ident(struct file *file, void *fh,
28 struct v4l2_dbg_chip_ident *chip);
29
30#ifdef CONFIG_VIDEO_ADV_DEBUG
31int cx23885_g_register(struct file *file, void *fh,
32 struct v4l2_dbg_register *reg);
33
34
35int cx23885_s_register(struct file *file, void *fh,
36 struct v4l2_dbg_register *reg);
37
38#endif
39#endif
diff --git a/drivers/media/video/cx23885/cx23885-ir.c b/drivers/media/video/cx23885/cx23885-ir.c
new file mode 100644
index 000000000000..6ae982cc9856
--- /dev/null
+++ b/drivers/media/video/cx23885/cx23885-ir.c
@@ -0,0 +1,101 @@
1/*
2 * Driver for the Conexant CX23885/7/8 PCIe bridge
3 *
4 * Infrared device support routines - non-input, non-vl42_subdev routines
5 *
6 * Copyright (C) 2009 Andy Walls <awalls@radix.net>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 * 02110-1301, USA.
22 */
23
24#include <media/v4l2-device.h>
25
26#include "cx23885.h"
27#include "cx23885-input.h"
28
29#define CX23885_IR_RX_FIFO_SERVICE_REQ 0
30#define CX23885_IR_RX_END_OF_RX_DETECTED 1
31#define CX23885_IR_RX_HW_FIFO_OVERRUN 2
32#define CX23885_IR_RX_SW_FIFO_OVERRUN 3
33
34#define CX23885_IR_TX_FIFO_SERVICE_REQ 0
35
36
37void cx23885_ir_rx_work_handler(struct work_struct *work)
38{
39 struct cx23885_dev *dev =
40 container_of(work, struct cx23885_dev, ir_rx_work);
41 u32 events = 0;
42 unsigned long *notifications = &dev->ir_rx_notifications;
43
44 if (test_and_clear_bit(CX23885_IR_RX_SW_FIFO_OVERRUN, notifications))
45 events |= V4L2_SUBDEV_IR_RX_SW_FIFO_OVERRUN;
46 if (test_and_clear_bit(CX23885_IR_RX_HW_FIFO_OVERRUN, notifications))
47 events |= V4L2_SUBDEV_IR_RX_HW_FIFO_OVERRUN;
48 if (test_and_clear_bit(CX23885_IR_RX_END_OF_RX_DETECTED, notifications))
49 events |= V4L2_SUBDEV_IR_RX_END_OF_RX_DETECTED;
50 if (test_and_clear_bit(CX23885_IR_RX_FIFO_SERVICE_REQ, notifications))
51 events |= V4L2_SUBDEV_IR_RX_FIFO_SERVICE_REQ;
52
53 if (events == 0)
54 return;
55
56 if (dev->ir_input)
57 cx23885_input_rx_work_handler(dev, events);
58}
59
60void cx23885_ir_tx_work_handler(struct work_struct *work)
61{
62 struct cx23885_dev *dev =
63 container_of(work, struct cx23885_dev, ir_tx_work);
64 u32 events = 0;
65 unsigned long *notifications = &dev->ir_tx_notifications;
66
67 if (test_and_clear_bit(CX23885_IR_TX_FIFO_SERVICE_REQ, notifications))
68 events |= V4L2_SUBDEV_IR_TX_FIFO_SERVICE_REQ;
69
70 if (events == 0)
71 return;
72
73}
74
75/* Called in an IRQ context */
76void cx23885_ir_rx_v4l2_dev_notify(struct v4l2_subdev *sd, u32 events)
77{
78 struct cx23885_dev *dev = to_cx23885(sd->v4l2_dev);
79 unsigned long *notifications = &dev->ir_rx_notifications;
80
81 if (events & V4L2_SUBDEV_IR_RX_FIFO_SERVICE_REQ)
82 set_bit(CX23885_IR_RX_FIFO_SERVICE_REQ, notifications);
83 if (events & V4L2_SUBDEV_IR_RX_END_OF_RX_DETECTED)
84 set_bit(CX23885_IR_RX_END_OF_RX_DETECTED, notifications);
85 if (events & V4L2_SUBDEV_IR_RX_HW_FIFO_OVERRUN)
86 set_bit(CX23885_IR_RX_HW_FIFO_OVERRUN, notifications);
87 if (events & V4L2_SUBDEV_IR_RX_SW_FIFO_OVERRUN)
88 set_bit(CX23885_IR_RX_SW_FIFO_OVERRUN, notifications);
89 schedule_work(&dev->ir_rx_work);
90}
91
92/* Called in an IRQ context */
93void cx23885_ir_tx_v4l2_dev_notify(struct v4l2_subdev *sd, u32 events)
94{
95 struct cx23885_dev *dev = to_cx23885(sd->v4l2_dev);
96 unsigned long *notifications = &dev->ir_tx_notifications;
97
98 if (events & V4L2_SUBDEV_IR_TX_FIFO_SERVICE_REQ)
99 set_bit(CX23885_IR_TX_FIFO_SERVICE_REQ, notifications);
100 schedule_work(&dev->ir_tx_work);
101}
diff --git a/drivers/media/video/cx23885/cx23885-ir.h b/drivers/media/video/cx23885/cx23885-ir.h
new file mode 100644
index 000000000000..9b8a6d5d1ef6
--- /dev/null
+++ b/drivers/media/video/cx23885/cx23885-ir.h
@@ -0,0 +1,31 @@
1/*
2 * Driver for the Conexant CX23885/7/8 PCIe bridge
3 *
4 * Infrared device support routines - non-input, non-vl42_subdev routines
5 *
6 * Copyright (C) 2009 Andy Walls <awalls@radix.net>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 * 02110-1301, USA.
22 */
23
24#ifndef _CX23885_IR_H_
25#define _CX23885_IR_H_
26void cx23885_ir_rx_v4l2_dev_notify(struct v4l2_subdev *sd, u32 events);
27void cx23885_ir_tx_v4l2_dev_notify(struct v4l2_subdev *sd, u32 events);
28
29void cx23885_ir_rx_work_handler(struct work_struct *work);
30void cx23885_ir_tx_work_handler(struct work_struct *work);
31#endif
diff --git a/drivers/media/video/cx23885/cx23885-reg.h b/drivers/media/video/cx23885/cx23885-reg.h
index eafbe5226bae..c0bc9a068954 100644
--- a/drivers/media/video/cx23885/cx23885-reg.h
+++ b/drivers/media/video/cx23885/cx23885-reg.h
@@ -212,8 +212,9 @@ Channel manager Data Structure entry = 20 DWORD
212 212
213#define DEV_CNTRL2 0x00040000 213#define DEV_CNTRL2 0x00040000
214 214
215#define PCI_MSK_GPIO1 (1 << 24) 215#define PCI_MSK_IR (1 << 28)
216#define PCI_MSK_GPIO0 (1 << 23) 216#define PCI_MSK_GPIO1 (1 << 24)
217#define PCI_MSK_GPIO0 (1 << 23)
217#define PCI_MSK_APB_DMA (1 << 12) 218#define PCI_MSK_APB_DMA (1 << 12)
218#define PCI_MSK_AL_WR (1 << 11) 219#define PCI_MSK_AL_WR (1 << 11)
219#define PCI_MSK_AL_RD (1 << 10) 220#define PCI_MSK_AL_RD (1 << 10)
diff --git a/drivers/media/video/cx23885/cx23885-video.c b/drivers/media/video/cx23885/cx23885-video.c
index 654cc253cd50..8b372b4f0de2 100644
--- a/drivers/media/video/cx23885/cx23885-video.c
+++ b/drivers/media/video/cx23885/cx23885-video.c
@@ -35,6 +35,7 @@
35#include "cx23885.h" 35#include "cx23885.h"
36#include <media/v4l2-common.h> 36#include <media/v4l2-common.h>
37#include <media/v4l2-ioctl.h> 37#include <media/v4l2-ioctl.h>
38#include "cx23885-ioctl.h"
38 39
39MODULE_DESCRIPTION("v4l2 driver module for cx23885 based TV cards"); 40MODULE_DESCRIPTION("v4l2 driver module for cx23885 based TV cards");
40MODULE_AUTHOR("Steven Toth <stoth@linuxtv.org>"); 41MODULE_AUTHOR("Steven Toth <stoth@linuxtv.org>");
@@ -401,6 +402,13 @@ static int cx23885_video_mux(struct cx23885_dev *dev, unsigned int input)
401 INPUT(input)->gpio2, INPUT(input)->gpio3); 402 INPUT(input)->gpio2, INPUT(input)->gpio3);
402 dev->input = input; 403 dev->input = input;
403 404
405 if (dev->board == CX23885_BOARD_MYGICA_X8506 ||
406 dev->board == CX23885_BOARD_MAGICPRO_PROHDTVE2) {
407 /* Select Analog TV */
408 if (INPUT(input)->type == CX23885_VMUX_TELEVISION)
409 cx23885_gpio_clear(dev, GPIO_0);
410 }
411
404 /* Tell the internal A/V decoder */ 412 /* Tell the internal A/V decoder */
405 v4l2_subdev_call(dev->sd_cx25840, video, s_routing, 413 v4l2_subdev_call(dev->sd_cx25840, video, s_routing,
406 INPUT(input)->vmux, 0, 0); 414 INPUT(input)->vmux, 0, 0);
@@ -1144,6 +1152,7 @@ static int cx23885_enum_input(struct cx23885_dev *dev, struct v4l2_input *i)
1144 [CX23885_VMUX_COMPOSITE3] = "Composite3", 1152 [CX23885_VMUX_COMPOSITE3] = "Composite3",
1145 [CX23885_VMUX_COMPOSITE4] = "Composite4", 1153 [CX23885_VMUX_COMPOSITE4] = "Composite4",
1146 [CX23885_VMUX_SVIDEO] = "S-Video", 1154 [CX23885_VMUX_SVIDEO] = "S-Video",
1155 [CX23885_VMUX_COMPONENT] = "Component",
1147 [CX23885_VMUX_TELEVISION] = "Television", 1156 [CX23885_VMUX_TELEVISION] = "Television",
1148 [CX23885_VMUX_CABLE] = "Cable TV", 1157 [CX23885_VMUX_CABLE] = "Cable TV",
1149 [CX23885_VMUX_DVB] = "DVB", 1158 [CX23885_VMUX_DVB] = "DVB",
@@ -1312,34 +1321,6 @@ static int vidioc_s_frequency(struct file *file, void *priv,
1312 cx23885_set_freq(dev, f); 1321 cx23885_set_freq(dev, f);
1313} 1322}
1314 1323
1315#ifdef CONFIG_VIDEO_ADV_DEBUG
1316static int vidioc_g_register(struct file *file, void *fh,
1317 struct v4l2_dbg_register *reg)
1318{
1319 struct cx23885_dev *dev = ((struct cx23885_fh *)fh)->dev;
1320
1321 if (!v4l2_chip_match_host(&reg->match))
1322 return -EINVAL;
1323
1324 call_all(dev, core, g_register, reg);
1325
1326 return 0;
1327}
1328
1329static int vidioc_s_register(struct file *file, void *fh,
1330 struct v4l2_dbg_register *reg)
1331{
1332 struct cx23885_dev *dev = ((struct cx23885_fh *)fh)->dev;
1333
1334 if (!v4l2_chip_match_host(&reg->match))
1335 return -EINVAL;
1336
1337 call_all(dev, core, s_register, reg);
1338
1339 return 0;
1340}
1341#endif
1342
1343/* ----------------------------------------------------------- */ 1324/* ----------------------------------------------------------- */
1344 1325
1345static void cx23885_vid_timeout(unsigned long data) 1326static void cx23885_vid_timeout(unsigned long data)
@@ -1449,9 +1430,10 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = {
1449 .vidioc_s_tuner = vidioc_s_tuner, 1430 .vidioc_s_tuner = vidioc_s_tuner,
1450 .vidioc_g_frequency = vidioc_g_frequency, 1431 .vidioc_g_frequency = vidioc_g_frequency,
1451 .vidioc_s_frequency = vidioc_s_frequency, 1432 .vidioc_s_frequency = vidioc_s_frequency,
1433 .vidioc_g_chip_ident = cx23885_g_chip_ident,
1452#ifdef CONFIG_VIDEO_ADV_DEBUG 1434#ifdef CONFIG_VIDEO_ADV_DEBUG
1453 .vidioc_g_register = vidioc_g_register, 1435 .vidioc_g_register = cx23885_g_register,
1454 .vidioc_s_register = vidioc_s_register, 1436 .vidioc_s_register = cx23885_s_register,
1455#endif 1437#endif
1456}; 1438};
1457 1439
@@ -1529,9 +1511,11 @@ int cx23885_video_register(struct cx23885_dev *dev)
1529 if (sd) { 1511 if (sd) {
1530 struct tuner_setup tun_setup; 1512 struct tuner_setup tun_setup;
1531 1513
1514 memset(&tun_setup, 0, sizeof(tun_setup));
1532 tun_setup.mode_mask = T_ANALOG_TV; 1515 tun_setup.mode_mask = T_ANALOG_TV;
1533 tun_setup.type = dev->tuner_type; 1516 tun_setup.type = dev->tuner_type;
1534 tun_setup.addr = v4l2_i2c_subdev_addr(sd); 1517 tun_setup.addr = v4l2_i2c_subdev_addr(sd);
1518 tun_setup.tuner_callback = cx23885_tuner_callback;
1535 1519
1536 v4l2_subdev_call(sd, tuner, s_type_addr, &tun_setup); 1520 v4l2_subdev_call(sd, tuner, s_type_addr, &tun_setup);
1537 } 1521 }
diff --git a/drivers/media/video/cx23885/cx23885.h b/drivers/media/video/cx23885/cx23885.h
index cc7a165561ff..fa744764dc8b 100644
--- a/drivers/media/video/cx23885/cx23885.h
+++ b/drivers/media/video/cx23885/cx23885.h
@@ -79,6 +79,8 @@
79#define CX23885_BOARD_MAGICPRO_PROHDTVE2 23 79#define CX23885_BOARD_MAGICPRO_PROHDTVE2 23
80#define CX23885_BOARD_HAUPPAUGE_HVR1850 24 80#define CX23885_BOARD_HAUPPAUGE_HVR1850 24
81#define CX23885_BOARD_COMPRO_VIDEOMATE_E800 25 81#define CX23885_BOARD_COMPRO_VIDEOMATE_E800 25
82#define CX23885_BOARD_HAUPPAUGE_HVR1290 26
83#define CX23885_BOARD_MYGICA_X8558PRO 27
82 84
83#define GPIO_0 0x00000001 85#define GPIO_0 0x00000001
84#define GPIO_1 0x00000002 86#define GPIO_1 0x00000002
@@ -157,6 +159,7 @@ enum cx23885_itype {
157 CX23885_VMUX_COMPOSITE3, 159 CX23885_VMUX_COMPOSITE3,
158 CX23885_VMUX_COMPOSITE4, 160 CX23885_VMUX_COMPOSITE4,
159 CX23885_VMUX_SVIDEO, 161 CX23885_VMUX_SVIDEO,
162 CX23885_VMUX_COMPONENT,
160 CX23885_VMUX_TELEVISION, 163 CX23885_VMUX_TELEVISION,
161 CX23885_VMUX_CABLE, 164 CX23885_VMUX_CABLE,
162 CX23885_VMUX_DVB, 165 CX23885_VMUX_DVB,
@@ -297,10 +300,6 @@ struct cx23885_tsport {
297 /* Allow a single tsport to have multiple frontends */ 300 /* Allow a single tsport to have multiple frontends */
298 u32 num_frontends; 301 u32 num_frontends;
299 void *port_priv; 302 void *port_priv;
300
301 /* FIXME: temporary hack */
302 int (*set_frontend_save) (struct dvb_frontend *,
303 struct dvb_frontend_parameters *);
304}; 303};
305 304
306struct cx23885_dev { 305struct cx23885_dev {
@@ -356,6 +355,16 @@ struct cx23885_dev {
356 unsigned int has_radio; 355 unsigned int has_radio;
357 struct v4l2_subdev *sd_cx25840; 356 struct v4l2_subdev *sd_cx25840;
358 357
358 /* Infrared */
359 struct v4l2_subdev *sd_ir;
360 struct work_struct ir_rx_work;
361 unsigned long ir_rx_notifications;
362 struct work_struct ir_tx_work;
363 unsigned long ir_tx_notifications;
364
365 struct card_ir *ir_input;
366 atomic_t ir_input_stopping;
367
359 /* V4l */ 368 /* V4l */
360 u32 freq; 369 u32 freq;
361 struct video_device *video_dev; 370 struct video_device *video_dev;
@@ -383,6 +392,13 @@ static inline struct cx23885_dev *to_cx23885(struct v4l2_device *v4l2_dev)
383#define call_all(dev, o, f, args...) \ 392#define call_all(dev, o, f, args...) \
384 v4l2_device_call_all(&dev->v4l2_dev, 0, o, f, ##args) 393 v4l2_device_call_all(&dev->v4l2_dev, 0, o, f, ##args)
385 394
395#define CX23885_HW_888_IR (1 << 0)
396
397#define call_hw(dev, grpid, o, f, args...) \
398 v4l2_device_call_all(&dev->v4l2_dev, grpid, o, f, ##args)
399
400extern struct v4l2_subdev *cx23885_find_hw(struct cx23885_dev *dev, u32 hw);
401
386extern struct list_head cx23885_devlist; 402extern struct list_head cx23885_devlist;
387 403
388#define SRAM_CH01 0 /* Video A */ 404#define SRAM_CH01 0 /* Video A */
@@ -455,6 +471,7 @@ extern void cx23885_wakeup(struct cx23885_tsport *port,
455 471
456extern void cx23885_gpio_set(struct cx23885_dev *dev, u32 mask); 472extern void cx23885_gpio_set(struct cx23885_dev *dev, u32 mask);
457extern void cx23885_gpio_clear(struct cx23885_dev *dev, u32 mask); 473extern void cx23885_gpio_clear(struct cx23885_dev *dev, u32 mask);
474extern u32 cx23885_gpio_get(struct cx23885_dev *dev, u32 mask);
458extern void cx23885_gpio_enable(struct cx23885_dev *dev, u32 mask, 475extern void cx23885_gpio_enable(struct cx23885_dev *dev, u32 mask,
459 int asoutput); 476 int asoutput);
460 477
@@ -471,6 +488,8 @@ extern int cx23885_tuner_callback(void *priv, int component,
471 int command, int arg); 488 int command, int arg);
472extern void cx23885_card_list(struct cx23885_dev *dev); 489extern void cx23885_card_list(struct cx23885_dev *dev);
473extern int cx23885_ir_init(struct cx23885_dev *dev); 490extern int cx23885_ir_init(struct cx23885_dev *dev);
491extern void cx23885_ir_pci_int_enable(struct cx23885_dev *dev);
492extern void cx23885_ir_fini(struct cx23885_dev *dev);
474extern void cx23885_gpio_setup(struct cx23885_dev *dev); 493extern void cx23885_gpio_setup(struct cx23885_dev *dev);
475extern void cx23885_card_setup(struct cx23885_dev *dev); 494extern void cx23885_card_setup(struct cx23885_dev *dev);
476extern void cx23885_card_setup_pre_i2c(struct cx23885_dev *dev); 495extern void cx23885_card_setup_pre_i2c(struct cx23885_dev *dev);
@@ -515,6 +534,10 @@ extern void cx23885_417_check_encoder(struct cx23885_dev *dev);
515extern void cx23885_mc417_init(struct cx23885_dev *dev); 534extern void cx23885_mc417_init(struct cx23885_dev *dev);
516extern int mc417_memory_read(struct cx23885_dev *dev, u32 address, u32 *value); 535extern int mc417_memory_read(struct cx23885_dev *dev, u32 address, u32 *value);
517extern int mc417_memory_write(struct cx23885_dev *dev, u32 address, u32 value); 536extern int mc417_memory_write(struct cx23885_dev *dev, u32 address, u32 value);
537extern int mc417_register_read(struct cx23885_dev *dev,
538 u16 address, u32 *value);
539extern int mc417_register_write(struct cx23885_dev *dev,
540 u16 address, u32 value);
518extern void mc417_gpio_set(struct cx23885_dev *dev, u32 mask); 541extern void mc417_gpio_set(struct cx23885_dev *dev, u32 mask);
519extern void mc417_gpio_clear(struct cx23885_dev *dev, u32 mask); 542extern void mc417_gpio_clear(struct cx23885_dev *dev, u32 mask);
520extern void mc417_gpio_enable(struct cx23885_dev *dev, u32 mask, int asoutput); 543extern void mc417_gpio_enable(struct cx23885_dev *dev, u32 mask, int asoutput);
diff --git a/drivers/media/video/cx23885/cx23888-ir.c b/drivers/media/video/cx23885/cx23888-ir.c
new file mode 100644
index 000000000000..3ccc8afeccf3
--- /dev/null
+++ b/drivers/media/video/cx23885/cx23888-ir.c
@@ -0,0 +1,1239 @@
1/*
2 * Driver for the Conexant CX23885/7/8 PCIe bridge
3 *
4 * CX23888 Integrated Consumer Infrared Controller
5 *
6 * Copyright (C) 2009 Andy Walls <awalls@radix.net>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 * 02110-1301, USA.
22 */
23
24#include <linux/kfifo.h>
25
26#include <media/v4l2-device.h>
27#include <media/v4l2-chip-ident.h>
28
29#include "cx23885.h"
30
31static unsigned int ir_888_debug;
32module_param(ir_888_debug, int, 0644);
33MODULE_PARM_DESC(ir_888_debug, "enable debug messages [CX23888 IR controller]");
34
35#define CX23888_IR_REG_BASE 0x170000
36/*
37 * These CX23888 register offsets have a straightforward one to one mapping
38 * to the CX23885 register offsets of 0x200 through 0x218
39 */
40#define CX23888_IR_CNTRL_REG 0x170000
41#define CNTRL_WIN_3_3 0x00000000
42#define CNTRL_WIN_4_3 0x00000001
43#define CNTRL_WIN_3_4 0x00000002
44#define CNTRL_WIN_4_4 0x00000003
45#define CNTRL_WIN 0x00000003
46#define CNTRL_EDG_NONE 0x00000000
47#define CNTRL_EDG_FALL 0x00000004
48#define CNTRL_EDG_RISE 0x00000008
49#define CNTRL_EDG_BOTH 0x0000000C
50#define CNTRL_EDG 0x0000000C
51#define CNTRL_DMD 0x00000010
52#define CNTRL_MOD 0x00000020
53#define CNTRL_RFE 0x00000040
54#define CNTRL_TFE 0x00000080
55#define CNTRL_RXE 0x00000100
56#define CNTRL_TXE 0x00000200
57#define CNTRL_RIC 0x00000400
58#define CNTRL_TIC 0x00000800
59#define CNTRL_CPL 0x00001000
60#define CNTRL_LBM 0x00002000
61#define CNTRL_R 0x00004000
62
63#define CX23888_IR_TXCLK_REG 0x170004
64#define TXCLK_TCD 0x0000FFFF
65
66#define CX23888_IR_RXCLK_REG 0x170008
67#define RXCLK_RCD 0x0000FFFF
68
69#define CX23888_IR_CDUTY_REG 0x17000C
70#define CDUTY_CDC 0x0000000F
71
72#define CX23888_IR_STATS_REG 0x170010
73#define STATS_RTO 0x00000001
74#define STATS_ROR 0x00000002
75#define STATS_RBY 0x00000004
76#define STATS_TBY 0x00000008
77#define STATS_RSR 0x00000010
78#define STATS_TSR 0x00000020
79
80#define CX23888_IR_IRQEN_REG 0x170014
81#define IRQEN_RTE 0x00000001
82#define IRQEN_ROE 0x00000002
83#define IRQEN_RSE 0x00000010
84#define IRQEN_TSE 0x00000020
85
86#define CX23888_IR_FILTR_REG 0x170018
87#define FILTR_LPF 0x0000FFFF
88
89/* This register doesn't follow the pattern; it's 0x23C on a CX23885 */
90#define CX23888_IR_FIFO_REG 0x170040
91#define FIFO_RXTX 0x0000FFFF
92#define FIFO_RXTX_LVL 0x00010000
93#define FIFO_RXTX_RTO 0x0001FFFF
94#define FIFO_RX_NDV 0x00020000
95#define FIFO_RX_DEPTH 8
96#define FIFO_TX_DEPTH 8
97
98/* CX23888 unique registers */
99#define CX23888_IR_SEEDP_REG 0x17001C
100#define CX23888_IR_TIMOL_REG 0x170020
101#define CX23888_IR_WAKE0_REG 0x170024
102#define CX23888_IR_WAKE1_REG 0x170028
103#define CX23888_IR_WAKE2_REG 0x17002C
104#define CX23888_IR_MASK0_REG 0x170030
105#define CX23888_IR_MASK1_REG 0x170034
106#define CX23888_IR_MAKS2_REG 0x170038
107#define CX23888_IR_DPIPG_REG 0x17003C
108#define CX23888_IR_LEARN_REG 0x170044
109
110#define CX23888_VIDCLK_FREQ 108000000 /* 108 MHz, BT.656 */
111#define CX23888_IR_REFCLK_FREQ (CX23888_VIDCLK_FREQ / 2)
112
113#define CX23888_IR_RX_KFIFO_SIZE (512 * sizeof(u32))
114#define CX23888_IR_TX_KFIFO_SIZE (512 * sizeof(u32))
115
116struct cx23888_ir_state {
117 struct v4l2_subdev sd;
118 struct cx23885_dev *dev;
119 u32 id;
120 u32 rev;
121
122 struct v4l2_subdev_ir_parameters rx_params;
123 struct mutex rx_params_lock;
124 atomic_t rxclk_divider;
125 atomic_t rx_invert;
126
127 struct kfifo *rx_kfifo;
128 spinlock_t rx_kfifo_lock;
129
130 struct v4l2_subdev_ir_parameters tx_params;
131 struct mutex tx_params_lock;
132 atomic_t txclk_divider;
133
134 struct kfifo *tx_kfifo;
135 spinlock_t tx_kfifo_lock;
136};
137
138static inline struct cx23888_ir_state *to_state(struct v4l2_subdev *sd)
139{
140 return v4l2_get_subdevdata(sd);
141}
142
143/*
144 * IR register block read and write functions
145 */
146static
147inline int cx23888_ir_write4(struct cx23885_dev *dev, u32 addr, u32 value)
148{
149 cx_write(addr, value);
150 return 0;
151}
152
153static inline u32 cx23888_ir_read4(struct cx23885_dev *dev, u32 addr)
154{
155 return cx_read(addr);
156}
157
158static inline int cx23888_ir_and_or4(struct cx23885_dev *dev, u32 addr,
159 u32 and_mask, u32 or_value)
160{
161 cx_andor(addr, ~and_mask, or_value);
162 return 0;
163}
164
165/*
166 * Rx and Tx Clock Divider register computations
167 *
168 * Note the largest clock divider value of 0xffff corresponds to:
169 * (0xffff + 1) * 1000 / 108/2 MHz = 1,213,629.629... ns
170 * which fits in 21 bits, so we'll use unsigned int for time arguments.
171 */
172static inline u16 count_to_clock_divider(unsigned int d)
173{
174 if (d > RXCLK_RCD + 1)
175 d = RXCLK_RCD;
176 else if (d < 2)
177 d = 1;
178 else
179 d--;
180 return (u16) d;
181}
182
183static inline u16 ns_to_clock_divider(unsigned int ns)
184{
185 return count_to_clock_divider(
186 DIV_ROUND_CLOSEST(CX23888_IR_REFCLK_FREQ / 1000000 * ns, 1000));
187}
188
189static inline unsigned int clock_divider_to_ns(unsigned int divider)
190{
191 /* Period of the Rx or Tx clock in ns */
192 return DIV_ROUND_CLOSEST((divider + 1) * 1000,
193 CX23888_IR_REFCLK_FREQ / 1000000);
194}
195
196static inline u16 carrier_freq_to_clock_divider(unsigned int freq)
197{
198 return count_to_clock_divider(
199 DIV_ROUND_CLOSEST(CX23888_IR_REFCLK_FREQ, freq * 16));
200}
201
202static inline unsigned int clock_divider_to_carrier_freq(unsigned int divider)
203{
204 return DIV_ROUND_CLOSEST(CX23888_IR_REFCLK_FREQ, (divider + 1) * 16);
205}
206
207static inline u16 freq_to_clock_divider(unsigned int freq,
208 unsigned int rollovers)
209{
210 return count_to_clock_divider(
211 DIV_ROUND_CLOSEST(CX23888_IR_REFCLK_FREQ, freq * rollovers));
212}
213
214static inline unsigned int clock_divider_to_freq(unsigned int divider,
215 unsigned int rollovers)
216{
217 return DIV_ROUND_CLOSEST(CX23888_IR_REFCLK_FREQ,
218 (divider + 1) * rollovers);
219}
220
221/*
222 * Low Pass Filter register calculations
223 *
224 * Note the largest count value of 0xffff corresponds to:
225 * 0xffff * 1000 / 108/2 MHz = 1,213,611.11... ns
226 * which fits in 21 bits, so we'll use unsigned int for time arguments.
227 */
228static inline u16 count_to_lpf_count(unsigned int d)
229{
230 if (d > FILTR_LPF)
231 d = FILTR_LPF;
232 else if (d < 4)
233 d = 0;
234 return (u16) d;
235}
236
237static inline u16 ns_to_lpf_count(unsigned int ns)
238{
239 return count_to_lpf_count(
240 DIV_ROUND_CLOSEST(CX23888_IR_REFCLK_FREQ / 1000000 * ns, 1000));
241}
242
243static inline unsigned int lpf_count_to_ns(unsigned int count)
244{
245 /* Duration of the Low Pass Filter rejection window in ns */
246 return DIV_ROUND_CLOSEST(count * 1000,
247 CX23888_IR_REFCLK_FREQ / 1000000);
248}
249
250static inline unsigned int lpf_count_to_us(unsigned int count)
251{
252 /* Duration of the Low Pass Filter rejection window in us */
253 return DIV_ROUND_CLOSEST(count, CX23888_IR_REFCLK_FREQ / 1000000);
254}
255
256/*
257 * FIFO register pulse width count compuations
258 */
259static u32 clock_divider_to_resolution(u16 divider)
260{
261 /*
262 * Resolution is the duration of 1 tick of the readable portion of
263 * of the pulse width counter as read from the FIFO. The two lsb's are
264 * not readable, hence the << 2. This function returns ns.
265 */
266 return DIV_ROUND_CLOSEST((1 << 2) * ((u32) divider + 1) * 1000,
267 CX23888_IR_REFCLK_FREQ / 1000000);
268}
269
270static u64 pulse_width_count_to_ns(u16 count, u16 divider)
271{
272 u64 n;
273 u32 rem;
274
275 /*
276 * The 2 lsb's of the pulse width timer count are not readable, hence
277 * the (count << 2) | 0x3
278 */
279 n = (((u64) count << 2) | 0x3) * (divider + 1) * 1000; /* millicycles */
280 rem = do_div(n, CX23888_IR_REFCLK_FREQ / 1000000); /* / MHz => ns */
281 if (rem >= CX23888_IR_REFCLK_FREQ / 1000000 / 2)
282 n++;
283 return n;
284}
285
286static unsigned int pulse_width_count_to_us(u16 count, u16 divider)
287{
288 u64 n;
289 u32 rem;
290
291 /*
292 * The 2 lsb's of the pulse width timer count are not readable, hence
293 * the (count << 2) | 0x3
294 */
295 n = (((u64) count << 2) | 0x3) * (divider + 1); /* cycles */
296 rem = do_div(n, CX23888_IR_REFCLK_FREQ / 1000000); /* / MHz => us */
297 if (rem >= CX23888_IR_REFCLK_FREQ / 1000000 / 2)
298 n++;
299 return (unsigned int) n;
300}
301
302/*
303 * Pulse Clocks computations: Combined Pulse Width Count & Rx Clock Counts
304 *
305 * The total pulse clock count is an 18 bit pulse width timer count as the most
306 * significant part and (up to) 16 bit clock divider count as a modulus.
307 * When the Rx clock divider ticks down to 0, it increments the 18 bit pulse
308 * width timer count's least significant bit.
309 */
310static u64 ns_to_pulse_clocks(u32 ns)
311{
312 u64 clocks;
313 u32 rem;
314 clocks = CX23888_IR_REFCLK_FREQ / 1000000 * (u64) ns; /* millicycles */
315 rem = do_div(clocks, 1000); /* /1000 = cycles */
316 if (rem >= 1000 / 2)
317 clocks++;
318 return clocks;
319}
320
321static u16 pulse_clocks_to_clock_divider(u64 count)
322{
323 u32 rem;
324
325 rem = do_div(count, (FIFO_RXTX << 2) | 0x3);
326
327 /* net result needs to be rounded down and decremented by 1 */
328 if (count > RXCLK_RCD + 1)
329 count = RXCLK_RCD;
330 else if (count < 2)
331 count = 1;
332 else
333 count--;
334 return (u16) count;
335}
336
337/*
338 * IR Control Register helpers
339 */
340enum tx_fifo_watermark {
341 TX_FIFO_HALF_EMPTY = 0,
342 TX_FIFO_EMPTY = CNTRL_TIC,
343};
344
345enum rx_fifo_watermark {
346 RX_FIFO_HALF_FULL = 0,
347 RX_FIFO_NOT_EMPTY = CNTRL_RIC,
348};
349
350static inline void control_tx_irq_watermark(struct cx23885_dev *dev,
351 enum tx_fifo_watermark level)
352{
353 cx23888_ir_and_or4(dev, CX23888_IR_CNTRL_REG, ~CNTRL_TIC, level);
354}
355
356static inline void control_rx_irq_watermark(struct cx23885_dev *dev,
357 enum rx_fifo_watermark level)
358{
359 cx23888_ir_and_or4(dev, CX23888_IR_CNTRL_REG, ~CNTRL_RIC, level);
360}
361
362static inline void control_tx_enable(struct cx23885_dev *dev, bool enable)
363{
364 cx23888_ir_and_or4(dev, CX23888_IR_CNTRL_REG, ~(CNTRL_TXE | CNTRL_TFE),
365 enable ? (CNTRL_TXE | CNTRL_TFE) : 0);
366}
367
368static inline void control_rx_enable(struct cx23885_dev *dev, bool enable)
369{
370 cx23888_ir_and_or4(dev, CX23888_IR_CNTRL_REG, ~(CNTRL_RXE | CNTRL_RFE),
371 enable ? (CNTRL_RXE | CNTRL_RFE) : 0);
372}
373
374static inline void control_tx_modulation_enable(struct cx23885_dev *dev,
375 bool enable)
376{
377 cx23888_ir_and_or4(dev, CX23888_IR_CNTRL_REG, ~CNTRL_MOD,
378 enable ? CNTRL_MOD : 0);
379}
380
381static inline void control_rx_demodulation_enable(struct cx23885_dev *dev,
382 bool enable)
383{
384 cx23888_ir_and_or4(dev, CX23888_IR_CNTRL_REG, ~CNTRL_DMD,
385 enable ? CNTRL_DMD : 0);
386}
387
388static inline void control_rx_s_edge_detection(struct cx23885_dev *dev,
389 u32 edge_types)
390{
391 cx23888_ir_and_or4(dev, CX23888_IR_CNTRL_REG, ~CNTRL_EDG_BOTH,
392 edge_types & CNTRL_EDG_BOTH);
393}
394
395static void control_rx_s_carrier_window(struct cx23885_dev *dev,
396 unsigned int carrier,
397 unsigned int *carrier_range_low,
398 unsigned int *carrier_range_high)
399{
400 u32 v;
401 unsigned int c16 = carrier * 16;
402
403 if (*carrier_range_low < DIV_ROUND_CLOSEST(c16, 16 + 3)) {
404 v = CNTRL_WIN_3_4;
405 *carrier_range_low = DIV_ROUND_CLOSEST(c16, 16 + 4);
406 } else {
407 v = CNTRL_WIN_3_3;
408 *carrier_range_low = DIV_ROUND_CLOSEST(c16, 16 + 3);
409 }
410
411 if (*carrier_range_high > DIV_ROUND_CLOSEST(c16, 16 - 3)) {
412 v |= CNTRL_WIN_4_3;
413 *carrier_range_high = DIV_ROUND_CLOSEST(c16, 16 - 4);
414 } else {
415 v |= CNTRL_WIN_3_3;
416 *carrier_range_high = DIV_ROUND_CLOSEST(c16, 16 - 3);
417 }
418 cx23888_ir_and_or4(dev, CX23888_IR_CNTRL_REG, ~CNTRL_WIN, v);
419}
420
421static inline void control_tx_polarity_invert(struct cx23885_dev *dev,
422 bool invert)
423{
424 cx23888_ir_and_or4(dev, CX23888_IR_CNTRL_REG, ~CNTRL_CPL,
425 invert ? CNTRL_CPL : 0);
426}
427
428/*
429 * IR Rx & Tx Clock Register helpers
430 */
431static unsigned int txclk_tx_s_carrier(struct cx23885_dev *dev,
432 unsigned int freq,
433 u16 *divider)
434{
435 *divider = carrier_freq_to_clock_divider(freq);
436 cx23888_ir_write4(dev, CX23888_IR_TXCLK_REG, *divider);
437 return clock_divider_to_carrier_freq(*divider);
438}
439
440static unsigned int rxclk_rx_s_carrier(struct cx23885_dev *dev,
441 unsigned int freq,
442 u16 *divider)
443{
444 *divider = carrier_freq_to_clock_divider(freq);
445 cx23888_ir_write4(dev, CX23888_IR_RXCLK_REG, *divider);
446 return clock_divider_to_carrier_freq(*divider);
447}
448
449static u32 txclk_tx_s_max_pulse_width(struct cx23885_dev *dev, u32 ns,
450 u16 *divider)
451{
452 u64 pulse_clocks;
453
454 if (ns > V4L2_SUBDEV_IR_PULSE_MAX_WIDTH_NS)
455 ns = V4L2_SUBDEV_IR_PULSE_MAX_WIDTH_NS;
456 pulse_clocks = ns_to_pulse_clocks(ns);
457 *divider = pulse_clocks_to_clock_divider(pulse_clocks);
458 cx23888_ir_write4(dev, CX23888_IR_TXCLK_REG, *divider);
459 return (u32) pulse_width_count_to_ns(FIFO_RXTX, *divider);
460}
461
462static u32 rxclk_rx_s_max_pulse_width(struct cx23885_dev *dev, u32 ns,
463 u16 *divider)
464{
465 u64 pulse_clocks;
466
467 if (ns > V4L2_SUBDEV_IR_PULSE_MAX_WIDTH_NS)
468 ns = V4L2_SUBDEV_IR_PULSE_MAX_WIDTH_NS;
469 pulse_clocks = ns_to_pulse_clocks(ns);
470 *divider = pulse_clocks_to_clock_divider(pulse_clocks);
471 cx23888_ir_write4(dev, CX23888_IR_RXCLK_REG, *divider);
472 return (u32) pulse_width_count_to_ns(FIFO_RXTX, *divider);
473}
474
475/*
476 * IR Tx Carrier Duty Cycle register helpers
477 */
478static unsigned int cduty_tx_s_duty_cycle(struct cx23885_dev *dev,
479 unsigned int duty_cycle)
480{
481 u32 n;
482 n = DIV_ROUND_CLOSEST(duty_cycle * 100, 625); /* 16ths of 100% */
483 if (n != 0)
484 n--;
485 if (n > 15)
486 n = 15;
487 cx23888_ir_write4(dev, CX23888_IR_CDUTY_REG, n);
488 return DIV_ROUND_CLOSEST((n + 1) * 100, 16);
489}
490
491/*
492 * IR Filter Register helpers
493 */
494static u32 filter_rx_s_min_width(struct cx23885_dev *dev, u32 min_width_ns)
495{
496 u32 count = ns_to_lpf_count(min_width_ns);
497 cx23888_ir_write4(dev, CX23888_IR_FILTR_REG, count);
498 return lpf_count_to_ns(count);
499}
500
501/*
502 * IR IRQ Enable Register helpers
503 */
504static inline void irqenable_rx(struct cx23885_dev *dev, u32 mask)
505{
506 mask &= (IRQEN_RTE | IRQEN_ROE | IRQEN_RSE);
507 cx23888_ir_and_or4(dev, CX23888_IR_IRQEN_REG,
508 ~(IRQEN_RTE | IRQEN_ROE | IRQEN_RSE), mask);
509}
510
511static inline void irqenable_tx(struct cx23885_dev *dev, u32 mask)
512{
513 mask &= IRQEN_TSE;
514 cx23888_ir_and_or4(dev, CX23888_IR_IRQEN_REG, ~IRQEN_TSE, mask);
515}
516
517/*
518 * V4L2 Subdevice IR Ops
519 */
520static int cx23888_ir_irq_handler(struct v4l2_subdev *sd, u32 status,
521 bool *handled)
522{
523 struct cx23888_ir_state *state = to_state(sd);
524 struct cx23885_dev *dev = state->dev;
525
526 u32 cntrl = cx23888_ir_read4(dev, CX23888_IR_CNTRL_REG);
527 u32 irqen = cx23888_ir_read4(dev, CX23888_IR_IRQEN_REG);
528 u32 stats = cx23888_ir_read4(dev, CX23888_IR_STATS_REG);
529
530 u32 rx_data[FIFO_RX_DEPTH];
531 int i, j, k;
532 u32 events, v;
533 int tsr, rsr, rto, ror, tse, rse, rte, roe, kror;
534
535 tsr = stats & STATS_TSR; /* Tx FIFO Service Request */
536 rsr = stats & STATS_RSR; /* Rx FIFO Service Request */
537 rto = stats & STATS_RTO; /* Rx Pulse Width Timer Time Out */
538 ror = stats & STATS_ROR; /* Rx FIFO Over Run */
539
540 tse = irqen & IRQEN_TSE; /* Tx FIFO Service Request IRQ Enable */
541 rse = irqen & IRQEN_RSE; /* Rx FIFO Service Reuqest IRQ Enable */
542 rte = irqen & IRQEN_RTE; /* Rx Pulse Width Timer Time Out IRQ Enable */
543 roe = irqen & IRQEN_ROE; /* Rx FIFO Over Run IRQ Enable */
544
545 *handled = false;
546 v4l2_dbg(2, ir_888_debug, sd, "IRQ Status: %s %s %s %s %s %s\n",
547 tsr ? "tsr" : " ", rsr ? "rsr" : " ",
548 rto ? "rto" : " ", ror ? "ror" : " ",
549 stats & STATS_TBY ? "tby" : " ",
550 stats & STATS_RBY ? "rby" : " ");
551
552 v4l2_dbg(2, ir_888_debug, sd, "IRQ Enables: %s %s %s %s\n",
553 tse ? "tse" : " ", rse ? "rse" : " ",
554 rte ? "rte" : " ", roe ? "roe" : " ");
555
556 /*
557 * Transmitter interrupt service
558 */
559 if (tse && tsr) {
560 /*
561 * TODO:
562 * Check the watermark threshold setting
563 * Pull FIFO_TX_DEPTH or FIFO_TX_DEPTH/2 entries from tx_kfifo
564 * Push the data to the hardware FIFO.
565 * If there was nothing more to send in the tx_kfifo, disable
566 * the TSR IRQ and notify the v4l2_device.
567 * If there was something in the tx_kfifo, check the tx_kfifo
568 * level and notify the v4l2_device, if it is low.
569 */
570 /* For now, inhibit TSR interrupt until Tx is implemented */
571 irqenable_tx(dev, 0);
572 events = V4L2_SUBDEV_IR_TX_FIFO_SERVICE_REQ;
573 v4l2_subdev_notify(sd, V4L2_SUBDEV_IR_TX_NOTIFY, &events);
574 *handled = true;
575 }
576
577 /*
578 * Receiver interrupt service
579 */
580 kror = 0;
581 if ((rse && rsr) || (rte && rto)) {
582 /*
583 * Receive data on RSR to clear the STATS_RSR.
584 * Receive data on RTO, since we may not have yet hit the RSR
585 * watermark when we receive the RTO.
586 */
587 for (i = 0, v = FIFO_RX_NDV;
588 (v & FIFO_RX_NDV) && !kror; i = 0) {
589 for (j = 0;
590 (v & FIFO_RX_NDV) && j < FIFO_RX_DEPTH; j++) {
591 v = cx23888_ir_read4(dev, CX23888_IR_FIFO_REG);
592 rx_data[i++] = v & ~FIFO_RX_NDV;
593 }
594 if (i == 0)
595 break;
596 j = i * sizeof(u32);
597 k = kfifo_put(state->rx_kfifo,
598 (unsigned char *) rx_data, j);
599 if (k != j)
600 kror++; /* rx_kfifo over run */
601 }
602 *handled = true;
603 }
604
605 events = 0;
606 v = 0;
607 if (kror) {
608 events |= V4L2_SUBDEV_IR_RX_SW_FIFO_OVERRUN;
609 v4l2_err(sd, "IR receiver software FIFO overrun\n");
610 }
611 if (roe && ror) {
612 /*
613 * The RX FIFO Enable (CNTRL_RFE) must be toggled to clear
614 * the Rx FIFO Over Run status (STATS_ROR)
615 */
616 v |= CNTRL_RFE;
617 events |= V4L2_SUBDEV_IR_RX_HW_FIFO_OVERRUN;
618 v4l2_err(sd, "IR receiver hardware FIFO overrun\n");
619 }
620 if (rte && rto) {
621 /*
622 * The IR Receiver Enable (CNTRL_RXE) must be toggled to clear
623 * the Rx Pulse Width Timer Time Out (STATS_RTO)
624 */
625 v |= CNTRL_RXE;
626 events |= V4L2_SUBDEV_IR_RX_END_OF_RX_DETECTED;
627 }
628 if (v) {
629 /* Clear STATS_ROR & STATS_RTO as needed by reseting hardware */
630 cx23888_ir_write4(dev, CX23888_IR_CNTRL_REG, cntrl & ~v);
631 cx23888_ir_write4(dev, CX23888_IR_CNTRL_REG, cntrl);
632 *handled = true;
633 }
634 if (kfifo_len(state->rx_kfifo) >= CX23888_IR_RX_KFIFO_SIZE / 2)
635 events |= V4L2_SUBDEV_IR_RX_FIFO_SERVICE_REQ;
636
637 if (events)
638 v4l2_subdev_notify(sd, V4L2_SUBDEV_IR_RX_NOTIFY, &events);
639 return 0;
640}
641
642/* Receiver */
643static int cx23888_ir_rx_read(struct v4l2_subdev *sd, u8 *buf, size_t count,
644 ssize_t *num)
645{
646 struct cx23888_ir_state *state = to_state(sd);
647 bool invert = (bool) atomic_read(&state->rx_invert);
648 u16 divider = (u16) atomic_read(&state->rxclk_divider);
649
650 unsigned int i, n;
651 u32 *p;
652 u32 u, v;
653
654 n = count / sizeof(u32) * sizeof(u32);
655 if (n == 0) {
656 *num = 0;
657 return 0;
658 }
659
660 n = kfifo_get(state->rx_kfifo, buf, n);
661
662 n /= sizeof(u32);
663 *num = n * sizeof(u32);
664
665 for (p = (u32 *) buf, i = 0; i < n; p++, i++) {
666 if ((*p & FIFO_RXTX_RTO) == FIFO_RXTX_RTO) {
667 *p = V4L2_SUBDEV_IR_PULSE_RX_SEQ_END;
668 v4l2_dbg(2, ir_888_debug, sd, "rx read: end of rx\n");
669 continue;
670 }
671
672 u = (*p & FIFO_RXTX_LVL) ? V4L2_SUBDEV_IR_PULSE_LEVEL_MASK : 0;
673 if (invert)
674 u = u ? 0 : V4L2_SUBDEV_IR_PULSE_LEVEL_MASK;
675
676 v = (u32) pulse_width_count_to_ns((u16) (*p & FIFO_RXTX),
677 divider);
678 if (v >= V4L2_SUBDEV_IR_PULSE_MAX_WIDTH_NS)
679 v = V4L2_SUBDEV_IR_PULSE_MAX_WIDTH_NS - 1;
680
681 *p = u | v;
682
683 v4l2_dbg(2, ir_888_debug, sd, "rx read: %10u ns %s\n",
684 v, u ? "mark" : "space");
685 }
686 return 0;
687}
688
689static int cx23888_ir_rx_g_parameters(struct v4l2_subdev *sd,
690 struct v4l2_subdev_ir_parameters *p)
691{
692 struct cx23888_ir_state *state = to_state(sd);
693 mutex_lock(&state->rx_params_lock);
694 memcpy(p, &state->rx_params, sizeof(struct v4l2_subdev_ir_parameters));
695 mutex_unlock(&state->rx_params_lock);
696 return 0;
697}
698
699static int cx23888_ir_rx_shutdown(struct v4l2_subdev *sd)
700{
701 struct cx23888_ir_state *state = to_state(sd);
702 struct cx23885_dev *dev = state->dev;
703
704 mutex_lock(&state->rx_params_lock);
705
706 /* Disable or slow down all IR Rx circuits and counters */
707 irqenable_rx(dev, 0);
708 control_rx_enable(dev, false);
709 control_rx_demodulation_enable(dev, false);
710 control_rx_s_edge_detection(dev, CNTRL_EDG_NONE);
711 filter_rx_s_min_width(dev, 0);
712 cx23888_ir_write4(dev, CX23888_IR_RXCLK_REG, RXCLK_RCD);
713
714 state->rx_params.shutdown = true;
715
716 mutex_unlock(&state->rx_params_lock);
717 return 0;
718}
719
720static int cx23888_ir_rx_s_parameters(struct v4l2_subdev *sd,
721 struct v4l2_subdev_ir_parameters *p)
722{
723 struct cx23888_ir_state *state = to_state(sd);
724 struct cx23885_dev *dev = state->dev;
725 struct v4l2_subdev_ir_parameters *o = &state->rx_params;
726 u16 rxclk_divider;
727
728 if (p->shutdown)
729 return cx23888_ir_rx_shutdown(sd);
730
731 if (p->mode != V4L2_SUBDEV_IR_MODE_PULSE_WIDTH)
732 return -ENOSYS;
733
734 mutex_lock(&state->rx_params_lock);
735
736 o->shutdown = p->shutdown;
737
738 o->mode = p->mode = V4L2_SUBDEV_IR_MODE_PULSE_WIDTH;
739
740 o->bytes_per_data_element = p->bytes_per_data_element = sizeof(u32);
741
742 /* Before we tweak the hardware, we have to disable the receiver */
743 irqenable_rx(dev, 0);
744 control_rx_enable(dev, false);
745
746 control_rx_demodulation_enable(dev, p->modulation);
747 o->modulation = p->modulation;
748
749 if (p->modulation) {
750 p->carrier_freq = rxclk_rx_s_carrier(dev, p->carrier_freq,
751 &rxclk_divider);
752
753 o->carrier_freq = p->carrier_freq;
754
755 o->duty_cycle = p->duty_cycle = 50;
756
757 control_rx_s_carrier_window(dev, p->carrier_freq,
758 &p->carrier_range_lower,
759 &p->carrier_range_upper);
760 o->carrier_range_lower = p->carrier_range_lower;
761 o->carrier_range_upper = p->carrier_range_upper;
762 } else {
763 p->max_pulse_width =
764 rxclk_rx_s_max_pulse_width(dev, p->max_pulse_width,
765 &rxclk_divider);
766 o->max_pulse_width = p->max_pulse_width;
767 }
768 atomic_set(&state->rxclk_divider, rxclk_divider);
769
770 p->noise_filter_min_width =
771 filter_rx_s_min_width(dev, p->noise_filter_min_width);
772 o->noise_filter_min_width = p->noise_filter_min_width;
773
774 p->resolution = clock_divider_to_resolution(rxclk_divider);
775 o->resolution = p->resolution;
776
777 /* FIXME - make this dependent on resolution for better performance */
778 control_rx_irq_watermark(dev, RX_FIFO_HALF_FULL);
779
780 control_rx_s_edge_detection(dev, CNTRL_EDG_BOTH);
781
782 o->invert = p->invert;
783 atomic_set(&state->rx_invert, p->invert);
784
785 o->interrupt_enable = p->interrupt_enable;
786 o->enable = p->enable;
787 if (p->enable) {
788 kfifo_reset(state->rx_kfifo);
789 if (p->interrupt_enable)
790 irqenable_rx(dev, IRQEN_RSE | IRQEN_RTE | IRQEN_ROE);
791 control_rx_enable(dev, p->enable);
792 }
793
794 mutex_unlock(&state->rx_params_lock);
795 return 0;
796}
797
798/* Transmitter */
799static int cx23888_ir_tx_write(struct v4l2_subdev *sd, u8 *buf, size_t count,
800 ssize_t *num)
801{
802 struct cx23888_ir_state *state = to_state(sd);
803 struct cx23885_dev *dev = state->dev;
804 /* For now enable the Tx FIFO Service interrupt & pretend we did work */
805 irqenable_tx(dev, IRQEN_TSE);
806 *num = count;
807 return 0;
808}
809
810static int cx23888_ir_tx_g_parameters(struct v4l2_subdev *sd,
811 struct v4l2_subdev_ir_parameters *p)
812{
813 struct cx23888_ir_state *state = to_state(sd);
814 mutex_lock(&state->tx_params_lock);
815 memcpy(p, &state->tx_params, sizeof(struct v4l2_subdev_ir_parameters));
816 mutex_unlock(&state->tx_params_lock);
817 return 0;
818}
819
820static int cx23888_ir_tx_shutdown(struct v4l2_subdev *sd)
821{
822 struct cx23888_ir_state *state = to_state(sd);
823 struct cx23885_dev *dev = state->dev;
824
825 mutex_lock(&state->tx_params_lock);
826
827 /* Disable or slow down all IR Tx circuits and counters */
828 irqenable_tx(dev, 0);
829 control_tx_enable(dev, false);
830 control_tx_modulation_enable(dev, false);
831 cx23888_ir_write4(dev, CX23888_IR_TXCLK_REG, TXCLK_TCD);
832
833 state->tx_params.shutdown = true;
834
835 mutex_unlock(&state->tx_params_lock);
836 return 0;
837}
838
839static int cx23888_ir_tx_s_parameters(struct v4l2_subdev *sd,
840 struct v4l2_subdev_ir_parameters *p)
841{
842 struct cx23888_ir_state *state = to_state(sd);
843 struct cx23885_dev *dev = state->dev;
844 struct v4l2_subdev_ir_parameters *o = &state->tx_params;
845 u16 txclk_divider;
846
847 if (p->shutdown)
848 return cx23888_ir_tx_shutdown(sd);
849
850 if (p->mode != V4L2_SUBDEV_IR_MODE_PULSE_WIDTH)
851 return -ENOSYS;
852
853 mutex_lock(&state->tx_params_lock);
854
855 o->shutdown = p->shutdown;
856
857 o->mode = p->mode = V4L2_SUBDEV_IR_MODE_PULSE_WIDTH;
858
859 o->bytes_per_data_element = p->bytes_per_data_element = sizeof(u32);
860
861 /* Before we tweak the hardware, we have to disable the transmitter */
862 irqenable_tx(dev, 0);
863 control_tx_enable(dev, false);
864
865 control_tx_modulation_enable(dev, p->modulation);
866 o->modulation = p->modulation;
867
868 if (p->modulation) {
869 p->carrier_freq = txclk_tx_s_carrier(dev, p->carrier_freq,
870 &txclk_divider);
871 o->carrier_freq = p->carrier_freq;
872
873 p->duty_cycle = cduty_tx_s_duty_cycle(dev, p->duty_cycle);
874 o->duty_cycle = p->duty_cycle;
875 } else {
876 p->max_pulse_width =
877 txclk_tx_s_max_pulse_width(dev, p->max_pulse_width,
878 &txclk_divider);
879 o->max_pulse_width = p->max_pulse_width;
880 }
881 atomic_set(&state->txclk_divider, txclk_divider);
882
883 p->resolution = clock_divider_to_resolution(txclk_divider);
884 o->resolution = p->resolution;
885
886 /* FIXME - make this dependent on resolution for better performance */
887 control_tx_irq_watermark(dev, TX_FIFO_HALF_EMPTY);
888
889 control_tx_polarity_invert(dev, p->invert);
890 o->invert = p->invert;
891
892 o->interrupt_enable = p->interrupt_enable;
893 o->enable = p->enable;
894 if (p->enable) {
895 kfifo_reset(state->tx_kfifo);
896 if (p->interrupt_enable)
897 irqenable_tx(dev, IRQEN_TSE);
898 control_tx_enable(dev, p->enable);
899 }
900
901 mutex_unlock(&state->tx_params_lock);
902 return 0;
903}
904
905
906/*
907 * V4L2 Subdevice Core Ops
908 */
909static int cx23888_ir_log_status(struct v4l2_subdev *sd)
910{
911 struct cx23888_ir_state *state = to_state(sd);
912 struct cx23885_dev *dev = state->dev;
913 char *s;
914 int i, j;
915
916 u32 cntrl = cx23888_ir_read4(dev, CX23888_IR_CNTRL_REG);
917 u32 txclk = cx23888_ir_read4(dev, CX23888_IR_TXCLK_REG) & TXCLK_TCD;
918 u32 rxclk = cx23888_ir_read4(dev, CX23888_IR_RXCLK_REG) & RXCLK_RCD;
919 u32 cduty = cx23888_ir_read4(dev, CX23888_IR_CDUTY_REG) & CDUTY_CDC;
920 u32 stats = cx23888_ir_read4(dev, CX23888_IR_STATS_REG);
921 u32 irqen = cx23888_ir_read4(dev, CX23888_IR_IRQEN_REG);
922 u32 filtr = cx23888_ir_read4(dev, CX23888_IR_FILTR_REG) & FILTR_LPF;
923
924 v4l2_info(sd, "IR Receiver:\n");
925 v4l2_info(sd, "\tEnabled: %s\n",
926 cntrl & CNTRL_RXE ? "yes" : "no");
927 v4l2_info(sd, "\tDemodulation from a carrier: %s\n",
928 cntrl & CNTRL_DMD ? "enabled" : "disabled");
929 v4l2_info(sd, "\tFIFO: %s\n",
930 cntrl & CNTRL_RFE ? "enabled" : "disabled");
931 switch (cntrl & CNTRL_EDG) {
932 case CNTRL_EDG_NONE:
933 s = "disabled";
934 break;
935 case CNTRL_EDG_FALL:
936 s = "falling edge";
937 break;
938 case CNTRL_EDG_RISE:
939 s = "rising edge";
940 break;
941 case CNTRL_EDG_BOTH:
942 s = "rising & falling edges";
943 break;
944 default:
945 s = "??? edge";
946 break;
947 }
948 v4l2_info(sd, "\tPulse timers' start/stop trigger: %s\n", s);
949 v4l2_info(sd, "\tFIFO data on pulse timer overflow: %s\n",
950 cntrl & CNTRL_R ? "not loaded" : "overflow marker");
951 v4l2_info(sd, "\tFIFO interrupt watermark: %s\n",
952 cntrl & CNTRL_RIC ? "not empty" : "half full or greater");
953 v4l2_info(sd, "\tLoopback mode: %s\n",
954 cntrl & CNTRL_LBM ? "loopback active" : "normal receive");
955 if (cntrl & CNTRL_DMD) {
956 v4l2_info(sd, "\tExpected carrier (16 clocks): %u Hz\n",
957 clock_divider_to_carrier_freq(rxclk));
958 switch (cntrl & CNTRL_WIN) {
959 case CNTRL_WIN_3_3:
960 i = 3;
961 j = 3;
962 break;
963 case CNTRL_WIN_4_3:
964 i = 4;
965 j = 3;
966 break;
967 case CNTRL_WIN_3_4:
968 i = 3;
969 j = 4;
970 break;
971 case CNTRL_WIN_4_4:
972 i = 4;
973 j = 4;
974 break;
975 default:
976 i = 0;
977 j = 0;
978 break;
979 }
980 v4l2_info(sd, "\tNext carrier edge window: 16 clocks "
981 "-%1d/+%1d, %u to %u Hz\n", i, j,
982 clock_divider_to_freq(rxclk, 16 + j),
983 clock_divider_to_freq(rxclk, 16 - i));
984 } else {
985 v4l2_info(sd, "\tMax measurable pulse width: %u us, "
986 "%llu ns\n",
987 pulse_width_count_to_us(FIFO_RXTX, rxclk),
988 pulse_width_count_to_ns(FIFO_RXTX, rxclk));
989 }
990 v4l2_info(sd, "\tLow pass filter: %s\n",
991 filtr ? "enabled" : "disabled");
992 if (filtr)
993 v4l2_info(sd, "\tMin acceptable pulse width (LPF): %u us, "
994 "%u ns\n",
995 lpf_count_to_us(filtr),
996 lpf_count_to_ns(filtr));
997 v4l2_info(sd, "\tPulse width timer timed-out: %s\n",
998 stats & STATS_RTO ? "yes" : "no");
999 v4l2_info(sd, "\tPulse width timer time-out intr: %s\n",
1000 irqen & IRQEN_RTE ? "enabled" : "disabled");
1001 v4l2_info(sd, "\tFIFO overrun: %s\n",
1002 stats & STATS_ROR ? "yes" : "no");
1003 v4l2_info(sd, "\tFIFO overrun interrupt: %s\n",
1004 irqen & IRQEN_ROE ? "enabled" : "disabled");
1005 v4l2_info(sd, "\tBusy: %s\n",
1006 stats & STATS_RBY ? "yes" : "no");
1007 v4l2_info(sd, "\tFIFO service requested: %s\n",
1008 stats & STATS_RSR ? "yes" : "no");
1009 v4l2_info(sd, "\tFIFO service request interrupt: %s\n",
1010 irqen & IRQEN_RSE ? "enabled" : "disabled");
1011
1012 v4l2_info(sd, "IR Transmitter:\n");
1013 v4l2_info(sd, "\tEnabled: %s\n",
1014 cntrl & CNTRL_TXE ? "yes" : "no");
1015 v4l2_info(sd, "\tModulation onto a carrier: %s\n",
1016 cntrl & CNTRL_MOD ? "enabled" : "disabled");
1017 v4l2_info(sd, "\tFIFO: %s\n",
1018 cntrl & CNTRL_TFE ? "enabled" : "disabled");
1019 v4l2_info(sd, "\tFIFO interrupt watermark: %s\n",
1020 cntrl & CNTRL_TIC ? "not empty" : "half full or less");
1021 v4l2_info(sd, "\tSignal polarity: %s\n",
1022 cntrl & CNTRL_CPL ? "0:mark 1:space" : "0:space 1:mark");
1023 if (cntrl & CNTRL_MOD) {
1024 v4l2_info(sd, "\tCarrier (16 clocks): %u Hz\n",
1025 clock_divider_to_carrier_freq(txclk));
1026 v4l2_info(sd, "\tCarrier duty cycle: %2u/16\n",
1027 cduty + 1);
1028 } else {
1029 v4l2_info(sd, "\tMax pulse width: %u us, "
1030 "%llu ns\n",
1031 pulse_width_count_to_us(FIFO_RXTX, txclk),
1032 pulse_width_count_to_ns(FIFO_RXTX, txclk));
1033 }
1034 v4l2_info(sd, "\tBusy: %s\n",
1035 stats & STATS_TBY ? "yes" : "no");
1036 v4l2_info(sd, "\tFIFO service requested: %s\n",
1037 stats & STATS_TSR ? "yes" : "no");
1038 v4l2_info(sd, "\tFIFO service request interrupt: %s\n",
1039 irqen & IRQEN_TSE ? "enabled" : "disabled");
1040
1041 return 0;
1042}
1043
1044static inline int cx23888_ir_dbg_match(const struct v4l2_dbg_match *match)
1045{
1046 return match->type == V4L2_CHIP_MATCH_HOST && match->addr == 2;
1047}
1048
1049static int cx23888_ir_g_chip_ident(struct v4l2_subdev *sd,
1050 struct v4l2_dbg_chip_ident *chip)
1051{
1052 struct cx23888_ir_state *state = to_state(sd);
1053
1054 if (cx23888_ir_dbg_match(&chip->match)) {
1055 chip->ident = state->id;
1056 chip->revision = state->rev;
1057 }
1058 return 0;
1059}
1060
1061#ifdef CONFIG_VIDEO_ADV_DEBUG
1062static int cx23888_ir_g_register(struct v4l2_subdev *sd,
1063 struct v4l2_dbg_register *reg)
1064{
1065 struct cx23888_ir_state *state = to_state(sd);
1066 u32 addr = CX23888_IR_REG_BASE + (u32) reg->reg;
1067
1068 if (!cx23888_ir_dbg_match(&reg->match))
1069 return -EINVAL;
1070 if ((addr & 0x3) != 0)
1071 return -EINVAL;
1072 if (addr < CX23888_IR_CNTRL_REG || addr > CX23888_IR_LEARN_REG)
1073 return -EINVAL;
1074 if (!capable(CAP_SYS_ADMIN))
1075 return -EPERM;
1076 reg->size = 4;
1077 reg->val = cx23888_ir_read4(state->dev, addr);
1078 return 0;
1079}
1080
1081static int cx23888_ir_s_register(struct v4l2_subdev *sd,
1082 struct v4l2_dbg_register *reg)
1083{
1084 struct cx23888_ir_state *state = to_state(sd);
1085 u32 addr = CX23888_IR_REG_BASE + (u32) reg->reg;
1086
1087 if (!cx23888_ir_dbg_match(&reg->match))
1088 return -EINVAL;
1089 if ((addr & 0x3) != 0)
1090 return -EINVAL;
1091 if (addr < CX23888_IR_CNTRL_REG || addr > CX23888_IR_LEARN_REG)
1092 return -EINVAL;
1093 if (!capable(CAP_SYS_ADMIN))
1094 return -EPERM;
1095 cx23888_ir_write4(state->dev, addr, reg->val);
1096 return 0;
1097}
1098#endif
1099
1100static const struct v4l2_subdev_core_ops cx23888_ir_core_ops = {
1101 .g_chip_ident = cx23888_ir_g_chip_ident,
1102 .log_status = cx23888_ir_log_status,
1103#ifdef CONFIG_VIDEO_ADV_DEBUG
1104 .g_register = cx23888_ir_g_register,
1105 .s_register = cx23888_ir_s_register,
1106#endif
1107};
1108
1109static const struct v4l2_subdev_ir_ops cx23888_ir_ir_ops = {
1110 .interrupt_service_routine = cx23888_ir_irq_handler,
1111
1112 .rx_read = cx23888_ir_rx_read,
1113 .rx_g_parameters = cx23888_ir_rx_g_parameters,
1114 .rx_s_parameters = cx23888_ir_rx_s_parameters,
1115
1116 .tx_write = cx23888_ir_tx_write,
1117 .tx_g_parameters = cx23888_ir_tx_g_parameters,
1118 .tx_s_parameters = cx23888_ir_tx_s_parameters,
1119};
1120
1121static const struct v4l2_subdev_ops cx23888_ir_controller_ops = {
1122 .core = &cx23888_ir_core_ops,
1123 .ir = &cx23888_ir_ir_ops,
1124};
1125
1126static const struct v4l2_subdev_ir_parameters default_rx_params = {
1127 .bytes_per_data_element = sizeof(u32),
1128 .mode = V4L2_SUBDEV_IR_MODE_PULSE_WIDTH,
1129
1130 .enable = false,
1131 .interrupt_enable = false,
1132 .shutdown = true,
1133
1134 .modulation = true,
1135 .carrier_freq = 36000, /* 36 kHz - RC-5, RC-6, and RC-6A carrier */
1136
1137 /* RC-5: 666,667 ns = 1/36 kHz * 32 cycles * 1 mark * 0.75 */
1138 /* RC-6A: 333,333 ns = 1/36 kHz * 16 cycles * 1 mark * 0.75 */
1139 .noise_filter_min_width = 333333, /* ns */
1140 .carrier_range_lower = 35000,
1141 .carrier_range_upper = 37000,
1142 .invert = false,
1143};
1144
1145static const struct v4l2_subdev_ir_parameters default_tx_params = {
1146 .bytes_per_data_element = sizeof(u32),
1147 .mode = V4L2_SUBDEV_IR_MODE_PULSE_WIDTH,
1148
1149 .enable = false,
1150 .interrupt_enable = false,
1151 .shutdown = true,
1152
1153 .modulation = true,
1154 .carrier_freq = 36000, /* 36 kHz - RC-5 carrier */
1155 .duty_cycle = 25, /* 25 % - RC-5 carrier */
1156 .invert = false,
1157};
1158
1159int cx23888_ir_probe(struct cx23885_dev *dev)
1160{
1161 struct cx23888_ir_state *state;
1162 struct v4l2_subdev *sd;
1163 struct v4l2_subdev_ir_parameters default_params;
1164 int ret;
1165
1166 state = kzalloc(sizeof(struct cx23888_ir_state), GFP_KERNEL);
1167 if (state == NULL)
1168 return -ENOMEM;
1169
1170 spin_lock_init(&state->rx_kfifo_lock);
1171 state->rx_kfifo = kfifo_alloc(CX23888_IR_RX_KFIFO_SIZE, GFP_KERNEL,
1172 &state->rx_kfifo_lock);
1173 if (state->rx_kfifo == NULL)
1174 return -ENOMEM;
1175
1176 spin_lock_init(&state->tx_kfifo_lock);
1177 state->tx_kfifo = kfifo_alloc(CX23888_IR_TX_KFIFO_SIZE, GFP_KERNEL,
1178 &state->tx_kfifo_lock);
1179 if (state->tx_kfifo == NULL) {
1180 kfifo_free(state->rx_kfifo);
1181 return -ENOMEM;
1182 }
1183
1184 state->dev = dev;
1185 state->id = V4L2_IDENT_CX23888_IR;
1186 state->rev = 0;
1187 sd = &state->sd;
1188
1189 v4l2_subdev_init(sd, &cx23888_ir_controller_ops);
1190 v4l2_set_subdevdata(sd, state);
1191 /* FIXME - fix the formatting of dev->v4l2_dev.name and use it */
1192 snprintf(sd->name, sizeof(sd->name), "%s/888-ir", dev->name);
1193 sd->grp_id = CX23885_HW_888_IR;
1194
1195 ret = v4l2_device_register_subdev(&dev->v4l2_dev, sd);
1196 if (ret == 0) {
1197 /*
1198 * Ensure no interrupts arrive from '888 specific conditions,
1199 * since we ignore them in this driver to have commonality with
1200 * similar IR controller cores.
1201 */
1202 cx23888_ir_write4(dev, CX23888_IR_IRQEN_REG, 0);
1203
1204 mutex_init(&state->rx_params_lock);
1205 memcpy(&default_params, &default_rx_params,
1206 sizeof(struct v4l2_subdev_ir_parameters));
1207 v4l2_subdev_call(sd, ir, rx_s_parameters, &default_params);
1208
1209 mutex_init(&state->tx_params_lock);
1210 memcpy(&default_params, &default_tx_params,
1211 sizeof(struct v4l2_subdev_ir_parameters));
1212 v4l2_subdev_call(sd, ir, tx_s_parameters, &default_params);
1213 } else {
1214 kfifo_free(state->rx_kfifo);
1215 kfifo_free(state->tx_kfifo);
1216 }
1217 return ret;
1218}
1219
1220int cx23888_ir_remove(struct cx23885_dev *dev)
1221{
1222 struct v4l2_subdev *sd;
1223 struct cx23888_ir_state *state;
1224
1225 sd = cx23885_find_hw(dev, CX23885_HW_888_IR);
1226 if (sd == NULL)
1227 return -ENODEV;
1228
1229 cx23888_ir_rx_shutdown(sd);
1230 cx23888_ir_tx_shutdown(sd);
1231
1232 state = to_state(sd);
1233 v4l2_device_unregister_subdev(sd);
1234 kfifo_free(state->rx_kfifo);
1235 kfifo_free(state->tx_kfifo);
1236 kfree(state);
1237 /* Nothing more to free() as state held the actual v4l2_subdev object */
1238 return 0;
1239}
diff --git a/drivers/media/video/cx23885/cx23888-ir.h b/drivers/media/video/cx23885/cx23888-ir.h
new file mode 100644
index 000000000000..3d446f9eb94b
--- /dev/null
+++ b/drivers/media/video/cx23885/cx23888-ir.h
@@ -0,0 +1,28 @@
1/*
2 * Driver for the Conexant CX23885/7/8 PCIe bridge
3 *
4 * CX23888 Integrated Consumer Infrared Controller
5 *
6 * Copyright (C) 2009 Andy Walls <awalls@radix.net>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 * 02110-1301, USA.
22 */
23
24#ifndef _CX23888_IR_H_
25#define _CX23888_IR_H_
26int cx23888_ir_probe(struct cx23885_dev *dev);
27int cx23888_ir_remove(struct cx23885_dev *dev);
28#endif
diff --git a/drivers/media/video/cx25840/cx25840-audio.c b/drivers/media/video/cx25840/cx25840-audio.c
index 2f846f5e0f9f..45608d50529c 100644
--- a/drivers/media/video/cx25840/cx25840-audio.c
+++ b/drivers/media/video/cx25840/cx25840-audio.c
@@ -23,87 +23,137 @@
23 23
24#include "cx25840-core.h" 24#include "cx25840-core.h"
25 25
26static int set_audclk_freq(struct i2c_client *client, u32 freq) 26/*
27 * Note: The PLL and SRC parameters are based on a reference frequency that
28 * would ideally be:
29 *
30 * NTSC Color subcarrier freq * 8 = 4.5 MHz/286 * 455/2 * 8 = 28.63636363... MHz
31 *
32 * However, it's not the exact reference frequency that matters, only that the
33 * firmware and modules that comprise the driver for a particular board all
34 * use the same value (close to the ideal value).
35 *
36 * Comments below will note which reference frequency is assumed for various
37 * parameters. They will usually be one of
38 *
39 * ref_freq = 28.636360 MHz
40 * or
41 * ref_freq = 28.636363 MHz
42 */
43
44static int cx25840_set_audclk_freq(struct i2c_client *client, u32 freq)
27{ 45{
28 struct cx25840_state *state = to_state(i2c_get_clientdata(client)); 46 struct cx25840_state *state = to_state(i2c_get_clientdata(client));
29 47
30 if (freq != 32000 && freq != 44100 && freq != 48000)
31 return -EINVAL;
32
33 /* common for all inputs and rates */
34 /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x10 */
35 if (!state->is_cx23885 && !state->is_cx231xx)
36 cx25840_write(client, 0x127, 0x50);
37
38 if (state->aud_input != CX25840_AUDIO_SERIAL) { 48 if (state->aud_input != CX25840_AUDIO_SERIAL) {
39 switch (freq) { 49 switch (freq) {
40 case 32000: 50 case 32000:
41 if (state->is_cx23885) { 51 /*
42 /* We don't have register values 52 * VID_PLL Integer = 0x0f, VID_PLL Post Divider = 0x04
43 * so avoid destroying registers. */ 53 * AUX_PLL Integer = 0x06, AUX PLL Post Divider = 0x10
44 break; 54 */
45 } 55 cx25840_write4(client, 0x108, 0x1006040f);
46 56
47 if (!state->is_cx231xx) { 57 /*
48 /* VID_PLL and AUX_PLL */ 58 * VID_PLL Fraction (register 0x10c) = 0x2be2fe
49 cx25840_write4(client, 0x108, 0x1006040f); 59 * 28636360 * 0xf.15f17f0/4 = 108 MHz
50 60 * 432 MHz pre-postdivide
51 /* AUX_PLL_FRAC */ 61 */
52 cx25840_write4(client, 0x110, 0x01bb39ee); 62
53 } 63 /*
54 64 * AUX_PLL Fraction = 0x1bb39ee
55 if (state->is_cx25836) 65 * 28636363 * 0x6.dd9cf70/0x10 = 32000 * 384
66 * 196.6 MHz pre-postdivide
67 * FIXME < 200 MHz is out of specified valid range
68 * FIXME 28636363 ref_freq doesn't match VID PLL ref
69 */
70 cx25840_write4(client, 0x110, 0x01bb39ee);
71
72 /*
73 * SA_MCLK_SEL = 1
74 * SA_MCLK_DIV = 0x10 = 384/384 * AUX_PLL post dvivider
75 */
76 cx25840_write(client, 0x127, 0x50);
77
78 if (is_cx2583x(state))
56 break; 79 break;
57 80
58 /* src3/4/6_ctl = 0x0801f77f */ 81 /* src3/4/6_ctl */
82 /* 0x1.f77f = (4 * 28636360/8 * 2/455) / 32000 */
59 cx25840_write4(client, 0x900, 0x0801f77f); 83 cx25840_write4(client, 0x900, 0x0801f77f);
60 cx25840_write4(client, 0x904, 0x0801f77f); 84 cx25840_write4(client, 0x904, 0x0801f77f);
61 cx25840_write4(client, 0x90c, 0x0801f77f); 85 cx25840_write4(client, 0x90c, 0x0801f77f);
62 break; 86 break;
63 87
64 case 44100: 88 case 44100:
65 if (state->is_cx23885) { 89 /*
66 /* We don't have register values 90 * VID_PLL Integer = 0x0f, VID_PLL Post Divider = 0x04
67 * so avoid destroying registers. */ 91 * AUX_PLL Integer = 0x09, AUX PLL Post Divider = 0x10
92 */
93 cx25840_write4(client, 0x108, 0x1009040f);
94
95 /*
96 * VID_PLL Fraction (register 0x10c) = 0x2be2fe
97 * 28636360 * 0xf.15f17f0/4 = 108 MHz
98 * 432 MHz pre-postdivide
99 */
100
101 /*
102 * AUX_PLL Fraction = 0x0ec6bd6
103 * 28636363 * 0x9.7635eb0/0x10 = 44100 * 384
104 * 271 MHz pre-postdivide
105 * FIXME 28636363 ref_freq doesn't match VID PLL ref
106 */
107 cx25840_write4(client, 0x110, 0x00ec6bd6);
108
109 /*
110 * SA_MCLK_SEL = 1
111 * SA_MCLK_DIV = 0x10 = 384/384 * AUX_PLL post dvivider
112 */
113 cx25840_write(client, 0x127, 0x50);
114
115 if (is_cx2583x(state))
68 break; 116 break;
69 }
70
71 if (!state->is_cx231xx) {
72 /* VID_PLL and AUX_PLL */
73 cx25840_write4(client, 0x108, 0x1009040f);
74
75 /* AUX_PLL_FRAC */
76 cx25840_write4(client, 0x110, 0x00ec6bd6);
77 }
78 117
79 if (state->is_cx25836) 118 /* src3/4/6_ctl */
80 break; 119 /* 0x1.6d59 = (4 * 28636360/8 * 2/455) / 44100 */
81
82 /* src3/4/6_ctl = 0x08016d59 */
83 cx25840_write4(client, 0x900, 0x08016d59); 120 cx25840_write4(client, 0x900, 0x08016d59);
84 cx25840_write4(client, 0x904, 0x08016d59); 121 cx25840_write4(client, 0x904, 0x08016d59);
85 cx25840_write4(client, 0x90c, 0x08016d59); 122 cx25840_write4(client, 0x90c, 0x08016d59);
86 break; 123 break;
87 124
88 case 48000: 125 case 48000:
89 if (state->is_cx23885) { 126 /*
90 /* We don't have register values 127 * VID_PLL Integer = 0x0f, VID_PLL Post Divider = 0x04
91 * so avoid destroying registers. */ 128 * AUX_PLL Integer = 0x0a, AUX PLL Post Divider = 0x10
92 break; 129 */
93 } 130 cx25840_write4(client, 0x108, 0x100a040f);
94 131
95 if (!state->is_cx231xx) { 132 /*
96 /* VID_PLL and AUX_PLL */ 133 * VID_PLL Fraction (register 0x10c) = 0x2be2fe
97 cx25840_write4(client, 0x108, 0x100a040f); 134 * 28636360 * 0xf.15f17f0/4 = 108 MHz
98 135 * 432 MHz pre-postdivide
99 /* AUX_PLL_FRAC */ 136 */
100 cx25840_write4(client, 0x110, 0x0098d6e5); 137
101 } 138 /*
102 139 * AUX_PLL Fraction = 0x098d6e5
103 if (state->is_cx25836) 140 * 28636363 * 0xa.4c6b728/0x10 = 48000 * 384
141 * 295 MHz pre-postdivide
142 * FIXME 28636363 ref_freq doesn't match VID PLL ref
143 */
144 cx25840_write4(client, 0x110, 0x0098d6e5);
145
146 /*
147 * SA_MCLK_SEL = 1
148 * SA_MCLK_DIV = 0x10 = 384/384 * AUX_PLL post dvivider
149 */
150 cx25840_write(client, 0x127, 0x50);
151
152 if (is_cx2583x(state))
104 break; 153 break;
105 154
106 /* src3/4/6_ctl = 0x08014faa */ 155 /* src3/4/6_ctl */
156 /* 0x1.4faa = (4 * 28636360/8 * 2/455) / 48000 */
107 cx25840_write4(client, 0x900, 0x08014faa); 157 cx25840_write4(client, 0x900, 0x08014faa);
108 cx25840_write4(client, 0x904, 0x08014faa); 158 cx25840_write4(client, 0x904, 0x08014faa);
109 cx25840_write4(client, 0x90c, 0x08014faa); 159 cx25840_write4(client, 0x90c, 0x08014faa);
@@ -112,91 +162,249 @@ static int set_audclk_freq(struct i2c_client *client, u32 freq)
112 } else { 162 } else {
113 switch (freq) { 163 switch (freq) {
114 case 32000: 164 case 32000:
115 if (state->is_cx23885) { 165 /*
116 /* We don't have register values 166 * VID_PLL Integer = 0x0f, VID_PLL Post Divider = 0x04
117 * so avoid destroying registers. */ 167 * AUX_PLL Integer = 0x08, AUX PLL Post Divider = 0x1e
118 break; 168 */
119 } 169 cx25840_write4(client, 0x108, 0x1e08040f);
120 170
121 if (!state->is_cx231xx) { 171 /*
122 /* VID_PLL and AUX_PLL */ 172 * VID_PLL Fraction (register 0x10c) = 0x2be2fe
123 cx25840_write4(client, 0x108, 0x1e08040f); 173 * 28636360 * 0xf.15f17f0/4 = 108 MHz
124 174 * 432 MHz pre-postdivide
125 /* AUX_PLL_FRAC */ 175 */
126 cx25840_write4(client, 0x110, 0x012a0869); 176
127 } 177 /*
178 * AUX_PLL Fraction = 0x12a0869
179 * 28636363 * 0x8.9504348/0x1e = 32000 * 256
180 * 246 MHz pre-postdivide
181 * FIXME 28636363 ref_freq doesn't match VID PLL ref
182 */
183 cx25840_write4(client, 0x110, 0x012a0869);
184
185 /*
186 * SA_MCLK_SEL = 1
187 * SA_MCLK_DIV = 0x14 = 256/384 * AUX_PLL post dvivider
188 */
189 cx25840_write(client, 0x127, 0x54);
128 190
129 if (state->is_cx25836) 191 if (is_cx2583x(state))
130 break; 192 break;
131 193
132 /* src1_ctl = 0x08010000 */ 194 /* src1_ctl */
195 /* 0x1.0000 = 32000/32000 */
133 cx25840_write4(client, 0x8f8, 0x08010000); 196 cx25840_write4(client, 0x8f8, 0x08010000);
134 197
135 /* src3/4/6_ctl = 0x08020000 */ 198 /* src3/4/6_ctl */
199 /* 0x2.0000 = 2 * (32000/32000) */
136 cx25840_write4(client, 0x900, 0x08020000); 200 cx25840_write4(client, 0x900, 0x08020000);
137 cx25840_write4(client, 0x904, 0x08020000); 201 cx25840_write4(client, 0x904, 0x08020000);
138 cx25840_write4(client, 0x90c, 0x08020000); 202 cx25840_write4(client, 0x90c, 0x08020000);
139
140 /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x14 */
141 cx25840_write(client, 0x127, 0x54);
142 break; 203 break;
143 204
144 case 44100: 205 case 44100:
145 if (state->is_cx23885) { 206 /*
146 /* We don't have register values 207 * VID_PLL Integer = 0x0f, VID_PLL Post Divider = 0x04
147 * so avoid destroying registers. */ 208 * AUX_PLL Integer = 0x09, AUX PLL Post Divider = 0x18
148 break; 209 */
149 } 210 cx25840_write4(client, 0x108, 0x1809040f);
150 211
151 212 /*
152 if (!state->is_cx231xx) { 213 * VID_PLL Fraction (register 0x10c) = 0x2be2fe
153 /* VID_PLL and AUX_PLL */ 214 * 28636360 * 0xf.15f17f0/4 = 108 MHz
154 cx25840_write4(client, 0x108, 0x1809040f); 215 * 432 MHz pre-postdivide
155 216 */
156 /* AUX_PLL_FRAC */ 217
157 cx25840_write4(client, 0x110, 0x00ec6bd6); 218 /*
158 } 219 * AUX_PLL Fraction = 0x0ec6bd6
159 220 * 28636363 * 0x9.7635eb0/0x18 = 44100 * 256
160 if (state->is_cx25836) 221 * 271 MHz pre-postdivide
222 * FIXME 28636363 ref_freq doesn't match VID PLL ref
223 */
224 cx25840_write4(client, 0x110, 0x00ec6bd6);
225
226 /*
227 * SA_MCLK_SEL = 1
228 * SA_MCLK_DIV = 0x10 = 256/384 * AUX_PLL post dvivider
229 */
230 cx25840_write(client, 0x127, 0x50);
231
232 if (is_cx2583x(state))
161 break; 233 break;
162 234
163 /* src1_ctl = 0x08010000 */ 235 /* src1_ctl */
236 /* 0x1.60cd = 44100/32000 */
164 cx25840_write4(client, 0x8f8, 0x080160cd); 237 cx25840_write4(client, 0x8f8, 0x080160cd);
165 238
166 /* src3/4/6_ctl = 0x08020000 */ 239 /* src3/4/6_ctl */
240 /* 0x1.7385 = 2 * (32000/44100) */
167 cx25840_write4(client, 0x900, 0x08017385); 241 cx25840_write4(client, 0x900, 0x08017385);
168 cx25840_write4(client, 0x904, 0x08017385); 242 cx25840_write4(client, 0x904, 0x08017385);
169 cx25840_write4(client, 0x90c, 0x08017385); 243 cx25840_write4(client, 0x90c, 0x08017385);
170 break; 244 break;
171 245
172 case 48000: 246 case 48000:
173 if (!state->is_cx23885 && !state->is_cx231xx) { 247 /*
174 /* VID_PLL and AUX_PLL */ 248 * VID_PLL Integer = 0x0f, VID_PLL Post Divider = 0x04
175 cx25840_write4(client, 0x108, 0x180a040f); 249 * AUX_PLL Integer = 0x0a, AUX PLL Post Divider = 0x18
250 */
251 cx25840_write4(client, 0x108, 0x180a040f);
252
253 /*
254 * VID_PLL Fraction (register 0x10c) = 0x2be2fe
255 * 28636360 * 0xf.15f17f0/4 = 108 MHz
256 * 432 MHz pre-postdivide
257 */
258
259 /*
260 * AUX_PLL Fraction = 0x098d6e5
261 * 28636363 * 0xa.4c6b728/0x18 = 48000 * 256
262 * 295 MHz pre-postdivide
263 * FIXME 28636363 ref_freq doesn't match VID PLL ref
264 */
265 cx25840_write4(client, 0x110, 0x0098d6e5);
266
267 /*
268 * SA_MCLK_SEL = 1
269 * SA_MCLK_DIV = 0x10 = 256/384 * AUX_PLL post dvivider
270 */
271 cx25840_write(client, 0x127, 0x50);
272
273 if (is_cx2583x(state))
274 break;
176 275
177 /* AUX_PLL_FRAC */ 276 /* src1_ctl */
178 cx25840_write4(client, 0x110, 0x0098d6e5); 277 /* 0x1.8000 = 48000/32000 */
179 } 278 cx25840_write4(client, 0x8f8, 0x08018000);
180 279
181 if (state->is_cx25836) 280 /* src3/4/6_ctl */
182 break; 281 /* 0x1.5555 = 2 * (32000/48000) */
282 cx25840_write4(client, 0x900, 0x08015555);
283 cx25840_write4(client, 0x904, 0x08015555);
284 cx25840_write4(client, 0x90c, 0x08015555);
285 break;
286 }
287 }
288
289 state->audclk_freq = freq;
290
291 return 0;
292}
293
294static inline int cx25836_set_audclk_freq(struct i2c_client *client, u32 freq)
295{
296 return cx25840_set_audclk_freq(client, freq);
297}
298
299static int cx23885_set_audclk_freq(struct i2c_client *client, u32 freq)
300{
301 struct cx25840_state *state = to_state(i2c_get_clientdata(client));
302
303 if (state->aud_input != CX25840_AUDIO_SERIAL) {
304 switch (freq) {
305 case 32000:
306 case 44100:
307 case 48000:
308 /* We don't have register values
309 * so avoid destroying registers. */
310 /* FIXME return -EINVAL; */
311 break;
312 }
313 } else {
314 switch (freq) {
315 case 32000:
316 case 44100:
317 /* We don't have register values
318 * so avoid destroying registers. */
319 /* FIXME return -EINVAL; */
320 break;
321
322 case 48000:
323 /* src1_ctl */
324 /* 0x1.867c = 48000 / (2 * 28636360/8 * 2/455) */
325 cx25840_write4(client, 0x8f8, 0x0801867c);
326
327 /* src3/4/6_ctl */
328 /* 0x1.4faa = (4 * 28636360/8 * 2/455) / 48000 */
329 cx25840_write4(client, 0x900, 0x08014faa);
330 cx25840_write4(client, 0x904, 0x08014faa);
331 cx25840_write4(client, 0x90c, 0x08014faa);
332 break;
333 }
334 }
335
336 state->audclk_freq = freq;
337
338 return 0;
339}
340
341static int cx231xx_set_audclk_freq(struct i2c_client *client, u32 freq)
342{
343 struct cx25840_state *state = to_state(i2c_get_clientdata(client));
344
345 if (state->aud_input != CX25840_AUDIO_SERIAL) {
346 switch (freq) {
347 case 32000:
348 /* src3/4/6_ctl */
349 /* 0x1.f77f = (4 * 28636360/8 * 2/455) / 32000 */
350 cx25840_write4(client, 0x900, 0x0801f77f);
351 cx25840_write4(client, 0x904, 0x0801f77f);
352 cx25840_write4(client, 0x90c, 0x0801f77f);
353 break;
354
355 case 44100:
356 /* src3/4/6_ctl */
357 /* 0x1.6d59 = (4 * 28636360/8 * 2/455) / 44100 */
358 cx25840_write4(client, 0x900, 0x08016d59);
359 cx25840_write4(client, 0x904, 0x08016d59);
360 cx25840_write4(client, 0x90c, 0x08016d59);
361 break;
362
363 case 48000:
364 /* src3/4/6_ctl */
365 /* 0x1.4faa = (4 * 28636360/8 * 2/455) / 48000 */
366 cx25840_write4(client, 0x900, 0x08014faa);
367 cx25840_write4(client, 0x904, 0x08014faa);
368 cx25840_write4(client, 0x90c, 0x08014faa);
369 break;
370 }
371 } else {
372 switch (freq) {
373 /* FIXME These cases make different assumptions about audclk */
374 case 32000:
375 /* src1_ctl */
376 /* 0x1.0000 = 32000/32000 */
377 cx25840_write4(client, 0x8f8, 0x08010000);
183 378
184 if (!state->is_cx23885 && !state->is_cx231xx) { 379 /* src3/4/6_ctl */
185 /* src1_ctl */ 380 /* 0x2.0000 = 2 * (32000/32000) */
186 cx25840_write4(client, 0x8f8, 0x08018000); 381 cx25840_write4(client, 0x900, 0x08020000);
382 cx25840_write4(client, 0x904, 0x08020000);
383 cx25840_write4(client, 0x90c, 0x08020000);
384 break;
187 385
188 /* src3/4/6_ctl */ 386 case 44100:
189 cx25840_write4(client, 0x900, 0x08015555); 387 /* src1_ctl */
190 cx25840_write4(client, 0x904, 0x08015555); 388 /* 0x1.60cd = 44100/32000 */
191 cx25840_write4(client, 0x90c, 0x08015555); 389 cx25840_write4(client, 0x8f8, 0x080160cd);
192 } else {
193 390
194 cx25840_write4(client, 0x8f8, 0x0801867c); 391 /* src3/4/6_ctl */
392 /* 0x1.7385 = 2 * (32000/44100) */
393 cx25840_write4(client, 0x900, 0x08017385);
394 cx25840_write4(client, 0x904, 0x08017385);
395 cx25840_write4(client, 0x90c, 0x08017385);
396 break;
195 397
196 cx25840_write4(client, 0x900, 0x08014faa); 398 case 48000:
197 cx25840_write4(client, 0x904, 0x08014faa); 399 /* src1_ctl */
198 cx25840_write4(client, 0x90c, 0x08014faa); 400 /* 0x1.867c = 48000 / (2 * 28636360/8 * 2/455) */
199 } 401 cx25840_write4(client, 0x8f8, 0x0801867c);
402
403 /* src3/4/6_ctl */
404 /* 0x1.4faa = (4 * 28636360/8 * 2/455) / 48000 */
405 cx25840_write4(client, 0x900, 0x08014faa);
406 cx25840_write4(client, 0x904, 0x08014faa);
407 cx25840_write4(client, 0x90c, 0x08014faa);
200 break; 408 break;
201 } 409 }
202 } 410 }
@@ -206,6 +414,25 @@ static int set_audclk_freq(struct i2c_client *client, u32 freq)
206 return 0; 414 return 0;
207} 415}
208 416
417static int set_audclk_freq(struct i2c_client *client, u32 freq)
418{
419 struct cx25840_state *state = to_state(i2c_get_clientdata(client));
420
421 if (freq != 32000 && freq != 44100 && freq != 48000)
422 return -EINVAL;
423
424 if (is_cx231xx(state))
425 return cx231xx_set_audclk_freq(client, freq);
426
427 if (is_cx2388x(state))
428 return cx23885_set_audclk_freq(client, freq);
429
430 if (is_cx2583x(state))
431 return cx25836_set_audclk_freq(client, freq);
432
433 return cx25840_set_audclk_freq(client, freq);
434}
435
209void cx25840_audio_set_path(struct i2c_client *client) 436void cx25840_audio_set_path(struct i2c_client *client)
210{ 437{
211 struct cx25840_state *state = to_state(i2c_get_clientdata(client)); 438 struct cx25840_state *state = to_state(i2c_get_clientdata(client));
@@ -243,7 +470,7 @@ void cx25840_audio_set_path(struct i2c_client *client)
243 cx25840_and_or(client, 0x810, ~0x1, 0x00); 470 cx25840_and_or(client, 0x810, ~0x1, 0x00);
244 471
245 /* Ensure the controller is running when we exit */ 472 /* Ensure the controller is running when we exit */
246 if (state->is_cx23885 || state->is_cx231xx) 473 if (is_cx2388x(state) || is_cx231xx(state))
247 cx25840_and_or(client, 0x803, ~0x10, 0x10); 474 cx25840_and_or(client, 0x803, ~0x10, 0x10);
248} 475}
249 476
@@ -383,7 +610,7 @@ int cx25840_s_clock_freq(struct v4l2_subdev *sd, u32 freq)
383 struct cx25840_state *state = to_state(sd); 610 struct cx25840_state *state = to_state(sd);
384 int retval; 611 int retval;
385 612
386 if (!state->is_cx25836) 613 if (!is_cx2583x(state))
387 cx25840_and_or(client, 0x810, ~0x1, 1); 614 cx25840_and_or(client, 0x810, ~0x1, 1);
388 if (state->aud_input != CX25840_AUDIO_SERIAL) { 615 if (state->aud_input != CX25840_AUDIO_SERIAL) {
389 cx25840_and_or(client, 0x803, ~0x10, 0); 616 cx25840_and_or(client, 0x803, ~0x10, 0);
@@ -392,7 +619,7 @@ int cx25840_s_clock_freq(struct v4l2_subdev *sd, u32 freq)
392 retval = set_audclk_freq(client, freq); 619 retval = set_audclk_freq(client, freq);
393 if (state->aud_input != CX25840_AUDIO_SERIAL) 620 if (state->aud_input != CX25840_AUDIO_SERIAL)
394 cx25840_and_or(client, 0x803, ~0x10, 0x10); 621 cx25840_and_or(client, 0x803, ~0x10, 0x10);
395 if (!state->is_cx25836) 622 if (!is_cx2583x(state))
396 cx25840_and_or(client, 0x810, ~0x1, 0); 623 cx25840_and_or(client, 0x810, ~0x1, 0);
397 return retval; 624 return retval;
398} 625}
diff --git a/drivers/media/video/cx25840/cx25840-core.c b/drivers/media/video/cx25840/cx25840-core.c
index 1aeaf18a9bea..385ecd58f1c0 100644
--- a/drivers/media/video/cx25840/cx25840-core.c
+++ b/drivers/media/video/cx25840/cx25840-core.c
@@ -259,6 +259,13 @@ static void cx23885_initialize(struct i2c_client *client)
259 struct cx25840_state *state = to_state(i2c_get_clientdata(client)); 259 struct cx25840_state *state = to_state(i2c_get_clientdata(client));
260 struct workqueue_struct *q; 260 struct workqueue_struct *q;
261 261
262 /*
263 * Come out of digital power down
264 * The CX23888, at least, needs this, otherwise registers aside from
265 * 0x0-0x2 can't be read or written.
266 */
267 cx25840_write(client, 0x000, 0);
268
262 /* Internal Reset */ 269 /* Internal Reset */
263 cx25840_and_or(client, 0x102, ~0x01, 0x01); 270 cx25840_and_or(client, 0x102, ~0x01, 0x01);
264 cx25840_and_or(client, 0x102, ~0x01, 0x00); 271 cx25840_and_or(client, 0x102, ~0x01, 0x00);
@@ -269,18 +276,45 @@ static void cx23885_initialize(struct i2c_client *client)
269 /* DIF in reset? */ 276 /* DIF in reset? */
270 cx25840_write(client, 0x398, 0); 277 cx25840_write(client, 0x398, 0);
271 278
272 /* Trust the default xtal, no division */ 279 /*
273 /* This changes for the cx23888 products */ 280 * Trust the default xtal, no division
281 * '885: 28.636363... MHz
282 * '887: 25.000000 MHz
283 * '888: 50.000000 MHz
284 */
274 cx25840_write(client, 0x2, 0x76); 285 cx25840_write(client, 0x2, 0x76);
275 286
276 /* Bring down the regulator for AUX clk */ 287 /* Power up all the PLL's and DLL */
277 cx25840_write(client, 0x1, 0x40); 288 cx25840_write(client, 0x1, 0x40);
278 289
279 /* Sys PLL frac */ 290 /* Sys PLL */
280 cx25840_write4(client, 0x11c, 0x01d1744c); 291 switch (state->id) {
281 292 case V4L2_IDENT_CX23888_AV:
282 /* Sys PLL int */ 293 /*
283 cx25840_write4(client, 0x118, 0x00000416); 294 * 50.0 MHz * (0xb + 0xe8ba26/0x2000000)/4 = 5 * 28.636363 MHz
295 * 572.73 MHz before post divide
296 */
297 cx25840_write4(client, 0x11c, 0x00e8ba26);
298 cx25840_write4(client, 0x118, 0x0000040b);
299 break;
300 case V4L2_IDENT_CX23887_AV:
301 /*
302 * 25.0 MHz * (0x16 + 0x1d1744c/0x2000000)/4 = 5 * 28.636363 MHz
303 * 572.73 MHz before post divide
304 */
305 cx25840_write4(client, 0x11c, 0x01d1744c);
306 cx25840_write4(client, 0x118, 0x00000416);
307 break;
308 case V4L2_IDENT_CX23885_AV:
309 default:
310 /*
311 * 28.636363 MHz * (0x14 + 0x0/0x2000000)/4 = 5 * 28.636363 MHz
312 * 572.73 MHz before post divide
313 */
314 cx25840_write4(client, 0x11c, 0x00000000);
315 cx25840_write4(client, 0x118, 0x00000414);
316 break;
317 }
284 318
285 /* Disable DIF bypass */ 319 /* Disable DIF bypass */
286 cx25840_write4(client, 0x33c, 0x00000001); 320 cx25840_write4(client, 0x33c, 0x00000001);
@@ -288,11 +322,15 @@ static void cx23885_initialize(struct i2c_client *client)
288 /* DIF Src phase inc */ 322 /* DIF Src phase inc */
289 cx25840_write4(client, 0x340, 0x0df7df83); 323 cx25840_write4(client, 0x340, 0x0df7df83);
290 324
291 /* Vid PLL frac */ 325 /*
292 cx25840_write4(client, 0x10c, 0x01b6db7b); 326 * Vid PLL
293 327 * Setup for a BT.656 pixel clock of 13.5 Mpixels/second
294 /* Vid PLL int */ 328 *
295 cx25840_write4(client, 0x108, 0x00000512); 329 * 28.636363 MHz * (0xf + 0x02be2c9/0x2000000)/4 = 8 * 13.5 MHz
330 * 432.0 MHz before post divide
331 */
332 cx25840_write4(client, 0x10c, 0x002be2c9);
333 cx25840_write4(client, 0x108, 0x0000040f);
296 334
297 /* Luma */ 335 /* Luma */
298 cx25840_write4(client, 0x414, 0x00107d12); 336 cx25840_write4(client, 0x414, 0x00107d12);
@@ -300,11 +338,43 @@ static void cx23885_initialize(struct i2c_client *client)
300 /* Chroma */ 338 /* Chroma */
301 cx25840_write4(client, 0x420, 0x3d008282); 339 cx25840_write4(client, 0x420, 0x3d008282);
302 340
303 /* Aux PLL frac */ 341 /*
304 cx25840_write4(client, 0x114, 0x017dbf48); 342 * Aux PLL
305 343 * Initial setup for audio sample clock:
306 /* Aux PLL int */ 344 * 48 ksps, 16 bits/sample, x160 multiplier = 122.88 MHz
307 cx25840_write4(client, 0x110, 0x000a030e); 345 * Intial I2S output/master clock(?):
346 * 48 ksps, 16 bits/sample, x16 multiplier = 12.288 MHz
347 */
348 switch (state->id) {
349 case V4L2_IDENT_CX23888_AV:
350 /*
351 * 50.0 MHz * (0x7 + 0x0bedfa4/0x2000000)/3 = 122.88 MHz
352 * 368.64 MHz before post divide
353 * 122.88 MHz / 0xa = 12.288 MHz
354 */
355 cx25840_write4(client, 0x114, 0x00bedfa4);
356 cx25840_write4(client, 0x110, 0x000a0307);
357 break;
358 case V4L2_IDENT_CX23887_AV:
359 /*
360 * 25.0 MHz * (0xe + 0x17dbf48/0x2000000)/3 = 122.88 MHz
361 * 368.64 MHz before post divide
362 * 122.88 MHz / 0xa = 12.288 MHz
363 */
364 cx25840_write4(client, 0x114, 0x017dbf48);
365 cx25840_write4(client, 0x110, 0x000a030e);
366 break;
367 case V4L2_IDENT_CX23885_AV:
368 default:
369 /*
370 * 28.636363 MHz * (0xc + 0x1bf0c9e/0x2000000)/3 = 122.88 MHz
371 * 368.64 MHz before post divide
372 * 122.88 MHz / 0xa = 12.288 MHz
373 */
374 cx25840_write4(client, 0x114, 0x01bf0c9e);
375 cx25840_write4(client, 0x110, 0x000a030c);
376 break;
377 };
308 378
309 /* ADC2 input select */ 379 /* ADC2 input select */
310 cx25840_write(client, 0x102, 0x10); 380 cx25840_write(client, 0x102, 0x10);
@@ -494,7 +564,7 @@ void cx25840_std_setup(struct i2c_client *client)
494 } 564 }
495 565
496 /* DEBUG: Displays configured PLL frequency */ 566 /* DEBUG: Displays configured PLL frequency */
497 if (!state->is_cx231xx) { 567 if (!is_cx231xx(state)) {
498 pll_int = cx25840_read(client, 0x108); 568 pll_int = cx25840_read(client, 0x108);
499 pll_frac = cx25840_read4(client, 0x10c) & 0x1ffffff; 569 pll_frac = cx25840_read4(client, 0x10c) & 0x1ffffff;
500 pll_post = cx25840_read(client, 0x109); 570 pll_post = cx25840_read(client, 0x109);
@@ -615,13 +685,30 @@ static void input_change(struct i2c_client *client)
615 } 685 }
616 cx25840_write(client, 0x80b, 0x00); 686 cx25840_write(client, 0x80b, 0x00);
617 } else if (std & V4L2_STD_PAL) { 687 } else if (std & V4L2_STD_PAL) {
618 /* Follow tuner change procedure for PAL */ 688 /* Autodetect audio standard and audio system */
619 cx25840_write(client, 0x808, 0xff); 689 cx25840_write(client, 0x808, 0xff);
620 cx25840_write(client, 0x80b, 0x10); 690 /* Since system PAL-L is pretty much non-existant and
691 not used by any public broadcast network, force
692 6.5 MHz carrier to be interpreted as System DK,
693 this avoids DK audio detection instability */
694 cx25840_write(client, 0x80b, 0x00);
621 } else if (std & V4L2_STD_SECAM) { 695 } else if (std & V4L2_STD_SECAM) {
622 /* Select autodetect for SECAM */ 696 /* Autodetect audio standard and audio system */
623 cx25840_write(client, 0x808, 0xff); 697 cx25840_write(client, 0x808, 0xff);
624 cx25840_write(client, 0x80b, 0x10); 698 /* If only one of SECAM-DK / SECAM-L is required, then force
699 6.5MHz carrier, else autodetect it */
700 if ((std & V4L2_STD_SECAM_DK) &&
701 !(std & (V4L2_STD_SECAM_L | V4L2_STD_SECAM_LC))) {
702 /* 6.5 MHz carrier to be interpreted as System DK */
703 cx25840_write(client, 0x80b, 0x00);
704 } else if (!(std & V4L2_STD_SECAM_DK) &&
705 (std & (V4L2_STD_SECAM_L | V4L2_STD_SECAM_LC))) {
706 /* 6.5 MHz carrier to be interpreted as System L */
707 cx25840_write(client, 0x80b, 0x08);
708 } else {
709 /* 6.5 MHz carrier to be autodetected */
710 cx25840_write(client, 0x80b, 0x10);
711 }
625 } 712 }
626 713
627 cx25840_and_or(client, 0x810, ~0x01, 0); 714 cx25840_and_or(client, 0x810, ~0x01, 0);
@@ -633,6 +720,10 @@ static int set_input(struct i2c_client *client, enum cx25840_video_input vid_inp
633 struct cx25840_state *state = to_state(i2c_get_clientdata(client)); 720 struct cx25840_state *state = to_state(i2c_get_clientdata(client));
634 u8 is_composite = (vid_input >= CX25840_COMPOSITE1 && 721 u8 is_composite = (vid_input >= CX25840_COMPOSITE1 &&
635 vid_input <= CX25840_COMPOSITE8); 722 vid_input <= CX25840_COMPOSITE8);
723 u8 is_component = (vid_input & CX25840_COMPONENT_ON) ==
724 CX25840_COMPONENT_ON;
725 int luma = vid_input & 0xf0;
726 int chroma = vid_input & 0xf00;
636 u8 reg; 727 u8 reg;
637 728
638 v4l_dbg(1, cx25840_debug, client, 729 v4l_dbg(1, cx25840_debug, client,
@@ -645,18 +736,14 @@ static int set_input(struct i2c_client *client, enum cx25840_video_input vid_inp
645 reg = vid_input & 0xff; 736 reg = vid_input & 0xff;
646 if ((vid_input & CX25840_SVIDEO_ON) == CX25840_SVIDEO_ON) 737 if ((vid_input & CX25840_SVIDEO_ON) == CX25840_SVIDEO_ON)
647 is_composite = 0; 738 is_composite = 0;
648 else 739 else if ((vid_input & CX25840_COMPONENT_ON) == 0)
649 is_composite = 1; 740 is_composite = 1;
650 741
651 v4l_dbg(1, cx25840_debug, client, "mux cfg 0x%x comp=%d\n", 742 v4l_dbg(1, cx25840_debug, client, "mux cfg 0x%x comp=%d\n",
652 reg, is_composite); 743 reg, is_composite);
653 } else 744 } else if (is_composite) {
654 if (is_composite) {
655 reg = 0xf0 + (vid_input - CX25840_COMPOSITE1); 745 reg = 0xf0 + (vid_input - CX25840_COMPOSITE1);
656 } else { 746 } else {
657 int luma = vid_input & 0xf0;
658 int chroma = vid_input & 0xf00;
659
660 if ((vid_input & ~0xff0) || 747 if ((vid_input & ~0xff0) ||
661 luma < CX25840_SVIDEO_LUMA1 || luma > CX25840_SVIDEO_LUMA8 || 748 luma < CX25840_SVIDEO_LUMA1 || luma > CX25840_SVIDEO_LUMA8 ||
662 chroma < CX25840_SVIDEO_CHROMA4 || chroma > CX25840_SVIDEO_CHROMA8) { 749 chroma < CX25840_SVIDEO_CHROMA4 || chroma > CX25840_SVIDEO_CHROMA8) {
@@ -678,7 +765,7 @@ static int set_input(struct i2c_client *client, enum cx25840_video_input vid_inp
678 * configuration in reg (for the cx23885) so we have no 765 * configuration in reg (for the cx23885) so we have no
679 * need to attempt to flip bits for earlier av decoders. 766 * need to attempt to flip bits for earlier av decoders.
680 */ 767 */
681 if (!state->is_cx23885 && !state->is_cx231xx) { 768 if (!is_cx2388x(state) && !is_cx231xx(state)) {
682 switch (aud_input) { 769 switch (aud_input) {
683 case CX25840_AUDIO_SERIAL: 770 case CX25840_AUDIO_SERIAL:
684 /* do nothing, use serial audio input */ 771 /* do nothing, use serial audio input */
@@ -698,10 +785,13 @@ static int set_input(struct i2c_client *client, enum cx25840_video_input vid_inp
698 785
699 cx25840_write(client, 0x103, reg); 786 cx25840_write(client, 0x103, reg);
700 787
701 /* Set INPUT_MODE to Composite (0) or S-Video (1) */ 788 /* Set INPUT_MODE to Composite, S-Video or Component */
702 cx25840_and_or(client, 0x401, ~0x6, is_composite ? 0 : 0x02); 789 if (is_component)
790 cx25840_and_or(client, 0x401, ~0x6, 0x6);
791 else
792 cx25840_and_or(client, 0x401, ~0x6, is_composite ? 0 : 0x02);
703 793
704 if (!state->is_cx23885 && !state->is_cx231xx) { 794 if (!is_cx2388x(state) && !is_cx231xx(state)) {
705 /* Set CH_SEL_ADC2 to 1 if input comes from CH3 */ 795 /* Set CH_SEL_ADC2 to 1 if input comes from CH3 */
706 cx25840_and_or(client, 0x102, ~0x2, (reg & 0x80) == 0 ? 2 : 0); 796 cx25840_and_or(client, 0x102, ~0x2, (reg & 0x80) == 0 ? 2 : 0);
707 /* Set DUAL_MODE_ADC2 to 1 if input comes from both CH2&CH3 */ 797 /* Set DUAL_MODE_ADC2 to 1 if input comes from both CH2&CH3 */
@@ -710,22 +800,31 @@ static int set_input(struct i2c_client *client, enum cx25840_video_input vid_inp
710 else 800 else
711 cx25840_and_or(client, 0x102, ~0x4, 0); 801 cx25840_and_or(client, 0x102, ~0x4, 0);
712 } else { 802 } else {
713 if (is_composite) 803 /* Set DUAL_MODE_ADC2 to 1 if component*/
804 cx25840_and_or(client, 0x102, ~0x4, is_component ? 0x4 : 0x0);
805 if (is_composite) {
714 /* ADC2 input select channel 2 */ 806 /* ADC2 input select channel 2 */
715 cx25840_and_or(client, 0x102, ~0x2, 0); 807 cx25840_and_or(client, 0x102, ~0x2, 0);
716 else 808 } else if (!is_component) {
717 /* ADC2 input select channel 3 */ 809 /* S-Video */
718 cx25840_and_or(client, 0x102, ~0x2, 2); 810 if (chroma >= CX25840_SVIDEO_CHROMA7) {
811 /* ADC2 input select channel 3 */
812 cx25840_and_or(client, 0x102, ~0x2, 2);
813 } else {
814 /* ADC2 input select channel 2 */
815 cx25840_and_or(client, 0x102, ~0x2, 0);
816 }
817 }
719 } 818 }
720 819
721 state->vid_input = vid_input; 820 state->vid_input = vid_input;
722 state->aud_input = aud_input; 821 state->aud_input = aud_input;
723 if (!state->is_cx25836) { 822 if (!is_cx2583x(state)) {
724 cx25840_audio_set_path(client); 823 cx25840_audio_set_path(client);
725 input_change(client); 824 input_change(client);
726 } 825 }
727 826
728 if (state->is_cx23885) { 827 if (is_cx2388x(state)) {
729 /* Audio channel 1 src : Parallel 1 */ 828 /* Audio channel 1 src : Parallel 1 */
730 cx25840_write(client, 0x124, 0x03); 829 cx25840_write(client, 0x124, 0x03);
731 830
@@ -741,7 +840,7 @@ static int set_input(struct i2c_client *client, enum cx25840_video_input vid_inp
741 */ 840 */
742 cx25840_write(client, 0x918, 0xa0); 841 cx25840_write(client, 0x918, 0xa0);
743 cx25840_write(client, 0x919, 0x01); 842 cx25840_write(client, 0x919, 0x01);
744 } else if (state->is_cx231xx) { 843 } else if (is_cx231xx(state)) {
745 /* Audio channel 1 src : Parallel 1 */ 844 /* Audio channel 1 src : Parallel 1 */
746 cx25840_write(client, 0x124, 0x03); 845 cx25840_write(client, 0x124, 0x03);
747 846
@@ -805,7 +904,7 @@ static int set_v4lstd(struct i2c_client *client)
805 cx25840_and_or(client, 0x400, ~0xf, fmt); 904 cx25840_and_or(client, 0x400, ~0xf, fmt);
806 cx25840_and_or(client, 0x403, ~0x3, pal_m); 905 cx25840_and_or(client, 0x403, ~0x3, pal_m);
807 cx25840_std_setup(client); 906 cx25840_std_setup(client);
808 if (!state->is_cx25836) 907 if (!is_cx2583x(state))
809 input_change(client); 908 input_change(client);
810 return 0; 909 return 0;
811} 910}
@@ -868,7 +967,7 @@ static int cx25840_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
868 case V4L2_CID_AUDIO_TREBLE: 967 case V4L2_CID_AUDIO_TREBLE:
869 case V4L2_CID_AUDIO_BALANCE: 968 case V4L2_CID_AUDIO_BALANCE:
870 case V4L2_CID_AUDIO_MUTE: 969 case V4L2_CID_AUDIO_MUTE:
871 if (state->is_cx25836) 970 if (is_cx2583x(state))
872 return -EINVAL; 971 return -EINVAL;
873 return cx25840_audio_s_ctrl(sd, ctrl); 972 return cx25840_audio_s_ctrl(sd, ctrl);
874 973
@@ -905,7 +1004,7 @@ static int cx25840_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
905 case V4L2_CID_AUDIO_TREBLE: 1004 case V4L2_CID_AUDIO_TREBLE:
906 case V4L2_CID_AUDIO_BALANCE: 1005 case V4L2_CID_AUDIO_BALANCE:
907 case V4L2_CID_AUDIO_MUTE: 1006 case V4L2_CID_AUDIO_MUTE:
908 if (state->is_cx25836) 1007 if (is_cx2583x(state))
909 return -EINVAL; 1008 return -EINVAL;
910 return cx25840_audio_g_ctrl(sd, ctrl); 1009 return cx25840_audio_g_ctrl(sd, ctrl);
911 default: 1010 default:
@@ -1209,11 +1308,11 @@ static int cx25840_load_fw(struct v4l2_subdev *sd)
1209 if (!state->is_initialized) { 1308 if (!state->is_initialized) {
1210 /* initialize and load firmware */ 1309 /* initialize and load firmware */
1211 state->is_initialized = 1; 1310 state->is_initialized = 1;
1212 if (state->is_cx25836) 1311 if (is_cx2583x(state))
1213 cx25836_initialize(client); 1312 cx25836_initialize(client);
1214 else if (state->is_cx23885) 1313 else if (is_cx2388x(state))
1215 cx23885_initialize(client); 1314 cx23885_initialize(client);
1216 else if (state->is_cx231xx) 1315 else if (is_cx231xx(state))
1217 cx231xx_initialize(client); 1316 cx231xx_initialize(client);
1218 else 1317 else
1219 cx25840_initialize(client); 1318 cx25840_initialize(client);
@@ -1256,17 +1355,17 @@ static int cx25840_s_stream(struct v4l2_subdev *sd, int enable)
1256 v4l_dbg(1, cx25840_debug, client, "%s output\n", 1355 v4l_dbg(1, cx25840_debug, client, "%s output\n",
1257 enable ? "enable" : "disable"); 1356 enable ? "enable" : "disable");
1258 if (enable) { 1357 if (enable) {
1259 if (state->is_cx23885 || state->is_cx231xx) { 1358 if (is_cx2388x(state) || is_cx231xx(state)) {
1260 u8 v = (cx25840_read(client, 0x421) | 0x0b); 1359 u8 v = (cx25840_read(client, 0x421) | 0x0b);
1261 cx25840_write(client, 0x421, v); 1360 cx25840_write(client, 0x421, v);
1262 } else { 1361 } else {
1263 cx25840_write(client, 0x115, 1362 cx25840_write(client, 0x115,
1264 state->is_cx25836 ? 0x0c : 0x8c); 1363 is_cx2583x(state) ? 0x0c : 0x8c);
1265 cx25840_write(client, 0x116, 1364 cx25840_write(client, 0x116,
1266 state->is_cx25836 ? 0x04 : 0x07); 1365 is_cx2583x(state) ? 0x04 : 0x07);
1267 } 1366 }
1268 } else { 1367 } else {
1269 if (state->is_cx23885 || state->is_cx231xx) { 1368 if (is_cx2388x(state) || is_cx231xx(state)) {
1270 u8 v = cx25840_read(client, 0x421) & ~(0x0b); 1369 u8 v = cx25840_read(client, 0x421) & ~(0x0b);
1271 cx25840_write(client, 0x421, v); 1370 cx25840_write(client, 0x421, v);
1272 } else { 1371 } else {
@@ -1292,7 +1391,7 @@ static int cx25840_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
1292 default: 1391 default:
1293 break; 1392 break;
1294 } 1393 }
1295 if (state->is_cx25836) 1394 if (is_cx2583x(state))
1296 return -EINVAL; 1395 return -EINVAL;
1297 1396
1298 switch (qc->id) { 1397 switch (qc->id) {
@@ -1346,7 +1445,7 @@ static int cx25840_s_audio_routing(struct v4l2_subdev *sd,
1346 struct cx25840_state *state = to_state(sd); 1445 struct cx25840_state *state = to_state(sd);
1347 struct i2c_client *client = v4l2_get_subdevdata(sd); 1446 struct i2c_client *client = v4l2_get_subdevdata(sd);
1348 1447
1349 if (state->is_cx25836) 1448 if (is_cx2583x(state))
1350 return -EINVAL; 1449 return -EINVAL;
1351 return set_input(client, state->vid_input, input); 1450 return set_input(client, state->vid_input, input);
1352} 1451}
@@ -1356,7 +1455,7 @@ static int cx25840_s_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *fr
1356 struct cx25840_state *state = to_state(sd); 1455 struct cx25840_state *state = to_state(sd);
1357 struct i2c_client *client = v4l2_get_subdevdata(sd); 1456 struct i2c_client *client = v4l2_get_subdevdata(sd);
1358 1457
1359 if (!state->is_cx25836) 1458 if (!is_cx2583x(state))
1360 input_change(client); 1459 input_change(client);
1361 return 0; 1460 return 0;
1362} 1461}
@@ -1373,7 +1472,7 @@ static int cx25840_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
1373 return 0; 1472 return 0;
1374 1473
1375 vt->signal = vpres ? 0xffff : 0x0; 1474 vt->signal = vpres ? 0xffff : 0x0;
1376 if (state->is_cx25836) 1475 if (is_cx2583x(state))
1377 return 0; 1476 return 0;
1378 1477
1379 vt->capability |= 1478 vt->capability |=
@@ -1404,7 +1503,7 @@ static int cx25840_s_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
1404 struct cx25840_state *state = to_state(sd); 1503 struct cx25840_state *state = to_state(sd);
1405 struct i2c_client *client = v4l2_get_subdevdata(sd); 1504 struct i2c_client *client = v4l2_get_subdevdata(sd);
1406 1505
1407 if (state->radio || state->is_cx25836) 1506 if (state->radio || is_cx2583x(state))
1408 return 0; 1507 return 0;
1409 1508
1410 switch (vt->audmode) { 1509 switch (vt->audmode) {
@@ -1445,11 +1544,11 @@ static int cx25840_reset(struct v4l2_subdev *sd, u32 val)
1445 struct cx25840_state *state = to_state(sd); 1544 struct cx25840_state *state = to_state(sd);
1446 struct i2c_client *client = v4l2_get_subdevdata(sd); 1545 struct i2c_client *client = v4l2_get_subdevdata(sd);
1447 1546
1448 if (state->is_cx25836) 1547 if (is_cx2583x(state))
1449 cx25836_initialize(client); 1548 cx25836_initialize(client);
1450 else if (state->is_cx23885) 1549 else if (is_cx2388x(state))
1451 cx23885_initialize(client); 1550 cx23885_initialize(client);
1452 else if (state->is_cx231xx) 1551 else if (is_cx231xx(state))
1453 cx231xx_initialize(client); 1552 cx231xx_initialize(client);
1454 else 1553 else
1455 cx25840_initialize(client); 1554 cx25840_initialize(client);
@@ -1470,7 +1569,7 @@ static int cx25840_log_status(struct v4l2_subdev *sd)
1470 struct i2c_client *client = v4l2_get_subdevdata(sd); 1569 struct i2c_client *client = v4l2_get_subdevdata(sd);
1471 1570
1472 log_video_status(client); 1571 log_video_status(client);
1473 if (!state->is_cx25836) 1572 if (!is_cx2583x(state))
1474 log_audio_status(client); 1573 log_audio_status(client);
1475 return 0; 1574 return 0;
1476} 1575}
@@ -1521,12 +1620,50 @@ static const struct v4l2_subdev_ops cx25840_ops = {
1521 1620
1522/* ----------------------------------------------------------------------- */ 1621/* ----------------------------------------------------------------------- */
1523 1622
1623static u32 get_cx2388x_ident(struct i2c_client *client)
1624{
1625 u32 ret;
1626
1627 /* Come out of digital power down */
1628 cx25840_write(client, 0x000, 0);
1629
1630 /* Detecting whether the part is cx23885/7/8 is more
1631 * difficult than it needs to be. No ID register. Instead we
1632 * probe certain registers indicated in the datasheets to look
1633 * for specific defaults that differ between the silicon designs. */
1634
1635 /* It's either 885/7 if the IR Tx Clk Divider register exists */
1636 if (cx25840_read4(client, 0x204) & 0xffff) {
1637 /* CX23885 returns bogus repetitive byte values for the DIF,
1638 * which doesn't exist for it. (Ex. 8a8a8a8a or 31313131) */
1639 ret = cx25840_read4(client, 0x300);
1640 if (((ret & 0xffff0000) >> 16) == (ret & 0xffff)) {
1641 /* No DIF */
1642 ret = V4L2_IDENT_CX23885_AV;
1643 } else {
1644 /* CX23887 has a broken DIF, but the registers
1645 * appear valid (but unsed), good enough to detect. */
1646 ret = V4L2_IDENT_CX23887_AV;
1647 }
1648 } else if (cx25840_read4(client, 0x300) & 0x0fffffff) {
1649 /* DIF PLL Freq Word reg exists; chip must be a CX23888 */
1650 ret = V4L2_IDENT_CX23888_AV;
1651 } else {
1652 v4l_err(client, "Unable to detect h/w, assuming cx23887\n");
1653 ret = V4L2_IDENT_CX23887_AV;
1654 }
1655
1656 /* Back into digital power down */
1657 cx25840_write(client, 0x000, 2);
1658 return ret;
1659}
1660
1524static int cx25840_probe(struct i2c_client *client, 1661static int cx25840_probe(struct i2c_client *client,
1525 const struct i2c_device_id *did) 1662 const struct i2c_device_id *did)
1526{ 1663{
1527 struct cx25840_state *state; 1664 struct cx25840_state *state;
1528 struct v4l2_subdev *sd; 1665 struct v4l2_subdev *sd;
1529 u32 id; 1666 u32 id = V4L2_IDENT_NONE;
1530 u16 device_id; 1667 u16 device_id;
1531 1668
1532 /* Check if the adapter supports the needed features */ 1669 /* Check if the adapter supports the needed features */
@@ -1543,17 +1680,22 @@ static int cx25840_probe(struct i2c_client *client,
1543 * 0x83 for the cx2583x and 0x84 for the cx2584x */ 1680 * 0x83 for the cx2583x and 0x84 for the cx2584x */
1544 if ((device_id & 0xff00) == 0x8300) { 1681 if ((device_id & 0xff00) == 0x8300) {
1545 id = V4L2_IDENT_CX25836 + ((device_id >> 4) & 0xf) - 6; 1682 id = V4L2_IDENT_CX25836 + ((device_id >> 4) & 0xf) - 6;
1546 } 1683 } else if ((device_id & 0xff00) == 0x8400) {
1547 else if ((device_id & 0xff00) == 0x8400) {
1548 id = V4L2_IDENT_CX25840 + ((device_id >> 4) & 0xf); 1684 id = V4L2_IDENT_CX25840 + ((device_id >> 4) & 0xf);
1549 } else if (device_id == 0x0000) { 1685 } else if (device_id == 0x0000) {
1550 id = V4L2_IDENT_CX25836 + ((device_id >> 4) & 0xf) - 6; 1686 id = get_cx2388x_ident(client);
1551 } else if (device_id == 0x1313) {
1552 id = V4L2_IDENT_CX25836 + ((device_id >> 4) & 0xf) - 6;
1553 } else if ((device_id & 0xfff0) == 0x5A30) { 1687 } else if ((device_id & 0xfff0) == 0x5A30) {
1554 id = V4L2_IDENT_CX25840 + ((device_id >> 4) & 0xf); 1688 /* The CX23100 (0x5A3C = 23100) doesn't have an A/V decoder */
1555 } 1689 id = V4L2_IDENT_CX2310X_AV;
1556 else { 1690 } else if ((device_id & 0xff) == (device_id >> 8)) {
1691 v4l_err(client,
1692 "likely a confused/unresponsive cx2388[578] A/V decoder"
1693 " found @ 0x%x (%s)\n",
1694 client->addr << 1, client->adapter->name);
1695 v4l_err(client, "A method to reset it from the cx25840 driver"
1696 " software is not known at this time\n");
1697 return -ENODEV;
1698 } else {
1557 v4l_dbg(1, cx25840_debug, client, "cx25840 not found\n"); 1699 v4l_dbg(1, cx25840_debug, client, "cx25840 not found\n");
1558 return -ENODEV; 1700 return -ENODEV;
1559 } 1701 }
@@ -1564,17 +1706,45 @@ static int cx25840_probe(struct i2c_client *client,
1564 1706
1565 sd = &state->sd; 1707 sd = &state->sd;
1566 v4l2_i2c_subdev_init(sd, client, &cx25840_ops); 1708 v4l2_i2c_subdev_init(sd, client, &cx25840_ops);
1567 /* Note: revision '(device_id & 0x0f) == 2' was never built. The 1709 switch (id) {
1568 marking skips from 0x1 == 22 to 0x3 == 23. */ 1710 case V4L2_IDENT_CX23885_AV:
1569 v4l_info(client, "cx25%3x-2%x found @ 0x%x (%s)\n", 1711 v4l_info(client, "cx23885 A/V decoder found @ 0x%x (%s)\n",
1570 (device_id & 0xfff0) >> 4, 1712 client->addr << 1, client->adapter->name);
1571 (device_id & 0x0f) < 3 ? (device_id & 0x0f) + 1 : (device_id & 0x0f), 1713 break;
1572 client->addr << 1, client->adapter->name); 1714 case V4L2_IDENT_CX23887_AV:
1715 v4l_info(client, "cx23887 A/V decoder found @ 0x%x (%s)\n",
1716 client->addr << 1, client->adapter->name);
1717 break;
1718 case V4L2_IDENT_CX23888_AV:
1719 v4l_info(client, "cx23888 A/V decoder found @ 0x%x (%s)\n",
1720 client->addr << 1, client->adapter->name);
1721 break;
1722 case V4L2_IDENT_CX2310X_AV:
1723 v4l_info(client, "cx%d A/V decoder found @ 0x%x (%s)\n",
1724 device_id, client->addr << 1, client->adapter->name);
1725 break;
1726 case V4L2_IDENT_CX25840:
1727 case V4L2_IDENT_CX25841:
1728 case V4L2_IDENT_CX25842:
1729 case V4L2_IDENT_CX25843:
1730 /* Note: revision '(device_id & 0x0f) == 2' was never built. The
1731 marking skips from 0x1 == 22 to 0x3 == 23. */
1732 v4l_info(client, "cx25%3x-2%x found @ 0x%x (%s)\n",
1733 (device_id & 0xfff0) >> 4,
1734 (device_id & 0x0f) < 3 ? (device_id & 0x0f) + 1
1735 : (device_id & 0x0f),
1736 client->addr << 1, client->adapter->name);
1737 break;
1738 case V4L2_IDENT_CX25836:
1739 case V4L2_IDENT_CX25837:
1740 default:
1741 v4l_info(client, "cx25%3x-%x found @ 0x%x (%s)\n",
1742 (device_id & 0xfff0) >> 4, device_id & 0x0f,
1743 client->addr << 1, client->adapter->name);
1744 break;
1745 }
1573 1746
1574 state->c = client; 1747 state->c = client;
1575 state->is_cx25836 = ((device_id & 0xff00) == 0x8300);
1576 state->is_cx23885 = (device_id == 0x0000) || (device_id == 0x1313);
1577 state->is_cx231xx = (device_id == 0x5a3e);
1578 state->vid_input = CX25840_COMPOSITE7; 1748 state->vid_input = CX25840_COMPOSITE7;
1579 state->aud_input = CX25840_AUDIO8; 1749 state->aud_input = CX25840_AUDIO8;
1580 state->audclk_freq = 48000; 1750 state->audclk_freq = 48000;
diff --git a/drivers/media/video/cx25840/cx25840-core.h b/drivers/media/video/cx25840/cx25840-core.h
index 814b56536994..55345444417f 100644
--- a/drivers/media/video/cx25840/cx25840-core.h
+++ b/drivers/media/video/cx25840/cx25840-core.h
@@ -23,6 +23,7 @@
23 23
24#include <linux/videodev2.h> 24#include <linux/videodev2.h>
25#include <media/v4l2-device.h> 25#include <media/v4l2-device.h>
26#include <media/v4l2-chip-ident.h>
26#include <linux/i2c.h> 27#include <linux/i2c.h>
27 28
28/* ENABLE_PVR150_WORKAROUND activates a workaround for a hardware bug that is 29/* ENABLE_PVR150_WORKAROUND activates a workaround for a hardware bug that is
@@ -48,9 +49,6 @@ struct cx25840_state {
48 int vbi_line_offset; 49 int vbi_line_offset;
49 u32 id; 50 u32 id;
50 u32 rev; 51 u32 rev;
51 int is_cx25836;
52 int is_cx23885;
53 int is_cx231xx;
54 int is_initialized; 52 int is_initialized;
55 wait_queue_head_t fw_wait; /* wake up when the fw load is finished */ 53 wait_queue_head_t fw_wait; /* wake up when the fw load is finished */
56 struct work_struct fw_work; /* work entry for fw load */ 54 struct work_struct fw_work; /* work entry for fw load */
@@ -61,6 +59,24 @@ static inline struct cx25840_state *to_state(struct v4l2_subdev *sd)
61 return container_of(sd, struct cx25840_state, sd); 59 return container_of(sd, struct cx25840_state, sd);
62} 60}
63 61
62static inline bool is_cx2583x(struct cx25840_state *state)
63{
64 return state->id == V4L2_IDENT_CX25836 ||
65 state->id == V4L2_IDENT_CX25837;
66}
67
68static inline bool is_cx231xx(struct cx25840_state *state)
69{
70 return state->id == V4L2_IDENT_CX2310X_AV;
71}
72
73static inline bool is_cx2388x(struct cx25840_state *state)
74{
75 return state->id == V4L2_IDENT_CX23885_AV ||
76 state->id == V4L2_IDENT_CX23887_AV ||
77 state->id == V4L2_IDENT_CX23888_AV;
78}
79
64/* ----------------------------------------------------------------------- */ 80/* ----------------------------------------------------------------------- */
65/* cx25850-core.c */ 81/* cx25850-core.c */
66int cx25840_write(struct i2c_client *client, u16 addr, u8 value); 82int cx25840_write(struct i2c_client *client, u16 addr, u8 value);
diff --git a/drivers/media/video/cx25840/cx25840-firmware.c b/drivers/media/video/cx25840/cx25840-firmware.c
index 1f483c1d0dbe..8150200511da 100644
--- a/drivers/media/video/cx25840/cx25840-firmware.c
+++ b/drivers/media/video/cx25840/cx25840-firmware.c
@@ -67,9 +67,9 @@ static const char *get_fw_name(struct i2c_client *client)
67 67
68 if (firmware[0]) 68 if (firmware[0])
69 return firmware; 69 return firmware;
70 if (state->is_cx23885) 70 if (is_cx2388x(state))
71 return "v4l-cx23885-avcore-01.fw"; 71 return "v4l-cx23885-avcore-01.fw";
72 if (state->is_cx231xx) 72 if (is_cx231xx(state))
73 return "v4l-cx231xx-avcore-01.fw"; 73 return "v4l-cx231xx-avcore-01.fw";
74 return "v4l-cx25840.fw"; 74 return "v4l-cx25840.fw";
75} 75}
@@ -112,13 +112,13 @@ int cx25840_loadfw(struct i2c_client *client)
112 int MAX_BUF_SIZE = FWSEND; 112 int MAX_BUF_SIZE = FWSEND;
113 u32 gpio_oe = 0, gpio_da = 0; 113 u32 gpio_oe = 0, gpio_da = 0;
114 114
115 if (state->is_cx23885) { 115 if (is_cx2388x(state)) {
116 /* Preserve the GPIO OE and output bits */ 116 /* Preserve the GPIO OE and output bits */
117 gpio_oe = cx25840_read(client, 0x160); 117 gpio_oe = cx25840_read(client, 0x160);
118 gpio_da = cx25840_read(client, 0x164); 118 gpio_da = cx25840_read(client, 0x164);
119 } 119 }
120 120
121 if ((state->is_cx231xx) && MAX_BUF_SIZE > 16) { 121 if (is_cx231xx(state) && MAX_BUF_SIZE > 16) {
122 v4l_err(client, " Firmware download size changed to 16 bytes max length\n"); 122 v4l_err(client, " Firmware download size changed to 16 bytes max length\n");
123 MAX_BUF_SIZE = 16; /* cx231xx cannot accept more than 16 bytes at a time */ 123 MAX_BUF_SIZE = 16; /* cx231xx cannot accept more than 16 bytes at a time */
124 } 124 }
@@ -156,7 +156,7 @@ int cx25840_loadfw(struct i2c_client *client)
156 size = fw->size; 156 size = fw->size;
157 release_firmware(fw); 157 release_firmware(fw);
158 158
159 if (state->is_cx23885) { 159 if (is_cx2388x(state)) {
160 /* Restore GPIO configuration after f/w load */ 160 /* Restore GPIO configuration after f/w load */
161 cx25840_write(client, 0x160, gpio_oe); 161 cx25840_write(client, 0x160, gpio_oe);
162 cx25840_write(client, 0x164, gpio_da); 162 cx25840_write(client, 0x164, gpio_da);
diff --git a/drivers/media/video/cx88/Kconfig b/drivers/media/video/cx88/Kconfig
index 49952980dab3..c7e5851d3486 100644
--- a/drivers/media/video/cx88/Kconfig
+++ b/drivers/media/video/cx88/Kconfig
@@ -61,6 +61,8 @@ config VIDEO_CX88_DVB
61 select DVB_STV0299 if !DVB_FE_CUSTOMISE 61 select DVB_STV0299 if !DVB_FE_CUSTOMISE
62 select DVB_STV0288 if !DVB_FE_CUSTOMISE 62 select DVB_STV0288 if !DVB_FE_CUSTOMISE
63 select DVB_STB6000 if !DVB_FE_CUSTOMISE 63 select DVB_STB6000 if !DVB_FE_CUSTOMISE
64 select DVB_STV0900 if !DVB_FE_CUSTOMISE
65 select DVB_STB6100 if !DVB_FE_CUSTOMISE
64 select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMISE 66 select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMISE
65 ---help--- 67 ---help---
66 This adds support for DVB/ATSC cards based on the 68 This adds support for DVB/ATSC cards based on the
diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c
index 33be6369871a..d844f2aaa01d 100644
--- a/drivers/media/video/cx88/cx88-cards.c
+++ b/drivers/media/video/cx88/cx88-cards.c
@@ -2075,6 +2075,18 @@ static const struct cx88_board cx88_boards[] = {
2075 }, 2075 },
2076 .mpeg = CX88_MPEG_DVB, 2076 .mpeg = CX88_MPEG_DVB,
2077 }, 2077 },
2078 [CX88_BOARD_PROF_7301] = {
2079 .name = "Prof 7301 DVB-S/S2",
2080 .tuner_type = UNSET,
2081 .radio_type = UNSET,
2082 .tuner_addr = ADDR_UNSET,
2083 .radio_addr = ADDR_UNSET,
2084 .input = { {
2085 .type = CX88_VMUX_DVB,
2086 .vmux = 0,
2087 } },
2088 .mpeg = CX88_MPEG_DVB,
2089 },
2078}; 2090};
2079 2091
2080/* ------------------------------------------------------------------ */ 2092/* ------------------------------------------------------------------ */
@@ -2535,6 +2547,10 @@ static const struct cx88_subid cx88_subids[] = {
2535 .subvendor = 0x107d, 2547 .subvendor = 0x107d,
2536 .subdevice = 0x6618, 2548 .subdevice = 0x6618,
2537 .card = CX88_BOARD_WINFAST_TV2000_XP_GLOBAL, 2549 .card = CX88_BOARD_WINFAST_TV2000_XP_GLOBAL,
2550 }, {
2551 .subvendor = 0xb034,
2552 .subdevice = 0x3034,
2553 .card = CX88_BOARD_PROF_7301,
2538 }, 2554 },
2539}; 2555};
2540 2556
@@ -3211,6 +3227,7 @@ static void cx88_card_setup(struct cx88_core *core)
3211 case CX88_BOARD_TBS_8920: 3227 case CX88_BOARD_TBS_8920:
3212 case CX88_BOARD_PROF_6200: 3228 case CX88_BOARD_PROF_6200:
3213 case CX88_BOARD_PROF_7300: 3229 case CX88_BOARD_PROF_7300:
3230 case CX88_BOARD_PROF_7301:
3214 case CX88_BOARD_SATTRADE_ST4200: 3231 case CX88_BOARD_SATTRADE_ST4200:
3215 cx_write(MO_GP0_IO, 0x8000); 3232 cx_write(MO_GP0_IO, 0x8000);
3216 msleep(100); 3233 msleep(100);
@@ -3267,7 +3284,7 @@ static void cx88_card_setup(struct cx88_core *core)
3267 ctl.fname); 3284 ctl.fname);
3268 call_all(core, tuner, s_config, &xc2028_cfg); 3285 call_all(core, tuner, s_config, &xc2028_cfg);
3269 } 3286 }
3270 call_all(core, tuner, s_standby); 3287 call_all(core, core, s_power, 0);
3271} 3288}
3272 3289
3273/* ------------------------------------------------------------------ */ 3290/* ------------------------------------------------------------------ */
diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c
index 518bcfe18bcb..b14296923250 100644
--- a/drivers/media/video/cx88/cx88-dvb.c
+++ b/drivers/media/video/cx88/cx88-dvb.c
@@ -53,6 +53,9 @@
53#include "stv0288.h" 53#include "stv0288.h"
54#include "stb6000.h" 54#include "stb6000.h"
55#include "cx24116.h" 55#include "cx24116.h"
56#include "stv0900.h"
57#include "stb6100.h"
58#include "stb6100_proc.h"
56 59
57MODULE_DESCRIPTION("driver for cx2388x based DVB cards"); 60MODULE_DESCRIPTION("driver for cx2388x based DVB cards");
58MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>"); 61MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>");
@@ -573,6 +576,15 @@ static int cx24116_set_ts_param(struct dvb_frontend *fe,
573 return 0; 576 return 0;
574} 577}
575 578
579static int stv0900_set_ts_param(struct dvb_frontend *fe,
580 int is_punctured)
581{
582 struct cx8802_dev *dev = fe->dvb->priv;
583 dev->ts_gen_cntrl = 0;
584
585 return 0;
586}
587
576static int cx24116_reset_device(struct dvb_frontend *fe) 588static int cx24116_reset_device(struct dvb_frontend *fe)
577{ 589{
578 struct cx8802_dev *dev = fe->dvb->priv; 590 struct cx8802_dev *dev = fe->dvb->priv;
@@ -601,6 +613,23 @@ static struct cx24116_config tevii_s460_config = {
601 .reset_device = cx24116_reset_device, 613 .reset_device = cx24116_reset_device,
602}; 614};
603 615
616static struct stv0900_config prof_7301_stv0900_config = {
617 .demod_address = 0x6a,
618/* demod_mode = 0,*/
619 .xtal = 27000000,
620 .clkmode = 3,/* 0-CLKI, 2-XTALI, else AUTO */
621 .diseqc_mode = 2,/* 2/3 PWM */
622 .tun1_maddress = 0,/* 0x60 */
623 .tun1_adc = 0,/* 2 Vpp */
624 .path1_mode = 3,
625 .set_ts_params = stv0900_set_ts_param,
626};
627
628static struct stb6100_config prof_7301_stb6100_config = {
629 .tuner_address = 0x60,
630 .refclock = 27000000,
631};
632
604static struct stv0299_config tevii_tuner_sharp_config = { 633static struct stv0299_config tevii_tuner_sharp_config = {
605 .demod_address = 0x68, 634 .demod_address = 0x68,
606 .inittab = sharp_z0194a_inittab, 635 .inittab = sharp_z0194a_inittab,
@@ -1149,6 +1178,31 @@ static int dvb_register(struct cx8802_dev *dev)
1149 goto frontend_detach; 1178 goto frontend_detach;
1150 } 1179 }
1151 break; 1180 break;
1181 case CX88_BOARD_PROF_7301:{
1182 struct dvb_tuner_ops *tuner_ops = NULL;
1183
1184 fe0->dvb.frontend = dvb_attach(stv0900_attach,
1185 &prof_7301_stv0900_config,
1186 &core->i2c_adap, 0);
1187 if (fe0->dvb.frontend != NULL) {
1188 if (!dvb_attach(stb6100_attach, fe0->dvb.frontend,
1189 &prof_7301_stb6100_config,
1190 &core->i2c_adap))
1191 goto frontend_detach;
1192
1193 tuner_ops = &fe0->dvb.frontend->ops.tuner_ops;
1194 tuner_ops->set_frequency = stb6100_set_freq;
1195 tuner_ops->get_frequency = stb6100_get_freq;
1196 tuner_ops->set_bandwidth = stb6100_set_bandw;
1197 tuner_ops->get_bandwidth = stb6100_get_bandw;
1198
1199 core->prev_set_voltage =
1200 fe0->dvb.frontend->ops.set_voltage;
1201 fe0->dvb.frontend->ops.set_voltage =
1202 tevii_dvbs_set_voltage;
1203 }
1204 break;
1205 }
1152 default: 1206 default:
1153 printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card isn't supported yet\n", 1207 printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card isn't supported yet\n",
1154 core->name); 1208 core->name);
@@ -1170,11 +1224,11 @@ static int dvb_register(struct cx8802_dev *dev)
1170 fe1->dvb.frontend->ops.ts_bus_ctrl = cx88_dvb_bus_ctrl; 1224 fe1->dvb.frontend->ops.ts_bus_ctrl = cx88_dvb_bus_ctrl;
1171 1225
1172 /* Put the analog decoder in standby to keep it quiet */ 1226 /* Put the analog decoder in standby to keep it quiet */
1173 call_all(core, tuner, s_standby); 1227 call_all(core, core, s_power, 0);
1174 1228
1175 /* register everything */ 1229 /* register everything */
1176 return videobuf_dvb_register_bus(&dev->frontends, THIS_MODULE, dev, 1230 return videobuf_dvb_register_bus(&dev->frontends, THIS_MODULE, dev,
1177 &dev->pci->dev, adapter_nr, mfe_shared); 1231 &dev->pci->dev, adapter_nr, mfe_shared, NULL);
1178 1232
1179frontend_detach: 1233frontend_detach:
1180 core->gate_ctrl = NULL; 1234 core->gate_ctrl = NULL;
diff --git a/drivers/media/video/cx88/cx88-input.c b/drivers/media/video/cx88/cx88-input.c
index 78b3635178af..92b8cdf9fb81 100644
--- a/drivers/media/video/cx88/cx88-input.c
+++ b/drivers/media/video/cx88/cx88-input.c
@@ -118,13 +118,13 @@ static void cx88_ir_handle_key(struct cx88_IR *ir)
118 118
119 data = (data << 4) | ((gpio_key & 0xf0) >> 4); 119 data = (data << 4) | ((gpio_key & 0xf0) >> 4);
120 120
121 ir_input_keydown(ir->input, &ir->ir, data, data); 121 ir_input_keydown(ir->input, &ir->ir, data);
122 ir_input_nokey(ir->input, &ir->ir); 122 ir_input_nokey(ir->input, &ir->ir);
123 123
124 } else if (ir->mask_keydown) { 124 } else if (ir->mask_keydown) {
125 /* bit set on keydown */ 125 /* bit set on keydown */
126 if (gpio & ir->mask_keydown) { 126 if (gpio & ir->mask_keydown) {
127 ir_input_keydown(ir->input, &ir->ir, data, data); 127 ir_input_keydown(ir->input, &ir->ir, data);
128 } else { 128 } else {
129 ir_input_nokey(ir->input, &ir->ir); 129 ir_input_nokey(ir->input, &ir->ir);
130 } 130 }
@@ -132,14 +132,14 @@ static void cx88_ir_handle_key(struct cx88_IR *ir)
132 } else if (ir->mask_keyup) { 132 } else if (ir->mask_keyup) {
133 /* bit cleared on keydown */ 133 /* bit cleared on keydown */
134 if (0 == (gpio & ir->mask_keyup)) { 134 if (0 == (gpio & ir->mask_keyup)) {
135 ir_input_keydown(ir->input, &ir->ir, data, data); 135 ir_input_keydown(ir->input, &ir->ir, data);
136 } else { 136 } else {
137 ir_input_nokey(ir->input, &ir->ir); 137 ir_input_nokey(ir->input, &ir->ir);
138 } 138 }
139 139
140 } else { 140 } else {
141 /* can't distinguish keydown/up :-/ */ 141 /* can't distinguish keydown/up :-/ */
142 ir_input_keydown(ir->input, &ir->ir, data, data); 142 ir_input_keydown(ir->input, &ir->ir, data);
143 ir_input_nokey(ir->input, &ir->ir); 143 ir_input_nokey(ir->input, &ir->ir);
144 } 144 }
145} 145}
@@ -303,6 +303,23 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
303 ir->mask_keydown = 0x02; 303 ir->mask_keydown = 0x02;
304 ir->polling = 50; /* ms */ 304 ir->polling = 50; /* ms */
305 break; 305 break;
306 case CX88_BOARD_OMICOM_SS4_PCI:
307 case CX88_BOARD_SATTRADE_ST4200:
308 case CX88_BOARD_TBS_8920:
309 case CX88_BOARD_TBS_8910:
310 case CX88_BOARD_PROF_7300:
311 case CX88_BOARD_PROF_7301:
312 case CX88_BOARD_PROF_6200:
313 ir_codes = &ir_codes_tbs_nec_table;
314 ir_type = IR_TYPE_PD;
315 ir->sampling = 0xff00; /* address */
316 break;
317 case CX88_BOARD_TEVII_S460:
318 case CX88_BOARD_TEVII_S420:
319 ir_codes = &ir_codes_tevii_nec_table;
320 ir_type = IR_TYPE_PD;
321 ir->sampling = 0xff00; /* address */
322 break;
306 case CX88_BOARD_DNTV_LIVE_DVB_T_PRO: 323 case CX88_BOARD_DNTV_LIVE_DVB_T_PRO:
307 ir_codes = &ir_codes_dntv_live_dvbt_pro_table; 324 ir_codes = &ir_codes_dntv_live_dvbt_pro_table;
308 ir_type = IR_TYPE_PD; 325 ir_type = IR_TYPE_PD;
@@ -343,7 +360,10 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
343 snprintf(ir->name, sizeof(ir->name), "cx88 IR (%s)", core->board.name); 360 snprintf(ir->name, sizeof(ir->name), "cx88 IR (%s)", core->board.name);
344 snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0", pci_name(pci)); 361 snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0", pci_name(pci));
345 362
346 ir_input_init(input_dev, &ir->ir, ir_type, ir_codes); 363 err = ir_input_init(input_dev, &ir->ir, ir_type, ir_codes);
364 if (err < 0)
365 goto err_out_free;
366
347 input_dev->name = ir->name; 367 input_dev->name = ir->name;
348 input_dev->phys = ir->phys; 368 input_dev->phys = ir->phys;
349 input_dev->id.bustype = BUS_PCI; 369 input_dev->id.bustype = BUS_PCI;
@@ -373,6 +393,7 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
373 cx88_ir_stop(core, ir); 393 cx88_ir_stop(core, ir);
374 core->ir = NULL; 394 core->ir = NULL;
375 err_out_free: 395 err_out_free:
396 ir_input_free(input_dev);
376 input_free_device(input_dev); 397 input_free_device(input_dev);
377 kfree(ir); 398 kfree(ir);
378 return err; 399 return err;
@@ -387,6 +408,7 @@ int cx88_ir_fini(struct cx88_core *core)
387 return 0; 408 return 0;
388 409
389 cx88_ir_stop(core, ir); 410 cx88_ir_stop(core, ir);
411 ir_input_free(ir->input);
390 input_unregister_device(ir->input); 412 input_unregister_device(ir->input);
391 kfree(ir); 413 kfree(ir);
392 414
@@ -432,8 +454,17 @@ void cx88_ir_irq(struct cx88_core *core)
432 454
433 /* decode it */ 455 /* decode it */
434 switch (core->boardnr) { 456 switch (core->boardnr) {
457 case CX88_BOARD_TEVII_S460:
458 case CX88_BOARD_TEVII_S420:
435 case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1: 459 case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1:
436 case CX88_BOARD_DNTV_LIVE_DVB_T_PRO: 460 case CX88_BOARD_DNTV_LIVE_DVB_T_PRO:
461 case CX88_BOARD_OMICOM_SS4_PCI:
462 case CX88_BOARD_SATTRADE_ST4200:
463 case CX88_BOARD_TBS_8920:
464 case CX88_BOARD_TBS_8910:
465 case CX88_BOARD_PROF_7300:
466 case CX88_BOARD_PROF_7301:
467 case CX88_BOARD_PROF_6200:
437 ircode = ir_decode_pulsedistance(ir->samples, ir->scount, 1, 4); 468 ircode = ir_decode_pulsedistance(ir->samples, ir->scount, 1, 4);
438 469
439 if (ircode == 0xffffffff) { /* decoding error */ 470 if (ircode == 0xffffffff) { /* decoding error */
@@ -461,7 +492,7 @@ void cx88_ir_irq(struct cx88_core *core)
461 492
462 ir_dprintk("Key Code: %x\n", (ircode >> 16) & 0x7f); 493 ir_dprintk("Key Code: %x\n", (ircode >> 16) & 0x7f);
463 494
464 ir_input_keydown(ir->input, &ir->ir, (ircode >> 16) & 0x7f, (ircode >> 16) & 0xff); 495 ir_input_keydown(ir->input, &ir->ir, (ircode >> 16) & 0x7f);
465 ir->release = jiffies + msecs_to_jiffies(120); 496 ir->release = jiffies + msecs_to_jiffies(120);
466 break; 497 break;
467 case CX88_BOARD_HAUPPAUGE: 498 case CX88_BOARD_HAUPPAUGE:
@@ -498,7 +529,7 @@ void cx88_ir_irq(struct cx88_core *core)
498 if ( dev != 0x1e && dev != 0x1f ) 529 if ( dev != 0x1e && dev != 0x1f )
499 /* not a hauppauge remote */ 530 /* not a hauppauge remote */
500 break; 531 break;
501 ir_input_keydown(ir->input, &ir->ir, code, ircode); 532 ir_input_keydown(ir->input, &ir->ir, code);
502 ir->release = jiffies + msecs_to_jiffies(120); 533 ir->release = jiffies + msecs_to_jiffies(120);
503 break; 534 break;
504 case CX88_BOARD_PINNACLE_PCTV_HD_800i: 535 case CX88_BOARD_PINNACLE_PCTV_HD_800i:
@@ -506,7 +537,7 @@ void cx88_ir_irq(struct cx88_core *core)
506 ir_dprintk("biphase decoded: %x\n", ircode); 537 ir_dprintk("biphase decoded: %x\n", ircode);
507 if ((ircode & 0xfffff000) != 0x3000) 538 if ((ircode & 0xfffff000) != 0x3000)
508 break; 539 break;
509 ir_input_keydown(ir->input, &ir->ir, ircode & 0x3f, ircode); 540 ir_input_keydown(ir->input, &ir->ir, ircode & 0x3f);
510 ir->release = jiffies + msecs_to_jiffies(120); 541 ir->release = jiffies + msecs_to_jiffies(120);
511 break; 542 break;
512 } 543 }
diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c
index 57e6b1241090..d7e8fcee559c 100644
--- a/drivers/media/video/cx88/cx88-video.c
+++ b/drivers/media/video/cx88/cx88-video.c
@@ -935,7 +935,7 @@ static int video_release(struct file *file)
935 935
936 mutex_lock(&dev->core->lock); 936 mutex_lock(&dev->core->lock);
937 if(atomic_dec_and_test(&dev->core->users)) 937 if(atomic_dec_and_test(&dev->core->users))
938 call_all(dev->core, tuner, s_standby); 938 call_all(dev->core, core, s_power, 0);
939 mutex_unlock(&dev->core->lock); 939 mutex_unlock(&dev->core->lock);
940 940
941 return 0; 941 return 0;
diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h
index d5cea41f4207..e1c521710103 100644
--- a/drivers/media/video/cx88/cx88.h
+++ b/drivers/media/video/cx88/cx88.h
@@ -238,6 +238,7 @@ extern struct sram_channel cx88_sram_channels[];
238#define CX88_BOARD_HAUPPAUGE_IRONLY 80 238#define CX88_BOARD_HAUPPAUGE_IRONLY 80
239#define CX88_BOARD_WINFAST_DTV1800H 81 239#define CX88_BOARD_WINFAST_DTV1800H 81
240#define CX88_BOARD_WINFAST_DTV2000H_J 82 240#define CX88_BOARD_WINFAST_DTV2000H_J 82
241#define CX88_BOARD_PROF_7301 83
241 242
242enum cx88_itype { 243enum cx88_itype {
243 CX88_VMUX_COMPOSITE1 = 1, 244 CX88_VMUX_COMPOSITE1 = 1,
diff --git a/drivers/media/video/davinci/vpfe_capture.c b/drivers/media/video/davinci/vpfe_capture.c
index 402ce43ef38e..12a1b3d7132d 100644
--- a/drivers/media/video/davinci/vpfe_capture.c
+++ b/drivers/media/video/davinci/vpfe_capture.c
@@ -660,7 +660,7 @@ static void vpfe_detach_irq(struct vpfe_device *vpfe_dev)
660 660
661 frame_format = ccdc_dev->hw_ops.get_frame_format(); 661 frame_format = ccdc_dev->hw_ops.get_frame_format();
662 if (frame_format == CCDC_FRMFMT_PROGRESSIVE) 662 if (frame_format == CCDC_FRMFMT_PROGRESSIVE)
663 free_irq(IRQ_VDINT1, vpfe_dev); 663 free_irq(vpfe_dev->ccdc_irq1, vpfe_dev);
664} 664}
665 665
666static int vpfe_attach_irq(struct vpfe_device *vpfe_dev) 666static int vpfe_attach_irq(struct vpfe_device *vpfe_dev)
@@ -1338,7 +1338,7 @@ static int vpfe_reqbufs(struct file *file, void *priv,
1338 vpfe_dev->memory = req_buf->memory; 1338 vpfe_dev->memory = req_buf->memory;
1339 videobuf_queue_dma_contig_init(&vpfe_dev->buffer_queue, 1339 videobuf_queue_dma_contig_init(&vpfe_dev->buffer_queue,
1340 &vpfe_videobuf_qops, 1340 &vpfe_videobuf_qops,
1341 NULL, 1341 vpfe_dev->pdev,
1342 &vpfe_dev->irqlock, 1342 &vpfe_dev->irqlock,
1343 req_buf->type, 1343 req_buf->type,
1344 vpfe_dev->fmt.fmt.pix.field, 1344 vpfe_dev->fmt.fmt.pix.field,
@@ -1413,6 +1413,41 @@ static int vpfe_dqbuf(struct file *file, void *priv,
1413 buf, file->f_flags & O_NONBLOCK); 1413 buf, file->f_flags & O_NONBLOCK);
1414} 1414}
1415 1415
1416static int vpfe_queryctrl(struct file *file, void *priv,
1417 struct v4l2_queryctrl *qctrl)
1418{
1419 struct vpfe_device *vpfe_dev = video_drvdata(file);
1420 struct vpfe_subdev_info *sdinfo;
1421
1422 sdinfo = vpfe_dev->current_subdev;
1423
1424 return v4l2_device_call_until_err(&vpfe_dev->v4l2_dev, sdinfo->grp_id,
1425 core, queryctrl, qctrl);
1426
1427}
1428
1429static int vpfe_g_ctrl(struct file *file, void *priv, struct v4l2_control *ctrl)
1430{
1431 struct vpfe_device *vpfe_dev = video_drvdata(file);
1432 struct vpfe_subdev_info *sdinfo;
1433
1434 sdinfo = vpfe_dev->current_subdev;
1435
1436 return v4l2_device_call_until_err(&vpfe_dev->v4l2_dev, sdinfo->grp_id,
1437 core, g_ctrl, ctrl);
1438}
1439
1440static int vpfe_s_ctrl(struct file *file, void *priv, struct v4l2_control *ctrl)
1441{
1442 struct vpfe_device *vpfe_dev = video_drvdata(file);
1443 struct vpfe_subdev_info *sdinfo;
1444
1445 sdinfo = vpfe_dev->current_subdev;
1446
1447 return v4l2_device_call_until_err(&vpfe_dev->v4l2_dev, sdinfo->grp_id,
1448 core, s_ctrl, ctrl);
1449}
1450
1416/* 1451/*
1417 * vpfe_calculate_offsets : This function calculates buffers offset 1452 * vpfe_calculate_offsets : This function calculates buffers offset
1418 * for top and bottom field 1453 * for top and bottom field
@@ -1577,7 +1612,7 @@ static int vpfe_cropcap(struct file *file, void *priv,
1577 1612
1578 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_cropcap\n"); 1613 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_cropcap\n");
1579 1614
1580 if (vpfe_dev->std_index > ARRAY_SIZE(vpfe_standards)) 1615 if (vpfe_dev->std_index >= ARRAY_SIZE(vpfe_standards))
1581 return -EINVAL; 1616 return -EINVAL;
1582 1617
1583 memset(crop, 0, sizeof(struct v4l2_cropcap)); 1618 memset(crop, 0, sizeof(struct v4l2_cropcap));
@@ -1710,6 +1745,9 @@ static const struct v4l2_ioctl_ops vpfe_ioctl_ops = {
1710 .vidioc_querystd = vpfe_querystd, 1745 .vidioc_querystd = vpfe_querystd,
1711 .vidioc_s_std = vpfe_s_std, 1746 .vidioc_s_std = vpfe_s_std,
1712 .vidioc_g_std = vpfe_g_std, 1747 .vidioc_g_std = vpfe_g_std,
1748 .vidioc_queryctrl = vpfe_queryctrl,
1749 .vidioc_g_ctrl = vpfe_g_ctrl,
1750 .vidioc_s_ctrl = vpfe_s_ctrl,
1713 .vidioc_reqbufs = vpfe_reqbufs, 1751 .vidioc_reqbufs = vpfe_reqbufs,
1714 .vidioc_querybuf = vpfe_querybuf, 1752 .vidioc_querybuf = vpfe_querybuf,
1715 .vidioc_qbuf = vpfe_qbuf, 1753 .vidioc_qbuf = vpfe_qbuf,
@@ -1978,8 +2016,7 @@ static __init int vpfe_probe(struct platform_device *pdev)
1978 platform_set_drvdata(pdev, vpfe_dev); 2016 platform_set_drvdata(pdev, vpfe_dev);
1979 /* set driver private data */ 2017 /* set driver private data */
1980 video_set_drvdata(vpfe_dev->video_dev, vpfe_dev); 2018 video_set_drvdata(vpfe_dev->video_dev, vpfe_dev);
1981 i2c_adap = i2c_get_adapter(1); 2019 i2c_adap = i2c_get_adapter(vpfe_cfg->i2c_adapter_id);
1982 vpfe_cfg = pdev->dev.platform_data;
1983 num_subdevs = vpfe_cfg->num_subdevs; 2020 num_subdevs = vpfe_cfg->num_subdevs;
1984 vpfe_dev->sd = kmalloc(sizeof(struct v4l2_subdev *) * num_subdevs, 2021 vpfe_dev->sd = kmalloc(sizeof(struct v4l2_subdev *) * num_subdevs,
1985 GFP_KERNEL); 2022 GFP_KERNEL);
diff --git a/drivers/media/video/em28xx/em28xx-audio.c b/drivers/media/video/em28xx/em28xx-audio.c
index ac947aecb9c3..bd783387b37d 100644
--- a/drivers/media/video/em28xx/em28xx-audio.c
+++ b/drivers/media/video/em28xx/em28xx-audio.c
@@ -293,7 +293,7 @@ static int snd_em28xx_capture_open(struct snd_pcm_substream *substream)
293 dprintk("opening device and trying to acquire exclusive lock\n"); 293 dprintk("opening device and trying to acquire exclusive lock\n");
294 294
295 if (!dev) { 295 if (!dev) {
296 printk(KERN_ERR "BUG: em28xx can't find device struct." 296 em28xx_err("BUG: em28xx can't find device struct."
297 " Can't proceed with open\n"); 297 " Can't proceed with open\n");
298 return -ENODEV; 298 return -ENODEV;
299 } 299 }
@@ -325,7 +325,7 @@ static int snd_em28xx_capture_open(struct snd_pcm_substream *substream)
325 325
326 return 0; 326 return 0;
327err: 327err:
328 printk(KERN_ERR "Error while configuring em28xx mixer\n"); 328 em28xx_err("Error while configuring em28xx mixer\n");
329 return ret; 329 return ret;
330} 330}
331 331
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c
index c0fd5c6feeac..82da205047be 100644
--- a/drivers/media/video/em28xx/em28xx-cards.c
+++ b/drivers/media/video/em28xx/em28xx-cards.c
@@ -225,6 +225,14 @@ static struct em28xx_reg_seq silvercrest_reg_seq[] = {
225 { -1, -1, -1, -1}, 225 { -1, -1, -1, -1},
226}; 226};
227 227
228static struct em28xx_reg_seq vc211a_enable[] = {
229 {EM28XX_R08_GPIO, 0xff, 0x07, 10},
230 {EM28XX_R08_GPIO, 0xff, 0x0f, 10},
231 {EM28XX_R08_GPIO, 0xff, 0x0b, 10},
232 { -1, -1, -1, -1},
233};
234
235
228/* 236/*
229 * Board definitions 237 * Board definitions
230 */ 238 */
@@ -829,7 +837,7 @@ struct em28xx_board em28xx_boards[] = {
829 .mts_firmware = 1, 837 .mts_firmware = 1,
830 .has_dvb = 1, 838 .has_dvb = 1,
831 .dvb_gpio = hauppauge_wintv_hvr_900_digital, 839 .dvb_gpio = hauppauge_wintv_hvr_900_digital,
832 .ir_codes = &ir_codes_hauppauge_new_table, 840 .ir_codes = &ir_codes_rc5_hauppauge_new_table,
833 .decoder = EM28XX_TVP5150, 841 .decoder = EM28XX_TVP5150,
834 .input = { { 842 .input = { {
835 .type = EM28XX_VMUX_TELEVISION, 843 .type = EM28XX_VMUX_TELEVISION,
@@ -1009,6 +1017,23 @@ struct em28xx_board em28xx_boards[] = {
1009 .amux = EM28XX_AMUX_LINE_IN, 1017 .amux = EM28XX_AMUX_LINE_IN,
1010 } }, 1018 } },
1011 }, 1019 },
1020 [EM2800_BOARD_VC211A] = {
1021 .name = "Actionmaster/LinXcel/Digitus VC211A",
1022 .is_em2800 = 1,
1023 .tuner_type = TUNER_ABSENT, /* Capture-only board */
1024 .decoder = EM28XX_SAA711X,
1025 .input = { {
1026 .type = EM28XX_VMUX_COMPOSITE1,
1027 .vmux = SAA7115_COMPOSITE0,
1028 .amux = EM28XX_AMUX_LINE_IN,
1029 .gpio = vc211a_enable,
1030 }, {
1031 .type = EM28XX_VMUX_SVIDEO,
1032 .vmux = SAA7115_SVIDEO3,
1033 .amux = EM28XX_AMUX_LINE_IN,
1034 .gpio = vc211a_enable,
1035 } },
1036 },
1012 [EM2800_BOARD_LEADTEK_WINFAST_USBII] = { 1037 [EM2800_BOARD_LEADTEK_WINFAST_USBII] = {
1013 .name = "Leadtek Winfast USB II", 1038 .name = "Leadtek Winfast USB II",
1014 .is_em2800 = 1, 1039 .is_em2800 = 1,
@@ -1381,10 +1406,14 @@ struct em28xx_board em28xx_boards[] = {
1381 }, 1406 },
1382 [EM2882_BOARD_TERRATEC_HYBRID_XS] = { 1407 [EM2882_BOARD_TERRATEC_HYBRID_XS] = {
1383 .name = "Terratec Hybrid XS (em2882)", 1408 .name = "Terratec Hybrid XS (em2882)",
1384 .valid = EM28XX_BOARD_NOT_VALIDATED,
1385 .tuner_type = TUNER_XC2028, 1409 .tuner_type = TUNER_XC2028,
1386 .tuner_gpio = default_tuner_gpio, 1410 .tuner_gpio = default_tuner_gpio,
1411 .mts_firmware = 1,
1387 .decoder = EM28XX_TVP5150, 1412 .decoder = EM28XX_TVP5150,
1413 .has_dvb = 1,
1414 .dvb_gpio = hauppauge_wintv_hvr_900_digital,
1415 .ir_codes = &ir_codes_terratec_cinergy_xs_table,
1416 .xclk = EM28XX_XCLK_FREQUENCY_12MHZ,
1388 .input = { { 1417 .input = { {
1389 .type = EM28XX_VMUX_TELEVISION, 1418 .type = EM28XX_VMUX_TELEVISION,
1390 .vmux = TVP5150_COMPOSITE0, 1419 .vmux = TVP5150_COMPOSITE0,
@@ -1608,6 +1637,8 @@ struct usb_device_id em28xx_id_table[] = {
1608 .driver_info = EM2820_BOARD_UNKNOWN }, 1637 .driver_info = EM2820_BOARD_UNKNOWN },
1609 { USB_DEVICE(0xeb1a, 0x2861), 1638 { USB_DEVICE(0xeb1a, 0x2861),
1610 .driver_info = EM2820_BOARD_UNKNOWN }, 1639 .driver_info = EM2820_BOARD_UNKNOWN },
1640 { USB_DEVICE(0xeb1a, 0x2862),
1641 .driver_info = EM2820_BOARD_UNKNOWN },
1611 { USB_DEVICE(0xeb1a, 0x2870), 1642 { USB_DEVICE(0xeb1a, 0x2870),
1612 .driver_info = EM2820_BOARD_UNKNOWN }, 1643 .driver_info = EM2820_BOARD_UNKNOWN },
1613 { USB_DEVICE(0xeb1a, 0x2881), 1644 { USB_DEVICE(0xeb1a, 0x2881),
@@ -2050,6 +2081,7 @@ static void em28xx_setup_xc3028(struct em28xx *dev, struct xc2028_ctrl *ctl)
2050 switch (dev->model) { 2081 switch (dev->model) {
2051 case EM2880_BOARD_EMPIRE_DUAL_TV: 2082 case EM2880_BOARD_EMPIRE_DUAL_TV:
2052 case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900: 2083 case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900:
2084 case EM2882_BOARD_TERRATEC_HYBRID_XS:
2053 ctl->demod = XC3028_FE_ZARLINK456; 2085 ctl->demod = XC3028_FE_ZARLINK456;
2054 break; 2086 break;
2055 case EM2880_BOARD_TERRATEC_HYBRID_XS: 2087 case EM2880_BOARD_TERRATEC_HYBRID_XS:
@@ -2227,6 +2259,7 @@ static int em28xx_hint_board(struct em28xx *dev)
2227/* ----------------------------------------------------------------------- */ 2259/* ----------------------------------------------------------------------- */
2228void em28xx_register_i2c_ir(struct em28xx *dev) 2260void em28xx_register_i2c_ir(struct em28xx *dev)
2229{ 2261{
2262 struct i2c_board_info info;
2230 const unsigned short addr_list[] = { 2263 const unsigned short addr_list[] = {
2231 0x30, 0x47, I2C_CLIENT_END 2264 0x30, 0x47, I2C_CLIENT_END
2232 }; 2265 };
@@ -2234,9 +2267,9 @@ void em28xx_register_i2c_ir(struct em28xx *dev)
2234 if (disable_ir) 2267 if (disable_ir)
2235 return; 2268 return;
2236 2269
2237 memset(&dev->info, 0, sizeof(&dev->info)); 2270 memset(&info, 0, sizeof(struct i2c_board_info));
2238 memset(&dev->init_data, 0, sizeof(dev->init_data)); 2271 memset(&dev->init_data, 0, sizeof(dev->init_data));
2239 strlcpy(dev->info.type, "ir_video", I2C_NAME_SIZE); 2272 strlcpy(info.type, "ir_video", I2C_NAME_SIZE);
2240 2273
2241 /* detect & configure */ 2274 /* detect & configure */
2242 switch (dev->model) { 2275 switch (dev->model) {
@@ -2259,8 +2292,8 @@ void em28xx_register_i2c_ir(struct em28xx *dev)
2259 } 2292 }
2260 2293
2261 if (dev->init_data.name) 2294 if (dev->init_data.name)
2262 dev->info.platform_data = &dev->init_data; 2295 info.platform_data = &dev->init_data;
2263 i2c_new_probed_device(&dev->i2c_adap, &dev->info, addr_list); 2296 i2c_new_probed_device(&dev->i2c_adap, &info, addr_list);
2264} 2297}
2265 2298
2266void em28xx_card_setup(struct em28xx *dev) 2299void em28xx_card_setup(struct em28xx *dev)
@@ -2524,6 +2557,9 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
2524 dev->chip_id = retval; 2557 dev->chip_id = retval;
2525 2558
2526 switch (dev->chip_id) { 2559 switch (dev->chip_id) {
2560 case CHIP_ID_EM2800:
2561 em28xx_info("chip ID is em2800\n");
2562 break;
2527 case CHIP_ID_EM2710: 2563 case CHIP_ID_EM2710:
2528 em28xx_info("chip ID is em2710\n"); 2564 em28xx_info("chip ID is em2710\n");
2529 break; 2565 break;
@@ -2650,7 +2686,7 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
2650 em28xx_init_extension(dev); 2686 em28xx_init_extension(dev);
2651 2687
2652 /* Save some power by putting tuner to sleep */ 2688 /* Save some power by putting tuner to sleep */
2653 v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_standby); 2689 v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_power, 0);
2654 2690
2655 return 0; 2691 return 0;
2656 2692
diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c
index a88257a7d94f..3f86d36dff2b 100644
--- a/drivers/media/video/em28xx/em28xx-core.c
+++ b/drivers/media/video/em28xx/em28xx-core.c
@@ -50,7 +50,7 @@ MODULE_PARM_DESC(reg_debug, "enable debug messages [URB reg]");
50 printk(KERN_INFO "%s %s :"fmt, \ 50 printk(KERN_INFO "%s %s :"fmt, \
51 dev->name, __func__ , ##arg); } while (0) 51 dev->name, __func__ , ##arg); } while (0)
52 52
53static int alt = EM28XX_PINOUT; 53static int alt;
54module_param(alt, int, 0644); 54module_param(alt, int, 0644);
55MODULE_PARM_DESC(alt, "alternate setting to use for video endpoint"); 55MODULE_PARM_DESC(alt, "alternate setting to use for video endpoint");
56 56
@@ -533,8 +533,15 @@ int em28xx_audio_setup(struct em28xx *dev)
533 533
534 vid1 = em28xx_read_ac97(dev, AC97_VENDOR_ID1); 534 vid1 = em28xx_read_ac97(dev, AC97_VENDOR_ID1);
535 if (vid1 < 0) { 535 if (vid1 < 0) {
536 /* Device likely doesn't support AC97 */ 536 /*
537 * Device likely doesn't support AC97
538 * Note: (some) em2800 devices without eeprom reports 0x91 on
539 * CHIPCFG register, even not having an AC97 chip
540 */
537 em28xx_warn("AC97 chip type couldn't be determined\n"); 541 em28xx_warn("AC97 chip type couldn't be determined\n");
542 dev->audio_mode.ac97 = EM28XX_NO_AC97;
543 dev->has_alsa_audio = 0;
544 dev->audio_mode.has_audio = 0;
538 goto init_audio; 545 goto init_audio;
539 } 546 }
540 547
@@ -778,6 +785,16 @@ int em28xx_set_alternate(struct em28xx *dev)
778 int i; 785 int i;
779 unsigned int min_pkt_size = dev->width * 2 + 4; 786 unsigned int min_pkt_size = dev->width * 2 + 4;
780 787
788 /*
789 * alt = 0 is used only for control messages, so, only values
790 * greater than 0 can be used for streaming.
791 */
792 if (alt && alt < dev->num_alt) {
793 em28xx_coredbg("alternate forced to %d\n", dev->alt);
794 dev->alt = alt;
795 goto set_alt;
796 }
797
781 /* When image size is bigger than a certain value, 798 /* When image size is bigger than a certain value,
782 the frame size should be increased, otherwise, only 799 the frame size should be increased, otherwise, only
783 green screen will be received. 800 green screen will be received.
@@ -798,6 +815,7 @@ int em28xx_set_alternate(struct em28xx *dev)
798 dev->alt = i; 815 dev->alt = i;
799 } 816 }
800 817
818set_alt:
801 if (dev->alt != prev_alt) { 819 if (dev->alt != prev_alt) {
802 em28xx_coredbg("minimum isoc packet size: %u (alt=%d)\n", 820 em28xx_coredbg("minimum isoc packet size: %u (alt=%d)\n",
803 min_pkt_size, dev->alt); 821 min_pkt_size, dev->alt);
diff --git a/drivers/media/video/em28xx/em28xx-dvb.c b/drivers/media/video/em28xx/em28xx-dvb.c
index db749461e5c6..cc0505eb900f 100644
--- a/drivers/media/video/em28xx/em28xx-dvb.c
+++ b/drivers/media/video/em28xx/em28xx-dvb.c
@@ -313,22 +313,20 @@ static int attach_xc3028(u8 addr, struct em28xx *dev)
313 cfg.i2c_addr = addr; 313 cfg.i2c_addr = addr;
314 314
315 if (!dev->dvb->frontend) { 315 if (!dev->dvb->frontend) {
316 printk(KERN_ERR "%s/2: dvb frontend not attached. " 316 em28xx_errdev("/2: dvb frontend not attached. "
317 "Can't attach xc3028\n", 317 "Can't attach xc3028\n");
318 dev->name);
319 return -EINVAL; 318 return -EINVAL;
320 } 319 }
321 320
322 fe = dvb_attach(xc2028_attach, dev->dvb->frontend, &cfg); 321 fe = dvb_attach(xc2028_attach, dev->dvb->frontend, &cfg);
323 if (!fe) { 322 if (!fe) {
324 printk(KERN_ERR "%s/2: xc3028 attach failed\n", 323 em28xx_errdev("/2: xc3028 attach failed\n");
325 dev->name);
326 dvb_frontend_detach(dev->dvb->frontend); 324 dvb_frontend_detach(dev->dvb->frontend);
327 dev->dvb->frontend = NULL; 325 dev->dvb->frontend = NULL;
328 return -EINVAL; 326 return -EINVAL;
329 } 327 }
330 328
331 printk(KERN_INFO "%s/2: xc3028 attached\n", dev->name); 329 em28xx_info("%s/2: xc3028 attached\n", dev->name);
332 330
333 return 0; 331 return 0;
334} 332}
@@ -463,7 +461,7 @@ static int dvb_init(struct em28xx *dev)
463 dvb = kzalloc(sizeof(struct em28xx_dvb), GFP_KERNEL); 461 dvb = kzalloc(sizeof(struct em28xx_dvb), GFP_KERNEL);
464 462
465 if (dvb == NULL) { 463 if (dvb == NULL) {
466 printk(KERN_INFO "em28xx_dvb: memory allocation failed\n"); 464 em28xx_info("em28xx_dvb: memory allocation failed\n");
467 return -ENOMEM; 465 return -ENOMEM;
468 } 466 }
469 dev->dvb = dvb; 467 dev->dvb = dvb;
@@ -493,6 +491,7 @@ static int dvb_init(struct em28xx *dev)
493 } 491 }
494 break; 492 break;
495 case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900: 493 case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900:
494 case EM2882_BOARD_TERRATEC_HYBRID_XS:
496 case EM2880_BOARD_EMPIRE_DUAL_TV: 495 case EM2880_BOARD_EMPIRE_DUAL_TV:
497 dvb->frontend = dvb_attach(zl10353_attach, 496 dvb->frontend = dvb_attach(zl10353_attach,
498 &em28xx_zl10353_xc3028_no_i2c_gate, 497 &em28xx_zl10353_xc3028_no_i2c_gate,
@@ -569,15 +568,12 @@ static int dvb_init(struct em28xx *dev)
569 } 568 }
570 break; 569 break;
571 default: 570 default:
572 printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card" 571 em28xx_errdev("/2: The frontend of your DVB/ATSC card"
573 " isn't supported yet\n", 572 " isn't supported yet\n");
574 dev->name);
575 break; 573 break;
576 } 574 }
577 if (NULL == dvb->frontend) { 575 if (NULL == dvb->frontend) {
578 printk(KERN_ERR 576 em28xx_errdev("/2: frontend initialization failed\n");
579 "%s/2: frontend initialization failed\n",
580 dev->name);
581 result = -EINVAL; 577 result = -EINVAL;
582 goto out_free; 578 goto out_free;
583 } 579 }
@@ -591,7 +587,7 @@ static int dvb_init(struct em28xx *dev)
591 goto out_free; 587 goto out_free;
592 588
593 em28xx_set_mode(dev, EM28XX_SUSPEND); 589 em28xx_set_mode(dev, EM28XX_SUSPEND);
594 printk(KERN_INFO "Successfully loaded em28xx-dvb\n"); 590 em28xx_info("Successfully loaded em28xx-dvb\n");
595 return 0; 591 return 0;
596 592
597out_free: 593out_free:
diff --git a/drivers/media/video/em28xx/em28xx-input.c b/drivers/media/video/em28xx/em28xx-input.c
index 7a0fe3816e3d..d96ec7c09dca 100644
--- a/drivers/media/video/em28xx/em28xx-input.c
+++ b/drivers/media/video/em28xx/em28xx-input.c
@@ -70,6 +70,7 @@ struct em28xx_IR {
70 int polling; 70 int polling;
71 struct delayed_work work; 71 struct delayed_work work;
72 unsigned int last_toggle:1; 72 unsigned int last_toggle:1;
73 unsigned int full_code:1;
73 unsigned int last_readcount; 74 unsigned int last_readcount;
74 unsigned int repeat_interval; 75 unsigned int repeat_interval;
75 76
@@ -246,9 +247,10 @@ static void em28xx_ir_handle_key(struct em28xx_IR *ir)
246 return; 247 return;
247 } 248 }
248 249
249 dprintk("ir->get_key result tb=%02x rc=%02x lr=%02x data=%02x\n", 250 dprintk("ir->get_key result tb=%02x rc=%02x lr=%02x data=%02x%02x\n",
250 poll_result.toggle_bit, poll_result.read_count, 251 poll_result.toggle_bit, poll_result.read_count,
251 ir->last_readcount, poll_result.rc_data[0]); 252 ir->last_readcount, poll_result.rc_address,
253 poll_result.rc_data[0]);
252 254
253 if (ir->dev->chip_id == CHIP_ID_EM2874) { 255 if (ir->dev->chip_id == CHIP_ID_EM2874) {
254 /* The em2874 clears the readcount field every time the 256 /* The em2874 clears the readcount field every time the
@@ -282,8 +284,15 @@ static void em28xx_ir_handle_key(struct em28xx_IR *ir)
282 284
283 if (do_sendkey) { 285 if (do_sendkey) {
284 dprintk("sending keypress\n"); 286 dprintk("sending keypress\n");
285 ir_input_keydown(ir->input, &ir->ir, poll_result.rc_data[0], 287
286 poll_result.rc_data[0]); 288 if (ir->full_code)
289 ir_input_keydown(ir->input, &ir->ir,
290 poll_result.rc_address << 8 |
291 poll_result.rc_data[0]);
292 else
293 ir_input_keydown(ir->input, &ir->ir,
294 poll_result.rc_data[0]);
295
287 ir_input_nokey(ir->input, &ir->ir); 296 ir_input_nokey(ir->input, &ir->ir);
288 } 297 }
289 298
@@ -333,6 +342,8 @@ int em28xx_ir_init(struct em28xx *dev)
333 switch (dev->chip_id) { 342 switch (dev->chip_id) {
334 case CHIP_ID_EM2860: 343 case CHIP_ID_EM2860:
335 case CHIP_ID_EM2883: 344 case CHIP_ID_EM2883:
345 if (dev->model == EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950)
346 ir->full_code = 1;
336 ir->get_key = default_polling_getkey; 347 ir->get_key = default_polling_getkey;
337 break; 348 break;
338 case CHIP_ID_EM2874: 349 case CHIP_ID_EM2874:
@@ -356,7 +367,11 @@ int em28xx_ir_init(struct em28xx *dev)
356 usb_make_path(dev->udev, ir->phys, sizeof(ir->phys)); 367 usb_make_path(dev->udev, ir->phys, sizeof(ir->phys));
357 strlcat(ir->phys, "/input0", sizeof(ir->phys)); 368 strlcat(ir->phys, "/input0", sizeof(ir->phys));
358 369
359 ir_input_init(input_dev, &ir->ir, IR_TYPE_OTHER, dev->board.ir_codes); 370 err = ir_input_init(input_dev, &ir->ir, IR_TYPE_OTHER,
371 dev->board.ir_codes);
372 if (err < 0)
373 goto err_out_free;
374
360 input_dev->name = ir->name; 375 input_dev->name = ir->name;
361 input_dev->phys = ir->phys; 376 input_dev->phys = ir->phys;
362 input_dev->id.bustype = BUS_USB; 377 input_dev->id.bustype = BUS_USB;
@@ -381,6 +396,7 @@ int em28xx_ir_init(struct em28xx *dev)
381 em28xx_ir_stop(ir); 396 em28xx_ir_stop(ir);
382 dev->ir = NULL; 397 dev->ir = NULL;
383 err_out_free: 398 err_out_free:
399 ir_input_free(input_dev);
384 input_free_device(input_dev); 400 input_free_device(input_dev);
385 kfree(ir); 401 kfree(ir);
386 return err; 402 return err;
@@ -395,6 +411,7 @@ int em28xx_ir_fini(struct em28xx *dev)
395 return 0; 411 return 0;
396 412
397 em28xx_ir_stop(ir); 413 em28xx_ir_stop(ir);
414 ir_input_free(ir->input);
398 input_unregister_device(ir->input); 415 input_unregister_device(ir->input);
399 kfree(ir); 416 kfree(ir);
400 417
diff --git a/drivers/media/video/em28xx/em28xx-reg.h b/drivers/media/video/em28xx/em28xx-reg.h
index ed12e7ffcbd0..058ac87639ce 100644
--- a/drivers/media/video/em28xx/em28xx-reg.h
+++ b/drivers/media/video/em28xx/em28xx-reg.h
@@ -192,6 +192,7 @@
192 192
193/* FIXME: Need to be populated with the other chip ID's */ 193/* FIXME: Need to be populated with the other chip ID's */
194enum em28xx_chip_id { 194enum em28xx_chip_id {
195 CHIP_ID_EM2800 = 7,
195 CHIP_ID_EM2710 = 17, 196 CHIP_ID_EM2710 = 17,
196 CHIP_ID_EM2820 = 18, /* Also used by some em2710 */ 197 CHIP_ID_EM2820 = 18, /* Also used by some em2710 */
197 CHIP_ID_EM2840 = 20, 198 CHIP_ID_EM2840 = 20,
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c
index 3a1dfb7726f8..7ad65370f274 100644
--- a/drivers/media/video/em28xx/em28xx-video.c
+++ b/drivers/media/video/em28xx/em28xx-video.c
@@ -1060,12 +1060,6 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
1060 /* the em2800 can only scale down to 50% */ 1060 /* the em2800 can only scale down to 50% */
1061 height = height > (3 * maxh / 4) ? maxh : maxh / 2; 1061 height = height > (3 * maxh / 4) ? maxh : maxh / 2;
1062 width = width > (3 * maxw / 4) ? maxw : maxw / 2; 1062 width = width > (3 * maxw / 4) ? maxw : maxw / 2;
1063 /* According to empiatech support the MaxPacketSize is too small
1064 * to support framesizes larger than 640x480 @ 30 fps or 640x576
1065 * @ 25 fps. As this would cut of a part of the image we prefer
1066 * 360x576 or 360x480 for now */
1067 if (width == maxw && height == maxh)
1068 width /= 2;
1069 } else { 1063 } else {
1070 /* width must even because of the YUYV format 1064 /* width must even because of the YUYV format
1071 height must be even because of interlacing */ 1065 height must be even because of interlacing */
@@ -2225,7 +2219,7 @@ static int em28xx_v4l2_close(struct file *filp)
2225 } 2219 }
2226 2220
2227 /* Save some power by putting tuner to sleep */ 2221 /* Save some power by putting tuner to sleep */
2228 v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_standby); 2222 v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_power, 0);
2229 2223
2230 /* do this before setting alternate! */ 2224 /* do this before setting alternate! */
2231 em28xx_uninit_isoc(dev); 2225 em28xx_uninit_isoc(dev);
diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h
index 0a73e8bf0d6e..441df644ddbe 100644
--- a/drivers/media/video/em28xx/em28xx.h
+++ b/drivers/media/video/em28xx/em28xx.h
@@ -110,6 +110,7 @@
110#define EM2820_BOARD_SILVERCREST_WEBCAM 71 110#define EM2820_BOARD_SILVERCREST_WEBCAM 71
111#define EM2861_BOARD_GADMEI_UTV330PLUS 72 111#define EM2861_BOARD_GADMEI_UTV330PLUS 72
112#define EM2870_BOARD_REDDO_DVB_C_USB_BOX 73 112#define EM2870_BOARD_REDDO_DVB_C_USB_BOX 73
113#define EM2800_BOARD_VC211A 74
113 114
114/* Limits minimum and default number of buffers */ 115/* Limits minimum and default number of buffers */
115#define EM28XX_MIN_BUF 4 116#define EM28XX_MIN_BUF 4
@@ -143,9 +144,6 @@
143 */ 144 */
144#define EM28XX_NUM_PACKETS 40 145#define EM28XX_NUM_PACKETS 40
145 146
146/* default alternate; 0 means choose the best */
147#define EM28XX_PINOUT 0
148
149#define EM28XX_INTERLACED_DEFAULT 1 147#define EM28XX_INTERLACED_DEFAULT 1
150 148
151/* 149/*
@@ -615,7 +613,6 @@ struct em28xx {
615 struct em28xx_dvb *dvb; 613 struct em28xx_dvb *dvb;
616 614
617 /* I2C keyboard data */ 615 /* I2C keyboard data */
618 struct i2c_board_info info;
619 struct IR_i2c_init_data init_data; 616 struct IR_i2c_init_data init_data;
620}; 617};
621 618
@@ -800,7 +797,7 @@ static inline unsigned int norm_maxw(struct em28xx *dev)
800 if (dev->board.is_webcam) 797 if (dev->board.is_webcam)
801 return dev->sensor_xres; 798 return dev->sensor_xres;
802 799
803 if (dev->board.max_range_640_480) 800 if (dev->board.max_range_640_480 || dev->board.is_em2800)
804 return 640; 801 return 640;
805 802
806 return 720; 803 return 720;
diff --git a/drivers/media/video/gspca/Kconfig b/drivers/media/video/gspca/Kconfig
index fe2e490ebc52..609d65b0b10d 100644
--- a/drivers/media/video/gspca/Kconfig
+++ b/drivers/media/video/gspca/Kconfig
@@ -76,10 +76,11 @@ config USB_GSPCA_MR97310A
76 module will be called gspca_mr97310a. 76 module will be called gspca_mr97310a.
77 77
78config USB_GSPCA_OV519 78config USB_GSPCA_OV519
79 tristate "OV519 USB Camera Driver" 79 tristate "OV51x / OVFX2 / W996xCF USB Camera Driver"
80 depends on VIDEO_V4L2 && USB_GSPCA 80 depends on VIDEO_V4L2 && USB_GSPCA
81 help 81 help
82 Say Y here if you want support for cameras based on the OV519 chip. 82 Say Y here if you want support for cameras based on one of these:
83 OV511(+), OV518(+), OV519, OVFX2, W9967CF, W9968CF
83 84
84 To compile this driver as a module, choose M here: the 85 To compile this driver as a module, choose M here: the
85 module will be called gspca_ov519. 86 module will be called gspca_ov519.
@@ -103,6 +104,15 @@ config USB_GSPCA_PAC207
103 To compile this driver as a module, choose M here: the 104 To compile this driver as a module, choose M here: the
104 module will be called gspca_pac207. 105 module will be called gspca_pac207.
105 106
107config USB_GSPCA_PAC7302
108 tristate "Pixart PAC7302 USB Camera Driver"
109 depends on VIDEO_V4L2 && USB_GSPCA
110 help
111 Say Y here if you want support for cameras based on the PAC7302 chip.
112
113 To compile this driver as a module, choose M here: the
114 module will be called gspca_pac7302.
115
106config USB_GSPCA_PAC7311 116config USB_GSPCA_PAC7311
107 tristate "Pixart PAC7311 USB Camera Driver" 117 tristate "Pixart PAC7311 USB Camera Driver"
108 depends on VIDEO_V4L2 && USB_GSPCA 118 depends on VIDEO_V4L2 && USB_GSPCA
@@ -229,6 +239,15 @@ config USB_GSPCA_STK014
229 To compile this driver as a module, choose M here: the 239 To compile this driver as a module, choose M here: the
230 module will be called gspca_stk014. 240 module will be called gspca_stk014.
231 241
242config USB_GSPCA_STV0680
243 tristate "STV0680 USB Camera Driver"
244 depends on VIDEO_V4L2 && USB_GSPCA
245 help
246 Say Y here if you want support for cameras based on the STV0680 chip.
247
248 To compile this driver as a module, choose M here: the
249 module will be called gspca_stv0680.
250
232config USB_GSPCA_SUNPLUS 251config USB_GSPCA_SUNPLUS
233 tristate "SUNPLUS USB Camera Driver" 252 tristate "SUNPLUS USB Camera Driver"
234 depends on VIDEO_V4L2 && USB_GSPCA 253 depends on VIDEO_V4L2 && USB_GSPCA
diff --git a/drivers/media/video/gspca/Makefile b/drivers/media/video/gspca/Makefile
index b7420818037e..ff2c7279d82e 100644
--- a/drivers/media/video/gspca/Makefile
+++ b/drivers/media/video/gspca/Makefile
@@ -8,6 +8,7 @@ obj-$(CONFIG_USB_GSPCA_MR97310A) += gspca_mr97310a.o
8obj-$(CONFIG_USB_GSPCA_OV519) += gspca_ov519.o 8obj-$(CONFIG_USB_GSPCA_OV519) += gspca_ov519.o
9obj-$(CONFIG_USB_GSPCA_OV534) += gspca_ov534.o 9obj-$(CONFIG_USB_GSPCA_OV534) += gspca_ov534.o
10obj-$(CONFIG_USB_GSPCA_PAC207) += gspca_pac207.o 10obj-$(CONFIG_USB_GSPCA_PAC207) += gspca_pac207.o
11obj-$(CONFIG_USB_GSPCA_PAC7302) += gspca_pac7302.o
11obj-$(CONFIG_USB_GSPCA_PAC7311) += gspca_pac7311.o 12obj-$(CONFIG_USB_GSPCA_PAC7311) += gspca_pac7311.o
12obj-$(CONFIG_USB_GSPCA_SN9C20X) += gspca_sn9c20x.o 13obj-$(CONFIG_USB_GSPCA_SN9C20X) += gspca_sn9c20x.o
13obj-$(CONFIG_USB_GSPCA_SONIXB) += gspca_sonixb.o 14obj-$(CONFIG_USB_GSPCA_SONIXB) += gspca_sonixb.o
@@ -22,6 +23,7 @@ obj-$(CONFIG_USB_GSPCA_SQ905) += gspca_sq905.o
22obj-$(CONFIG_USB_GSPCA_SQ905C) += gspca_sq905c.o 23obj-$(CONFIG_USB_GSPCA_SQ905C) += gspca_sq905c.o
23obj-$(CONFIG_USB_GSPCA_SUNPLUS) += gspca_sunplus.o 24obj-$(CONFIG_USB_GSPCA_SUNPLUS) += gspca_sunplus.o
24obj-$(CONFIG_USB_GSPCA_STK014) += gspca_stk014.o 25obj-$(CONFIG_USB_GSPCA_STK014) += gspca_stk014.o
26obj-$(CONFIG_USB_GSPCA_STV0680) += gspca_stv0680.o
25obj-$(CONFIG_USB_GSPCA_T613) += gspca_t613.o 27obj-$(CONFIG_USB_GSPCA_T613) += gspca_t613.o
26obj-$(CONFIG_USB_GSPCA_TV8532) += gspca_tv8532.o 28obj-$(CONFIG_USB_GSPCA_TV8532) += gspca_tv8532.o
27obj-$(CONFIG_USB_GSPCA_VC032X) += gspca_vc032x.o 29obj-$(CONFIG_USB_GSPCA_VC032X) += gspca_vc032x.o
@@ -37,6 +39,7 @@ gspca_mr97310a-objs := mr97310a.o
37gspca_ov519-objs := ov519.o 39gspca_ov519-objs := ov519.o
38gspca_ov534-objs := ov534.o 40gspca_ov534-objs := ov534.o
39gspca_pac207-objs := pac207.o 41gspca_pac207-objs := pac207.o
42gspca_pac7302-objs := pac7302.o
40gspca_pac7311-objs := pac7311.o 43gspca_pac7311-objs := pac7311.o
41gspca_sn9c20x-objs := sn9c20x.o 44gspca_sn9c20x-objs := sn9c20x.o
42gspca_sonixb-objs := sonixb.o 45gspca_sonixb-objs := sonixb.o
@@ -50,6 +53,7 @@ gspca_spca561-objs := spca561.o
50gspca_sq905-objs := sq905.o 53gspca_sq905-objs := sq905.o
51gspca_sq905c-objs := sq905c.o 54gspca_sq905c-objs := sq905c.o
52gspca_stk014-objs := stk014.o 55gspca_stk014-objs := stk014.o
56gspca_stv0680-objs := stv0680.o
53gspca_sunplus-objs := sunplus.o 57gspca_sunplus-objs := sunplus.o
54gspca_t613-objs := t613.o 58gspca_t613-objs := t613.o
55gspca_tv8532-objs := tv8532.o 59gspca_tv8532-objs := tv8532.o
diff --git a/drivers/media/video/gspca/conex.c b/drivers/media/video/gspca/conex.c
index eca003566ae3..2f0b8d621e00 100644
--- a/drivers/media/video/gspca/conex.c
+++ b/drivers/media/video/gspca/conex.c
@@ -888,8 +888,7 @@ static void sd_stop0(struct gspca_dev *gspca_dev)
888} 888}
889 889
890static void sd_pkt_scan(struct gspca_dev *gspca_dev, 890static void sd_pkt_scan(struct gspca_dev *gspca_dev,
891 struct gspca_frame *frame, /* target */ 891 u8 *data, /* isoc packet */
892 __u8 *data, /* isoc packet */
893 int len) /* iso packet length */ 892 int len) /* iso packet length */
894{ 893{
895 struct sd *sd = (struct sd *) gspca_dev; 894 struct sd *sd = (struct sd *) gspca_dev;
@@ -897,16 +896,15 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
897 if (data[0] == 0xff && data[1] == 0xd8) { 896 if (data[0] == 0xff && data[1] == 0xd8) {
898 897
899 /* start of frame */ 898 /* start of frame */
900 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, 899 gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
901 data, 0);
902 900
903 /* put the JPEG header in the new frame */ 901 /* put the JPEG header in the new frame */
904 gspca_frame_add(gspca_dev, FIRST_PACKET, frame, 902 gspca_frame_add(gspca_dev, FIRST_PACKET,
905 sd->jpeg_hdr, JPEG_HDR_SZ); 903 sd->jpeg_hdr, JPEG_HDR_SZ);
906 data += 2; 904 data += 2;
907 len -= 2; 905 len -= 2;
908 } 906 }
909 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); 907 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
910} 908}
911 909
912static void setbrightness(struct gspca_dev*gspca_dev) 910static void setbrightness(struct gspca_dev*gspca_dev)
diff --git a/drivers/media/video/gspca/etoms.c b/drivers/media/video/gspca/etoms.c
index c1461e63647f..9de86419ae1e 100644
--- a/drivers/media/video/gspca/etoms.c
+++ b/drivers/media/video/gspca/etoms.c
@@ -752,8 +752,7 @@ static void do_autogain(struct gspca_dev *gspca_dev)
752#undef LIMIT 752#undef LIMIT
753 753
754static void sd_pkt_scan(struct gspca_dev *gspca_dev, 754static void sd_pkt_scan(struct gspca_dev *gspca_dev,
755 struct gspca_frame *frame, /* target */ 755 u8 *data, /* isoc packet */
756 __u8 *data, /* isoc packet */
757 int len) /* iso packet length */ 756 int len) /* iso packet length */
758{ 757{
759 int seqframe; 758 int seqframe;
@@ -767,14 +766,13 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
767 data[2], data[3], data[4], data[5]); 766 data[2], data[3], data[4], data[5]);
768 data += 30; 767 data += 30;
769 /* don't change datalength as the chips provided it */ 768 /* don't change datalength as the chips provided it */
770 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, 769 gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
771 data, 0); 770 gspca_frame_add(gspca_dev, FIRST_PACKET, data, len);
772 gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, len);
773 return; 771 return;
774 } 772 }
775 if (len) { 773 if (len) {
776 data += 8; 774 data += 8;
777 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); 775 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
778 } else { /* Drop Packet */ 776 } else { /* Drop Packet */
779 gspca_dev->last_packet_type = DISCARD_PACKET; 777 gspca_dev->last_packet_type = DISCARD_PACKET;
780 } 778 }
diff --git a/drivers/media/video/gspca/finepix.c b/drivers/media/video/gspca/finepix.c
index 480ec5c87d0e..5d90e7448579 100644
--- a/drivers/media/video/gspca/finepix.c
+++ b/drivers/media/video/gspca/finepix.c
@@ -82,7 +82,6 @@ static void dostream(struct work_struct *work)
82 struct gspca_dev *gspca_dev = &dev->gspca_dev; 82 struct gspca_dev *gspca_dev = &dev->gspca_dev;
83 struct urb *urb = gspca_dev->urb[0]; 83 struct urb *urb = gspca_dev->urb[0];
84 u8 *data = urb->transfer_buffer; 84 u8 *data = urb->transfer_buffer;
85 struct gspca_frame *frame;
86 int ret = 0; 85 int ret = 0;
87 int len; 86 int len;
88 87
@@ -118,10 +117,6 @@ again:
118 } 117 }
119 if (!gspca_dev->present || !gspca_dev->streaming) 118 if (!gspca_dev->present || !gspca_dev->streaming)
120 goto out; 119 goto out;
121 frame = gspca_get_i_frame(&dev->gspca_dev);
122 if (frame == NULL)
123 gspca_dev->last_packet_type = DISCARD_PACKET;
124
125 if (len < FPIX_MAX_TRANSFER || 120 if (len < FPIX_MAX_TRANSFER ||
126 (data[len - 2] == 0xff && 121 (data[len - 2] == 0xff &&
127 data[len - 1] == 0xd9)) { 122 data[len - 1] == 0xd9)) {
@@ -132,21 +127,17 @@ again:
132 * but there's nothing we can do. We also end 127 * but there's nothing we can do. We also end
133 * here if the the jpeg ends right at the end 128 * here if the the jpeg ends right at the end
134 * of the frame. */ 129 * of the frame. */
135 if (frame) 130 gspca_frame_add(gspca_dev, LAST_PACKET,
136 frame = gspca_frame_add(gspca_dev, 131 data, len);
137 LAST_PACKET,
138 frame,
139 data, len);
140 break; 132 break;
141 } 133 }
142 134
143 /* got a partial image */ 135 /* got a partial image */
144 if (frame) 136 gspca_frame_add(gspca_dev,
145 gspca_frame_add(gspca_dev, 137 gspca_dev->last_packet_type
146 gspca_dev->last_packet_type 138 == LAST_PACKET
147 == LAST_PACKET 139 ? FIRST_PACKET : INTER_PACKET,
148 ? FIRST_PACKET : INTER_PACKET, 140 data, len);
149 frame, data, len);
150 } 141 }
151 142
152 /* We must wait before trying reading the next 143 /* We must wait before trying reading the next
diff --git a/drivers/media/video/gspca/gl860/gl860-mi1320.c b/drivers/media/video/gspca/gl860/gl860-mi1320.c
index 39f6261c1a0c..1355e526ee84 100644
--- a/drivers/media/video/gspca/gl860/gl860-mi1320.c
+++ b/drivers/media/video/gspca/gl860/gl860-mi1320.c
@@ -1,6 +1,5 @@
1/* @file gl860-mi1320.c 1/* Subdriver for the GL860 chip with the MI1320 sensor
2 * @author Olivier LORIN from my logs 2 * Author Olivier LORIN from own logs
3 * @date 2009-08-27
4 * 3 *
5 * This program is free software; you can redistribute it and/or modify 4 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by 5 * it under the terms of the GNU General Public License as published by
@@ -127,49 +126,49 @@ static u8 dat_wbalBL[] =
127 126
128static u8 dat_hvflip1[] = {0xf0, 0x00, 0xf1, 0x00}; 127static u8 dat_hvflip1[] = {0xf0, 0x00, 0xf1, 0x00};
129 128
130static u8 s000[] = 129static u8 dat_common00[] =
131 "\x00\x01\x07\x6a\x06\x63\x0d\x6a" "\xc0\x00\x10\x10\xc1\x03\xc2\x42" 130 "\x00\x01\x07\x6a\x06\x63\x0d\x6a" "\xc0\x00\x10\x10\xc1\x03\xc2\x42"
132 "\xd8\x04\x58\x00\x04\x02"; 131 "\xd8\x04\x58\x00\x04\x02";
133static u8 s001[] = 132static u8 dat_common01[] =
134 "\x0d\x00\xf1\x0b\x0d\x00\xf1\x08" "\x35\x00\xf1\x22\x68\x00\xf1\x5d" 133 "\x0d\x00\xf1\x0b\x0d\x00\xf1\x08" "\x35\x00\xf1\x22\x68\x00\xf1\x5d"
135 "\xf0\x00\xf1\x01\x06\x70\xf1\x0e" "\xf0\x00\xf1\x02\xdd\x18\xf1\xe0"; 134 "\xf0\x00\xf1\x01\x06\x70\xf1\x0e" "\xf0\x00\xf1\x02\xdd\x18\xf1\xe0";
136static u8 s002[] = 135static u8 dat_common02[] =
137 "\x05\x01\xf1\x84\x06\x00\xf1\x44" "\x07\x00\xf1\xbe\x08\x00\xf1\x1e" 136 "\x05\x01\xf1\x84\x06\x00\xf1\x44" "\x07\x00\xf1\xbe\x08\x00\xf1\x1e"
138 "\x20\x01\xf1\x03\x21\x84\xf1\x00" "\x22\x0d\xf1\x0f\x24\x80\xf1\x00" 137 "\x20\x01\xf1\x03\x21\x84\xf1\x00" "\x22\x0d\xf1\x0f\x24\x80\xf1\x00"
139 "\x34\x18\xf1\x2d\x35\x00\xf1\x22" "\x43\x83\xf1\x83\x59\x00\xf1\xff"; 138 "\x34\x18\xf1\x2d\x35\x00\xf1\x22" "\x43\x83\xf1\x83\x59\x00\xf1\xff";
140static u8 s003[] = 139static u8 dat_common03[] =
141 "\xf0\x00\xf1\x02\x39\x06\xf1\x8c" "\x3a\x06\xf1\x8c\x3b\x03\xf1\xda" 140 "\xf0\x00\xf1\x02\x39\x06\xf1\x8c" "\x3a\x06\xf1\x8c\x3b\x03\xf1\xda"
142 "\x3c\x05\xf1\x30\x57\x01\xf1\x0c" "\x58\x01\xf1\x42\x59\x01\xf1\x0c" 141 "\x3c\x05\xf1\x30\x57\x01\xf1\x0c" "\x58\x01\xf1\x42\x59\x01\xf1\x0c"
143 "\x5a\x01\xf1\x42\x5c\x13\xf1\x0e" "\x5d\x17\xf1\x12\x64\x1e\xf1\x1c"; 142 "\x5a\x01\xf1\x42\x5c\x13\xf1\x0e" "\x5d\x17\xf1\x12\x64\x1e\xf1\x1c";
144static u8 s004[] = 143static u8 dat_common04[] =
145 "\xf0\x00\xf1\x02\x24\x5f\xf1\x20" "\x28\xea\xf1\x02\x5f\x41\xf1\x43"; 144 "\xf0\x00\xf1\x02\x24\x5f\xf1\x20" "\x28\xea\xf1\x02\x5f\x41\xf1\x43";
146static u8 s005[] = 145static u8 dat_common05[] =
147 "\x02\x00\xf1\xee\x03\x29\xf1\x1a" "\x04\x02\xf1\xa4\x09\x00\xf1\x68" 146 "\x02\x00\xf1\xee\x03\x29\xf1\x1a" "\x04\x02\xf1\xa4\x09\x00\xf1\x68"
148 "\x0a\x00\xf1\x2a\x0b\x00\xf1\x04" "\x0c\x00\xf1\x93\x0d\x00\xf1\x82" 147 "\x0a\x00\xf1\x2a\x0b\x00\xf1\x04" "\x0c\x00\xf1\x93\x0d\x00\xf1\x82"
149 "\x0e\x00\xf1\x40\x0f\x00\xf1\x5f" "\x10\x00\xf1\x4e\x11\x00\xf1\x5b"; 148 "\x0e\x00\xf1\x40\x0f\x00\xf1\x5f" "\x10\x00\xf1\x4e\x11\x00\xf1\x5b";
150static u8 s006[] = 149static u8 dat_common06[] =
151 "\x15\x00\xf1\xc9\x16\x00\xf1\x5e" "\x17\x00\xf1\x9d\x18\x00\xf1\x06" 150 "\x15\x00\xf1\xc9\x16\x00\xf1\x5e" "\x17\x00\xf1\x9d\x18\x00\xf1\x06"
152 "\x19\x00\xf1\x89\x1a\x00\xf1\x12" "\x1b\x00\xf1\xa1\x1c\x00\xf1\xe4" 151 "\x19\x00\xf1\x89\x1a\x00\xf1\x12" "\x1b\x00\xf1\xa1\x1c\x00\xf1\xe4"
153 "\x1d\x00\xf1\x7a\x1e\x00\xf1\x64" "\xf6\x00\xf1\x5f"; 152 "\x1d\x00\xf1\x7a\x1e\x00\xf1\x64" "\xf6\x00\xf1\x5f";
154static u8 s007[] = 153static u8 dat_common07[] =
155 "\xf0\x00\xf1\x01\x53\x09\xf1\x03" "\x54\x3d\xf1\x1c\x55\x99\xf1\x72" 154 "\xf0\x00\xf1\x01\x53\x09\xf1\x03" "\x54\x3d\xf1\x1c\x55\x99\xf1\x72"
156 "\x56\xc1\xf1\xb1\x57\xd8\xf1\xce" "\x58\xe0\xf1\x00\xdc\x0a\xf1\x03" 155 "\x56\xc1\xf1\xb1\x57\xd8\xf1\xce" "\x58\xe0\xf1\x00\xdc\x0a\xf1\x03"
157 "\xdd\x45\xf1\x20\xde\xae\xf1\x82" "\xdf\xdc\xf1\xc9\xe0\xf6\xf1\xea" 156 "\xdd\x45\xf1\x20\xde\xae\xf1\x82" "\xdf\xdc\xf1\xc9\xe0\xf6\xf1\xea"
158 "\xe1\xff\xf1\x00"; 157 "\xe1\xff\xf1\x00";
159static u8 s008[] = 158static u8 dat_common08[] =
160 "\xf0\x00\xf1\x01\x80\x00\xf1\x06" "\x81\xf6\xf1\x08\x82\xfb\xf1\xf7" 159 "\xf0\x00\xf1\x01\x80\x00\xf1\x06" "\x81\xf6\xf1\x08\x82\xfb\xf1\xf7"
161 "\x83\x00\xf1\xfe\xb6\x07\xf1\x03" "\xb7\x18\xf1\x0c\x84\xfb\xf1\x06" 160 "\x83\x00\xf1\xfe\xb6\x07\xf1\x03" "\xb7\x18\xf1\x0c\x84\xfb\xf1\x06"
162 "\x85\xfb\xf1\xf9\x86\x00\xf1\xff" "\xb8\x07\xf1\x04\xb9\x16\xf1\x0a"; 161 "\x85\xfb\xf1\xf9\x86\x00\xf1\xff" "\xb8\x07\xf1\x04\xb9\x16\xf1\x0a";
163static u8 s009[] = 162static u8 dat_common09[] =
164 "\x87\xfa\xf1\x05\x88\xfc\xf1\xf9" "\x89\x00\xf1\xff\xba\x06\xf1\x03" 163 "\x87\xfa\xf1\x05\x88\xfc\xf1\xf9" "\x89\x00\xf1\xff\xba\x06\xf1\x03"
165 "\xbb\x17\xf1\x09\x8a\xe8\xf1\x14" "\x8b\xf7\xf1\xf0\x8c\xfd\xf1\xfa" 164 "\xbb\x17\xf1\x09\x8a\xe8\xf1\x14" "\x8b\xf7\xf1\xf0\x8c\xfd\xf1\xfa"
166 "\x8d\x00\xf1\x00\xbc\x05\xf1\x01" "\xbd\x0c\xf1\x08\xbe\x00\xf1\x14"; 165 "\x8d\x00\xf1\x00\xbc\x05\xf1\x01" "\xbd\x0c\xf1\x08\xbe\x00\xf1\x14";
167static u8 s010[] = 166static u8 dat_common10[] =
168 "\x8e\xea\xf1\x13\x8f\xf7\xf1\xf2" "\x90\xfd\xf1\xfa\x91\x00\xf1\x00" 167 "\x8e\xea\xf1\x13\x8f\xf7\xf1\xf2" "\x90\xfd\xf1\xfa\x91\x00\xf1\x00"
169 "\xbf\x05\xf1\x01\xc0\x0a\xf1\x08" "\xc1\x00\xf1\x0c\x92\xed\xf1\x0f" 168 "\xbf\x05\xf1\x01\xc0\x0a\xf1\x08" "\xc1\x00\xf1\x0c\x92\xed\xf1\x0f"
170 "\x93\xf9\xf1\xf4\x94\xfe\xf1\xfb" "\x95\x00\xf1\x00\xc2\x04\xf1\x01" 169 "\x93\xf9\xf1\xf4\x94\xfe\xf1\xfb" "\x95\x00\xf1\x00\xc2\x04\xf1\x01"
171 "\xc3\x0a\xf1\x07\xc4\x00\xf1\x10"; 170 "\xc3\x0a\xf1\x07\xc4\x00\xf1\x10";
172static u8 s011[] = 171static u8 dat_common11[] =
173 "\xf0\x00\xf1\x01\x05\x00\xf1\x06" "\x25\x00\xf1\x55\x34\x10\xf1\x10" 172 "\xf0\x00\xf1\x01\x05\x00\xf1\x06" "\x25\x00\xf1\x55\x34\x10\xf1\x10"
174 "\x35\xf0\xf1\x10\x3a\x02\xf1\x03" "\x3b\x04\xf1\x2a\x9b\x43\xf1\x00" 173 "\x35\xf0\xf1\x10\x3a\x02\xf1\x03" "\x3b\x04\xf1\x2a\x9b\x43\xf1\x00"
175 "\xa4\x03\xf1\xc0\xa7\x02\xf1\x81"; 174 "\xa4\x03\xf1\xc0\xa7\x02\xf1\x81";
@@ -222,26 +221,26 @@ void mi1320_init_settings(struct gspca_dev *gspca_dev)
222 221
223static void common(struct gspca_dev *gspca_dev) 222static void common(struct gspca_dev *gspca_dev)
224{ 223{
225 s32 n; /* reserved for FETCH macros */ 224 s32 n; /* reserved for FETCH functions */
226 225
227 ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 22, s000); 226 ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 22, dat_common00);
228 ctrl_out(gspca_dev, 0x40, 1, 0x0041, 0x0000, 0, NULL); 227 ctrl_out(gspca_dev, 0x40, 1, 0x0041, 0x0000, 0, NULL);
229 ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 32, s001); 228 ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 32, dat_common01);
230 n = fetch_validx(gspca_dev, tbl_common, ARRAY_SIZE(tbl_common)); 229 n = fetch_validx(gspca_dev, tbl_common, ARRAY_SIZE(tbl_common));
231 ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 48, s002); 230 ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 48, dat_common02);
232 ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 48, s003); 231 ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 48, dat_common03);
233 ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 16, s004); 232 ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 16, dat_common04);
234 ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 48, s005); 233 ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 48, dat_common05);
235 ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 44, s006); 234 ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 44, dat_common06);
236 keep_on_fetching_validx(gspca_dev, tbl_common, 235 keep_on_fetching_validx(gspca_dev, tbl_common,
237 ARRAY_SIZE(tbl_common), n); 236 ARRAY_SIZE(tbl_common), n);
238 ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 52, s007); 237 ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 52, dat_common07);
239 ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 48, s008); 238 ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 48, dat_common08);
240 ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 48, s009); 239 ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 48, dat_common09);
241 ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 56, s010); 240 ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 56, dat_common10);
242 keep_on_fetching_validx(gspca_dev, tbl_common, 241 keep_on_fetching_validx(gspca_dev, tbl_common,
243 ARRAY_SIZE(tbl_common), n); 242 ARRAY_SIZE(tbl_common), n);
244 ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 40, s011); 243 ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 40, dat_common11);
245 keep_on_fetching_validx(gspca_dev, tbl_common, 244 keep_on_fetching_validx(gspca_dev, tbl_common,
246 ARRAY_SIZE(tbl_common), n); 245 ARRAY_SIZE(tbl_common), n);
247} 246}
diff --git a/drivers/media/video/gspca/gl860/gl860-mi2020.c b/drivers/media/video/gspca/gl860/gl860-mi2020.c
index ffb09fed3e8c..80cb3f1b36f7 100644
--- a/drivers/media/video/gspca/gl860/gl860-mi2020.c
+++ b/drivers/media/video/gspca/gl860/gl860-mi2020.c
@@ -1,7 +1,6 @@
1/* @file gl860-mi2020.c 1/* Subdriver for the GL860 chip with the MI2020 sensor
2 * @author Olivier LORIN, from Ice/Soro2005's logs(A), Fret_saw/Hulkie's 2 * Author Olivier LORIN, from Ice/Soro2005's logs(A), Fret_saw/Hulkie's
3 * logs(B) and Tricid"s logs(C). With the help of Kytrix/BUGabundo/Blazercist. 3 * logs(B) and Tricid"s logs(C). With the help of Kytrix/BUGabundo/Blazercist.
4 * @date 2009-08-27
5 * 4 *
6 * This program is free software; you can redistribute it and/or modify 5 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by 6 * it under the terms of the GNU General Public License as published by
@@ -41,7 +40,7 @@ static u8 dat_freq1[] = { 0x8c, 0xa4, 0x04 };
41static u8 dat_multi5[] = { 0x8c, 0xa1, 0x03 }; 40static u8 dat_multi5[] = { 0x8c, 0xa1, 0x03 };
42static u8 dat_multi6[] = { 0x90, 0x00, 0x05 }; 41static u8 dat_multi6[] = { 0x90, 0x00, 0x05 };
43 42
44static struct validx tbl_common_a[] = { 43static struct validx tbl_common1[] = {
45 {0x0000, 0x0000}, 44 {0x0000, 0x0000},
46 {1, 0xffff}, /* msleep(35); */ 45 {1, 0xffff}, /* msleep(35); */
47 {0x006a, 0x0007}, {0x0063, 0x0006}, {0x006a, 0x000d}, {0x0000, 0x00c0}, 46 {0x006a, 0x0007}, {0x0063, 0x0006}, {0x006a, 0x000d}, {0x0000, 0x00c0},
@@ -49,7 +48,7 @@ static struct validx tbl_common_a[] = {
49 {0x0000, 0x0058}, {0x0002, 0x0004}, {0x0041, 0x0000}, 48 {0x0000, 0x0058}, {0x0002, 0x0004}, {0x0041, 0x0000},
50}; 49};
51 50
52static struct validx tbl_common_b[] = { 51static struct validx tbl_common2[] = {
53 {0x006a, 0x0007}, 52 {0x006a, 0x0007},
54 {35, 0xffff}, 53 {35, 0xffff},
55 {0x00ef, 0x0006}, 54 {0x00ef, 0x0006},
@@ -60,7 +59,7 @@ static struct validx tbl_common_b[] = {
60 {0x0004, 0x00d8}, {0x0000, 0x0058}, {0x0041, 0x0000}, 59 {0x0004, 0x00d8}, {0x0000, 0x0058}, {0x0041, 0x0000},
61}; 60};
62 61
63static struct idxdata tbl_common_c[] = { 62static struct idxdata tbl_common3[] = {
64 {0x32, "\x02\x00\x08"}, {0x33, "\xf4\x03\x1d"}, 63 {0x32, "\x02\x00\x08"}, {0x33, "\xf4\x03\x1d"},
65 {6, "\xff\xff\xff"}, /* 12 */ 64 {6, "\xff\xff\xff"}, /* 12 */
66 {0x34, "\x1e\x8f\x09"}, {0x34, "\x1c\x01\x28"}, {0x34, "\x1e\x8f\x09"}, 65 {0x34, "\x1e\x8f\x09"}, {0x34, "\x1c\x01\x28"}, {0x34, "\x1e\x8f\x09"},
@@ -109,7 +108,7 @@ static struct idxdata tbl_common_c[] = {
109 {0x33, "\x8c\xa2\x03"}, {0x33, "\x90\x00\xbb"}, 108 {0x33, "\x8c\xa2\x03"}, {0x33, "\x90\x00\xbb"},
110}; 109};
111 110
112static struct idxdata tbl_common_d[] = { 111static struct idxdata tbl_common4[] = {
113 {0x33, "\x8c\x22\x2e"}, {0x33, "\x90\x00\xa0"}, {0x33, "\x8c\xa4\x08"}, 112 {0x33, "\x8c\x22\x2e"}, {0x33, "\x90\x00\xa0"}, {0x33, "\x8c\xa4\x08"},
114 {0x33, "\x90\x00\x1f"}, {0x33, "\x8c\xa4\x09"}, {0x33, "\x90\x00\x21"}, 113 {0x33, "\x90\x00\x1f"}, {0x33, "\x8c\xa4\x09"}, {0x33, "\x90\x00\x21"},
115 {0x33, "\x8c\xa4\x0a"}, {0x33, "\x90\x00\x25"}, {0x33, "\x8c\xa4\x0b"}, 114 {0x33, "\x8c\xa4\x0a"}, {0x33, "\x90\x00\x25"}, {0x33, "\x8c\xa4\x0b"},
@@ -118,7 +117,7 @@ static struct idxdata tbl_common_d[] = {
118 {0x33, "\x90\x00\xa0"}, {0x33, "\x8c\x24\x17"}, {0x33, "\x90\x00\xc0"}, 117 {0x33, "\x90\x00\xa0"}, {0x33, "\x8c\x24\x17"}, {0x33, "\x90\x00\xc0"},
119}; 118};
120 119
121static struct idxdata tbl_common_e[] = { 120static struct idxdata tbl_common5[] = {
122 {0x33, "\x8c\xa4\x04"}, {0x33, "\x90\x00\x80"}, {0x33, "\x8c\xa7\x9d"}, 121 {0x33, "\x8c\xa4\x04"}, {0x33, "\x90\x00\x80"}, {0x33, "\x8c\xa7\x9d"},
123 {0x33, "\x90\x00\x00"}, {0x33, "\x8c\xa7\x9e"}, {0x33, "\x90\x00\x00"}, 122 {0x33, "\x90\x00\x00"}, {0x33, "\x8c\xa7\x9e"}, {0x33, "\x90\x00\x00"},
124 {0x33, "\x8c\xa2\x0c"}, {0x33, "\x90\x00\x17"}, {0x33, "\x8c\xa2\x15"}, 123 {0x33, "\x8c\xa2\x0c"}, {0x33, "\x90\x00\x17"}, {0x33, "\x8c\xa2\x15"},
@@ -180,7 +179,7 @@ static struct validx tbl_init_at_startup[] = {
180 {53, 0xffff}, 179 {53, 0xffff},
181}; 180};
182 181
183static struct idxdata tbl_init_post_alt_low_a[] = { 182static struct idxdata tbl_init_post_alt_low1[] = {
184 {0x33, "\x8c\x27\x15"}, {0x33, "\x90\x00\x25"}, {0x33, "\x8c\x22\x2e"}, 183 {0x33, "\x8c\x27\x15"}, {0x33, "\x90\x00\x25"}, {0x33, "\x8c\x22\x2e"},
185 {0x33, "\x90\x00\x81"}, {0x33, "\x8c\xa4\x08"}, {0x33, "\x90\x00\x17"}, 184 {0x33, "\x90\x00\x81"}, {0x33, "\x8c\xa4\x08"}, {0x33, "\x90\x00\x17"},
186 {0x33, "\x8c\xa4\x09"}, {0x33, "\x90\x00\x1a"}, {0x33, "\x8c\xa4\x0a"}, 185 {0x33, "\x8c\xa4\x09"}, {0x33, "\x90\x00\x1a"}, {0x33, "\x8c\xa4\x0a"},
@@ -189,7 +188,7 @@ static struct idxdata tbl_init_post_alt_low_a[] = {
189 {0x33, "\x90\x00\x9b"}, 188 {0x33, "\x90\x00\x9b"},
190}; 189};
191 190
192static struct idxdata tbl_init_post_alt_low_b[] = { 191static struct idxdata tbl_init_post_alt_low2[] = {
193 {0x33, "\x8c\x27\x03"}, {0x33, "\x90\x03\x24"}, {0x33, "\x8c\x27\x05"}, 192 {0x33, "\x8c\x27\x03"}, {0x33, "\x90\x03\x24"}, {0x33, "\x8c\x27\x05"},
194 {0x33, "\x90\x02\x58"}, {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x05"}, 193 {0x33, "\x90\x02\x58"}, {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x05"},
195 {2, "\xff\xff\xff"}, 194 {2, "\xff\xff\xff"},
@@ -197,7 +196,7 @@ static struct idxdata tbl_init_post_alt_low_b[] = {
197 {2, "\xff\xff\xff"}, 196 {2, "\xff\xff\xff"},
198}; 197};
199 198
200static struct idxdata tbl_init_post_alt_low_c[] = { 199static struct idxdata tbl_init_post_alt_low3[] = {
201 {0x34, "\x1e\x8f\x09"}, {0x34, "\x1c\x01\x28"}, {0x34, "\x1e\x8f\x09"}, 200 {0x34, "\x1e\x8f\x09"}, {0x34, "\x1c\x01\x28"}, {0x34, "\x1e\x8f\x09"},
202 {2, "\xff\xff\xff"}, 201 {2, "\xff\xff\xff"},
203 {0x34, "\x1e\x8f\x09"}, {0x32, "\x14\x06\xe6"}, {0x33, "\x8c\xa1\x20"}, 202 {0x34, "\x1e\x8f\x09"}, {0x32, "\x14\x06\xe6"}, {0x33, "\x8c\xa1\x20"},
@@ -221,7 +220,7 @@ static struct idxdata tbl_init_post_alt_low_c[] = {
221 {1, "\xff\xff\xff"}, 220 {1, "\xff\xff\xff"},
222}; 221};
223 222
224static struct idxdata tbl_init_post_alt_low_d[] = { 223static struct idxdata tbl_init_post_alt_low4[] = {
225 {0x32, "\x10\x01\xf8"}, {0x34, "\xce\x01\xa8"}, {0x34, "\xd0\x66\x33"}, 224 {0x32, "\x10\x01\xf8"}, {0x34, "\xce\x01\xa8"}, {0x34, "\xd0\x66\x33"},
226 {0x34, "\xd2\x31\x9a"}, {0x34, "\xd4\x94\x63"}, {0x34, "\xd6\x4b\x25"}, 225 {0x34, "\xd2\x31\x9a"}, {0x34, "\xd4\x94\x63"}, {0x34, "\xd6\x4b\x25"},
227 {0x34, "\xd8\x26\x70"}, {0x34, "\xda\x72\x4c"}, {0x34, "\xdc\xff\x04"}, 226 {0x34, "\xd8\x26\x70"}, {0x34, "\xda\x72\x4c"}, {0x34, "\xdc\xff\x04"},
@@ -267,7 +266,7 @@ static struct idxdata tbl_init_post_alt_low_d[] = {
267 {0x32, "\x6c\x14\x08"}, 266 {0x32, "\x6c\x14\x08"},
268}; 267};
269 268
270static struct idxdata tbl_init_post_alt_big_a[] = { 269static struct idxdata tbl_init_post_alt_big1[] = {
271 {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x05"}, 270 {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x05"},
272 {2, "\xff\xff\xff"}, 271 {2, "\xff\xff\xff"},
273 {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x06"}, 272 {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x06"},
@@ -288,7 +287,7 @@ static struct idxdata tbl_init_post_alt_big_a[] = {
288 {0x34, "\x04\x00\x2a"}, {0x33, "\x8c\xa7\x02"}, {0x33, "\x90\x00\x01"}, 287 {0x34, "\x04\x00\x2a"}, {0x33, "\x8c\xa7\x02"}, {0x33, "\x90\x00\x01"},
289}; 288};
290 289
291static struct idxdata tbl_init_post_alt_big_b[] = { 290static struct idxdata tbl_init_post_alt_big2[] = {
292 {0x32, "\x10\x01\xf8"}, {0x34, "\xce\x01\xa8"}, {0x34, "\xd0\x66\x33"}, 291 {0x32, "\x10\x01\xf8"}, {0x34, "\xce\x01\xa8"}, {0x34, "\xd0\x66\x33"},
293 {0x34, "\xd2\x31\x9a"}, {0x34, "\xd4\x94\x63"}, {0x34, "\xd6\x4b\x25"}, 292 {0x34, "\xd2\x31\x9a"}, {0x34, "\xd4\x94\x63"}, {0x34, "\xd6\x4b\x25"},
294 {0x34, "\xd8\x26\x70"}, {0x34, "\xda\x72\x4c"}, {0x34, "\xdc\xff\x04"}, 293 {0x34, "\xd8\x26\x70"}, {0x34, "\xda\x72\x4c"}, {0x34, "\xdc\xff\x04"},
@@ -317,7 +316,7 @@ static struct idxdata tbl_init_post_alt_big_b[] = {
317 {0x32, "\x10\x01\xfc"}, {0x33, "\x8c\xa1\x18"}, {0x33, "\x90\x00\x3c"}, 316 {0x32, "\x10\x01\xfc"}, {0x33, "\x8c\xa1\x18"}, {0x33, "\x90\x00\x3c"},
318}; 317};
319 318
320static struct idxdata tbl_init_post_alt_big_c[] = { 319static struct idxdata tbl_init_post_alt_big3[] = {
321 {0x33, "\x8c\xa1\x02"}, 320 {0x33, "\x8c\xa1\x02"},
322 {0x33, "\x90\x00\x1f"}, 321 {0x33, "\x90\x00\x1f"},
323 {0x33, "\x8c\xa1\x02"}, 322 {0x33, "\x8c\xa1\x02"},
@@ -388,14 +387,14 @@ static void common(struct gspca_dev *gspca_dev)
388 s32 reso = gspca_dev->cam.cam_mode[(s32) gspca_dev->curr_mode].priv; 387 s32 reso = gspca_dev->cam.cam_mode[(s32) gspca_dev->curr_mode].priv;
389 388
390 if (_MI2020b_) { 389 if (_MI2020b_) {
391 fetch_validx(gspca_dev, tbl_common_a, ARRAY_SIZE(tbl_common_a)); 390 fetch_validx(gspca_dev, tbl_common1, ARRAY_SIZE(tbl_common1));
392 } else { 391 } else {
393 if (_MI2020_) 392 if (_MI2020_)
394 ctrl_out(gspca_dev, 0x40, 1, 0x0008, 0x0004, 0, NULL); 393 ctrl_out(gspca_dev, 0x40, 1, 0x0008, 0x0004, 0, NULL);
395 else 394 else
396 ctrl_out(gspca_dev, 0x40, 1, 0x0002, 0x0004, 0, NULL); 395 ctrl_out(gspca_dev, 0x40, 1, 0x0002, 0x0004, 0, NULL);
397 msleep(35); 396 msleep(35);
398 fetch_validx(gspca_dev, tbl_common_b, ARRAY_SIZE(tbl_common_b)); 397 fetch_validx(gspca_dev, tbl_common2, ARRAY_SIZE(tbl_common2));
399 } 398 }
400 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x86\x25\x01"); 399 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x86\x25\x01");
401 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x86\x25\x00"); 400 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x86\x25\x00");
@@ -403,13 +402,13 @@ static void common(struct gspca_dev *gspca_dev)
403 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0030, 3, "\x1a\x0a\xcc"); 402 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0030, 3, "\x1a\x0a\xcc");
404 if (reso == IMAGE_1600) 403 if (reso == IMAGE_1600)
405 msleep(2); /* 1600 */ 404 msleep(2); /* 1600 */
406 fetch_idxdata(gspca_dev, tbl_common_c, ARRAY_SIZE(tbl_common_c)); 405 fetch_idxdata(gspca_dev, tbl_common3, ARRAY_SIZE(tbl_common3));
407 406
408 if (_MI2020b_ || _MI2020_) 407 if (_MI2020b_ || _MI2020_)
409 fetch_idxdata(gspca_dev, tbl_common_d, 408 fetch_idxdata(gspca_dev, tbl_common4,
410 ARRAY_SIZE(tbl_common_d)); 409 ARRAY_SIZE(tbl_common4));
411 410
412 fetch_idxdata(gspca_dev, tbl_common_e, ARRAY_SIZE(tbl_common_e)); 411 fetch_idxdata(gspca_dev, tbl_common5, ARRAY_SIZE(tbl_common5));
413 if (_MI2020b_ || _MI2020_) { 412 if (_MI2020b_ || _MI2020_) {
414 /* Different from fret */ 413 /* Different from fret */
415 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x78"); 414 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x78");
@@ -525,15 +524,15 @@ static int mi2020_init_post_alt(struct gspca_dev *gspca_dev)
525 12, dat_800); 524 12, dat_800);
526 525
527 if (_MI2020c_) 526 if (_MI2020c_)
528 fetch_idxdata(gspca_dev, tbl_init_post_alt_low_a, 527 fetch_idxdata(gspca_dev, tbl_init_post_alt_low1,
529 ARRAY_SIZE(tbl_init_post_alt_low_a)); 528 ARRAY_SIZE(tbl_init_post_alt_low1));
530 529
531 if (reso == IMAGE_800) 530 if (reso == IMAGE_800)
532 fetch_idxdata(gspca_dev, tbl_init_post_alt_low_b, 531 fetch_idxdata(gspca_dev, tbl_init_post_alt_low2,
533 ARRAY_SIZE(tbl_init_post_alt_low_b)); 532 ARRAY_SIZE(tbl_init_post_alt_low2));
534 533
535 fetch_idxdata(gspca_dev, tbl_init_post_alt_low_c, 534 fetch_idxdata(gspca_dev, tbl_init_post_alt_low3,
536 ARRAY_SIZE(tbl_init_post_alt_low_c)); 535 ARRAY_SIZE(tbl_init_post_alt_low3));
537 536
538 if (_MI2020b_) { 537 if (_MI2020b_) {
539 ctrl_out(gspca_dev, 0x40, 1, 0x0001, 0x0010, 0, NULL); 538 ctrl_out(gspca_dev, 0x40, 1, 0x0001, 0x0010, 0, NULL);
@@ -574,8 +573,8 @@ static int mi2020_init_post_alt(struct gspca_dev *gspca_dev)
574 msleep(5);/* " */ 573 msleep(5);/* " */
575 574
576 if (_MI2020c_) { 575 if (_MI2020c_) {
577 fetch_idxdata(gspca_dev, tbl_init_post_alt_low_d, 576 fetch_idxdata(gspca_dev, tbl_init_post_alt_low4,
578 ARRAY_SIZE(tbl_init_post_alt_low_d)); 577 ARRAY_SIZE(tbl_init_post_alt_low4));
579 } else { 578 } else {
580 ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0000, 1, &c); 579 ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0000, 1, &c);
581 msleep(14); /* 0xd8 */ 580 msleep(14); /* 0xd8 */
@@ -644,8 +643,8 @@ static int mi2020_init_post_alt(struct gspca_dev *gspca_dev)
644 3, "\x90\x04\xb0"); 643 3, "\x90\x04\xb0");
645 } 644 }
646 645
647 fetch_idxdata(gspca_dev, tbl_init_post_alt_big_a, 646 fetch_idxdata(gspca_dev, tbl_init_post_alt_big1,
648 ARRAY_SIZE(tbl_init_post_alt_big_a)); 647 ARRAY_SIZE(tbl_init_post_alt_big1));
649 648
650 if (reso == IMAGE_1600) 649 if (reso == IMAGE_1600)
651 msleep(13); /* 1600 */ 650 msleep(13); /* 1600 */
@@ -708,8 +707,8 @@ static int mi2020_init_post_alt(struct gspca_dev *gspca_dev)
708 msleep(14); 707 msleep(14);
709 708
710 if (_MI2020c_) 709 if (_MI2020c_)
711 fetch_idxdata(gspca_dev, tbl_init_post_alt_big_b, 710 fetch_idxdata(gspca_dev, tbl_init_post_alt_big2,
712 ARRAY_SIZE(tbl_init_post_alt_big_b)); 711 ARRAY_SIZE(tbl_init_post_alt_big2));
713 712
714 /* flip/mirror */ 713 /* flip/mirror */
715 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip1); 714 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip1);
@@ -738,8 +737,8 @@ static int mi2020_init_post_alt(struct gspca_dev *gspca_dev)
738 sd->nbIm = 0; 737 sd->nbIm = 0;
739 738
740 if (_MI2020c_) 739 if (_MI2020c_)
741 fetch_idxdata(gspca_dev, tbl_init_post_alt_big_c, 740 fetch_idxdata(gspca_dev, tbl_init_post_alt_big3,
742 ARRAY_SIZE(tbl_init_post_alt_big_c)); 741 ARRAY_SIZE(tbl_init_post_alt_big3));
743 } 742 }
744 743
745 sd->vold.mirror = mirror; 744 sd->vold.mirror = mirror;
diff --git a/drivers/media/video/gspca/gl860/gl860-ov2640.c b/drivers/media/video/gspca/gl860/gl860-ov2640.c
index 14b9c373f9f7..768cac5cd72b 100644
--- a/drivers/media/video/gspca/gl860/gl860-ov2640.c
+++ b/drivers/media/video/gspca/gl860/gl860-ov2640.c
@@ -1,6 +1,5 @@
1/* @file gl860-ov2640.c 1/* Subdriver for the GL860 chip with the OV2640 sensor
2 * @author Olivier LORIN, from Malmostoso's logs 2 * Author Olivier LORIN, from Malmostoso's logs
3 * @date 2009-08-27
4 * 3 *
5 * This program is free software; you can redistribute it and/or modify 4 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by 5 * it under the terms of the GNU General Public License as published by
@@ -21,8 +20,12 @@
21#include "gl860.h" 20#include "gl860.h"
22 21
23static u8 dat_init1[] = "\x00\x41\x07\x6a\x06\x61\x0d\x6a" "\x10\x10\xc1\x01"; 22static u8 dat_init1[] = "\x00\x41\x07\x6a\x06\x61\x0d\x6a" "\x10\x10\xc1\x01";
24static u8 dat_init2[] = {0x61}; /* expected */ 23
25static u8 dat_init3[] = {0x51}; /* expected */ 24static u8 c61[] = {0x61}; /* expected */
25static u8 c51[] = {0x51}; /* expected */
26static u8 c50[] = {0x50}; /* expected */
27static u8 c28[] = {0x28}; /* expected */
28static u8 ca8[] = {0xa8}; /* expected */
26 29
27static u8 dat_post[] = 30static u8 dat_post[] =
28 "\x00\x41\x07\x6a\x06\xef\x0d\x6a" "\x10\x10\xc1\x01"; 31 "\x00\x41\x07\x6a\x06\xef\x0d\x6a" "\x10\x10\xc1\x01";
@@ -32,10 +35,6 @@ static u8 dat_800[] = "\xd0\x01\xd1\x10\xd2\x58\xd3\x02\xd4\x18\xd5\x21";
32static u8 dat_1280[] = "\xd0\x01\xd1\x18\xd2\xc0\xd3\x02\xd4\x28\xd5\x01"; 35static u8 dat_1280[] = "\xd0\x01\xd1\x18\xd2\xc0\xd3\x02\xd4\x28\xd5\x01";
33static u8 dat_1600[] = "\xd0\x01\xd1\x20\xd2\xb0\xd3\x02\xd4\x30\xd5\x41"; 36static u8 dat_1600[] = "\xd0\x01\xd1\x20\xd2\xb0\xd3\x02\xd4\x30\xd5\x41";
34 37
35static u8 c50[] = {0x50}; /* expected */
36static u8 c28[] = {0x28}; /* expected */
37static u8 ca8[] = {0xa8}; /* expected */
38
39static struct validx tbl_init_at_startup[] = { 38static struct validx tbl_init_at_startup[] = {
40 {0x0000, 0x0000}, {0x0010, 0x0010}, {0x0008, 0x00c0}, {0x0001, 0x00c1}, 39 {0x0000, 0x0000}, {0x0010, 0x0010}, {0x0008, 0x00c0}, {0x0001, 0x00c1},
41 {0x0001, 0x00c2}, {0x0020, 0x0006}, {0x006a, 0x000d}, 40 {0x0001, 0x00c2}, {0x0020, 0x0006}, {0x006a, 0x000d},
@@ -92,7 +91,7 @@ static struct validx tbl_common[] = {
92 {0x6000, 0x0010}, 91 {0x6000, 0x0010},
93}; 92};
94 93
95static struct validx tbl_sensor_settings_common_a[] = { 94static struct validx tbl_sensor_settings_common1[] = {
96 {0x0041, 0x0000}, {0x006a, 0x0007}, {0x00ef, 0x0006}, {0x006a, 0x000d}, 95 {0x0041, 0x0000}, {0x006a, 0x0007}, {0x00ef, 0x0006}, {0x006a, 0x000d},
97 {0x0000, 0x00c0}, {0x0010, 0x0010}, {0x0001, 0x00c1}, {0x0041, 0x00c2}, 96 {0x0000, 0x00c0}, {0x0010, 0x0010}, {0x0001, 0x00c1}, {0x0041, 0x00c2},
98 {0x0004, 0x00d8}, {0x0012, 0x0004}, {0x0000, 0x0058}, {0x0041, 0x0000}, 97 {0x0004, 0x00d8}, {0x0012, 0x0004}, {0x0000, 0x0058}, {0x0041, 0x0000},
@@ -104,40 +103,10 @@ static struct validx tbl_sensor_settings_common_a[] = {
104 {0x0040, 0x0000}, 103 {0x0040, 0x0000},
105}; 104};
106 105
107static struct validx tbl_sensor_settings_common_b[] = { 106static struct validx tbl_sensor_settings_common2[] = {
108 {0x6001, 0x00ff}, {0x6038, 0x000c}, 107 {0x6001, 0x00ff}, {0x6038, 0x000c},
109 {10, 0xffff}, 108 {10, 0xffff},
110 {0x6000, 0x0011}, 109 {0x6000, 0x0011},
111 /* backlight=31/64 */
112 {0x6001, 0x00ff}, {0x603e, 0x0024}, {0x6034, 0x0025},
113 /* bright=0/256 */
114 {0x6000, 0x00ff}, {0x6009, 0x007c}, {0x6000, 0x007d},
115 /* wbal=64/128 */
116 {0x6000, 0x00ff}, {0x6003, 0x007c}, {0x6040, 0x007d},
117 /* cntr=0/256 */
118 {0x6000, 0x00ff}, {0x6007, 0x007c}, {0x6000, 0x007d},
119 /* sat=128/256 */
120 {0x6000, 0x00ff}, {0x6001, 0x007c}, {0x6080, 0x007d},
121 /* sharpness=0/32 */
122 {0x6000, 0x00ff}, {0x6001, 0x0092}, {0x60c0, 0x0093},
123 /* hue=0/256 */
124 {0x6000, 0x00ff}, {0x6002, 0x007c}, {0x6000, 0x007d},
125 /* gam=32/64 */
126 {0x6000, 0x00ff}, {0x6008, 0x007c}, {0x6020, 0x007d},
127 /* image right up */
128 {0xffff, 0xffff},
129 {15, 0xffff},
130 {0x6001, 0x00ff}, {0x6000, 0x8004},
131 {0xffff, 0xffff},
132 {0x60a8, 0x0004},
133 {15, 0xffff},
134 {0x6001, 0x00ff}, {0x6000, 0x8004},
135 {0xffff, 0xffff},
136 {0x60f8, 0x0004},
137 /* image right up */
138 {0xffff, 0xffff},
139 /* backlight=31/64 */
140 {0x6001, 0x00ff}, {0x603e, 0x0024}, {0x6034, 0x0025},
141}; 110};
142 111
143static struct validx tbl_640[] = { 112static struct validx tbl_640[] = {
@@ -166,7 +135,7 @@ static struct validx tbl_800[] = {
166 {0x60ff, 0x00dd}, {0x6020, 0x008c}, {0x6001, 0x00ff}, {0x6044, 0x0018}, 135 {0x60ff, 0x00dd}, {0x6020, 0x008c}, {0x6001, 0x00ff}, {0x6044, 0x0018},
167}; 136};
168 137
169static struct validx tbl_big_a[] = { 138static struct validx tbl_big1[] = {
170 {0x0002, 0x00c1}, {0x6000, 0x00ff}, {0x60f1, 0x00dd}, {0x6004, 0x00e0}, 139 {0x0002, 0x00c1}, {0x6000, 0x00ff}, {0x60f1, 0x00dd}, {0x6004, 0x00e0},
171 {0x6001, 0x00ff}, {0x6000, 0x0012}, {0x6000, 0x0000}, {0x6000, 0x0045}, 140 {0x6001, 0x00ff}, {0x6000, 0x0012}, {0x6000, 0x0000}, {0x6000, 0x0045},
172 {0x6000, 0x0010}, {0x6000, 0x0011}, {0x6011, 0x0017}, {0x6075, 0x0018}, 141 {0x6000, 0x0010}, {0x6000, 0x0011}, {0x6011, 0x0017}, {0x6075, 0x0018},
@@ -176,14 +145,14 @@ static struct validx tbl_big_a[] = {
176 {0x60c8, 0x00c0}, {0x6096, 0x00c1}, {0x6000, 0x008c}, 145 {0x60c8, 0x00c0}, {0x6096, 0x00c1}, {0x6000, 0x008c},
177}; 146};
178 147
179static struct validx tbl_big_b[] = { 148static struct validx tbl_big2[] = {
180 {0x603d, 0x0086}, {0x6000, 0x0050}, {0x6090, 0x0051}, {0x602c, 0x0052}, 149 {0x603d, 0x0086}, {0x6000, 0x0050}, {0x6090, 0x0051}, {0x602c, 0x0052},
181 {0x6000, 0x0053}, {0x6000, 0x0054}, {0x6088, 0x0055}, {0x6000, 0x0057}, 150 {0x6000, 0x0053}, {0x6000, 0x0054}, {0x6088, 0x0055}, {0x6000, 0x0057},
182 {0x6040, 0x005a}, {0x60f0, 0x005b}, {0x6001, 0x005c}, {0x6082, 0x00d3}, 151 {0x6040, 0x005a}, {0x60f0, 0x005b}, {0x6001, 0x005c}, {0x6082, 0x00d3},
183 {0x6000, 0x008e}, 152 {0x6000, 0x008e},
184}; 153};
185 154
186static struct validx tbl_big_c[] = { 155static struct validx tbl_big3[] = {
187 {0x6004, 0x00da}, {0x6000, 0x00e0}, {0x6067, 0x00e1}, {0x60ff, 0x00dd}, 156 {0x6004, 0x00da}, {0x6000, 0x00e0}, {0x6067, 0x00e1}, {0x60ff, 0x00dd},
188 {0x6001, 0x00ff}, {0x6000, 0x00ff}, {0x60f1, 0x00dd}, {0x6004, 0x00e0}, 157 {0x6001, 0x00ff}, {0x6000, 0x00ff}, {0x60f1, 0x00dd}, {0x6004, 0x00e0},
189 {0x6001, 0x00ff}, {0x6000, 0x0011}, {0x6000, 0x00ff}, {0x6010, 0x00c7}, 158 {0x6001, 0x00ff}, {0x6000, 0x0011}, {0x6000, 0x00ff}, {0x6010, 0x00c7},
@@ -223,17 +192,19 @@ void ov2640_init_settings(struct gspca_dev *gspca_dev)
223 sd->vcur.hue = 0; 192 sd->vcur.hue = 0;
224 sd->vcur.saturation = 128; 193 sd->vcur.saturation = 128;
225 sd->vcur.whitebal = 64; 194 sd->vcur.whitebal = 64;
195 sd->vcur.mirror = 0;
196 sd->vcur.flip = 0;
226 197
227 sd->vmax.backlight = 64; 198 sd->vmax.backlight = 64;
228 sd->vmax.brightness = 255; 199 sd->vmax.brightness = 255;
229 sd->vmax.sharpness = 31; 200 sd->vmax.sharpness = 31;
230 sd->vmax.contrast = 255; 201 sd->vmax.contrast = 255;
231 sd->vmax.gamma = 64; 202 sd->vmax.gamma = 64;
232 sd->vmax.hue = 255 + 1; 203 sd->vmax.hue = 254 + 2;
233 sd->vmax.saturation = 255; 204 sd->vmax.saturation = 255;
234 sd->vmax.whitebal = 128; 205 sd->vmax.whitebal = 128;
235 sd->vmax.mirror = 0; 206 sd->vmax.mirror = 1;
236 sd->vmax.flip = 0; 207 sd->vmax.flip = 1;
237 sd->vmax.AC50Hz = 0; 208 sd->vmax.AC50Hz = 0;
238 209
239 sd->dev_camera_settings = ov2640_camera_settings; 210 sd->dev_camera_settings = ov2640_camera_settings;
@@ -259,11 +230,11 @@ static int ov2640_init_at_startup(struct gspca_dev *gspca_dev)
259 230
260 common(gspca_dev); 231 common(gspca_dev);
261 232
262 ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0006, 1, dat_init2); 233 ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0006, 1, c61);
263 234
264 ctrl_out(gspca_dev, 0x40, 1, 0x00ef, 0x0006, 0, NULL); 235 ctrl_out(gspca_dev, 0x40, 1, 0x00ef, 0x0006, 0, NULL);
265 236
266 ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0000, 1, dat_init3); 237 ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0000, 1, c51);
267 238
268 ctrl_out(gspca_dev, 0x40, 1, 0x0051, 0x0000, 0, NULL); 239 ctrl_out(gspca_dev, 0x40, 1, 0x0051, 0x0000, 0, NULL);
269/* ctrl_out(gspca_dev, 0x40, 11, 0x0000, 0x0000, 0, NULL); */ 240/* ctrl_out(gspca_dev, 0x40, 11, 0x0000, 0x0000, 0, NULL); */
@@ -275,6 +246,8 @@ static int ov2640_init_pre_alt(struct gspca_dev *gspca_dev)
275{ 246{
276 struct sd *sd = (struct sd *) gspca_dev; 247 struct sd *sd = (struct sd *) gspca_dev;
277 248
249 sd->mirrorMask = 0;
250
278 sd->vold.backlight = -1; 251 sd->vold.backlight = -1;
279 sd->vold.brightness = -1; 252 sd->vold.brightness = -1;
280 sd->vold.sharpness = -1; 253 sd->vold.sharpness = -1;
@@ -283,6 +256,8 @@ static int ov2640_init_pre_alt(struct gspca_dev *gspca_dev)
283 sd->vold.gamma = -1; 256 sd->vold.gamma = -1;
284 sd->vold.hue = -1; 257 sd->vold.hue = -1;
285 sd->vold.whitebal = -1; 258 sd->vold.whitebal = -1;
259 sd->vold.mirror = -1;
260 sd->vold.flip = -1;
286 261
287 ov2640_init_post_alt(gspca_dev); 262 ov2640_init_post_alt(gspca_dev);
288 263
@@ -292,16 +267,16 @@ static int ov2640_init_pre_alt(struct gspca_dev *gspca_dev)
292static int ov2640_init_post_alt(struct gspca_dev *gspca_dev) 267static int ov2640_init_post_alt(struct gspca_dev *gspca_dev)
293{ 268{
294 s32 reso = gspca_dev->cam.cam_mode[(s32) gspca_dev->curr_mode].priv; 269 s32 reso = gspca_dev->cam.cam_mode[(s32) gspca_dev->curr_mode].priv;
295 s32 n; /* reserved for FETCH macros */ 270 s32 n; /* reserved for FETCH functions */
296 271
297 ctrl_out(gspca_dev, 0x40, 5, 0x0001, 0x0000, 0, NULL); 272 ctrl_out(gspca_dev, 0x40, 5, 0x0001, 0x0000, 0, NULL);
298 273
299 n = fetch_validx(gspca_dev, tbl_sensor_settings_common_a, 274 n = fetch_validx(gspca_dev, tbl_sensor_settings_common1,
300 ARRAY_SIZE(tbl_sensor_settings_common_a)); 275 ARRAY_SIZE(tbl_sensor_settings_common1));
301 ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 12, dat_post); 276 ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 12, dat_post);
302 common(gspca_dev); 277 common(gspca_dev);
303 keep_on_fetching_validx(gspca_dev, tbl_sensor_settings_common_a, 278 keep_on_fetching_validx(gspca_dev, tbl_sensor_settings_common1,
304 ARRAY_SIZE(tbl_sensor_settings_common_a), n); 279 ARRAY_SIZE(tbl_sensor_settings_common1), n);
305 280
306 switch (reso) { 281 switch (reso) {
307 case IMAGE_640: 282 case IMAGE_640:
@@ -316,18 +291,18 @@ static int ov2640_init_post_alt(struct gspca_dev *gspca_dev)
316 291
317 case IMAGE_1600: 292 case IMAGE_1600:
318 case IMAGE_1280: 293 case IMAGE_1280:
319 n = fetch_validx(gspca_dev, tbl_big_a, ARRAY_SIZE(tbl_big_a)); 294 n = fetch_validx(gspca_dev, tbl_big1, ARRAY_SIZE(tbl_big1));
320 295
321 if (reso == IMAGE_1280) { 296 if (reso == IMAGE_1280) {
322 n = fetch_validx(gspca_dev, tbl_big_b, 297 n = fetch_validx(gspca_dev, tbl_big2,
323 ARRAY_SIZE(tbl_big_b)); 298 ARRAY_SIZE(tbl_big2));
324 } else { 299 } else {
325 ctrl_out(gspca_dev, 0x40, 1, 0x601d, 0x0086, 0, NULL); 300 ctrl_out(gspca_dev, 0x40, 1, 0x601d, 0x0086, 0, NULL);
326 ctrl_out(gspca_dev, 0x40, 1, 0x6001, 0x00d7, 0, NULL); 301 ctrl_out(gspca_dev, 0x40, 1, 0x6001, 0x00d7, 0, NULL);
327 ctrl_out(gspca_dev, 0x40, 1, 0x6082, 0x00d3, 0, NULL); 302 ctrl_out(gspca_dev, 0x40, 1, 0x6082, 0x00d3, 0, NULL);
328 } 303 }
329 304
330 n = fetch_validx(gspca_dev, tbl_big_c, ARRAY_SIZE(tbl_big_c)); 305 n = fetch_validx(gspca_dev, tbl_big3, ARRAY_SIZE(tbl_big3));
331 306
332 if (reso == IMAGE_1280) { 307 if (reso == IMAGE_1280) {
333 ctrl_out(gspca_dev, 0x40, 1, 0x6001, 0x00ff, 0, NULL); 308 ctrl_out(gspca_dev, 0x40, 1, 0x6001, 0x00ff, 0, NULL);
@@ -343,20 +318,8 @@ static int ov2640_init_post_alt(struct gspca_dev *gspca_dev)
343 break; 318 break;
344 } 319 }
345 320
346 n = fetch_validx(gspca_dev, tbl_sensor_settings_common_b, 321 n = fetch_validx(gspca_dev, tbl_sensor_settings_common2,
347 ARRAY_SIZE(tbl_sensor_settings_common_b)); 322 ARRAY_SIZE(tbl_sensor_settings_common2));
348 ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0000, 1, c50);
349 keep_on_fetching_validx(gspca_dev, tbl_sensor_settings_common_b,
350 ARRAY_SIZE(tbl_sensor_settings_common_b), n);
351 ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x8004, 1, c28);
352 keep_on_fetching_validx(gspca_dev, tbl_sensor_settings_common_b,
353 ARRAY_SIZE(tbl_sensor_settings_common_b), n);
354 ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x8004, 1, ca8);
355 keep_on_fetching_validx(gspca_dev, tbl_sensor_settings_common_b,
356 ARRAY_SIZE(tbl_sensor_settings_common_b), n);
357 ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0000, 1, c50);
358 keep_on_fetching_validx(gspca_dev, tbl_sensor_settings_common_b,
359 ARRAY_SIZE(tbl_sensor_settings_common_b), n);
360 323
361 ov2640_camera_settings(gspca_dev); 324 ov2640_camera_settings(gspca_dev);
362 325
@@ -393,18 +356,20 @@ static int ov2640_camera_settings(struct gspca_dev *gspca_dev)
393 s32 sat = sd->vcur.saturation; 356 s32 sat = sd->vcur.saturation;
394 s32 hue = sd->vcur.hue; 357 s32 hue = sd->vcur.hue;
395 s32 wbal = sd->vcur.whitebal; 358 s32 wbal = sd->vcur.whitebal;
359 s32 mirror = (((sd->vcur.mirror > 0) ^ sd->mirrorMask) == 0);
360 s32 flip = (((sd->vcur.flip > 0) ^ sd->mirrorMask) == 0);
396 361
397 if (backlight != sd->vold.backlight) { 362 if (backlight != sd->vold.backlight) {
363 /* No sd->vold.backlight=backlight; (to be done again later) */
398 if (backlight < 0 || backlight > sd->vmax.backlight) 364 if (backlight < 0 || backlight > sd->vmax.backlight)
399 backlight = 0; 365 backlight = 0;
400 366
401 ctrl_out(gspca_dev, 0x40, 1, 0x6001 , 0x00ff, 367 ctrl_out(gspca_dev, 0x40, 1, 0x6001 , 0x00ff,
402 0, NULL); 368 0, NULL);
403 ctrl_out(gspca_dev, 0x40, 1, 0x601f + backlight , 0x0024, 369 ctrl_out(gspca_dev, 0x40, 1, 0x601e + backlight , 0x0024,
404 0, NULL); 370 0, NULL);
405 ctrl_out(gspca_dev, 0x40, 1, 0x601f + backlight - 10, 0x0025, 371 ctrl_out(gspca_dev, 0x40, 1, 0x601e + backlight - 10, 0x0025,
406 0, NULL); 372 0, NULL);
407 /* No sd->vold.backlight=backlight; (to be done again later) */
408 } 373 }
409 374
410 if (bright != sd->vold.brightness) { 375 if (bright != sd->vold.brightness) {
@@ -466,7 +431,7 @@ static int ov2640_camera_settings(struct gspca_dev *gspca_dev)
466 ctrl_out(gspca_dev, 0x40, 1, 0x6002 , 0x007c, 0, NULL); 431 ctrl_out(gspca_dev, 0x40, 1, 0x6002 , 0x007c, 0, NULL);
467 ctrl_out(gspca_dev, 0x40, 1, 0x6000 + hue * (hue < 255), 0x007d, 432 ctrl_out(gspca_dev, 0x40, 1, 0x6000 + hue * (hue < 255), 0x007d,
468 0, NULL); 433 0, NULL);
469 if (hue >= sd->vmax.hue) 434 if (hue >= 255)
470 sd->swapRB = 1; 435 sd->swapRB = 1;
471 else 436 else
472 sd->swapRB = 0; 437 sd->swapRB = 0;
@@ -482,14 +447,33 @@ static int ov2640_camera_settings(struct gspca_dev *gspca_dev)
482 ctrl_out(gspca_dev, 0x40, 1, 0x6000 + gam, 0x007d, 0, NULL); 447 ctrl_out(gspca_dev, 0x40, 1, 0x6000 + gam, 0x007d, 0, NULL);
483 } 448 }
484 449
450 if (mirror != sd->vold.mirror || flip != sd->vold.flip) {
451 sd->vold.mirror = mirror;
452 sd->vold.flip = flip;
453
454 mirror = 0x80 * mirror;
455 ctrl_out(gspca_dev, 0x40, 1, 0x6001, 0x00ff, 0, NULL);
456 ctrl_out(gspca_dev, 0x40, 1, 0x6000, 0x8004, 0, NULL);
457 ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x8004, 1, c28);
458 ctrl_out(gspca_dev, 0x40, 1, 0x6028 + mirror, 0x0004, 0, NULL);
459
460 flip = 0x50 * flip + mirror;
461 ctrl_out(gspca_dev, 0x40, 1, 0x6001, 0x00ff, 0, NULL);
462 ctrl_out(gspca_dev, 0x40, 1, 0x6000, 0x8004, 0, NULL);
463 ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x8004, 1, ca8);
464 ctrl_out(gspca_dev, 0x40, 1, 0x6028 + flip, 0x0004, 0, NULL);
465
466 ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0000, 1, c50);
467 }
468
485 if (backlight != sd->vold.backlight) { 469 if (backlight != sd->vold.backlight) {
486 sd->vold.backlight = backlight; 470 sd->vold.backlight = backlight;
487 471
488 ctrl_out(gspca_dev, 0x40, 1, 0x6001 , 0x00ff, 472 ctrl_out(gspca_dev, 0x40, 1, 0x6001 , 0x00ff,
489 0, NULL); 473 0, NULL);
490 ctrl_out(gspca_dev, 0x40, 1, 0x601f + backlight , 0x0024, 474 ctrl_out(gspca_dev, 0x40, 1, 0x601e + backlight , 0x0024,
491 0, NULL); 475 0, NULL);
492 ctrl_out(gspca_dev, 0x40, 1, 0x601f + backlight - 10, 0x0025, 476 ctrl_out(gspca_dev, 0x40, 1, 0x601e + backlight - 10, 0x0025,
493 0, NULL); 477 0, NULL);
494 } 478 }
495 479
diff --git a/drivers/media/video/gspca/gl860/gl860-ov9655.c b/drivers/media/video/gspca/gl860/gl860-ov9655.c
index eda3346f939c..d412694c50af 100644
--- a/drivers/media/video/gspca/gl860/gl860-ov9655.c
+++ b/drivers/media/video/gspca/gl860/gl860-ov9655.c
@@ -1,7 +1,6 @@
1/* @file gl860-ov9655.c 1/* Subdriver for the GL860 chip with the OV9655 sensor
2 * @author Olivier LORIN, from logs done by Simon (Sur3) and Almighurt 2 * Author Olivier LORIN, from logs done by Simon (Sur3) and Almighurt
3 * on dsd's weblog 3 * on dsd's weblog
4 * @date 2009-08-27
5 * 4 *
6 * This program is free software; you can redistribute it and/or modify 5 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by 6 * it under the terms of the GNU General Public License as published by
@@ -104,14 +103,14 @@ static u8 *tbl_800[] = {
104}; 103};
105 104
106static u8 c04[] = {0x04}; 105static u8 c04[] = {0x04};
107static u8 dat_post_1[] = "\x04\x00\x10\x20\xa1\x00\x00\x02"; 106static u8 dat_post1[] = "\x04\x00\x10\x20\xa1\x00\x00\x02";
108static u8 dat_post_2[] = "\x10\x10\xc1\x02"; 107static u8 dat_post2[] = "\x10\x10\xc1\x02";
109static u8 dat_post_3[] = "\x04\x00\x10\x7c\xa1\x00\x00\x04"; 108static u8 dat_post3[] = "\x04\x00\x10\x7c\xa1\x00\x00\x04";
110static u8 dat_post_4[] = "\x10\x02\xc1\x06"; 109static u8 dat_post4[] = "\x10\x02\xc1\x06";
111static u8 dat_post_5[] = "\x04\x00\x10\x7b\xa1\x00\x00\x08"; 110static u8 dat_post5[] = "\x04\x00\x10\x7b\xa1\x00\x00\x08";
112static u8 dat_post_6[] = "\x10\x10\xc1\x05"; 111static u8 dat_post6[] = "\x10\x10\xc1\x05";
113static u8 dat_post_7[] = "\x04\x00\x10\x7c\xa1\x00\x00\x08"; 112static u8 dat_post7[] = "\x04\x00\x10\x7c\xa1\x00\x00\x08";
114static u8 dat_post_8[] = "\x04\x00\x10\x7c\xa1\x00\x00\x09"; 113static u8 dat_post8[] = "\x04\x00\x10\x7c\xa1\x00\x00\x09";
115 114
116static struct validx tbl_init_post_alt[] = { 115static struct validx tbl_init_post_alt[] = {
117 {0x6032, 0x00ff}, {0x6032, 0x00ff}, {0x6032, 0x00ff}, {0x603c, 0x00ff}, 116 {0x6032, 0x00ff}, {0x6032, 0x00ff}, {0x6032, 0x00ff}, {0x603c, 0x00ff},
@@ -212,7 +211,7 @@ static int ov9655_init_pre_alt(struct gspca_dev *gspca_dev)
212static int ov9655_init_post_alt(struct gspca_dev *gspca_dev) 211static int ov9655_init_post_alt(struct gspca_dev *gspca_dev)
213{ 212{
214 s32 reso = gspca_dev->cam.cam_mode[(s32) gspca_dev->curr_mode].priv; 213 s32 reso = gspca_dev->cam.cam_mode[(s32) gspca_dev->curr_mode].priv;
215 s32 n; /* reserved for FETCH macros */ 214 s32 n; /* reserved for FETCH functions */
216 s32 i; 215 s32 i;
217 u8 **tbl; 216 u8 **tbl;
218 217
@@ -243,7 +242,7 @@ static int ov9655_init_post_alt(struct gspca_dev *gspca_dev)
243 ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x801e, 1, c04); 242 ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x801e, 1, c04);
244 keep_on_fetching_validx(gspca_dev, tbl_init_post_alt, 243 keep_on_fetching_validx(gspca_dev, tbl_init_post_alt,
245 ARRAY_SIZE(tbl_init_post_alt), n); 244 ARRAY_SIZE(tbl_init_post_alt), n);
246 ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post_1); 245 ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post1);
247 keep_on_fetching_validx(gspca_dev, tbl_init_post_alt, 246 keep_on_fetching_validx(gspca_dev, tbl_init_post_alt,
248 ARRAY_SIZE(tbl_init_post_alt), n); 247 ARRAY_SIZE(tbl_init_post_alt), n);
249 248
@@ -259,7 +258,7 @@ static int ov9655_init_post_alt(struct gspca_dev *gspca_dev)
259 ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x801e, 1, c04); 258 ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x801e, 1, c04);
260 keep_on_fetching_validx(gspca_dev, tbl_init_post_alt, 259 keep_on_fetching_validx(gspca_dev, tbl_init_post_alt,
261 ARRAY_SIZE(tbl_init_post_alt), n); 260 ARRAY_SIZE(tbl_init_post_alt), n);
262 ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post_1); 261 ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post1);
263 keep_on_fetching_validx(gspca_dev, tbl_init_post_alt, 262 keep_on_fetching_validx(gspca_dev, tbl_init_post_alt,
264 ARRAY_SIZE(tbl_init_post_alt), n); 263 ARRAY_SIZE(tbl_init_post_alt), n);
265 264
@@ -270,18 +269,18 @@ static int ov9655_init_post_alt(struct gspca_dev *gspca_dev)
270 keep_on_fetching_validx(gspca_dev, tbl_init_post_alt, 269 keep_on_fetching_validx(gspca_dev, tbl_init_post_alt,
271 ARRAY_SIZE(tbl_init_post_alt), n); 270 ARRAY_SIZE(tbl_init_post_alt), n);
272 271
273 ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post_1); 272 ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post1);
274 273
275 ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 4, dat_post_2); 274 ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 4, dat_post2);
276 ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post_3); 275 ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post3);
277 276
278 ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 4, dat_post_4); 277 ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 4, dat_post4);
279 ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post_5); 278 ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post5);
280 279
281 ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 4, dat_post_6); 280 ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 4, dat_post6);
282 ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post_7); 281 ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post7);
283 282
284 ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post_8); 283 ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post8);
285 284
286 ov9655_camera_settings(gspca_dev); 285 ov9655_camera_settings(gspca_dev);
287 286
diff --git a/drivers/media/video/gspca/gl860/gl860.c b/drivers/media/video/gspca/gl860/gl860.c
index 6ef59ac7f502..a695e0ae13c2 100644
--- a/drivers/media/video/gspca/gl860/gl860.c
+++ b/drivers/media/video/gspca/gl860/gl860.c
@@ -1,9 +1,7 @@
1/* @file gl860.c 1/* GSPCA subdrivers for Genesys Logic webcams with the GL860 chip
2 * @date 2009-08-27 2 * Subdriver core
3 * 3 *
4 * Genesys Logic webcam with gl860 subdrivers 4 * 2009/09/24 Olivier Lorin <o.lorin@laposte.net>
5 *
6 * Driver by Olivier Lorin <o.lorin@laposte.net>
7 * GSPCA by Jean-Francois Moine <http://moinejf.free.fr> 5 * GSPCA by Jean-Francois Moine <http://moinejf.free.fr>
8 * Thanks BUGabundo and Malmostoso for your amazing help! 6 * Thanks BUGabundo and Malmostoso for your amazing help!
9 * 7 *
@@ -23,8 +21,8 @@
23#include "gspca.h" 21#include "gspca.h"
24#include "gl860.h" 22#include "gl860.h"
25 23
26MODULE_AUTHOR("Olivier Lorin <lorin@laposte.net>"); 24MODULE_AUTHOR("Olivier Lorin <o.lorin@laposte.net>");
27MODULE_DESCRIPTION("GSPCA/Genesys Logic GL860 USB Camera Driver"); 25MODULE_DESCRIPTION("Genesys Logic USB PC Camera Driver");
28MODULE_LICENSE("GPL"); 26MODULE_LICENSE("GPL");
29 27
30/*======================== static function declarations ====================*/ 28/*======================== static function declarations ====================*/
@@ -38,7 +36,7 @@ static int sd_isoc_init(struct gspca_dev *gspca_dev);
38static int sd_start(struct gspca_dev *gspca_dev); 36static int sd_start(struct gspca_dev *gspca_dev);
39static void sd_stop0(struct gspca_dev *gspca_dev); 37static void sd_stop0(struct gspca_dev *gspca_dev);
40static void sd_pkt_scan(struct gspca_dev *gspca_dev, 38static void sd_pkt_scan(struct gspca_dev *gspca_dev,
41 struct gspca_frame *frame, u8 *data, s32 len); 39 u8 *data, int len);
42static void sd_callback(struct gspca_dev *gspca_dev); 40static void sd_callback(struct gspca_dev *gspca_dev);
43 41
44static int gl860_guess_sensor(struct gspca_dev *gspca_dev, 42static int gl860_guess_sensor(struct gspca_dev *gspca_dev,
@@ -53,7 +51,7 @@ MODULE_PARM_DESC(AC50Hz, " Does AC power frequency is 50Hz? (0/1)");
53static char sensor[7]; 51static char sensor[7];
54module_param_string(sensor, sensor, sizeof(sensor), 0644); 52module_param_string(sensor, sensor, sizeof(sensor), 0644);
55MODULE_PARM_DESC(sensor, 53MODULE_PARM_DESC(sensor,
56 " Driver sensor ('MI1320'/'MI2020'/'OV9655'/'OV2640'/'')"); 54 " Driver sensor ('MI1320'/'MI2020'/'OV9655'/'OV2640')");
57 55
58/*============================ webcam controls =============================*/ 56/*============================ webcam controls =============================*/
59 57
@@ -156,7 +154,7 @@ static int gl860_build_control_table(struct gspca_dev *gspca_dev)
156 SET_MY_CTRL(V4L2_CID_VFLIP, 154 SET_MY_CTRL(V4L2_CID_VFLIP,
157 V4L2_CTRL_TYPE_BOOLEAN, "Flip", flip) 155 V4L2_CTRL_TYPE_BOOLEAN, "Flip", flip)
158 SET_MY_CTRL(V4L2_CID_POWER_LINE_FREQUENCY, 156 SET_MY_CTRL(V4L2_CID_POWER_LINE_FREQUENCY,
159 V4L2_CTRL_TYPE_BOOLEAN, "50Hz", AC50Hz) 157 V4L2_CTRL_TYPE_BOOLEAN, "AC power 50Hz", AC50Hz)
160 158
161 return nCtrls; 159 return nCtrls;
162} 160}
@@ -435,7 +433,7 @@ static void sd_stop0(struct gspca_dev *gspca_dev)
435 433
436/* This function is called when an image is being received */ 434/* This function is called when an image is being received */
437static void sd_pkt_scan(struct gspca_dev *gspca_dev, 435static void sd_pkt_scan(struct gspca_dev *gspca_dev,
438 struct gspca_frame *frame, u8 *data, s32 len) 436 u8 *data, int len)
439{ 437{
440 struct sd *sd = (struct sd *) gspca_dev; 438 struct sd *sd = (struct sd *) gspca_dev;
441 static s32 nSkipped; 439 static s32 nSkipped;
@@ -447,11 +445,11 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
447 /* Test only against 0202h, so endianess does not matter */ 445 /* Test only against 0202h, so endianess does not matter */
448 switch (*(s16 *) data) { 446 switch (*(s16 *) data) {
449 case 0x0202: /* End of frame, start a new one */ 447 case 0x0202: /* End of frame, start a new one */
450 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, data, 0); 448 gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
451 nSkipped = 0; 449 nSkipped = 0;
452 if (sd->nbIm >= 0 && sd->nbIm < 10) 450 if (sd->nbIm >= 0 && sd->nbIm < 10)
453 sd->nbIm++; 451 sd->nbIm++;
454 gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, 0); 452 gspca_frame_add(gspca_dev, FIRST_PACKET, NULL, 0);
455 break; 453 break;
456 454
457 default: 455 default:
@@ -466,7 +464,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
466 nSkipped = nToSkip + 1; 464 nSkipped = nToSkip + 1;
467 } 465 }
468 gspca_frame_add(gspca_dev, 466 gspca_frame_add(gspca_dev,
469 INTER_PACKET, frame, data, len); 467 INTER_PACKET, data, len);
470 } 468 }
471 break; 469 break;
472 } 470 }
@@ -702,6 +700,7 @@ static int gl860_guess_sensor(struct gspca_dev *gspca_dev,
702 ctrl_out(gspca_dev, 0x40, 1, 0x006a, 0x000d, 0, NULL); 700 ctrl_out(gspca_dev, 0x40, 1, 0x006a, 0x000d, 0, NULL);
703 msleep(56); 701 msleep(56);
704 702
703 PDEBUG(D_PROBE, "probing for sensor MI2020 or OVXXXX");
705 nOV = 0; 704 nOV = 0;
706 for (ntry = 0; ntry < 4; ntry++) { 705 for (ntry = 0; ntry < 4; ntry++) {
707 ctrl_out(gspca_dev, 0x40, 1, 0x0040, 0x0000, 0, NULL); 706 ctrl_out(gspca_dev, 0x40, 1, 0x0040, 0x0000, 0, NULL);
@@ -711,14 +710,14 @@ static int gl860_guess_sensor(struct gspca_dev *gspca_dev,
711 ctrl_out(gspca_dev, 0x40, 1, 0x7a00, 0x8030, 0, NULL); 710 ctrl_out(gspca_dev, 0x40, 1, 0x7a00, 0x8030, 0, NULL);
712 msleep(10); 711 msleep(10);
713 ctrl_in(gspca_dev, 0xc0, 2, 0x7a00, 0x8030, 1, &probe); 712 ctrl_in(gspca_dev, 0xc0, 2, 0x7a00, 0x8030, 1, &probe);
714 PDEBUG(D_PROBE, "1st probe=%02x", probe); 713 PDEBUG(D_PROBE, "probe=0x%02x", probe);
715 if (probe == 0xff) 714 if (probe == 0xff)
716 nOV++; 715 nOV++;
717 } 716 }
718 717
719 if (nOV) { 718 if (nOV) {
720 PDEBUG(D_PROBE, "0xff -> sensor OVXXXX"); 719 PDEBUG(D_PROBE, "0xff -> OVXXXX");
721 PDEBUG(D_PROBE, "Probing for sensor OV2640 or OV9655"); 720 PDEBUG(D_PROBE, "probing for sensor OV2640 or OV9655");
722 721
723 nb26 = nb96 = 0; 722 nb26 = nb96 = 0;
724 for (ntry = 0; ntry < 4; ntry++) { 723 for (ntry = 0; ntry < 4; ntry++) {
@@ -728,40 +727,38 @@ static int gl860_guess_sensor(struct gspca_dev *gspca_dev,
728 ctrl_out(gspca_dev, 0x40, 1, 0x6000, 0x800a, 727 ctrl_out(gspca_dev, 0x40, 1, 0x6000, 0x800a,
729 0, NULL); 728 0, NULL);
730 msleep(10); 729 msleep(10);
730
731 /* Wait for 26(OV2640) or 96(OV9655) */ 731 /* Wait for 26(OV2640) or 96(OV9655) */
732 ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x800a, 732 ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x800a,
733 1, &probe); 733 1, &probe);
734 734
735 PDEBUG(D_PROBE, "2nd probe=%02x", probe);
736 if (probe == 0x00)
737 nb26++;
738 if (probe == 0x26 || probe == 0x40) { 735 if (probe == 0x26 || probe == 0x40) {
736 PDEBUG(D_PROBE,
737 "probe=0x%02x -> OV2640",
738 probe);
739 sd->sensor = ID_OV2640; 739 sd->sensor = ID_OV2640;
740 nb26 += 4; 740 nb26 += 4;
741 break; 741 break;
742 } 742 }
743 if (probe == 0x96 || probe == 0x55) { 743 if (probe == 0x96 || probe == 0x55) {
744 PDEBUG(D_PROBE,
745 "probe=0x%02x -> OV9655",
746 probe);
744 sd->sensor = ID_OV9655; 747 sd->sensor = ID_OV9655;
745 nb96 += 4; 748 nb96 += 4;
746 break; 749 break;
747 } 750 }
751 PDEBUG(D_PROBE, "probe=0x%02x", probe);
752 if (probe == 0x00)
753 nb26++;
748 if (probe == 0xff) 754 if (probe == 0xff)
749 nb96++; 755 nb96++;
750 msleep(3); 756 msleep(3);
751 } 757 }
752 if (nb26 < 4 && nb96 < 4) { 758 if (nb26 < 4 && nb96 < 4)
753 PDEBUG(D_PROBE, "No relevant answer ");
754 PDEBUG(D_PROBE, "* 1.3Mpixels -> use OV9655");
755 PDEBUG(D_PROBE, "* 2.0Mpixels -> use OV2640");
756 PDEBUG(D_PROBE,
757 "To force a sensor, add that line to "
758 "/etc/modprobe.d/options.conf:");
759 PDEBUG(D_PROBE, "options gspca_gl860 "
760 "sensor=\"OV2640\" or \"OV9655\"");
761 return -1; 759 return -1;
762 } 760 } else {
763 } else { /* probe = 0 */ 761 PDEBUG(D_PROBE, "Not any 0xff -> MI2020");
764 PDEBUG(D_PROBE, "No 0xff -> sensor MI2020");
765 sd->sensor = ID_MI2020; 762 sd->sensor = ID_MI2020;
766 } 763 }
767 } 764 }
diff --git a/drivers/media/video/gspca/gl860/gl860.h b/drivers/media/video/gspca/gl860/gl860.h
index cef4e24c1e61..305061ff8387 100644
--- a/drivers/media/video/gspca/gl860/gl860.h
+++ b/drivers/media/video/gspca/gl860/gl860.h
@@ -1,6 +1,7 @@
1/* @file gl860.h 1/* GSPCA subdrivers for Genesys Logic webcams with the GL860 chip
2 * @author Olivier LORIN, tiré du pilote Syntek par Nicolas VIVIEN 2 * Subdriver declarations
3 * @date 2009-08-27 3 *
4 * 2009/10/14 Olivier LORIN <o.lorin@laposte.net>
4 * 5 *
5 * This program is free software; you can redistribute it and/or modify 6 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by 7 * it under the terms of the GNU General Public License as published by
diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c
index 23d3fb776918..4076f8e5a6fc 100644
--- a/drivers/media/video/gspca/gspca.c
+++ b/drivers/media/video/gspca/gspca.c
@@ -47,7 +47,7 @@ MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>");
47MODULE_DESCRIPTION("GSPCA USB Camera Driver"); 47MODULE_DESCRIPTION("GSPCA USB Camera Driver");
48MODULE_LICENSE("GPL"); 48MODULE_LICENSE("GPL");
49 49
50#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 7, 0) 50#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 8, 0)
51 51
52#ifdef GSPCA_DEBUG 52#ifdef GSPCA_DEBUG
53int gspca_debug = D_ERR | D_PROBE; 53int gspca_debug = D_ERR | D_PROBE;
@@ -74,7 +74,7 @@ static void PDEBUG_MODE(char *txt, __u32 pixfmt, int w, int h)
74#define PDEBUG_MODE(txt, pixfmt, w, h) 74#define PDEBUG_MODE(txt, pixfmt, w, h)
75#endif 75#endif
76 76
77/* specific memory types - !! should different from V4L2_MEMORY_xxx */ 77/* specific memory types - !! should be different from V4L2_MEMORY_xxx */
78#define GSPCA_MEMORY_NO 0 /* V4L2_MEMORY_xxx starts from 1 */ 78#define GSPCA_MEMORY_NO 0 /* V4L2_MEMORY_xxx starts from 1 */
79#define GSPCA_MEMORY_READ 7 79#define GSPCA_MEMORY_READ 7
80 80
@@ -126,7 +126,6 @@ EXPORT_SYMBOL(gspca_get_i_frame);
126static void fill_frame(struct gspca_dev *gspca_dev, 126static void fill_frame(struct gspca_dev *gspca_dev,
127 struct urb *urb) 127 struct urb *urb)
128{ 128{
129 struct gspca_frame *frame;
130 u8 *data; /* address of data in the iso message */ 129 u8 *data; /* address of data in the iso message */
131 int i, len, st; 130 int i, len, st;
132 cam_pkt_op pkt_scan; 131 cam_pkt_op pkt_scan;
@@ -135,21 +134,16 @@ static void fill_frame(struct gspca_dev *gspca_dev,
135 if (urb->status == -ESHUTDOWN) 134 if (urb->status == -ESHUTDOWN)
136 return; /* disconnection */ 135 return; /* disconnection */
137#ifdef CONFIG_PM 136#ifdef CONFIG_PM
138 if (!gspca_dev->frozen) 137 if (gspca_dev->frozen)
138 return;
139#endif 139#endif
140 PDEBUG(D_ERR|D_PACK, "urb status: %d", urb->status); 140 PDEBUG(D_ERR|D_PACK, "urb status: %d", urb->status);
141 return; 141 urb->status = 0;
142 goto resubmit;
142 } 143 }
143 pkt_scan = gspca_dev->sd_desc->pkt_scan; 144 pkt_scan = gspca_dev->sd_desc->pkt_scan;
144 for (i = 0; i < urb->number_of_packets; i++) { 145 for (i = 0; i < urb->number_of_packets; i++) {
145 146
146 /* check the availability of the frame buffer */
147 frame = gspca_get_i_frame(gspca_dev);
148 if (!frame) {
149 gspca_dev->last_packet_type = DISCARD_PACKET;
150 break;
151 }
152
153 /* check the packet status and length */ 147 /* check the packet status and length */
154 len = urb->iso_frame_desc[i].actual_length; 148 len = urb->iso_frame_desc[i].actual_length;
155 if (len == 0) { 149 if (len == 0) {
@@ -171,9 +165,10 @@ static void fill_frame(struct gspca_dev *gspca_dev,
171 i, urb->iso_frame_desc[i].offset, len); 165 i, urb->iso_frame_desc[i].offset, len);
172 data = (u8 *) urb->transfer_buffer 166 data = (u8 *) urb->transfer_buffer
173 + urb->iso_frame_desc[i].offset; 167 + urb->iso_frame_desc[i].offset;
174 pkt_scan(gspca_dev, frame, data, len); 168 pkt_scan(gspca_dev, data, len);
175 } 169 }
176 170
171resubmit:
177 /* resubmit the URB */ 172 /* resubmit the URB */
178 st = usb_submit_urb(urb, GFP_ATOMIC); 173 st = usb_submit_urb(urb, GFP_ATOMIC);
179 if (st < 0) 174 if (st < 0)
@@ -201,7 +196,6 @@ static void isoc_irq(struct urb *urb)
201static void bulk_irq(struct urb *urb) 196static void bulk_irq(struct urb *urb)
202{ 197{
203 struct gspca_dev *gspca_dev = (struct gspca_dev *) urb->context; 198 struct gspca_dev *gspca_dev = (struct gspca_dev *) urb->context;
204 struct gspca_frame *frame;
205 int st; 199 int st;
206 200
207 PDEBUG(D_PACK, "bulk irq"); 201 PDEBUG(D_PACK, "bulk irq");
@@ -212,29 +206,22 @@ static void bulk_irq(struct urb *urb)
212 break; 206 break;
213 case -ESHUTDOWN: 207 case -ESHUTDOWN:
214 return; /* disconnection */ 208 return; /* disconnection */
215 case -ECONNRESET:
216 urb->status = 0;
217 break;
218 default: 209 default:
219#ifdef CONFIG_PM 210#ifdef CONFIG_PM
220 if (!gspca_dev->frozen) 211 if (gspca_dev->frozen)
212 return;
221#endif 213#endif
222 PDEBUG(D_ERR|D_PACK, "urb status: %d", urb->status); 214 PDEBUG(D_ERR|D_PACK, "urb status: %d", urb->status);
223 return; 215 urb->status = 0;
216 goto resubmit;
224 } 217 }
225 218
226 /* check the availability of the frame buffer */ 219 PDEBUG(D_PACK, "packet l:%d", urb->actual_length);
227 frame = gspca_get_i_frame(gspca_dev); 220 gspca_dev->sd_desc->pkt_scan(gspca_dev,
228 if (!frame) { 221 urb->transfer_buffer,
229 gspca_dev->last_packet_type = DISCARD_PACKET; 222 urb->actual_length);
230 } else {
231 PDEBUG(D_PACK, "packet l:%d", urb->actual_length);
232 gspca_dev->sd_desc->pkt_scan(gspca_dev,
233 frame,
234 urb->transfer_buffer,
235 urb->actual_length);
236 }
237 223
224resubmit:
238 /* resubmit the URB */ 225 /* resubmit the URB */
239 if (gspca_dev->cam.bulk_nurbs != 0) { 226 if (gspca_dev->cam.bulk_nurbs != 0) {
240 st = usb_submit_urb(urb, GFP_ATOMIC); 227 st = usb_submit_urb(urb, GFP_ATOMIC);
@@ -255,24 +242,27 @@ static void bulk_irq(struct urb *urb)
255 * DISCARD_PACKET invalidates the whole frame. 242 * DISCARD_PACKET invalidates the whole frame.
256 * On LAST_PACKET, a new frame is returned. 243 * On LAST_PACKET, a new frame is returned.
257 */ 244 */
258struct gspca_frame *gspca_frame_add(struct gspca_dev *gspca_dev, 245void gspca_frame_add(struct gspca_dev *gspca_dev,
259 enum gspca_packet_type packet_type, 246 enum gspca_packet_type packet_type,
260 struct gspca_frame *frame, 247 const u8 *data,
261 const __u8 *data, 248 int len)
262 int len)
263{ 249{
250 struct gspca_frame *frame;
264 int i, j; 251 int i, j;
265 252
266 PDEBUG(D_PACK, "add t:%d l:%d", packet_type, len); 253 PDEBUG(D_PACK, "add t:%d l:%d", packet_type, len);
267 254
255 /* check the availability of the frame buffer */
256 frame = gspca_dev->cur_frame;
257 if ((frame->v4l2_buf.flags & BUF_ALL_FLAGS)
258 != V4L2_BUF_FLAG_QUEUED) {
259 gspca_dev->last_packet_type = DISCARD_PACKET;
260 return;
261 }
262
268 /* when start of a new frame, if the current frame buffer 263 /* when start of a new frame, if the current frame buffer
269 * is not queued, discard the whole frame */ 264 * is not queued, discard the whole frame */
270 if (packet_type == FIRST_PACKET) { 265 if (packet_type == FIRST_PACKET) {
271 if ((frame->v4l2_buf.flags & BUF_ALL_FLAGS)
272 != V4L2_BUF_FLAG_QUEUED) {
273 gspca_dev->last_packet_type = DISCARD_PACKET;
274 return frame;
275 }
276 frame->data_end = frame->data; 266 frame->data_end = frame->data;
277 jiffies_to_timeval(get_jiffies_64(), 267 jiffies_to_timeval(get_jiffies_64(),
278 &frame->v4l2_buf.timestamp); 268 &frame->v4l2_buf.timestamp);
@@ -280,7 +270,7 @@ struct gspca_frame *gspca_frame_add(struct gspca_dev *gspca_dev,
280 } else if (gspca_dev->last_packet_type == DISCARD_PACKET) { 270 } else if (gspca_dev->last_packet_type == DISCARD_PACKET) {
281 if (packet_type == LAST_PACKET) 271 if (packet_type == LAST_PACKET)
282 gspca_dev->last_packet_type = packet_type; 272 gspca_dev->last_packet_type = packet_type;
283 return frame; 273 return;
284 } 274 }
285 275
286 /* append the packet to the frame buffer */ 276 /* append the packet to the frame buffer */
@@ -312,9 +302,9 @@ struct gspca_frame *gspca_frame_add(struct gspca_dev *gspca_dev,
312 i, 302 i,
313 gspca_dev->fr_o); 303 gspca_dev->fr_o);
314 j = gspca_dev->fr_queue[i]; 304 j = gspca_dev->fr_queue[i];
315 frame = &gspca_dev->frame[j]; 305 gspca_dev->cur_frame = &gspca_dev->frame[j];
316 } 306 }
317 return frame; 307 return;
318} 308}
319EXPORT_SYMBOL(gspca_frame_add); 309EXPORT_SYMBOL(gspca_frame_add);
320 310
@@ -395,6 +385,7 @@ static int frame_alloc(struct gspca_dev *gspca_dev,
395 frame->v4l2_buf.m.offset = i * frsz; 385 frame->v4l2_buf.m.offset = i * frsz;
396 } 386 }
397 gspca_dev->fr_i = gspca_dev->fr_o = gspca_dev->fr_q = 0; 387 gspca_dev->fr_i = gspca_dev->fr_o = gspca_dev->fr_q = 0;
388 gspca_dev->cur_frame = &gspca_dev->frame[0];
398 gspca_dev->last_packet_type = DISCARD_PACKET; 389 gspca_dev->last_packet_type = DISCARD_PACKET;
399 gspca_dev->sequence = 0; 390 gspca_dev->sequence = 0;
400 return 0; 391 return 0;
@@ -475,10 +466,18 @@ static struct usb_host_endpoint *get_ep(struct gspca_dev *gspca_dev)
475 xfer = gspca_dev->cam.bulk ? USB_ENDPOINT_XFER_BULK 466 xfer = gspca_dev->cam.bulk ? USB_ENDPOINT_XFER_BULK
476 : USB_ENDPOINT_XFER_ISOC; 467 : USB_ENDPOINT_XFER_ISOC;
477 i = gspca_dev->alt; /* previous alt setting */ 468 i = gspca_dev->alt; /* previous alt setting */
478 while (--i >= 0) { 469 if (gspca_dev->cam.reverse_alts) {
479 ep = alt_xfer(&intf->altsetting[i], xfer); 470 while (++i < gspca_dev->nbalt) {
480 if (ep) 471 ep = alt_xfer(&intf->altsetting[i], xfer);
481 break; 472 if (ep)
473 break;
474 }
475 } else {
476 while (--i >= 0) {
477 ep = alt_xfer(&intf->altsetting[i], xfer);
478 if (ep)
479 break;
480 }
482 } 481 }
483 if (ep == NULL) { 482 if (ep == NULL) {
484 err("no transfer endpoint found"); 483 err("no transfer endpoint found");
@@ -599,7 +598,11 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev)
599 598
600 /* set the higher alternate setting and 599 /* set the higher alternate setting and
601 * loop until urb submit succeeds */ 600 * loop until urb submit succeeds */
602 gspca_dev->alt = gspca_dev->nbalt; 601 if (gspca_dev->cam.reverse_alts)
602 gspca_dev->alt = 0;
603 else
604 gspca_dev->alt = gspca_dev->nbalt;
605
603 if (gspca_dev->sd_desc->isoc_init) { 606 if (gspca_dev->sd_desc->isoc_init) {
604 ret = gspca_dev->sd_desc->isoc_init(gspca_dev); 607 ret = gspca_dev->sd_desc->isoc_init(gspca_dev);
605 if (ret < 0) 608 if (ret < 0)
@@ -641,15 +644,19 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev)
641 } 644 }
642 if (ret >= 0) 645 if (ret >= 0)
643 break; 646 break;
644 PDEBUG(D_ERR|D_STREAM,
645 "usb_submit_urb alt %d err %d", gspca_dev->alt, ret);
646 gspca_dev->streaming = 0; 647 gspca_dev->streaming = 0;
647 destroy_urbs(gspca_dev); 648 destroy_urbs(gspca_dev);
648 if (ret != -ENOSPC) 649 if (ret != -ENOSPC) {
650 PDEBUG(D_ERR|D_STREAM,
651 "usb_submit_urb alt %d err %d",
652 gspca_dev->alt, ret);
649 goto out; 653 goto out;
654 }
650 655
651 /* the bandwidth is not wide enough 656 /* the bandwidth is not wide enough
652 * negociate or try a lower alternate setting */ 657 * negociate or try a lower alternate setting */
658 PDEBUG(D_ERR|D_STREAM,
659 "bandwidth not wide enough - trying again");
653 msleep(20); /* wait for kill complete */ 660 msleep(20); /* wait for kill complete */
654 if (gspca_dev->sd_desc->isoc_nego) { 661 if (gspca_dev->sd_desc->isoc_nego) {
655 ret = gspca_dev->sd_desc->isoc_nego(gspca_dev); 662 ret = gspca_dev->sd_desc->isoc_nego(gspca_dev);
@@ -980,7 +987,7 @@ static void gspca_release(struct video_device *vfd)
980{ 987{
981 struct gspca_dev *gspca_dev = container_of(vfd, struct gspca_dev, vdev); 988 struct gspca_dev *gspca_dev = container_of(vfd, struct gspca_dev, vdev);
982 989
983 PDEBUG(D_STREAM, "device released"); 990 PDEBUG(D_PROBE, "/dev/video%d released", gspca_dev->vdev.num);
984 991
985 kfree(gspca_dev->usb_buf); 992 kfree(gspca_dev->usb_buf);
986 kfree(gspca_dev); 993 kfree(gspca_dev);
@@ -991,7 +998,7 @@ static int dev_open(struct file *file)
991 struct gspca_dev *gspca_dev; 998 struct gspca_dev *gspca_dev;
992 int ret; 999 int ret;
993 1000
994 PDEBUG(D_STREAM, "%s open", current->comm); 1001 PDEBUG(D_STREAM, "[%s] open", current->comm);
995 gspca_dev = (struct gspca_dev *) video_devdata(file); 1002 gspca_dev = (struct gspca_dev *) video_devdata(file);
996 if (mutex_lock_interruptible(&gspca_dev->queue_lock)) 1003 if (mutex_lock_interruptible(&gspca_dev->queue_lock))
997 return -ERESTARTSYS; 1004 return -ERESTARTSYS;
@@ -1037,7 +1044,7 @@ static int dev_close(struct file *file)
1037{ 1044{
1038 struct gspca_dev *gspca_dev = file->private_data; 1045 struct gspca_dev *gspca_dev = file->private_data;
1039 1046
1040 PDEBUG(D_STREAM, "%s close", current->comm); 1047 PDEBUG(D_STREAM, "[%s] close", current->comm);
1041 if (mutex_lock_interruptible(&gspca_dev->queue_lock)) 1048 if (mutex_lock_interruptible(&gspca_dev->queue_lock))
1042 return -ERESTARTSYS; 1049 return -ERESTARTSYS;
1043 gspca_dev->users--; 1050 gspca_dev->users--;
@@ -1138,10 +1145,13 @@ static int vidioc_queryctrl(struct file *file, void *priv,
1138 } 1145 }
1139 } else { 1146 } else {
1140 ctrls = get_ctrl(gspca_dev, id); 1147 ctrls = get_ctrl(gspca_dev, id);
1148 i = ctrls - gspca_dev->sd_desc->ctrls;
1141 } 1149 }
1142 if (ctrls == NULL) 1150 if (ctrls == NULL)
1143 return -EINVAL; 1151 return -EINVAL;
1144 memcpy(q_ctrl, ctrls, sizeof *q_ctrl); 1152 memcpy(q_ctrl, ctrls, sizeof *q_ctrl);
1153 if (gspca_dev->ctrl_inac & (1 << i))
1154 q_ctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
1145 return 0; 1155 return 0;
1146} 1156}
1147 1157
@@ -1603,7 +1613,7 @@ static int dev_mmap(struct file *file, struct vm_area_struct *vma)
1603 size -= PAGE_SIZE; 1613 size -= PAGE_SIZE;
1604 } 1614 }
1605 1615
1606 vma->vm_ops = &gspca_vm_ops; 1616 vma->vm_ops = (struct vm_operations_struct *) &gspca_vm_ops;
1607 vma->vm_private_data = frame; 1617 vma->vm_private_data = frame;
1608 gspca_vm_open(vma); 1618 gspca_vm_open(vma);
1609 ret = 0; 1619 ret = 0;
@@ -2001,11 +2011,15 @@ int gspca_dev_probe(struct usb_interface *intf,
2001 PDEBUG(D_PROBE, "probing %04x:%04x", id->idVendor, id->idProduct); 2011 PDEBUG(D_PROBE, "probing %04x:%04x", id->idVendor, id->idProduct);
2002 2012
2003 /* we don't handle multi-config cameras */ 2013 /* we don't handle multi-config cameras */
2004 if (dev->descriptor.bNumConfigurations != 1) 2014 if (dev->descriptor.bNumConfigurations != 1) {
2015 PDEBUG(D_ERR, "Too many config");
2005 return -ENODEV; 2016 return -ENODEV;
2017 }
2006 interface = &intf->cur_altsetting->desc; 2018 interface = &intf->cur_altsetting->desc;
2007 if (interface->bInterfaceNumber > 0) 2019 if (interface->bInterfaceNumber > 0) {
2020 PDEBUG(D_ERR, "intf != 0");
2008 return -ENODEV; 2021 return -ENODEV;
2022 }
2009 2023
2010 /* create the device */ 2024 /* create the device */
2011 if (dev_size < sizeof *gspca_dev) 2025 if (dev_size < sizeof *gspca_dev)
@@ -2059,7 +2073,7 @@ int gspca_dev_probe(struct usb_interface *intf,
2059 } 2073 }
2060 2074
2061 usb_set_intfdata(intf, gspca_dev); 2075 usb_set_intfdata(intf, gspca_dev);
2062 PDEBUG(D_PROBE, "probe ok"); 2076 PDEBUG(D_PROBE, "/dev/video%d created", gspca_dev->vdev.num);
2063 return 0; 2077 return 0;
2064out: 2078out:
2065 kfree(gspca_dev->usb_buf); 2079 kfree(gspca_dev->usb_buf);
@@ -2078,6 +2092,7 @@ void gspca_disconnect(struct usb_interface *intf)
2078{ 2092{
2079 struct gspca_dev *gspca_dev = usb_get_intfdata(intf); 2093 struct gspca_dev *gspca_dev = usb_get_intfdata(intf);
2080 2094
2095 PDEBUG(D_PROBE, "/dev/video%d disconnect", gspca_dev->vdev.num);
2081 mutex_lock(&gspca_dev->usb_lock); 2096 mutex_lock(&gspca_dev->usb_lock);
2082 gspca_dev->present = 0; 2097 gspca_dev->present = 0;
2083 2098
@@ -2096,7 +2111,7 @@ void gspca_disconnect(struct usb_interface *intf)
2096 /* (this will call gspca_release() immediatly or on last close) */ 2111 /* (this will call gspca_release() immediatly or on last close) */
2097 video_unregister_device(&gspca_dev->vdev); 2112 video_unregister_device(&gspca_dev->vdev);
2098 2113
2099 PDEBUG(D_PROBE, "disconnect complete"); 2114/* PDEBUG(D_PROBE, "disconnect complete"); */
2100} 2115}
2101EXPORT_SYMBOL(gspca_disconnect); 2116EXPORT_SYMBOL(gspca_disconnect);
2102 2117
diff --git a/drivers/media/video/gspca/gspca.h b/drivers/media/video/gspca/gspca.h
index 70b1fd830876..181617355ec3 100644
--- a/drivers/media/video/gspca/gspca.h
+++ b/drivers/media/video/gspca/gspca.h
@@ -58,6 +58,7 @@ struct cam {
58 u8 npkt; /* number of packets in an ISOC message 58 u8 npkt; /* number of packets in an ISOC message
59 * 0 is the default value: 32 packets */ 59 * 0 is the default value: 32 packets */
60 u32 input_flags; /* value for ENUM_INPUT status flags */ 60 u32 input_flags; /* value for ENUM_INPUT status flags */
61 char reverse_alts; /* Alt settings are in high to low order */
61}; 62};
62 63
63struct gspca_dev; 64struct gspca_dev;
@@ -78,8 +79,7 @@ typedef int (*cam_streamparm_op) (struct gspca_dev *,
78typedef int (*cam_qmnu_op) (struct gspca_dev *, 79typedef int (*cam_qmnu_op) (struct gspca_dev *,
79 struct v4l2_querymenu *); 80 struct v4l2_querymenu *);
80typedef void (*cam_pkt_op) (struct gspca_dev *gspca_dev, 81typedef void (*cam_pkt_op) (struct gspca_dev *gspca_dev,
81 struct gspca_frame *frame, 82 u8 *data,
82 __u8 *data,
83 int len); 83 int len);
84 84
85struct ctrl { 85struct ctrl {
@@ -142,6 +142,7 @@ struct gspca_dev {
142 struct cam cam; /* device information */ 142 struct cam cam; /* device information */
143 const struct sd_desc *sd_desc; /* subdriver description */ 143 const struct sd_desc *sd_desc; /* subdriver description */
144 unsigned ctrl_dis; /* disabled controls (bit map) */ 144 unsigned ctrl_dis; /* disabled controls (bit map) */
145 unsigned ctrl_inac; /* inactive controls (bit map) */
145 146
146#define USB_BUF_SZ 64 147#define USB_BUF_SZ 64
147 __u8 *usb_buf; /* buffer for USB exchanges */ 148 __u8 *usb_buf; /* buffer for USB exchanges */
@@ -149,6 +150,7 @@ struct gspca_dev {
149 150
150 __u8 *frbuf; /* buffer for nframes */ 151 __u8 *frbuf; /* buffer for nframes */
151 struct gspca_frame frame[GSPCA_MAX_FRAMES]; 152 struct gspca_frame frame[GSPCA_MAX_FRAMES];
153 struct gspca_frame *cur_frame; /* frame beeing filled */
152 __u32 frsz; /* frame size */ 154 __u32 frsz; /* frame size */
153 char nframes; /* number of frames */ 155 char nframes; /* number of frames */
154 char fr_i; /* frame being filled */ 156 char fr_i; /* frame being filled */
@@ -189,11 +191,10 @@ int gspca_dev_probe(struct usb_interface *intf,
189 int dev_size, 191 int dev_size,
190 struct module *module); 192 struct module *module);
191void gspca_disconnect(struct usb_interface *intf); 193void gspca_disconnect(struct usb_interface *intf);
192struct gspca_frame *gspca_frame_add(struct gspca_dev *gspca_dev, 194void gspca_frame_add(struct gspca_dev *gspca_dev,
193 enum gspca_packet_type packet_type, 195 enum gspca_packet_type packet_type,
194 struct gspca_frame *frame, 196 const u8 *data,
195 const __u8 *data, 197 int len);
196 int len);
197struct gspca_frame *gspca_get_i_frame(struct gspca_dev *gspca_dev); 198struct gspca_frame *gspca_get_i_frame(struct gspca_dev *gspca_dev);
198#ifdef CONFIG_PM 199#ifdef CONFIG_PM
199int gspca_suspend(struct usb_interface *intf, pm_message_t message); 200int gspca_suspend(struct usb_interface *intf, pm_message_t message);
diff --git a/drivers/media/video/gspca/jeilinj.c b/drivers/media/video/gspca/jeilinj.c
index a11c97ebeb0f..2019b04f9235 100644
--- a/drivers/media/video/gspca/jeilinj.c
+++ b/drivers/media/video/gspca/jeilinj.c
@@ -181,11 +181,9 @@ static void jlj_dostream(struct work_struct *work)
181{ 181{
182 struct sd *dev = container_of(work, struct sd, work_struct); 182 struct sd *dev = container_of(work, struct sd, work_struct);
183 struct gspca_dev *gspca_dev = &dev->gspca_dev; 183 struct gspca_dev *gspca_dev = &dev->gspca_dev;
184 struct gspca_frame *frame;
185 int blocks_left; /* 0x200-sized blocks remaining in current frame. */ 184 int blocks_left; /* 0x200-sized blocks remaining in current frame. */
186 int size_in_blocks; 185 int size_in_blocks;
187 int act_len; 186 int act_len;
188 int discarding = 0; /* true if we failed to get space for frame. */
189 int packet_type; 187 int packet_type;
190 int ret; 188 int ret;
191 u8 *buffer; 189 u8 *buffer;
@@ -196,15 +194,6 @@ static void jlj_dostream(struct work_struct *work)
196 goto quit_stream; 194 goto quit_stream;
197 } 195 }
198 while (gspca_dev->present && gspca_dev->streaming) { 196 while (gspca_dev->present && gspca_dev->streaming) {
199 if (!gspca_dev->present)
200 goto quit_stream;
201 /* Start a new frame, and add the JPEG header, first thing */
202 frame = gspca_get_i_frame(gspca_dev);
203 if (frame && !discarding)
204 gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
205 dev->jpeg_hdr, JPEG_HDR_SZ);
206 else
207 discarding = 1;
208 /* 197 /*
209 * Now request data block 0. Line 0 reports the size 198 * Now request data block 0. Line 0 reports the size
210 * to download, in blocks of size 0x200, and also tells the 199 * to download, in blocks of size 0x200, and also tells the
@@ -222,14 +211,15 @@ static void jlj_dostream(struct work_struct *work)
222 size_in_blocks = buffer[0x0a]; 211 size_in_blocks = buffer[0x0a];
223 blocks_left = buffer[0x0a] - 1; 212 blocks_left = buffer[0x0a] - 1;
224 PDEBUG(D_STREAM, "blocks_left = 0x%x", blocks_left); 213 PDEBUG(D_STREAM, "blocks_left = 0x%x", blocks_left);
225 packet_type = INTER_PACKET; 214
226 if (frame && !discarding) 215 /* Start a new frame, and add the JPEG header, first thing */
227 /* Toss line 0 of data block 0, keep the rest. */ 216 gspca_frame_add(gspca_dev, FIRST_PACKET,
228 gspca_frame_add(gspca_dev, packet_type, 217 dev->jpeg_hdr, JPEG_HDR_SZ);
229 frame, buffer + FRAME_HEADER_LEN, 218 /* Toss line 0 of data block 0, keep the rest. */
219 gspca_frame_add(gspca_dev, INTER_PACKET,
220 buffer + FRAME_HEADER_LEN,
230 JEILINJ_MAX_TRANSFER - FRAME_HEADER_LEN); 221 JEILINJ_MAX_TRANSFER - FRAME_HEADER_LEN);
231 else 222
232 discarding = 1;
233 while (blocks_left > 0) { 223 while (blocks_left > 0) {
234 if (!gspca_dev->present) 224 if (!gspca_dev->present)
235 goto quit_stream; 225 goto quit_stream;
@@ -246,12 +236,8 @@ static void jlj_dostream(struct work_struct *work)
246 packet_type = LAST_PACKET; 236 packet_type = LAST_PACKET;
247 else 237 else
248 packet_type = INTER_PACKET; 238 packet_type = INTER_PACKET;
249 if (frame && !discarding) 239 gspca_frame_add(gspca_dev, packet_type,
250 gspca_frame_add(gspca_dev, packet_type, 240 buffer, JEILINJ_MAX_TRANSFER);
251 frame, buffer,
252 JEILINJ_MAX_TRANSFER);
253 else
254 discarding = 1;
255 } 241 }
256 } 242 }
257quit_stream: 243quit_stream:
diff --git a/drivers/media/video/gspca/m5602/m5602_core.c b/drivers/media/video/gspca/m5602/m5602_core.c
index 7f1e5415850b..844fc1d886d1 100644
--- a/drivers/media/video/gspca/m5602/m5602_core.c
+++ b/drivers/media/video/gspca/m5602/m5602_core.c
@@ -274,8 +274,7 @@ static int m5602_start_transfer(struct gspca_dev *gspca_dev)
274} 274}
275 275
276static void m5602_urb_complete(struct gspca_dev *gspca_dev, 276static void m5602_urb_complete(struct gspca_dev *gspca_dev,
277 struct gspca_frame *frame, 277 u8 *data, int len)
278 __u8 *data, int len)
279{ 278{
280 struct sd *sd = (struct sd *) gspca_dev; 279 struct sd *sd = (struct sd *) gspca_dev;
281 280
@@ -295,19 +294,27 @@ static void m5602_urb_complete(struct gspca_dev *gspca_dev,
295 len -= 6; 294 len -= 6;
296 295
297 /* Complete the last frame (if any) */ 296 /* Complete the last frame (if any) */
298 frame = gspca_frame_add(gspca_dev, LAST_PACKET, 297 gspca_frame_add(gspca_dev, LAST_PACKET,
299 frame, data, 0); 298 NULL, 0);
300 sd->frame_count++; 299 sd->frame_count++;
301 300
302 /* Create a new frame */ 301 /* Create a new frame */
303 gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, len); 302 gspca_frame_add(gspca_dev, FIRST_PACKET, data, len);
304 303
305 PDEBUG(D_FRAM, "Starting new frame %d", 304 PDEBUG(D_FRAM, "Starting new frame %d",
306 sd->frame_count); 305 sd->frame_count);
307 306
308 } else { 307 } else {
309 int cur_frame_len = frame->data_end - frame->data; 308 struct gspca_frame *frame;
309 int cur_frame_len;
310 310
311 frame = gspca_get_i_frame(gspca_dev);
312 if (frame == NULL) {
313 gspca_dev->last_packet_type = DISCARD_PACKET;
314 return;
315 }
316
317 cur_frame_len = frame->data_end - frame->data;
311 /* Remove urb header */ 318 /* Remove urb header */
312 data += 4; 319 data += 4;
313 len -= 4; 320 len -= 4;
@@ -316,12 +323,12 @@ static void m5602_urb_complete(struct gspca_dev *gspca_dev,
316 PDEBUG(D_FRAM, "Continuing frame %d copying %d bytes", 323 PDEBUG(D_FRAM, "Continuing frame %d copying %d bytes",
317 sd->frame_count, len); 324 sd->frame_count, len);
318 325
319 gspca_frame_add(gspca_dev, INTER_PACKET, frame, 326 gspca_frame_add(gspca_dev, INTER_PACKET,
320 data, len); 327 data, len);
321 } else if (frame->v4l2_buf.length - cur_frame_len > 0) { 328 } else if (frame->v4l2_buf.length - cur_frame_len > 0) {
322 /* Add the remaining data up to frame size */ 329 /* Add the remaining data up to frame size */
323 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, 330 gspca_frame_add(gspca_dev, INTER_PACKET, data,
324 frame->v4l2_buf.length - cur_frame_len); 331 frame->v4l2_buf.length - cur_frame_len);
325 } 332 }
326 } 333 }
327} 334}
diff --git a/drivers/media/video/gspca/mars.c b/drivers/media/video/gspca/mars.c
index de769caf013d..9cf8d68c71bf 100644
--- a/drivers/media/video/gspca/mars.c
+++ b/drivers/media/video/gspca/mars.c
@@ -325,8 +325,7 @@ static void sd_stop0(struct gspca_dev *gspca_dev)
325} 325}
326 326
327static void sd_pkt_scan(struct gspca_dev *gspca_dev, 327static void sd_pkt_scan(struct gspca_dev *gspca_dev,
328 struct gspca_frame *frame, /* target */ 328 u8 *data, /* isoc packet */
329 __u8 *data, /* isoc packet */
330 int len) /* iso packet length */ 329 int len) /* iso packet length */
331{ 330{
332 struct sd *sd = (struct sd *) gspca_dev; 331 struct sd *sd = (struct sd *) gspca_dev;
@@ -348,11 +347,11 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
348 || data[5 + p] == 0x67) { 347 || data[5 + p] == 0x67) {
349 PDEBUG(D_PACK, "sof offset: %d len: %d", 348 PDEBUG(D_PACK, "sof offset: %d len: %d",
350 p, len); 349 p, len);
351 frame = gspca_frame_add(gspca_dev, LAST_PACKET, 350 gspca_frame_add(gspca_dev, LAST_PACKET,
352 frame, data, p); 351 data, p);
353 352
354 /* put the JPEG header */ 353 /* put the JPEG header */
355 gspca_frame_add(gspca_dev, FIRST_PACKET, frame, 354 gspca_frame_add(gspca_dev, FIRST_PACKET,
356 sd->jpeg_hdr, JPEG_HDR_SZ); 355 sd->jpeg_hdr, JPEG_HDR_SZ);
357 data += p + 16; 356 data += p + 16;
358 len -= p + 16; 357 len -= p + 16;
@@ -360,7 +359,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
360 } 359 }
361 } 360 }
362 } 361 }
363 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); 362 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
364} 363}
365 364
366static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) 365static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
diff --git a/drivers/media/video/gspca/mr97310a.c b/drivers/media/video/gspca/mr97310a.c
index f8328b9efae5..126d968dd9e0 100644
--- a/drivers/media/video/gspca/mr97310a.c
+++ b/drivers/media/video/gspca/mr97310a.c
@@ -1,23 +1,30 @@
1/* 1/*
2 * Mars MR97310A library 2 * Mars MR97310A library
3 * 3 *
4 * The original mr97310a driver, which supported the Aiptek Pencam VGA+, is
4 * Copyright (C) 2009 Kyle Guinn <elyk03@gmail.com> 5 * Copyright (C) 2009 Kyle Guinn <elyk03@gmail.com>
5 * 6 *
6 * Support for the MR97310A cameras in addition to the Aiptek Pencam VGA+ 7 * Support for the MR97310A cameras in addition to the Aiptek Pencam VGA+
7 * and for the routines for detecting and classifying these various cameras, 8 * and for the routines for detecting and classifying these various cameras,
9 * is Copyright (C) 2009 Theodore Kilgore <kilgota@auburn.edu>
8 * 10 *
11 * Support for the control settings for the CIF cameras is
12 * Copyright (C) 2009 Hans de Goede <hdgoede@redhat.com> and
13 * Thomas Kaiser <thomas@kaiser-linux.li>
14 *
15 * Support for the control settings for the VGA cameras is
9 * Copyright (C) 2009 Theodore Kilgore <kilgota@auburn.edu> 16 * Copyright (C) 2009 Theodore Kilgore <kilgota@auburn.edu>
10 * 17 *
11 * Acknowledgements: 18 * Several previously unsupported cameras are owned and have been tested by
19 * Hans de Goede <hdgoede@redhat.com> and
20 * Thomas Kaiser <thomas@kaiser-linux.li> and
21 * Theodore Kilgore <kilgota@auburn.edu> and
22 * Edmond Rodriguez <erodrig_97@yahoo.com> and
23 * Aurelien Jacobs <aurel@gnuage.org>
12 * 24 *
13 * The MR97311A support in gspca/mars.c has been helpful in understanding some 25 * The MR97311A support in gspca/mars.c has been helpful in understanding some
14 * of the registers in these cameras. 26 * of the registers in these cameras.
15 * 27 *
16 * Hans de Goede <hdgoede@redhat.com> and
17 * Thomas Kaiser <thomas@kaiser-linux.li>
18 * have assisted with their experience. Each of them has also helped by
19 * testing a previously unsupported camera.
20 *
21 * This program is free software; you can redistribute it and/or modify 28 * This program is free software; you can redistribute it and/or modify
22 * it under the terms of the GNU General Public License as published by 29 * it under the terms of the GNU General Public License as published by
23 * the Free Software Foundation; either version 2 of the License, or 30 * the Free Software Foundation; either version 2 of the License, or
@@ -40,11 +47,9 @@
40#define CAM_TYPE_CIF 0 47#define CAM_TYPE_CIF 0
41#define CAM_TYPE_VGA 1 48#define CAM_TYPE_VGA 1
42 49
43#define MR97310A_BRIGHTNESS_MIN -254
44#define MR97310A_BRIGHTNESS_MAX 255
45#define MR97310A_BRIGHTNESS_DEFAULT 0 50#define MR97310A_BRIGHTNESS_DEFAULT 0
46 51
47#define MR97310A_EXPOSURE_MIN 300 52#define MR97310A_EXPOSURE_MIN 0
48#define MR97310A_EXPOSURE_MAX 4095 53#define MR97310A_EXPOSURE_MAX 4095
49#define MR97310A_EXPOSURE_DEFAULT 1000 54#define MR97310A_EXPOSURE_DEFAULT 1000
50 55
@@ -52,6 +57,10 @@
52#define MR97310A_GAIN_MAX 31 57#define MR97310A_GAIN_MAX 31
53#define MR97310A_GAIN_DEFAULT 25 58#define MR97310A_GAIN_DEFAULT 25
54 59
60#define MR97310A_MIN_CLOCKDIV_MIN 3
61#define MR97310A_MIN_CLOCKDIV_MAX 8
62#define MR97310A_MIN_CLOCKDIV_DEFAULT 3
63
55MODULE_AUTHOR("Kyle Guinn <elyk03@gmail.com>," 64MODULE_AUTHOR("Kyle Guinn <elyk03@gmail.com>,"
56 "Theodore Kilgore <kilgota@auburn.edu>"); 65 "Theodore Kilgore <kilgota@auburn.edu>");
57MODULE_DESCRIPTION("GSPCA/Mars-Semi MR97310A USB Camera Driver"); 66MODULE_DESCRIPTION("GSPCA/Mars-Semi MR97310A USB Camera Driver");
@@ -69,10 +78,12 @@ struct sd {
69 u8 cam_type; /* 0 is CIF and 1 is VGA */ 78 u8 cam_type; /* 0 is CIF and 1 is VGA */
70 u8 sensor_type; /* We use 0 and 1 here, too. */ 79 u8 sensor_type; /* We use 0 and 1 here, too. */
71 u8 do_lcd_stop; 80 u8 do_lcd_stop;
81 u8 adj_colors;
72 82
73 int brightness; 83 int brightness;
74 u16 exposure; 84 u16 exposure;
75 u8 gain; 85 u8 gain;
86 u8 min_clockdiv;
76}; 87};
77 88
78struct sensor_w_data { 89struct sensor_w_data {
@@ -82,26 +93,31 @@ struct sensor_w_data {
82 int len; 93 int len;
83}; 94};
84 95
96static void sd_stopN(struct gspca_dev *gspca_dev);
85static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); 97static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
86static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); 98static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
87static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val); 99static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val);
88static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val); 100static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val);
89static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val); 101static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val);
90static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val); 102static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val);
103static int sd_setmin_clockdiv(struct gspca_dev *gspca_dev, __s32 val);
104static int sd_getmin_clockdiv(struct gspca_dev *gspca_dev, __s32 *val);
91static void setbrightness(struct gspca_dev *gspca_dev); 105static void setbrightness(struct gspca_dev *gspca_dev);
92static void setexposure(struct gspca_dev *gspca_dev); 106static void setexposure(struct gspca_dev *gspca_dev);
93static void setgain(struct gspca_dev *gspca_dev); 107static void setgain(struct gspca_dev *gspca_dev);
94 108
95/* V4L2 controls supported by the driver */ 109/* V4L2 controls supported by the driver */
96static struct ctrl sd_ctrls[] = { 110static struct ctrl sd_ctrls[] = {
111/* Separate brightness control description for Argus QuickClix as it has
112 different limits from the other mr97310a cameras */
97 { 113 {
98#define BRIGHTNESS_IDX 0 114#define NORM_BRIGHTNESS_IDX 0
99 { 115 {
100 .id = V4L2_CID_BRIGHTNESS, 116 .id = V4L2_CID_BRIGHTNESS,
101 .type = V4L2_CTRL_TYPE_INTEGER, 117 .type = V4L2_CTRL_TYPE_INTEGER,
102 .name = "Brightness", 118 .name = "Brightness",
103 .minimum = MR97310A_BRIGHTNESS_MIN, 119 .minimum = -254,
104 .maximum = MR97310A_BRIGHTNESS_MAX, 120 .maximum = 255,
105 .step = 1, 121 .step = 1,
106 .default_value = MR97310A_BRIGHTNESS_DEFAULT, 122 .default_value = MR97310A_BRIGHTNESS_DEFAULT,
107 .flags = 0, 123 .flags = 0,
@@ -110,7 +126,22 @@ static struct ctrl sd_ctrls[] = {
110 .get = sd_getbrightness, 126 .get = sd_getbrightness,
111 }, 127 },
112 { 128 {
113#define EXPOSURE_IDX 1 129#define ARGUS_QC_BRIGHTNESS_IDX 1
130 {
131 .id = V4L2_CID_BRIGHTNESS,
132 .type = V4L2_CTRL_TYPE_INTEGER,
133 .name = "Brightness",
134 .minimum = 0,
135 .maximum = 15,
136 .step = 1,
137 .default_value = MR97310A_BRIGHTNESS_DEFAULT,
138 .flags = 0,
139 },
140 .set = sd_setbrightness,
141 .get = sd_getbrightness,
142 },
143 {
144#define EXPOSURE_IDX 2
114 { 145 {
115 .id = V4L2_CID_EXPOSURE, 146 .id = V4L2_CID_EXPOSURE,
116 .type = V4L2_CTRL_TYPE_INTEGER, 147 .type = V4L2_CTRL_TYPE_INTEGER,
@@ -125,7 +156,7 @@ static struct ctrl sd_ctrls[] = {
125 .get = sd_getexposure, 156 .get = sd_getexposure,
126 }, 157 },
127 { 158 {
128#define GAIN_IDX 2 159#define GAIN_IDX 3
129 { 160 {
130 .id = V4L2_CID_GAIN, 161 .id = V4L2_CID_GAIN,
131 .type = V4L2_CTRL_TYPE_INTEGER, 162 .type = V4L2_CTRL_TYPE_INTEGER,
@@ -139,6 +170,21 @@ static struct ctrl sd_ctrls[] = {
139 .set = sd_setgain, 170 .set = sd_setgain,
140 .get = sd_getgain, 171 .get = sd_getgain,
141 }, 172 },
173 {
174#define MIN_CLOCKDIV_IDX 4
175 {
176 .id = V4L2_CID_PRIVATE_BASE,
177 .type = V4L2_CTRL_TYPE_INTEGER,
178 .name = "Minimum Clock Divider",
179 .minimum = MR97310A_MIN_CLOCKDIV_MIN,
180 .maximum = MR97310A_MIN_CLOCKDIV_MAX,
181 .step = 1,
182 .default_value = MR97310A_MIN_CLOCKDIV_DEFAULT,
183 .flags = 0,
184 },
185 .set = sd_setmin_clockdiv,
186 .get = sd_getmin_clockdiv,
187 },
142}; 188};
143 189
144static const struct v4l2_pix_format vga_mode[] = { 190static const struct v4l2_pix_format vga_mode[] = {
@@ -230,12 +276,17 @@ static int sensor_write1(struct gspca_dev *gspca_dev, u8 reg, u8 data)
230 int rc; 276 int rc;
231 277
232 buf = data; 278 buf = data;
233 rc = sensor_write_reg(gspca_dev, reg, 0x01, &buf, 1); 279 if (sd->cam_type == CAM_TYPE_CIF) {
280 rc = sensor_write_reg(gspca_dev, reg, 0x01, &buf, 1);
281 confirm_reg = sd->sensor_type ? 0x13 : 0x11;
282 } else {
283 rc = sensor_write_reg(gspca_dev, reg, 0x00, &buf, 1);
284 confirm_reg = 0x11;
285 }
234 if (rc < 0) 286 if (rc < 0)
235 return rc; 287 return rc;
236 288
237 buf = 0x01; 289 buf = 0x01;
238 confirm_reg = sd->sensor_type ? 0x13 : 0x11;
239 rc = sensor_write_reg(gspca_dev, confirm_reg, 0x00, &buf, 1); 290 rc = sensor_write_reg(gspca_dev, confirm_reg, 0x00, &buf, 1);
240 if (rc < 0) 291 if (rc < 0)
241 return rc; 292 return rc;
@@ -243,18 +294,26 @@ static int sensor_write1(struct gspca_dev *gspca_dev, u8 reg, u8 data)
243 return 0; 294 return 0;
244} 295}
245 296
246static int cam_get_response16(struct gspca_dev *gspca_dev) 297static int cam_get_response16(struct gspca_dev *gspca_dev, u8 reg, int verbose)
247{ 298{
248 __u8 *data = gspca_dev->usb_buf;
249 int err_code; 299 int err_code;
250 300
251 data[0] = 0x21; 301 gspca_dev->usb_buf[0] = reg;
252 err_code = mr_write(gspca_dev, 1); 302 err_code = mr_write(gspca_dev, 1);
253 if (err_code < 0) 303 if (err_code < 0)
254 return err_code; 304 return err_code;
255 305
256 err_code = mr_read(gspca_dev, 16); 306 err_code = mr_read(gspca_dev, 16);
257 return err_code; 307 if (err_code < 0)
308 return err_code;
309
310 if (verbose)
311 PDEBUG(D_PROBE, "Register: %02x reads %02x%02x%02x", reg,
312 gspca_dev->usb_buf[0],
313 gspca_dev->usb_buf[1],
314 gspca_dev->usb_buf[2]);
315
316 return 0;
258} 317}
259 318
260static int zero_the_pointer(struct gspca_dev *gspca_dev) 319static int zero_the_pointer(struct gspca_dev *gspca_dev)
@@ -264,7 +323,7 @@ static int zero_the_pointer(struct gspca_dev *gspca_dev)
264 u8 status = 0; 323 u8 status = 0;
265 int tries = 0; 324 int tries = 0;
266 325
267 err_code = cam_get_response16(gspca_dev); 326 err_code = cam_get_response16(gspca_dev, 0x21, 0);
268 if (err_code < 0) 327 if (err_code < 0)
269 return err_code; 328 return err_code;
270 329
@@ -275,7 +334,7 @@ static int zero_the_pointer(struct gspca_dev *gspca_dev)
275 if (err_code < 0) 334 if (err_code < 0)
276 return err_code; 335 return err_code;
277 336
278 err_code = cam_get_response16(gspca_dev); 337 err_code = cam_get_response16(gspca_dev, 0x21, 0);
279 if (err_code < 0) 338 if (err_code < 0)
280 return err_code; 339 return err_code;
281 340
@@ -285,7 +344,7 @@ static int zero_the_pointer(struct gspca_dev *gspca_dev)
285 if (err_code < 0) 344 if (err_code < 0)
286 return err_code; 345 return err_code;
287 346
288 err_code = cam_get_response16(gspca_dev); 347 err_code = cam_get_response16(gspca_dev, 0x21, 0);
289 if (err_code < 0) 348 if (err_code < 0)
290 return err_code; 349 return err_code;
291 350
@@ -295,7 +354,7 @@ static int zero_the_pointer(struct gspca_dev *gspca_dev)
295 if (err_code < 0) 354 if (err_code < 0)
296 return err_code; 355 return err_code;
297 356
298 err_code = cam_get_response16(gspca_dev); 357 err_code = cam_get_response16(gspca_dev, 0x21, 0);
299 if (err_code < 0) 358 if (err_code < 0)
300 return err_code; 359 return err_code;
301 360
@@ -306,7 +365,7 @@ static int zero_the_pointer(struct gspca_dev *gspca_dev)
306 return err_code; 365 return err_code;
307 366
308 while (status != 0x0a && tries < 256) { 367 while (status != 0x0a && tries < 256) {
309 err_code = cam_get_response16(gspca_dev); 368 err_code = cam_get_response16(gspca_dev, 0x21, 0);
310 status = data[0]; 369 status = data[0];
311 tries++; 370 tries++;
312 if (err_code < 0) 371 if (err_code < 0)
@@ -323,7 +382,7 @@ static int zero_the_pointer(struct gspca_dev *gspca_dev)
323 if (err_code < 0) 382 if (err_code < 0)
324 return err_code; 383 return err_code;
325 384
326 err_code = cam_get_response16(gspca_dev); 385 err_code = cam_get_response16(gspca_dev, 0x21, 0);
327 status = data[0]; 386 status = data[0];
328 tries++; 387 tries++;
329 if (err_code < 0) 388 if (err_code < 0)
@@ -342,89 +401,202 @@ static int zero_the_pointer(struct gspca_dev *gspca_dev)
342 return 0; 401 return 0;
343} 402}
344 403
345static u8 get_sensor_id(struct gspca_dev *gspca_dev) 404static int stream_start(struct gspca_dev *gspca_dev)
346{ 405{
347 int err_code; 406 gspca_dev->usb_buf[0] = 0x01;
348 407 gspca_dev->usb_buf[1] = 0x01;
349 gspca_dev->usb_buf[0] = 0x1e; 408 return mr_write(gspca_dev, 2);
350 err_code = mr_write(gspca_dev, 1); 409}
351 if (err_code < 0)
352 return err_code;
353 410
354 err_code = mr_read(gspca_dev, 16); 411static void stream_stop(struct gspca_dev *gspca_dev)
355 if (err_code < 0) 412{
356 return err_code; 413 gspca_dev->usb_buf[0] = 0x01;
414 gspca_dev->usb_buf[1] = 0x00;
415 if (mr_write(gspca_dev, 2) < 0)
416 PDEBUG(D_ERR, "Stream Stop failed");
417}
357 418
358 PDEBUG(D_PROBE, "Byte zero reported is %01x", gspca_dev->usb_buf[0]); 419static void lcd_stop(struct gspca_dev *gspca_dev)
420{
421 gspca_dev->usb_buf[0] = 0x19;
422 gspca_dev->usb_buf[1] = 0x54;
423 if (mr_write(gspca_dev, 2) < 0)
424 PDEBUG(D_ERR, "LCD Stop failed");
425}
359 426
360 return gspca_dev->usb_buf[0]; 427static int isoc_enable(struct gspca_dev *gspca_dev)
428{
429 gspca_dev->usb_buf[0] = 0x00;
430 gspca_dev->usb_buf[1] = 0x4d; /* ISOC transfering enable... */
431 return mr_write(gspca_dev, 2);
361} 432}
362 433
363/* this function is called at probe time */ 434/* This function is called at probe time */
364static int sd_config(struct gspca_dev *gspca_dev, 435static int sd_config(struct gspca_dev *gspca_dev,
365 const struct usb_device_id *id) 436 const struct usb_device_id *id)
366{ 437{
367 struct sd *sd = (struct sd *) gspca_dev; 438 struct sd *sd = (struct sd *) gspca_dev;
368 struct cam *cam; 439 struct cam *cam;
369 __u8 *data = gspca_dev->usb_buf;
370 int err_code; 440 int err_code;
371 441
372 cam = &gspca_dev->cam; 442 cam = &gspca_dev->cam;
373 cam->cam_mode = vga_mode; 443 cam->cam_mode = vga_mode;
374 cam->nmodes = ARRAY_SIZE(vga_mode); 444 cam->nmodes = ARRAY_SIZE(vga_mode);
445 sd->do_lcd_stop = 0;
446
447 /* Several of the supported CIF cameras share the same USB ID but
448 * require different initializations and different control settings.
449 * The same is true of the VGA cameras. Therefore, we are forced
450 * to start the initialization process in order to determine which
451 * camera is present. Some of the supported cameras require the
452 * memory pointer to be set to 0 as the very first item of business
453 * or else they will not stream. So we do that immediately.
454 */
455 err_code = zero_the_pointer(gspca_dev);
456 if (err_code < 0)
457 return err_code;
458
459 err_code = stream_start(gspca_dev);
460 if (err_code < 0)
461 return err_code;
375 462
376 if (id->idProduct == 0x010e) { 463 if (id->idProduct == 0x0110 || id->idProduct == 0x010e) {
377 sd->cam_type = CAM_TYPE_CIF; 464 sd->cam_type = CAM_TYPE_CIF;
378 cam->nmodes--; 465 cam->nmodes--;
379 466 err_code = cam_get_response16(gspca_dev, 0x06, 1);
380 data[0] = 0x01;
381 data[1] = 0x01;
382 err_code = mr_write(gspca_dev, 2);
383 if (err_code < 0) 467 if (err_code < 0)
384 return err_code; 468 return err_code;
385
386 msleep(200);
387 data[0] = get_sensor_id(gspca_dev);
388 /* 469 /*
389 * Known CIF cameras. If you have another to report, please do 470 * All but one of the known CIF cameras share the same USB ID,
471 * but two different init routines are in use, and the control
472 * settings are different, too. We need to detect which camera
473 * of the two known varieties is connected!
390 * 474 *
391 * Name byte just read sd->sensor_type 475 * A list of known CIF cameras follows. They all report either
392 * reported by 476 * 0002 for type 0 or 0003 for type 1.
393 * Sakar Spy-shot 0x28 T. Kilgore 0 477 * If you have another to report, please do
394 * Innovage 0xf5 (unstable) T. Kilgore 0 478 *
395 * Vivitar Mini 0x53 H. De Goede 0 479 * Name sd->sensor_type reported by
396 * Vivitar Mini 0x04 / 0x24 E. Rodriguez 0 480 *
397 * Vivitar Mini 0x08 T. Kilgore 1 481 * Sakar Spy-shot 0 T. Kilgore
398 * Elta-Media 8212dc 0x23 T. Kaiser 1 482 * Innovage 0 T. Kilgore
399 * Philips dig. keych. 0x37 T. Kilgore 1 483 * Vivitar Mini 0 H. De Goede
484 * Vivitar Mini 0 E. Rodriguez
485 * Vivitar Mini 1 T. Kilgore
486 * Elta-Media 8212dc 1 T. Kaiser
487 * Philips dig. keych. 1 T. Kilgore
488 * Trust Spyc@m 100 1 A. Jacobs
400 */ 489 */
401 if ((data[0] & 0x78) == 8 || 490 switch (gspca_dev->usb_buf[1]) {
402 ((data[0] & 0x2) == 0x2 && data[0] != 0x53)) 491 case 2:
403 sd->sensor_type = 1;
404 else
405 sd->sensor_type = 0; 492 sd->sensor_type = 0;
406 493 break;
494 case 3:
495 sd->sensor_type = 1;
496 break;
497 default:
498 PDEBUG(D_ERR, "Unknown CIF Sensor id : %02x",
499 gspca_dev->usb_buf[1]);
500 return -ENODEV;
501 }
407 PDEBUG(D_PROBE, "MR97310A CIF camera detected, sensor: %d", 502 PDEBUG(D_PROBE, "MR97310A CIF camera detected, sensor: %d",
408 sd->sensor_type); 503 sd->sensor_type);
504 } else {
505 sd->cam_type = CAM_TYPE_VGA;
409 506
410 if (force_sensor_type != -1) { 507 err_code = cam_get_response16(gspca_dev, 0x07, 1);
411 sd->sensor_type = !! force_sensor_type; 508 if (err_code < 0)
412 PDEBUG(D_PROBE, "Forcing sensor type to: %d", 509 return err_code;
413 sd->sensor_type); 510
511 /*
512 * Here is a table of the responses to the previous command
513 * from the known MR97310A VGA cameras.
514 *
515 * Name gspca_dev->usb_buf[] sd->sensor_type
516 * sd->do_lcd_stop
517 * Aiptek Pencam VGA+ 0300 0 1
518 * ION digital 0350 0 1
519 * Argus DC-1620 0450 1 0
520 * Argus QuickClix 0420 1 1
521 *
522 * Based upon these results, we assume default settings
523 * and then correct as necessary, as follows.
524 *
525 */
526
527 sd->sensor_type = 1;
528 sd->do_lcd_stop = 0;
529 sd->adj_colors = 0;
530 if ((gspca_dev->usb_buf[0] != 0x03) &&
531 (gspca_dev->usb_buf[0] != 0x04)) {
532 PDEBUG(D_ERR, "Unknown VGA Sensor id Byte 0: %02x",
533 gspca_dev->usb_buf[1]);
534 PDEBUG(D_ERR, "Defaults assumed, may not work");
535 PDEBUG(D_ERR, "Please report this");
536 }
537 /* Sakar Digital color needs to be adjusted. */
538 if ((gspca_dev->usb_buf[0] == 0x03) &&
539 (gspca_dev->usb_buf[1] == 0x50))
540 sd->adj_colors = 1;
541 if (gspca_dev->usb_buf[0] == 0x04) {
542 sd->do_lcd_stop = 1;
543 switch (gspca_dev->usb_buf[1]) {
544 case 0x50:
545 sd->sensor_type = 0;
546 PDEBUG(D_PROBE, "sensor_type corrected to 0");
547 break;
548 case 0x20:
549 /* Nothing to do here. */
550 break;
551 default:
552 PDEBUG(D_ERR,
553 "Unknown VGA Sensor id Byte 1: %02x",
554 gspca_dev->usb_buf[1]);
555 PDEBUG(D_ERR,
556 "Defaults assumed, may not work");
557 PDEBUG(D_ERR, "Please report this");
558 }
414 } 559 }
560 PDEBUG(D_PROBE, "MR97310A VGA camera detected, sensor: %d",
561 sd->sensor_type);
562 }
563 /* Stop streaming as we've started it to probe the sensor type. */
564 sd_stopN(gspca_dev);
565
566 if (force_sensor_type != -1) {
567 sd->sensor_type = !!force_sensor_type;
568 PDEBUG(D_PROBE, "Forcing sensor type to: %d",
569 sd->sensor_type);
570 }
415 571
572 /* Setup controls depending on camera type */
573 if (sd->cam_type == CAM_TYPE_CIF) {
574 /* No brightness for sensor_type 0 */
416 if (sd->sensor_type == 0) 575 if (sd->sensor_type == 0)
417 gspca_dev->ctrl_dis = (1 << BRIGHTNESS_IDX); 576 gspca_dev->ctrl_dis = (1 << NORM_BRIGHTNESS_IDX) |
577 (1 << ARGUS_QC_BRIGHTNESS_IDX);
578 else
579 gspca_dev->ctrl_dis = (1 << ARGUS_QC_BRIGHTNESS_IDX) |
580 (1 << MIN_CLOCKDIV_IDX);
418 } else { 581 } else {
419 sd->cam_type = CAM_TYPE_VGA; 582 /* All controls need to be disabled if VGA sensor_type is 0 */
420 PDEBUG(D_PROBE, "MR97310A VGA camera detected"); 583 if (sd->sensor_type == 0)
421 gspca_dev->ctrl_dis = (1 << BRIGHTNESS_IDX) | 584 gspca_dev->ctrl_dis = (1 << NORM_BRIGHTNESS_IDX) |
422 (1 << EXPOSURE_IDX) | (1 << GAIN_IDX); 585 (1 << ARGUS_QC_BRIGHTNESS_IDX) |
586 (1 << EXPOSURE_IDX) |
587 (1 << GAIN_IDX) |
588 (1 << MIN_CLOCKDIV_IDX);
589 else if (sd->do_lcd_stop)
590 /* Argus QuickClix has different brightness limits */
591 gspca_dev->ctrl_dis = (1 << NORM_BRIGHTNESS_IDX);
592 else
593 gspca_dev->ctrl_dis = (1 << ARGUS_QC_BRIGHTNESS_IDX);
423 } 594 }
424 595
425 sd->brightness = MR97310A_BRIGHTNESS_DEFAULT; 596 sd->brightness = MR97310A_BRIGHTNESS_DEFAULT;
426 sd->exposure = MR97310A_EXPOSURE_DEFAULT; 597 sd->exposure = MR97310A_EXPOSURE_DEFAULT;
427 sd->gain = MR97310A_GAIN_DEFAULT; 598 sd->gain = MR97310A_GAIN_DEFAULT;
599 sd->min_clockdiv = MR97310A_MIN_CLOCKDIV_DEFAULT;
428 600
429 return 0; 601 return 0;
430} 602}
@@ -455,11 +627,6 @@ static int start_cif_cam(struct gspca_dev *gspca_dev)
455 }; 627 };
456 628
457 /* Note: Some of the above descriptions guessed from MR97113A driver */ 629 /* Note: Some of the above descriptions guessed from MR97113A driver */
458 data[0] = 0x01;
459 data[1] = 0x01;
460 err_code = mr_write(gspca_dev, 2);
461 if (err_code < 0)
462 return err_code;
463 630
464 memcpy(data, startup_string, 11); 631 memcpy(data, startup_string, 11);
465 if (sd->sensor_type) 632 if (sd->sensor_type)
@@ -533,22 +700,7 @@ static int start_cif_cam(struct gspca_dev *gspca_dev)
533 err_code = sensor_write_regs(gspca_dev, cif_sensor1_init_data, 700 err_code = sensor_write_regs(gspca_dev, cif_sensor1_init_data,
534 ARRAY_SIZE(cif_sensor1_init_data)); 701 ARRAY_SIZE(cif_sensor1_init_data));
535 } 702 }
536 if (err_code < 0) 703 return err_code;
537 return err_code;
538
539 setbrightness(gspca_dev);
540 setexposure(gspca_dev);
541 setgain(gspca_dev);
542
543 msleep(200);
544
545 data[0] = 0x00;
546 data[1] = 0x4d; /* ISOC transfering enable... */
547 err_code = mr_write(gspca_dev, 2);
548 if (err_code < 0)
549 return err_code;
550
551 return 0;
552} 704}
553 705
554static int start_vga_cam(struct gspca_dev *gspca_dev) 706static int start_vga_cam(struct gspca_dev *gspca_dev)
@@ -558,84 +710,8 @@ static int start_vga_cam(struct gspca_dev *gspca_dev)
558 int err_code; 710 int err_code;
559 const __u8 startup_string[] = {0x00, 0x0d, 0x01, 0x00, 0x00, 0x2b, 711 const __u8 startup_string[] = {0x00, 0x0d, 0x01, 0x00, 0x00, 0x2b,
560 0x00, 0x00, 0x00, 0x50, 0xc0}; 712 0x00, 0x00, 0x00, 0x50, 0xc0};
561
562 /* What some of these mean is explained in start_cif_cam(), above */ 713 /* What some of these mean is explained in start_cif_cam(), above */
563 sd->sof_read = 0;
564
565 /*
566 * We have to know which camera we have, because the register writes
567 * depend upon the camera. This test, run before we actually enter
568 * the initialization routine, distinguishes most of the cameras, If
569 * needed, another routine is done later, too.
570 */
571 memset(data, 0, 16);
572 data[0] = 0x20;
573 err_code = mr_write(gspca_dev, 1);
574 if (err_code < 0)
575 return err_code;
576
577 err_code = mr_read(gspca_dev, 16);
578 if (err_code < 0)
579 return err_code;
580
581 PDEBUG(D_PROBE, "Byte reported is %02x", data[0]);
582
583 msleep(200);
584 /*
585 * Known VGA cameras. If you have another to report, please do
586 *
587 * Name byte just read sd->sensor_type
588 * sd->do_lcd_stop
589 * Aiptek Pencam VGA+ 0x31 0 1
590 * ION digital 0x31 0 1
591 * Argus DC-1620 0x30 1 0
592 * Argus QuickClix 0x30 1 1 (not caught here)
593 */
594 sd->sensor_type = data[0] & 1;
595 sd->do_lcd_stop = (~data[0]) & 1;
596
597
598
599 /* Streaming setup begins here. */
600
601
602 data[0] = 0x01;
603 data[1] = 0x01;
604 err_code = mr_write(gspca_dev, 2);
605 if (err_code < 0)
606 return err_code;
607 714
608 /*
609 * A second test can now resolve any remaining ambiguity in the
610 * identification of the camera type,
611 */
612 if (!sd->sensor_type) {
613 data[0] = get_sensor_id(gspca_dev);
614 if (data[0] == 0x7f) {
615 sd->sensor_type = 1;
616 PDEBUG(D_PROBE, "sensor_type corrected to 1");
617 }
618 msleep(200);
619 }
620
621 if (force_sensor_type != -1) {
622 sd->sensor_type = !! force_sensor_type;
623 PDEBUG(D_PROBE, "Forcing sensor type to: %d",
624 sd->sensor_type);
625 }
626
627 /*
628 * Known VGA cameras.
629 * This test is only run if the previous test returned 0x30, but
630 * here is the information for all others, too, just for reference.
631 *
632 * Name byte just read sd->sensor_type
633 *
634 * Aiptek Pencam VGA+ 0xfb (this test not run) 1
635 * ION digital 0xbd (this test not run) 1
636 * Argus DC-1620 0xe5 (no change) 0
637 * Argus QuickClix 0x7f (reclassified) 1
638 */
639 memcpy(data, startup_string, 11); 715 memcpy(data, startup_string, 11);
640 if (!sd->sensor_type) { 716 if (!sd->sensor_type) {
641 data[5] = 0x00; 717 data[5] = 0x00;
@@ -689,29 +765,44 @@ static int start_vga_cam(struct gspca_dev *gspca_dev)
689 err_code = sensor_write_regs(gspca_dev, vga_sensor0_init_data, 765 err_code = sensor_write_regs(gspca_dev, vga_sensor0_init_data,
690 ARRAY_SIZE(vga_sensor0_init_data)); 766 ARRAY_SIZE(vga_sensor0_init_data));
691 } else { /* sd->sensor_type = 1 */ 767 } else { /* sd->sensor_type = 1 */
692 const struct sensor_w_data vga_sensor1_init_data[] = { 768 const struct sensor_w_data color_adj[] = {
693 {0x02, 0x00, {0x06, 0x59, 0x0c, 0x16, 0x00, 769 {0x02, 0x00, {0x06, 0x59, 0x0c, 0x16, 0x00,
694 0x07, 0x00, 0x01}, 8}, 770 /* adjusted blue, green, red gain correct
771 too much blue from the Sakar Digital */
772 0x05, 0x01, 0x04}, 8}
773 };
774
775 const struct sensor_w_data color_no_adj[] = {
776 {0x02, 0x00, {0x06, 0x59, 0x0c, 0x16, 0x00,
777 /* default blue, green, red gain settings */
778 0x07, 0x00, 0x01}, 8}
779 };
780
781 const struct sensor_w_data vga_sensor1_init_data[] = {
695 {0x11, 0x04, {0x01}, 1}, 782 {0x11, 0x04, {0x01}, 1},
696 /*{0x0a, 0x00, {0x00, 0x01, 0x00, 0x00, 0x01, */ 783 {0x0a, 0x00, {0x00, 0x01, 0x00, 0x00, 0x01,
697 {0x0a, 0x00, {0x01, 0x06, 0x00, 0x00, 0x01, 784 /* These settings may be better for some cameras */
785 /* {0x0a, 0x00, {0x01, 0x06, 0x00, 0x00, 0x01, */
698 0x00, 0x0a}, 7}, 786 0x00, 0x0a}, 7},
699 {0x11, 0x04, {0x01}, 1}, 787 {0x11, 0x04, {0x01}, 1},
700 {0x12, 0x00, {0x00, 0x63, 0x00, 0x70, 0x00, 0x00}, 6}, 788 {0x12, 0x00, {0x00, 0x63, 0x00, 0x70, 0x00, 0x00}, 6},
701 {0x11, 0x04, {0x01}, 1}, 789 {0x11, 0x04, {0x01}, 1},
702 {0, 0, {0}, 0} 790 {0, 0, {0}, 0}
703 }; 791 };
792
793 if (sd->adj_colors)
794 err_code = sensor_write_regs(gspca_dev, color_adj,
795 ARRAY_SIZE(color_adj));
796 else
797 err_code = sensor_write_regs(gspca_dev, color_no_adj,
798 ARRAY_SIZE(color_no_adj));
799
800 if (err_code < 0)
801 return err_code;
802
704 err_code = sensor_write_regs(gspca_dev, vga_sensor1_init_data, 803 err_code = sensor_write_regs(gspca_dev, vga_sensor1_init_data,
705 ARRAY_SIZE(vga_sensor1_init_data)); 804 ARRAY_SIZE(vga_sensor1_init_data));
706 } 805 }
707 if (err_code < 0)
708 return err_code;
709
710 msleep(200);
711 data[0] = 0x00;
712 data[1] = 0x4d; /* ISOC transfering enable... */
713 err_code = mr_write(gspca_dev, 2);
714
715 return err_code; 806 return err_code;
716} 807}
717 808
@@ -719,97 +810,120 @@ static int sd_start(struct gspca_dev *gspca_dev)
719{ 810{
720 struct sd *sd = (struct sd *) gspca_dev; 811 struct sd *sd = (struct sd *) gspca_dev;
721 int err_code; 812 int err_code;
722 struct cam *cam;
723 813
724 cam = &gspca_dev->cam;
725 sd->sof_read = 0; 814 sd->sof_read = 0;
726 /* 815
727 * Some of the supported cameras require the memory pointer to be 816 /* Some of the VGA cameras require the memory pointer
728 * set to 0, or else they will not stream. 817 * to be set to 0 again. We have been forced to start the
729 */ 818 * stream in sd_config() to detect the hardware, and closed it.
730 zero_the_pointer(gspca_dev); 819 * Thus, we need here to do a completely fresh and clean start. */
731 msleep(200); 820 err_code = zero_the_pointer(gspca_dev);
821 if (err_code < 0)
822 return err_code;
823
824 err_code = stream_start(gspca_dev);
825 if (err_code < 0)
826 return err_code;
827
732 if (sd->cam_type == CAM_TYPE_CIF) { 828 if (sd->cam_type == CAM_TYPE_CIF) {
733 err_code = start_cif_cam(gspca_dev); 829 err_code = start_cif_cam(gspca_dev);
734 } else { 830 } else {
735 err_code = start_vga_cam(gspca_dev); 831 err_code = start_vga_cam(gspca_dev);
736 } 832 }
737 return err_code; 833 if (err_code < 0)
834 return err_code;
835
836 setbrightness(gspca_dev);
837 setexposure(gspca_dev);
838 setgain(gspca_dev);
839
840 return isoc_enable(gspca_dev);
738} 841}
739 842
740static void sd_stopN(struct gspca_dev *gspca_dev) 843static void sd_stopN(struct gspca_dev *gspca_dev)
741{ 844{
742 struct sd *sd = (struct sd *) gspca_dev; 845 struct sd *sd = (struct sd *) gspca_dev;
743 int result;
744
745 gspca_dev->usb_buf[0] = 1;
746 gspca_dev->usb_buf[1] = 0;
747 result = mr_write(gspca_dev, 2);
748 if (result < 0)
749 PDEBUG(D_ERR, "Camera Stop failed");
750 846
847 stream_stop(gspca_dev);
751 /* Not all the cams need this, but even if not, probably a good idea */ 848 /* Not all the cams need this, but even if not, probably a good idea */
752 zero_the_pointer(gspca_dev); 849 zero_the_pointer(gspca_dev);
753 if (sd->do_lcd_stop) { 850 if (sd->do_lcd_stop)
754 gspca_dev->usb_buf[0] = 0x19; 851 lcd_stop(gspca_dev);
755 gspca_dev->usb_buf[1] = 0x54;
756 result = mr_write(gspca_dev, 2);
757 if (result < 0)
758 PDEBUG(D_ERR, "Camera Stop failed");
759 }
760} 852}
761 853
762static void setbrightness(struct gspca_dev *gspca_dev) 854static void setbrightness(struct gspca_dev *gspca_dev)
763{ 855{
764 struct sd *sd = (struct sd *) gspca_dev; 856 struct sd *sd = (struct sd *) gspca_dev;
765 u8 val; 857 u8 val;
766 858 u8 sign_reg = 7; /* This reg and the next one used on CIF cams. */
767 if (gspca_dev->ctrl_dis & (1 << BRIGHTNESS_IDX)) 859 u8 value_reg = 8; /* VGA cams seem to use regs 0x0b and 0x0c */
860 const u8 quick_clix_table[] =
861 /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 */
862 { 0, 4, 8, 12, 1, 2, 3, 5, 6, 9, 7, 10, 13, 11, 14, 15};
863 /*
864 * This control is disabled for CIF type 1 and VGA type 0 cameras.
865 * It does not quite act linearly for the Argus QuickClix camera,
866 * but it does control brightness. The values are 0 - 15 only, and
867 * the table above makes them act consecutively.
868 */
869 if ((gspca_dev->ctrl_dis & (1 << NORM_BRIGHTNESS_IDX)) &&
870 (gspca_dev->ctrl_dis & (1 << ARGUS_QC_BRIGHTNESS_IDX)))
768 return; 871 return;
769 872
770 /* Note register 7 is also seen as 0x8x or 0xCx in dumps */ 873 if (sd->cam_type == CAM_TYPE_VGA) {
874 sign_reg += 4;
875 value_reg += 4;
876 }
877
878 /* Note register 7 is also seen as 0x8x or 0xCx in some dumps */
771 if (sd->brightness > 0) { 879 if (sd->brightness > 0) {
772 sensor_write1(gspca_dev, 7, 0x00); 880 sensor_write1(gspca_dev, sign_reg, 0x00);
773 val = sd->brightness; 881 val = sd->brightness;
774 } else { 882 } else {
775 sensor_write1(gspca_dev, 7, 0x01); 883 sensor_write1(gspca_dev, sign_reg, 0x01);
776 val = 257 - sd->brightness; 884 val = (257 - sd->brightness);
777 } 885 }
778 sensor_write1(gspca_dev, 8, val); 886 /* Use lookup table for funky Argus QuickClix brightness */
887 if (sd->do_lcd_stop)
888 val = quick_clix_table[val];
889
890 sensor_write1(gspca_dev, value_reg, val);
779} 891}
780 892
781static void setexposure(struct gspca_dev *gspca_dev) 893static void setexposure(struct gspca_dev *gspca_dev)
782{ 894{
783 struct sd *sd = (struct sd *) gspca_dev; 895 struct sd *sd = (struct sd *) gspca_dev;
784 u8 val; 896 int exposure;
897 u8 buf[2];
785 898
786 if (gspca_dev->ctrl_dis & (1 << EXPOSURE_IDX)) 899 if (gspca_dev->ctrl_dis & (1 << EXPOSURE_IDX))
787 return; 900 return;
788 901
789 if (sd->sensor_type) { 902 if (sd->cam_type == CAM_TYPE_CIF && sd->sensor_type == 1) {
790 val = sd->exposure >> 4; 903 /* This cam does not like exposure settings < 300,
791 sensor_write1(gspca_dev, 3, val); 904 so scale 0 - 4095 to 300 - 4095 */
792 val = sd->exposure & 0xf; 905 exposure = (sd->exposure * 9267) / 10000 + 300;
793 sensor_write1(gspca_dev, 4, val); 906 sensor_write1(gspca_dev, 3, exposure >> 4);
907 sensor_write1(gspca_dev, 4, exposure & 0x0f);
794 } else { 908 } else {
795 u8 clockdiv;
796 int exposure;
797
798 /* We have both a clock divider and an exposure register. 909 /* We have both a clock divider and an exposure register.
799 We first calculate the clock divider, as that determines 910 We first calculate the clock divider, as that determines
800 the maximum exposure and then we calculayte the exposure 911 the maximum exposure and then we calculate the exposure
801 register setting (which goes from 0 - 511). 912 register setting (which goes from 0 - 511).
802 913
803 Note our 0 - 4095 exposure is mapped to 0 - 511 914 Note our 0 - 4095 exposure is mapped to 0 - 511
804 milliseconds exposure time */ 915 milliseconds exposure time */
805 clockdiv = (60 * sd->exposure + 7999) / 8000; 916 u8 clockdiv = (60 * sd->exposure + 7999) / 8000;
806 917
807 /* Limit framerate to not exceed usb bandwidth */ 918 /* Limit framerate to not exceed usb bandwidth */
808 if (clockdiv < 3 && gspca_dev->width >= 320) 919 if (clockdiv < sd->min_clockdiv && gspca_dev->width >= 320)
809 clockdiv = 3; 920 clockdiv = sd->min_clockdiv;
810 else if (clockdiv < 2) 921 else if (clockdiv < 2)
811 clockdiv = 2; 922 clockdiv = 2;
812 923
924 if (sd->cam_type == CAM_TYPE_VGA && clockdiv < 4)
925 clockdiv = 4;
926
813 /* Frame exposure time in ms = 1000 * clockdiv / 60 -> 927 /* Frame exposure time in ms = 1000 * clockdiv / 60 ->
814 exposure = (sd->exposure / 8) * 511 / (1000 * clockdiv / 60) */ 928 exposure = (sd->exposure / 8) * 511 / (1000 * clockdiv / 60) */
815 exposure = (60 * 511 * sd->exposure) / (8000 * clockdiv); 929 exposure = (60 * 511 * sd->exposure) / (8000 * clockdiv);
@@ -819,9 +933,10 @@ static void setexposure(struct gspca_dev *gspca_dev)
819 /* exposure register value is reversed! */ 933 /* exposure register value is reversed! */
820 exposure = 511 - exposure; 934 exposure = 511 - exposure;
821 935
936 buf[0] = exposure & 0xff;
937 buf[1] = exposure >> 8;
938 sensor_write_reg(gspca_dev, 0x0e, 0, buf, 2);
822 sensor_write1(gspca_dev, 0x02, clockdiv); 939 sensor_write1(gspca_dev, 0x02, clockdiv);
823 sensor_write1(gspca_dev, 0x0e, exposure & 0xff);
824 sensor_write1(gspca_dev, 0x0f, exposure >> 8);
825 } 940 }
826} 941}
827 942
@@ -832,7 +947,7 @@ static void setgain(struct gspca_dev *gspca_dev)
832 if (gspca_dev->ctrl_dis & (1 << GAIN_IDX)) 947 if (gspca_dev->ctrl_dis & (1 << GAIN_IDX))
833 return; 948 return;
834 949
835 if (sd->sensor_type) { 950 if (sd->cam_type == CAM_TYPE_CIF && sd->sensor_type == 1) {
836 sensor_write1(gspca_dev, 0x0e, sd->gain); 951 sensor_write1(gspca_dev, 0x0e, sd->gain);
837 } else { 952 } else {
838 sensor_write1(gspca_dev, 0x10, sd->gain); 953 sensor_write1(gspca_dev, 0x10, sd->gain);
@@ -893,17 +1008,35 @@ static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
893 return 0; 1008 return 0;
894} 1009}
895 1010
1011static int sd_setmin_clockdiv(struct gspca_dev *gspca_dev, __s32 val)
1012{
1013 struct sd *sd = (struct sd *) gspca_dev;
1014
1015 sd->min_clockdiv = val;
1016 if (gspca_dev->streaming)
1017 setexposure(gspca_dev);
1018 return 0;
1019}
1020
1021static int sd_getmin_clockdiv(struct gspca_dev *gspca_dev, __s32 *val)
1022{
1023 struct sd *sd = (struct sd *) gspca_dev;
1024
1025 *val = sd->min_clockdiv;
1026 return 0;
1027}
1028
896/* Include pac common sof detection functions */ 1029/* Include pac common sof detection functions */
897#include "pac_common.h" 1030#include "pac_common.h"
898 1031
899static void sd_pkt_scan(struct gspca_dev *gspca_dev, 1032static void sd_pkt_scan(struct gspca_dev *gspca_dev,
900 struct gspca_frame *frame, /* target */ 1033 u8 *data, /* isoc packet */
901 __u8 *data, /* isoc packet */ 1034 int len) /* iso packet length */
902 int len) /* iso packet length */
903{ 1035{
1036 struct sd *sd = (struct sd *) gspca_dev;
904 unsigned char *sof; 1037 unsigned char *sof;
905 1038
906 sof = pac_find_sof(gspca_dev, data, len); 1039 sof = pac_find_sof(&sd->sof_read, data, len);
907 if (sof) { 1040 if (sof) {
908 int n; 1041 int n;
909 1042
@@ -913,15 +1046,15 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
913 n -= sizeof pac_sof_marker; 1046 n -= sizeof pac_sof_marker;
914 else 1047 else
915 n = 0; 1048 n = 0;
916 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, 1049 gspca_frame_add(gspca_dev, LAST_PACKET,
917 data, n); 1050 data, n);
918 /* Start next frame. */ 1051 /* Start next frame. */
919 gspca_frame_add(gspca_dev, FIRST_PACKET, frame, 1052 gspca_frame_add(gspca_dev, FIRST_PACKET,
920 pac_sof_marker, sizeof pac_sof_marker); 1053 pac_sof_marker, sizeof pac_sof_marker);
921 len -= sof - data; 1054 len -= sof - data;
922 data = sof; 1055 data = sof;
923 } 1056 }
924 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); 1057 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
925} 1058}
926 1059
927/* sub-driver description */ 1060/* sub-driver description */
@@ -938,6 +1071,7 @@ static const struct sd_desc sd_desc = {
938 1071
939/* -- module initialisation -- */ 1072/* -- module initialisation -- */
940static const __devinitdata struct usb_device_id device_table[] = { 1073static const __devinitdata struct usb_device_id device_table[] = {
1074 {USB_DEVICE(0x08ca, 0x0110)}, /* Trust Spyc@m 100 */
941 {USB_DEVICE(0x08ca, 0x0111)}, /* Aiptek Pencam VGA+ */ 1075 {USB_DEVICE(0x08ca, 0x0111)}, /* Aiptek Pencam VGA+ */
942 {USB_DEVICE(0x093a, 0x010f)}, /* All other known MR97310A VGA cams */ 1076 {USB_DEVICE(0x093a, 0x010f)}, /* All other known MR97310A VGA cams */
943 {USB_DEVICE(0x093a, 0x010e)}, /* All known MR97310A CIF cams */ 1077 {USB_DEVICE(0x093a, 0x010e)}, /* All known MR97310A CIF cams */
diff --git a/drivers/media/video/gspca/ov519.c b/drivers/media/video/gspca/ov519.c
index a5c190e93799..ad9ec339981d 100644
--- a/drivers/media/video/gspca/ov519.c
+++ b/drivers/media/video/gspca/ov519.c
@@ -2,14 +2,19 @@
2 * OV519 driver 2 * OV519 driver
3 * 3 *
4 * Copyright (C) 2008 Jean-Francois Moine (http://moinejf.free.fr) 4 * Copyright (C) 2008 Jean-Francois Moine (http://moinejf.free.fr)
5 * Copyright (C) 2009 Hans de Goede <hdegoede@redhat.com>
5 * 6 *
6 * This module is adapted from the ov51x-jpeg package, which itself 7 * This module is adapted from the ov51x-jpeg package, which itself
7 * was adapted from the ov511 driver. 8 * was adapted from the ov511 driver.
8 * 9 *
9 * Original copyright for the ov511 driver is: 10 * Original copyright for the ov511 driver is:
10 * 11 *
11 * Copyright (c) 1999-2004 Mark W. McClelland 12 * Copyright (c) 1999-2006 Mark W. McClelland
12 * Support for OV519, OV8610 Copyright (c) 2003 Joerg Heckenbach 13 * Support for OV519, OV8610 Copyright (c) 2003 Joerg Heckenbach
14 * Many improvements by Bret Wallach <bwallac1@san.rr.com>
15 * Color fixes by by Orion Sky Lawlor <olawlor@acm.org> (2/26/2000)
16 * OV7620 fixes by Charl P. Botha <cpbotha@ieee.org>
17 * Changes by Claudio Matsuoka <claudio@conectiva.com>
13 * 18 *
14 * ov51x-jpeg original copyright is: 19 * ov51x-jpeg original copyright is:
15 * 20 *
@@ -58,6 +63,8 @@ struct sd {
58#define BRIDGE_OV518 2 63#define BRIDGE_OV518 2
59#define BRIDGE_OV518PLUS 3 64#define BRIDGE_OV518PLUS 3
60#define BRIDGE_OV519 4 65#define BRIDGE_OV519 4
66#define BRIDGE_OVFX2 5
67#define BRIDGE_W9968CF 6
61#define BRIDGE_MASK 7 68#define BRIDGE_MASK 7
62 69
63 char invert_led; 70 char invert_led;
@@ -73,6 +80,10 @@ struct sd {
73 __u8 vflip; 80 __u8 vflip;
74 __u8 autobrightness; 81 __u8 autobrightness;
75 __u8 freq; 82 __u8 freq;
83 __u8 quality;
84#define QUALITY_MIN 50
85#define QUALITY_MAX 70
86#define QUALITY_DEF 50
76 87
77 __u8 stopped; /* Streaming is temporarily paused */ 88 __u8 stopped; /* Streaming is temporarily paused */
78 89
@@ -81,17 +92,31 @@ struct sd {
81 92
82 char sensor; /* Type of image sensor chip (SEN_*) */ 93 char sensor; /* Type of image sensor chip (SEN_*) */
83#define SEN_UNKNOWN 0 94#define SEN_UNKNOWN 0
84#define SEN_OV6620 1 95#define SEN_OV2610 1
85#define SEN_OV6630 2 96#define SEN_OV3610 2
86#define SEN_OV66308AF 3 97#define SEN_OV6620 3
87#define SEN_OV7610 4 98#define SEN_OV6630 4
88#define SEN_OV7620 5 99#define SEN_OV66308AF 5
89#define SEN_OV7640 6 100#define SEN_OV7610 6
90#define SEN_OV7670 7 101#define SEN_OV7620 7
91#define SEN_OV76BE 8 102#define SEN_OV7640 8
92#define SEN_OV8610 9 103#define SEN_OV7670 9
104#define SEN_OV76BE 10
105#define SEN_OV8610 11
106
107 u8 sensor_addr;
108 int sensor_width;
109 int sensor_height;
110 int sensor_reg_cache[256];
111
112 u8 *jpeg_hdr;
93}; 113};
94 114
115/* Note this is a bit of a hack, but the w9968cf driver needs the code for all
116 the ov sensors which is already present here. When we have the time we
117 really should move the sensor drivers to v4l2 sub drivers. */
118#include "w996Xcf.c"
119
95/* V4L2 controls supported by the driver */ 120/* V4L2 controls supported by the driver */
96static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); 121static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
97static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); 122static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
@@ -345,6 +370,75 @@ static const struct v4l2_pix_format ov511_sif_mode[] = {
345 .priv = 0}, 370 .priv = 0},
346}; 371};
347 372
373static const struct v4l2_pix_format ovfx2_vga_mode[] = {
374 {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
375 .bytesperline = 320,
376 .sizeimage = 320 * 240,
377 .colorspace = V4L2_COLORSPACE_SRGB,
378 .priv = 1},
379 {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
380 .bytesperline = 640,
381 .sizeimage = 640 * 480,
382 .colorspace = V4L2_COLORSPACE_SRGB,
383 .priv = 0},
384};
385static const struct v4l2_pix_format ovfx2_cif_mode[] = {
386 {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
387 .bytesperline = 160,
388 .sizeimage = 160 * 120,
389 .colorspace = V4L2_COLORSPACE_SRGB,
390 .priv = 3},
391 {176, 144, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
392 .bytesperline = 176,
393 .sizeimage = 176 * 144,
394 .colorspace = V4L2_COLORSPACE_SRGB,
395 .priv = 1},
396 {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
397 .bytesperline = 320,
398 .sizeimage = 320 * 240,
399 .colorspace = V4L2_COLORSPACE_SRGB,
400 .priv = 2},
401 {352, 288, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
402 .bytesperline = 352,
403 .sizeimage = 352 * 288,
404 .colorspace = V4L2_COLORSPACE_SRGB,
405 .priv = 0},
406};
407static const struct v4l2_pix_format ovfx2_ov2610_mode[] = {
408 {1600, 1200, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
409 .bytesperline = 1600,
410 .sizeimage = 1600 * 1200,
411 .colorspace = V4L2_COLORSPACE_SRGB},
412};
413static const struct v4l2_pix_format ovfx2_ov3610_mode[] = {
414 {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
415 .bytesperline = 640,
416 .sizeimage = 640 * 480,
417 .colorspace = V4L2_COLORSPACE_SRGB,
418 .priv = 1},
419 {800, 600, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
420 .bytesperline = 800,
421 .sizeimage = 800 * 600,
422 .colorspace = V4L2_COLORSPACE_SRGB,
423 .priv = 1},
424 {1024, 768, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
425 .bytesperline = 1024,
426 .sizeimage = 1024 * 768,
427 .colorspace = V4L2_COLORSPACE_SRGB,
428 .priv = 1},
429 {1600, 1200, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
430 .bytesperline = 1600,
431 .sizeimage = 1600 * 1200,
432 .colorspace = V4L2_COLORSPACE_SRGB,
433 .priv = 0},
434 {2048, 1536, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
435 .bytesperline = 2048,
436 .sizeimage = 2048 * 1536,
437 .colorspace = V4L2_COLORSPACE_SRGB,
438 .priv = 0},
439};
440
441
348/* Registers common to OV511 / OV518 */ 442/* Registers common to OV511 / OV518 */
349#define R51x_FIFO_PSIZE 0x30 /* 2 bytes wide w/ OV518(+) */ 443#define R51x_FIFO_PSIZE 0x30 /* 2 bytes wide w/ OV518(+) */
350#define R51x_SYS_RESET 0x50 444#define R51x_SYS_RESET 0x50
@@ -406,6 +500,30 @@ static const struct v4l2_pix_format ov511_sif_mode[] = {
406 500
407#define OV511_ENDPOINT_ADDRESS 1 /* Isoc endpoint number */ 501#define OV511_ENDPOINT_ADDRESS 1 /* Isoc endpoint number */
408 502
503/*
504 * The FX2 chip does not give us a zero length read at end of frame.
505 * It does, however, give a short read at the end of a frame, if
506 * neccessary, rather than run two frames together.
507 *
508 * By choosing the right bulk transfer size, we are guaranteed to always
509 * get a short read for the last read of each frame. Frame sizes are
510 * always a composite number (width * height, or a multiple) so if we
511 * choose a prime number, we are guaranteed that the last read of a
512 * frame will be short.
513 *
514 * But it isn't that easy: the 2.6 kernel requires a multiple of 4KB,
515 * otherwise EOVERFLOW "babbling" errors occur. I have not been able
516 * to figure out why. [PMiller]
517 *
518 * The constant (13 * 4096) is the largest "prime enough" number less than 64KB.
519 *
520 * It isn't enough to know the number of bytes per frame, in case we
521 * have data dropouts or buffer overruns (even though the FX2 double
522 * buffers, there are some pretty strict real time constraints for
523 * isochronous transfer for larger frame sizes).
524 */
525#define OVFX2_BULK_SIZE (13 * 4096)
526
409/* I2C registers */ 527/* I2C registers */
410#define R51x_I2C_W_SID 0x41 528#define R51x_I2C_W_SID 0x41
411#define R51x_I2C_SADDR_3 0x42 529#define R51x_I2C_SADDR_3 0x42
@@ -413,9 +531,11 @@ static const struct v4l2_pix_format ov511_sif_mode[] = {
413#define R51x_I2C_R_SID 0x44 531#define R51x_I2C_R_SID 0x44
414#define R51x_I2C_DATA 0x45 532#define R51x_I2C_DATA 0x45
415#define R518_I2C_CTL 0x47 /* OV518(+) only */ 533#define R518_I2C_CTL 0x47 /* OV518(+) only */
534#define OVFX2_I2C_ADDR 0x00
416 535
417/* I2C ADDRESSES */ 536/* I2C ADDRESSES */
418#define OV7xx0_SID 0x42 537#define OV7xx0_SID 0x42
538#define OV_HIRES_SID 0x60 /* OV9xxx / OV2xxx / OV3xxx */
419#define OV8xx0_SID 0xa0 539#define OV8xx0_SID 0xa0
420#define OV6xx0_SID 0xc0 540#define OV6xx0_SID 0xc0
421 541
@@ -508,6 +628,696 @@ struct ov_i2c_regvals {
508 __u8 val; 628 __u8 val;
509}; 629};
510 630
631/* Settings for OV2610 camera chip */
632static const struct ov_i2c_regvals norm_2610[] =
633{
634 { 0x12, 0x80 }, /* reset */
635};
636
637static const struct ov_i2c_regvals norm_3620b[] =
638{
639 /*
640 * From the datasheet: "Note that after writing to register COMH
641 * (0x12) to change the sensor mode, registers related to the
642 * sensor’s cropping window will be reset back to their default
643 * values."
644 *
645 * "wait 4096 external clock ... to make sure the sensor is
646 * stable and ready to access registers" i.e. 160us at 24MHz
647 */
648
649 { 0x12, 0x80 }, /* COMH reset */
650 { 0x12, 0x00 }, /* QXGA, master */
651
652 /*
653 * 11 CLKRC "Clock Rate Control"
654 * [7] internal frequency doublers: on
655 * [6] video port mode: master
656 * [5:0] clock divider: 1
657 */
658 { 0x11, 0x80 },
659
660 /*
661 * 13 COMI "Common Control I"
662 * = 192 (0xC0) 11000000
663 * COMI[7] "AEC speed selection"
664 * = 1 (0x01) 1....... "Faster AEC correction"
665 * COMI[6] "AEC speed step selection"
666 * = 1 (0x01) .1...... "Big steps, fast"
667 * COMI[5] "Banding filter on off"
668 * = 0 (0x00) ..0..... "Off"
669 * COMI[4] "Banding filter option"
670 * = 0 (0x00) ...0.... "Main clock is 48 MHz and
671 * the PLL is ON"
672 * COMI[3] "Reserved"
673 * = 0 (0x00) ....0...
674 * COMI[2] "AGC auto manual control selection"
675 * = 0 (0x00) .....0.. "Manual"
676 * COMI[1] "AWB auto manual control selection"
677 * = 0 (0x00) ......0. "Manual"
678 * COMI[0] "Exposure control"
679 * = 0 (0x00) .......0 "Manual"
680 */
681 { 0x13, 0xC0 },
682
683 /*
684 * 09 COMC "Common Control C"
685 * = 8 (0x08) 00001000
686 * COMC[7:5] "Reserved"
687 * = 0 (0x00) 000.....
688 * COMC[4] "Sleep Mode Enable"
689 * = 0 (0x00) ...0.... "Normal mode"
690 * COMC[3:2] "Sensor sampling reset timing selection"
691 * = 2 (0x02) ....10.. "Longer reset time"
692 * COMC[1:0] "Output drive current select"
693 * = 0 (0x00) ......00 "Weakest"
694 */
695 { 0x09, 0x08 },
696
697 /*
698 * 0C COMD "Common Control D"
699 * = 8 (0x08) 00001000
700 * COMD[7] "Reserved"
701 * = 0 (0x00) 0.......
702 * COMD[6] "Swap MSB and LSB at the output port"
703 * = 0 (0x00) .0...... "False"
704 * COMD[5:3] "Reserved"
705 * = 1 (0x01) ..001...
706 * COMD[2] "Output Average On Off"
707 * = 0 (0x00) .....0.. "Output Normal"
708 * COMD[1] "Sensor precharge voltage selection"
709 * = 0 (0x00) ......0. "Selects internal
710 * reference precharge
711 * voltage"
712 * COMD[0] "Snapshot option"
713 * = 0 (0x00) .......0 "Enable live video output
714 * after snapshot sequence"
715 */
716 { 0x0c, 0x08 },
717
718 /*
719 * 0D COME "Common Control E"
720 * = 161 (0xA1) 10100001
721 * COME[7] "Output average option"
722 * = 1 (0x01) 1....... "Output average of 4 pixels"
723 * COME[6] "Anti-blooming control"
724 * = 0 (0x00) .0...... "Off"
725 * COME[5:3] "Reserved"
726 * = 4 (0x04) ..100...
727 * COME[2] "Clock output power down pin status"
728 * = 0 (0x00) .....0.. "Tri-state data output pin
729 * on power down"
730 * COME[1] "Data output pin status selection at power down"
731 * = 0 (0x00) ......0. "Tri-state VSYNC, PCLK,
732 * HREF, and CHSYNC pins on
733 * power down"
734 * COME[0] "Auto zero circuit select"
735 * = 1 (0x01) .......1 "On"
736 */
737 { 0x0d, 0xA1 },
738
739 /*
740 * 0E COMF "Common Control F"
741 * = 112 (0x70) 01110000
742 * COMF[7] "System clock selection"
743 * = 0 (0x00) 0....... "Use 24 MHz system clock"
744 * COMF[6:4] "Reserved"
745 * = 7 (0x07) .111....
746 * COMF[3] "Manual auto negative offset canceling selection"
747 * = 0 (0x00) ....0... "Auto detect negative
748 * offset and cancel it"
749 * COMF[2:0] "Reserved"
750 * = 0 (0x00) .....000
751 */
752 { 0x0e, 0x70 },
753
754 /*
755 * 0F COMG "Common Control G"
756 * = 66 (0x42) 01000010
757 * COMG[7] "Optical black output selection"
758 * = 0 (0x00) 0....... "Disable"
759 * COMG[6] "Black level calibrate selection"
760 * = 1 (0x01) .1...... "Use optical black pixels
761 * to calibrate"
762 * COMG[5:4] "Reserved"
763 * = 0 (0x00) ..00....
764 * COMG[3] "Channel offset adjustment"
765 * = 0 (0x00) ....0... "Disable offset adjustment"
766 * COMG[2] "ADC black level calibration option"
767 * = 0 (0x00) .....0.. "Use B/G line and G/R
768 * line to calibrate each
769 * channel's black level"
770 * COMG[1] "Reserved"
771 * = 1 (0x01) ......1.
772 * COMG[0] "ADC black level calibration enable"
773 * = 0 (0x00) .......0 "Disable"
774 */
775 { 0x0f, 0x42 },
776
777 /*
778 * 14 COMJ "Common Control J"
779 * = 198 (0xC6) 11000110
780 * COMJ[7:6] "AGC gain ceiling"
781 * = 3 (0x03) 11...... "8x"
782 * COMJ[5:4] "Reserved"
783 * = 0 (0x00) ..00....
784 * COMJ[3] "Auto banding filter"
785 * = 0 (0x00) ....0... "Banding filter is always
786 * on off depending on
787 * COMI[5] setting"
788 * COMJ[2] "VSYNC drop option"
789 * = 1 (0x01) .....1.. "SYNC is dropped if frame
790 * data is dropped"
791 * COMJ[1] "Frame data drop"
792 * = 1 (0x01) ......1. "Drop frame data if
793 * exposure is not within
794 * tolerance. In AEC mode,
795 * data is normally dropped
796 * when data is out of
797 * range."
798 * COMJ[0] "Reserved"
799 * = 0 (0x00) .......0
800 */
801 { 0x14, 0xC6 },
802
803 /*
804 * 15 COMK "Common Control K"
805 * = 2 (0x02) 00000010
806 * COMK[7] "CHSYNC pin output swap"
807 * = 0 (0x00) 0....... "CHSYNC"
808 * COMK[6] "HREF pin output swap"
809 * = 0 (0x00) .0...... "HREF"
810 * COMK[5] "PCLK output selection"
811 * = 0 (0x00) ..0..... "PCLK always output"
812 * COMK[4] "PCLK edge selection"
813 * = 0 (0x00) ...0.... "Data valid on falling edge"
814 * COMK[3] "HREF output polarity"
815 * = 0 (0x00) ....0... "positive"
816 * COMK[2] "Reserved"
817 * = 0 (0x00) .....0..
818 * COMK[1] "VSYNC polarity"
819 * = 1 (0x01) ......1. "negative"
820 * COMK[0] "HSYNC polarity"
821 * = 0 (0x00) .......0 "positive"
822 */
823 { 0x15, 0x02 },
824
825 /*
826 * 33 CHLF "Current Control"
827 * = 9 (0x09) 00001001
828 * CHLF[7:6] "Sensor current control"
829 * = 0 (0x00) 00......
830 * CHLF[5] "Sensor current range control"
831 * = 0 (0x00) ..0..... "normal range"
832 * CHLF[4] "Sensor current"
833 * = 0 (0x00) ...0.... "normal current"
834 * CHLF[3] "Sensor buffer current control"
835 * = 1 (0x01) ....1... "half current"
836 * CHLF[2] "Column buffer current control"
837 * = 0 (0x00) .....0.. "normal current"
838 * CHLF[1] "Analog DSP current control"
839 * = 0 (0x00) ......0. "normal current"
840 * CHLF[1] "ADC current control"
841 * = 0 (0x00) ......0. "normal current"
842 */
843 { 0x33, 0x09 },
844
845 /*
846 * 34 VBLM "Blooming Control"
847 * = 80 (0x50) 01010000
848 * VBLM[7] "Hard soft reset switch"
849 * = 0 (0x00) 0....... "Hard reset"
850 * VBLM[6:4] "Blooming voltage selection"
851 * = 5 (0x05) .101....
852 * VBLM[3:0] "Sensor current control"
853 * = 0 (0x00) ....0000
854 */
855 { 0x34, 0x50 },
856
857 /*
858 * 36 VCHG "Sensor Precharge Voltage Control"
859 * = 0 (0x00) 00000000
860 * VCHG[7] "Reserved"
861 * = 0 (0x00) 0.......
862 * VCHG[6:4] "Sensor precharge voltage control"
863 * = 0 (0x00) .000....
864 * VCHG[3:0] "Sensor array common reference"
865 * = 0 (0x00) ....0000
866 */
867 { 0x36, 0x00 },
868
869 /*
870 * 37 ADC "ADC Reference Control"
871 * = 4 (0x04) 00000100
872 * ADC[7:4] "Reserved"
873 * = 0 (0x00) 0000....
874 * ADC[3] "ADC input signal range"
875 * = 0 (0x00) ....0... "Input signal 1.0x"
876 * ADC[2:0] "ADC range control"
877 * = 4 (0x04) .....100
878 */
879 { 0x37, 0x04 },
880
881 /*
882 * 38 ACOM "Analog Common Ground"
883 * = 82 (0x52) 01010010
884 * ACOM[7] "Analog gain control"
885 * = 0 (0x00) 0....... "Gain 1x"
886 * ACOM[6] "Analog black level calibration"
887 * = 1 (0x01) .1...... "On"
888 * ACOM[5:0] "Reserved"
889 * = 18 (0x12) ..010010
890 */
891 { 0x38, 0x52 },
892
893 /*
894 * 3A FREFA "Internal Reference Adjustment"
895 * = 0 (0x00) 00000000
896 * FREFA[7:0] "Range"
897 * = 0 (0x00) 00000000
898 */
899 { 0x3a, 0x00 },
900
901 /*
902 * 3C FVOPT "Internal Reference Adjustment"
903 * = 31 (0x1F) 00011111
904 * FVOPT[7:0] "Range"
905 * = 31 (0x1F) 00011111
906 */
907 { 0x3c, 0x1F },
908
909 /*
910 * 44 Undocumented = 0 (0x00) 00000000
911 * 44[7:0] "It's a secret"
912 * = 0 (0x00) 00000000
913 */
914 { 0x44, 0x00 },
915
916 /*
917 * 40 Undocumented = 0 (0x00) 00000000
918 * 40[7:0] "It's a secret"
919 * = 0 (0x00) 00000000
920 */
921 { 0x40, 0x00 },
922
923 /*
924 * 41 Undocumented = 0 (0x00) 00000000
925 * 41[7:0] "It's a secret"
926 * = 0 (0x00) 00000000
927 */
928 { 0x41, 0x00 },
929
930 /*
931 * 42 Undocumented = 0 (0x00) 00000000
932 * 42[7:0] "It's a secret"
933 * = 0 (0x00) 00000000
934 */
935 { 0x42, 0x00 },
936
937 /*
938 * 43 Undocumented = 0 (0x00) 00000000
939 * 43[7:0] "It's a secret"
940 * = 0 (0x00) 00000000
941 */
942 { 0x43, 0x00 },
943
944 /*
945 * 45 Undocumented = 128 (0x80) 10000000
946 * 45[7:0] "It's a secret"
947 * = 128 (0x80) 10000000
948 */
949 { 0x45, 0x80 },
950
951 /*
952 * 48 Undocumented = 192 (0xC0) 11000000
953 * 48[7:0] "It's a secret"
954 * = 192 (0xC0) 11000000
955 */
956 { 0x48, 0xC0 },
957
958 /*
959 * 49 Undocumented = 25 (0x19) 00011001
960 * 49[7:0] "It's a secret"
961 * = 25 (0x19) 00011001
962 */
963 { 0x49, 0x19 },
964
965 /*
966 * 4B Undocumented = 128 (0x80) 10000000
967 * 4B[7:0] "It's a secret"
968 * = 128 (0x80) 10000000
969 */
970 { 0x4B, 0x80 },
971
972 /*
973 * 4D Undocumented = 196 (0xC4) 11000100
974 * 4D[7:0] "It's a secret"
975 * = 196 (0xC4) 11000100
976 */
977 { 0x4D, 0xC4 },
978
979 /*
980 * 35 VREF "Reference Voltage Control"
981 * = 76 (0x4C) 01001100
982 * VREF[7:5] "Column high reference control"
983 * = 2 (0x02) 010..... "higher voltage"
984 * VREF[4:2] "Column low reference control"
985 * = 3 (0x03) ...011.. "Highest voltage"
986 * VREF[1:0] "Reserved"
987 * = 0 (0x00) ......00
988 */
989 { 0x35, 0x4C },
990
991 /*
992 * 3D Undocumented = 0 (0x00) 00000000
993 * 3D[7:0] "It's a secret"
994 * = 0 (0x00) 00000000
995 */
996 { 0x3D, 0x00 },
997
998 /*
999 * 3E Undocumented = 0 (0x00) 00000000
1000 * 3E[7:0] "It's a secret"
1001 * = 0 (0x00) 00000000
1002 */
1003 { 0x3E, 0x00 },
1004
1005 /*
1006 * 3B FREFB "Internal Reference Adjustment"
1007 * = 24 (0x18) 00011000
1008 * FREFB[7:0] "Range"
1009 * = 24 (0x18) 00011000
1010 */
1011 { 0x3b, 0x18 },
1012
1013 /*
1014 * 33 CHLF "Current Control"
1015 * = 25 (0x19) 00011001
1016 * CHLF[7:6] "Sensor current control"
1017 * = 0 (0x00) 00......
1018 * CHLF[5] "Sensor current range control"
1019 * = 0 (0x00) ..0..... "normal range"
1020 * CHLF[4] "Sensor current"
1021 * = 1 (0x01) ...1.... "double current"
1022 * CHLF[3] "Sensor buffer current control"
1023 * = 1 (0x01) ....1... "half current"
1024 * CHLF[2] "Column buffer current control"
1025 * = 0 (0x00) .....0.. "normal current"
1026 * CHLF[1] "Analog DSP current control"
1027 * = 0 (0x00) ......0. "normal current"
1028 * CHLF[1] "ADC current control"
1029 * = 0 (0x00) ......0. "normal current"
1030 */
1031 { 0x33, 0x19 },
1032
1033 /*
1034 * 34 VBLM "Blooming Control"
1035 * = 90 (0x5A) 01011010
1036 * VBLM[7] "Hard soft reset switch"
1037 * = 0 (0x00) 0....... "Hard reset"
1038 * VBLM[6:4] "Blooming voltage selection"
1039 * = 5 (0x05) .101....
1040 * VBLM[3:0] "Sensor current control"
1041 * = 10 (0x0A) ....1010
1042 */
1043 { 0x34, 0x5A },
1044
1045 /*
1046 * 3B FREFB "Internal Reference Adjustment"
1047 * = 0 (0x00) 00000000
1048 * FREFB[7:0] "Range"
1049 * = 0 (0x00) 00000000
1050 */
1051 { 0x3b, 0x00 },
1052
1053 /*
1054 * 33 CHLF "Current Control"
1055 * = 9 (0x09) 00001001
1056 * CHLF[7:6] "Sensor current control"
1057 * = 0 (0x00) 00......
1058 * CHLF[5] "Sensor current range control"
1059 * = 0 (0x00) ..0..... "normal range"
1060 * CHLF[4] "Sensor current"
1061 * = 0 (0x00) ...0.... "normal current"
1062 * CHLF[3] "Sensor buffer current control"
1063 * = 1 (0x01) ....1... "half current"
1064 * CHLF[2] "Column buffer current control"
1065 * = 0 (0x00) .....0.. "normal current"
1066 * CHLF[1] "Analog DSP current control"
1067 * = 0 (0x00) ......0. "normal current"
1068 * CHLF[1] "ADC current control"
1069 * = 0 (0x00) ......0. "normal current"
1070 */
1071 { 0x33, 0x09 },
1072
1073 /*
1074 * 34 VBLM "Blooming Control"
1075 * = 80 (0x50) 01010000
1076 * VBLM[7] "Hard soft reset switch"
1077 * = 0 (0x00) 0....... "Hard reset"
1078 * VBLM[6:4] "Blooming voltage selection"
1079 * = 5 (0x05) .101....
1080 * VBLM[3:0] "Sensor current control"
1081 * = 0 (0x00) ....0000
1082 */
1083 { 0x34, 0x50 },
1084
1085 /*
1086 * 12 COMH "Common Control H"
1087 * = 64 (0x40) 01000000
1088 * COMH[7] "SRST"
1089 * = 0 (0x00) 0....... "No-op"
1090 * COMH[6:4] "Resolution selection"
1091 * = 4 (0x04) .100.... "XGA"
1092 * COMH[3] "Master slave selection"
1093 * = 0 (0x00) ....0... "Master mode"
1094 * COMH[2] "Internal B/R channel option"
1095 * = 0 (0x00) .....0.. "B/R use same channel"
1096 * COMH[1] "Color bar test pattern"
1097 * = 0 (0x00) ......0. "Off"
1098 * COMH[0] "Reserved"
1099 * = 0 (0x00) .......0
1100 */
1101 { 0x12, 0x40 },
1102
1103 /*
1104 * 17 HREFST "Horizontal window start"
1105 * = 31 (0x1F) 00011111
1106 * HREFST[7:0] "Horizontal window start, 8 MSBs"
1107 * = 31 (0x1F) 00011111
1108 */
1109 { 0x17, 0x1F },
1110
1111 /*
1112 * 18 HREFEND "Horizontal window end"
1113 * = 95 (0x5F) 01011111
1114 * HREFEND[7:0] "Horizontal Window End, 8 MSBs"
1115 * = 95 (0x5F) 01011111
1116 */
1117 { 0x18, 0x5F },
1118
1119 /*
1120 * 19 VSTRT "Vertical window start"
1121 * = 0 (0x00) 00000000
1122 * VSTRT[7:0] "Vertical Window Start, 8 MSBs"
1123 * = 0 (0x00) 00000000
1124 */
1125 { 0x19, 0x00 },
1126
1127 /*
1128 * 1A VEND "Vertical window end"
1129 * = 96 (0x60) 01100000
1130 * VEND[7:0] "Vertical Window End, 8 MSBs"
1131 * = 96 (0x60) 01100000
1132 */
1133 { 0x1a, 0x60 },
1134
1135 /*
1136 * 32 COMM "Common Control M"
1137 * = 18 (0x12) 00010010
1138 * COMM[7:6] "Pixel clock divide option"
1139 * = 0 (0x00) 00...... "/1"
1140 * COMM[5:3] "Horizontal window end position, 3 LSBs"
1141 * = 2 (0x02) ..010...
1142 * COMM[2:0] "Horizontal window start position, 3 LSBs"
1143 * = 2 (0x02) .....010
1144 */
1145 { 0x32, 0x12 },
1146
1147 /*
1148 * 03 COMA "Common Control A"
1149 * = 74 (0x4A) 01001010
1150 * COMA[7:4] "AWB Update Threshold"
1151 * = 4 (0x04) 0100....
1152 * COMA[3:2] "Vertical window end line control 2 LSBs"
1153 * = 2 (0x02) ....10..
1154 * COMA[1:0] "Vertical window start line control 2 LSBs"
1155 * = 2 (0x02) ......10
1156 */
1157 { 0x03, 0x4A },
1158
1159 /*
1160 * 11 CLKRC "Clock Rate Control"
1161 * = 128 (0x80) 10000000
1162 * CLKRC[7] "Internal frequency doublers on off seclection"
1163 * = 1 (0x01) 1....... "On"
1164 * CLKRC[6] "Digital video master slave selection"
1165 * = 0 (0x00) .0...... "Master mode, sensor
1166 * provides PCLK"
1167 * CLKRC[5:0] "Clock divider { CLK = PCLK/(1+CLKRC[5:0]) }"
1168 * = 0 (0x00) ..000000
1169 */
1170 { 0x11, 0x80 },
1171
1172 /*
1173 * 12 COMH "Common Control H"
1174 * = 0 (0x00) 00000000
1175 * COMH[7] "SRST"
1176 * = 0 (0x00) 0....... "No-op"
1177 * COMH[6:4] "Resolution selection"
1178 * = 0 (0x00) .000.... "QXGA"
1179 * COMH[3] "Master slave selection"
1180 * = 0 (0x00) ....0... "Master mode"
1181 * COMH[2] "Internal B/R channel option"
1182 * = 0 (0x00) .....0.. "B/R use same channel"
1183 * COMH[1] "Color bar test pattern"
1184 * = 0 (0x00) ......0. "Off"
1185 * COMH[0] "Reserved"
1186 * = 0 (0x00) .......0
1187 */
1188 { 0x12, 0x00 },
1189
1190 /*
1191 * 12 COMH "Common Control H"
1192 * = 64 (0x40) 01000000
1193 * COMH[7] "SRST"
1194 * = 0 (0x00) 0....... "No-op"
1195 * COMH[6:4] "Resolution selection"
1196 * = 4 (0x04) .100.... "XGA"
1197 * COMH[3] "Master slave selection"
1198 * = 0 (0x00) ....0... "Master mode"
1199 * COMH[2] "Internal B/R channel option"
1200 * = 0 (0x00) .....0.. "B/R use same channel"
1201 * COMH[1] "Color bar test pattern"
1202 * = 0 (0x00) ......0. "Off"
1203 * COMH[0] "Reserved"
1204 * = 0 (0x00) .......0
1205 */
1206 { 0x12, 0x40 },
1207
1208 /*
1209 * 17 HREFST "Horizontal window start"
1210 * = 31 (0x1F) 00011111
1211 * HREFST[7:0] "Horizontal window start, 8 MSBs"
1212 * = 31 (0x1F) 00011111
1213 */
1214 { 0x17, 0x1F },
1215
1216 /*
1217 * 18 HREFEND "Horizontal window end"
1218 * = 95 (0x5F) 01011111
1219 * HREFEND[7:0] "Horizontal Window End, 8 MSBs"
1220 * = 95 (0x5F) 01011111
1221 */
1222 { 0x18, 0x5F },
1223
1224 /*
1225 * 19 VSTRT "Vertical window start"
1226 * = 0 (0x00) 00000000
1227 * VSTRT[7:0] "Vertical Window Start, 8 MSBs"
1228 * = 0 (0x00) 00000000
1229 */
1230 { 0x19, 0x00 },
1231
1232 /*
1233 * 1A VEND "Vertical window end"
1234 * = 96 (0x60) 01100000
1235 * VEND[7:0] "Vertical Window End, 8 MSBs"
1236 * = 96 (0x60) 01100000
1237 */
1238 { 0x1a, 0x60 },
1239
1240 /*
1241 * 32 COMM "Common Control M"
1242 * = 18 (0x12) 00010010
1243 * COMM[7:6] "Pixel clock divide option"
1244 * = 0 (0x00) 00...... "/1"
1245 * COMM[5:3] "Horizontal window end position, 3 LSBs"
1246 * = 2 (0x02) ..010...
1247 * COMM[2:0] "Horizontal window start position, 3 LSBs"
1248 * = 2 (0x02) .....010
1249 */
1250 { 0x32, 0x12 },
1251
1252 /*
1253 * 03 COMA "Common Control A"
1254 * = 74 (0x4A) 01001010
1255 * COMA[7:4] "AWB Update Threshold"
1256 * = 4 (0x04) 0100....
1257 * COMA[3:2] "Vertical window end line control 2 LSBs"
1258 * = 2 (0x02) ....10..
1259 * COMA[1:0] "Vertical window start line control 2 LSBs"
1260 * = 2 (0x02) ......10
1261 */
1262 { 0x03, 0x4A },
1263
1264 /*
1265 * 02 RED "Red Gain Control"
1266 * = 175 (0xAF) 10101111
1267 * RED[7] "Action"
1268 * = 1 (0x01) 1....... "gain = 1/(1+bitrev([6:0]))"
1269 * RED[6:0] "Value"
1270 * = 47 (0x2F) .0101111
1271 */
1272 { 0x02, 0xAF },
1273
1274 /*
1275 * 2D ADDVSL "VSYNC Pulse Width"
1276 * = 210 (0xD2) 11010010
1277 * ADDVSL[7:0] "VSYNC pulse width, LSB"
1278 * = 210 (0xD2) 11010010
1279 */
1280 { 0x2d, 0xD2 },
1281
1282 /*
1283 * 00 GAIN = 24 (0x18) 00011000
1284 * GAIN[7:6] "Reserved"
1285 * = 0 (0x00) 00......
1286 * GAIN[5] "Double"
1287 * = 0 (0x00) ..0..... "False"
1288 * GAIN[4] "Double"
1289 * = 1 (0x01) ...1.... "True"
1290 * GAIN[3:0] "Range"
1291 * = 8 (0x08) ....1000
1292 */
1293 { 0x00, 0x18 },
1294
1295 /*
1296 * 01 BLUE "Blue Gain Control"
1297 * = 240 (0xF0) 11110000
1298 * BLUE[7] "Action"
1299 * = 1 (0x01) 1....... "gain = 1/(1+bitrev([6:0]))"
1300 * BLUE[6:0] "Value"
1301 * = 112 (0x70) .1110000
1302 */
1303 { 0x01, 0xF0 },
1304
1305 /*
1306 * 10 AEC "Automatic Exposure Control"
1307 * = 10 (0x0A) 00001010
1308 * AEC[7:0] "Automatic Exposure Control, 8 MSBs"
1309 * = 10 (0x0A) 00001010
1310 */
1311 { 0x10, 0x0A },
1312
1313 { 0xE1, 0x67 },
1314 { 0xE3, 0x03 },
1315 { 0xE4, 0x26 },
1316 { 0xE5, 0x3E },
1317 { 0xF8, 0x01 },
1318 { 0xFF, 0x01 },
1319};
1320
511static const struct ov_i2c_regvals norm_6x20[] = { 1321static const struct ov_i2c_regvals norm_6x20[] = {
512 { 0x12, 0x80 }, /* reset */ 1322 { 0x12, 0x80 }, /* reset */
513 { 0x11, 0x01 }, 1323 { 0x11, 0x01 },
@@ -678,6 +1488,7 @@ static const struct ov_i2c_regvals norm_7610[] = {
678}; 1488};
679 1489
680static const struct ov_i2c_regvals norm_7620[] = { 1490static const struct ov_i2c_regvals norm_7620[] = {
1491 { 0x12, 0x80 }, /* reset */
681 { 0x00, 0x00 }, /* gain */ 1492 { 0x00, 0x00 }, /* gain */
682 { 0x01, 0x80 }, /* blue gain */ 1493 { 0x01, 0x80 }, /* blue gain */
683 { 0x02, 0x80 }, /* red gain */ 1494 { 0x02, 0x80 }, /* red gain */
@@ -1042,10 +1853,28 @@ static unsigned char ov7670_abs_to_sm(unsigned char v)
1042} 1853}
1043 1854
1044/* Write a OV519 register */ 1855/* Write a OV519 register */
1045static int reg_w(struct sd *sd, __u16 index, __u8 value) 1856static int reg_w(struct sd *sd, __u16 index, __u16 value)
1046{ 1857{
1047 int ret; 1858 int ret, req = 0;
1048 int req = (sd->bridge <= BRIDGE_OV511PLUS) ? 2 : 1; 1859
1860 switch (sd->bridge) {
1861 case BRIDGE_OV511:
1862 case BRIDGE_OV511PLUS:
1863 req = 2;
1864 break;
1865 case BRIDGE_OVFX2:
1866 req = 0x0a;
1867 /* fall through */
1868 case BRIDGE_W9968CF:
1869 ret = usb_control_msg(sd->gspca_dev.dev,
1870 usb_sndctrlpipe(sd->gspca_dev.dev, 0),
1871 req,
1872 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
1873 value, index, NULL, 0, 500);
1874 goto leave;
1875 default:
1876 req = 1;
1877 }
1049 1878
1050 sd->gspca_dev.usb_buf[0] = value; 1879 sd->gspca_dev.usb_buf[0] = value;
1051 ret = usb_control_msg(sd->gspca_dev.dev, 1880 ret = usb_control_msg(sd->gspca_dev.dev,
@@ -1054,17 +1883,35 @@ static int reg_w(struct sd *sd, __u16 index, __u8 value)
1054 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 1883 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
1055 0, index, 1884 0, index,
1056 sd->gspca_dev.usb_buf, 1, 500); 1885 sd->gspca_dev.usb_buf, 1, 500);
1057 if (ret < 0) 1886leave:
1058 PDEBUG(D_ERR, "Write reg [%02x] %02x failed", index, value); 1887 if (ret < 0) {
1059 return ret; 1888 PDEBUG(D_ERR, "Write reg 0x%04x -> [0x%02x] failed",
1889 value, index);
1890 return ret;
1891 }
1892
1893 PDEBUG(D_USBO, "Write reg 0x%04x -> [0x%02x]", value, index);
1894 return 0;
1060} 1895}
1061 1896
1062/* Read from a OV519 register */ 1897/* Read from a OV519 register, note not valid for the w9968cf!! */
1063/* returns: negative is error, pos or zero is data */ 1898/* returns: negative is error, pos or zero is data */
1064static int reg_r(struct sd *sd, __u16 index) 1899static int reg_r(struct sd *sd, __u16 index)
1065{ 1900{
1066 int ret; 1901 int ret;
1067 int req = (sd->bridge <= BRIDGE_OV511PLUS) ? 3 : 1; 1902 int req;
1903
1904 switch (sd->bridge) {
1905 case BRIDGE_OV511:
1906 case BRIDGE_OV511PLUS:
1907 req = 3;
1908 break;
1909 case BRIDGE_OVFX2:
1910 req = 0x0b;
1911 break;
1912 default:
1913 req = 1;
1914 }
1068 1915
1069 ret = usb_control_msg(sd->gspca_dev.dev, 1916 ret = usb_control_msg(sd->gspca_dev.dev,
1070 usb_rcvctrlpipe(sd->gspca_dev.dev, 0), 1917 usb_rcvctrlpipe(sd->gspca_dev.dev, 0),
@@ -1072,10 +1919,12 @@ static int reg_r(struct sd *sd, __u16 index)
1072 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 1919 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
1073 0, index, sd->gspca_dev.usb_buf, 1, 500); 1920 0, index, sd->gspca_dev.usb_buf, 1, 500);
1074 1921
1075 if (ret >= 0) 1922 if (ret >= 0) {
1076 ret = sd->gspca_dev.usb_buf[0]; 1923 ret = sd->gspca_dev.usb_buf[0];
1077 else 1924 PDEBUG(D_USBI, "Read reg [0x%02X] -> 0x%04X", index, ret);
1925 } else
1078 PDEBUG(D_ERR, "Read reg [0x%02x] failed", index); 1926 PDEBUG(D_ERR, "Read reg [0x%02x] failed", index);
1927
1079 return ret; 1928 return ret;
1080} 1929}
1081 1930
@@ -1095,6 +1944,7 @@ static int reg_r8(struct sd *sd,
1095 ret = sd->gspca_dev.usb_buf[0]; 1944 ret = sd->gspca_dev.usb_buf[0];
1096 else 1945 else
1097 PDEBUG(D_ERR, "Read reg 8 [0x%02x] failed", index); 1946 PDEBUG(D_ERR, "Read reg 8 [0x%02x] failed", index);
1947
1098 return ret; 1948 return ret;
1099} 1949}
1100 1950
@@ -1140,9 +1990,12 @@ static int ov518_reg_w32(struct sd *sd, __u16 index, u32 value, int n)
1140 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 1990 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
1141 0, index, 1991 0, index,
1142 sd->gspca_dev.usb_buf, n, 500); 1992 sd->gspca_dev.usb_buf, n, 500);
1143 if (ret < 0) 1993 if (ret < 0) {
1144 PDEBUG(D_ERR, "Write reg32 [%02x] %08x failed", index, value); 1994 PDEBUG(D_ERR, "Write reg32 [%02x] %08x failed", index, value);
1145 return ret; 1995 return ret;
1996 }
1997
1998 return 0;
1146} 1999}
1147 2000
1148static int ov511_i2c_w(struct sd *sd, __u8 reg, __u8 value) 2001static int ov511_i2c_w(struct sd *sd, __u8 reg, __u8 value)
@@ -1324,32 +2177,110 @@ static int ov518_i2c_r(struct sd *sd, __u8 reg)
1324 return value; 2177 return value;
1325} 2178}
1326 2179
2180static int ovfx2_i2c_w(struct sd *sd, __u8 reg, __u8 value)
2181{
2182 int ret;
2183
2184 ret = usb_control_msg(sd->gspca_dev.dev,
2185 usb_sndctrlpipe(sd->gspca_dev.dev, 0),
2186 0x02,
2187 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
2188 (__u16)value, (__u16)reg, NULL, 0, 500);
2189
2190 if (ret < 0) {
2191 PDEBUG(D_ERR, "i2c 0x%02x -> [0x%02x] failed", value, reg);
2192 return ret;
2193 }
2194
2195 PDEBUG(D_USBO, "i2c 0x%02x -> [0x%02x]", value, reg);
2196 return 0;
2197}
2198
2199static int ovfx2_i2c_r(struct sd *sd, __u8 reg)
2200{
2201 int ret;
2202
2203 ret = usb_control_msg(sd->gspca_dev.dev,
2204 usb_rcvctrlpipe(sd->gspca_dev.dev, 0),
2205 0x03,
2206 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
2207 0, (__u16)reg, sd->gspca_dev.usb_buf, 1, 500);
2208
2209 if (ret >= 0) {
2210 ret = sd->gspca_dev.usb_buf[0];
2211 PDEBUG(D_USBI, "i2c [0x%02X] -> 0x%02X", reg, ret);
2212 } else
2213 PDEBUG(D_ERR, "i2c read [0x%02x] failed", reg);
2214
2215 return ret;
2216}
2217
1327static int i2c_w(struct sd *sd, __u8 reg, __u8 value) 2218static int i2c_w(struct sd *sd, __u8 reg, __u8 value)
1328{ 2219{
2220 int ret = -1;
2221
2222 if (sd->sensor_reg_cache[reg] == value)
2223 return 0;
2224
1329 switch (sd->bridge) { 2225 switch (sd->bridge) {
1330 case BRIDGE_OV511: 2226 case BRIDGE_OV511:
1331 case BRIDGE_OV511PLUS: 2227 case BRIDGE_OV511PLUS:
1332 return ov511_i2c_w(sd, reg, value); 2228 ret = ov511_i2c_w(sd, reg, value);
2229 break;
1333 case BRIDGE_OV518: 2230 case BRIDGE_OV518:
1334 case BRIDGE_OV518PLUS: 2231 case BRIDGE_OV518PLUS:
1335 case BRIDGE_OV519: 2232 case BRIDGE_OV519:
1336 return ov518_i2c_w(sd, reg, value); 2233 ret = ov518_i2c_w(sd, reg, value);
2234 break;
2235 case BRIDGE_OVFX2:
2236 ret = ovfx2_i2c_w(sd, reg, value);
2237 break;
2238 case BRIDGE_W9968CF:
2239 ret = w9968cf_i2c_w(sd, reg, value);
2240 break;
1337 } 2241 }
1338 return -1; /* Should never happen */ 2242
2243 if (ret >= 0) {
2244 /* Up on sensor reset empty the register cache */
2245 if (reg == 0x12 && (value & 0x80))
2246 memset(sd->sensor_reg_cache, -1,
2247 sizeof(sd->sensor_reg_cache));
2248 else
2249 sd->sensor_reg_cache[reg] = value;
2250 }
2251
2252 return ret;
1339} 2253}
1340 2254
1341static int i2c_r(struct sd *sd, __u8 reg) 2255static int i2c_r(struct sd *sd, __u8 reg)
1342{ 2256{
2257 int ret = -1;
2258
2259 if (sd->sensor_reg_cache[reg] != -1)
2260 return sd->sensor_reg_cache[reg];
2261
1343 switch (sd->bridge) { 2262 switch (sd->bridge) {
1344 case BRIDGE_OV511: 2263 case BRIDGE_OV511:
1345 case BRIDGE_OV511PLUS: 2264 case BRIDGE_OV511PLUS:
1346 return ov511_i2c_r(sd, reg); 2265 ret = ov511_i2c_r(sd, reg);
2266 break;
1347 case BRIDGE_OV518: 2267 case BRIDGE_OV518:
1348 case BRIDGE_OV518PLUS: 2268 case BRIDGE_OV518PLUS:
1349 case BRIDGE_OV519: 2269 case BRIDGE_OV519:
1350 return ov518_i2c_r(sd, reg); 2270 ret = ov518_i2c_r(sd, reg);
2271 break;
2272 case BRIDGE_OVFX2:
2273 ret = ovfx2_i2c_r(sd, reg);
2274 break;
2275 case BRIDGE_W9968CF:
2276 ret = w9968cf_i2c_r(sd, reg);
2277 break;
1351 } 2278 }
1352 return -1; /* Should never happen */ 2279
2280 if (ret >= 0)
2281 sd->sensor_reg_cache[reg] = ret;
2282
2283 return ret;
1353} 2284}
1354 2285
1355/* Writes bits at positions specified by mask to an I2C reg. Bits that are in 2286/* Writes bits at positions specified by mask to an I2C reg. Bits that are in
@@ -1389,6 +2320,10 @@ static inline int ov51x_stop(struct sd *sd)
1389 return reg_w_mask(sd, R51x_SYS_RESET, 0x3a, 0x3a); 2320 return reg_w_mask(sd, R51x_SYS_RESET, 0x3a, 0x3a);
1390 case BRIDGE_OV519: 2321 case BRIDGE_OV519:
1391 return reg_w(sd, OV519_SYS_RESET1, 0x0f); 2322 return reg_w(sd, OV519_SYS_RESET1, 0x0f);
2323 case BRIDGE_OVFX2:
2324 return reg_w_mask(sd, 0x0f, 0x00, 0x02);
2325 case BRIDGE_W9968CF:
2326 return reg_w(sd, 0x3c, 0x0a05); /* stop USB transfer */
1392 } 2327 }
1393 2328
1394 return 0; 2329 return 0;
@@ -1418,18 +2353,27 @@ static inline int ov51x_restart(struct sd *sd)
1418 return reg_w(sd, R51x_SYS_RESET, 0x00); 2353 return reg_w(sd, R51x_SYS_RESET, 0x00);
1419 case BRIDGE_OV519: 2354 case BRIDGE_OV519:
1420 return reg_w(sd, OV519_SYS_RESET1, 0x00); 2355 return reg_w(sd, OV519_SYS_RESET1, 0x00);
2356 case BRIDGE_OVFX2:
2357 return reg_w_mask(sd, 0x0f, 0x02, 0x02);
2358 case BRIDGE_W9968CF:
2359 return reg_w(sd, 0x3c, 0x8a05); /* USB FIFO enable */
1421 } 2360 }
1422 2361
1423 return 0; 2362 return 0;
1424} 2363}
1425 2364
2365static int ov51x_set_slave_ids(struct sd *sd, __u8 slave);
2366
1426/* This does an initial reset of an OmniVision sensor and ensures that I2C 2367/* This does an initial reset of an OmniVision sensor and ensures that I2C
1427 * is synchronized. Returns <0 on failure. 2368 * is synchronized. Returns <0 on failure.
1428 */ 2369 */
1429static int init_ov_sensor(struct sd *sd) 2370static int init_ov_sensor(struct sd *sd, __u8 slave)
1430{ 2371{
1431 int i; 2372 int i;
1432 2373
2374 if (ov51x_set_slave_ids(sd, slave) < 0)
2375 return -EIO;
2376
1433 /* Reset the sensor */ 2377 /* Reset the sensor */
1434 if (i2c_w(sd, 0x12, 0x80) < 0) 2378 if (i2c_w(sd, 0x12, 0x80) < 0)
1435 return -EIO; 2379 return -EIO;
@@ -1466,6 +2410,14 @@ static int ov51x_set_slave_ids(struct sd *sd,
1466{ 2410{
1467 int rc; 2411 int rc;
1468 2412
2413 switch (sd->bridge) {
2414 case BRIDGE_OVFX2:
2415 return reg_w(sd, OVFX2_I2C_ADDR, slave);
2416 case BRIDGE_W9968CF:
2417 sd->sensor_addr = slave;
2418 return 0;
2419 }
2420
1469 rc = reg_w(sd, R51x_I2C_W_SID, slave); 2421 rc = reg_w(sd, R51x_I2C_W_SID, slave);
1470 if (rc < 0) 2422 if (rc < 0)
1471 return rc; 2423 return rc;
@@ -1508,6 +2460,39 @@ static int write_i2c_regvals(struct sd *sd,
1508 * 2460 *
1509 ***************************************************************************/ 2461 ***************************************************************************/
1510 2462
2463/* This initializes the OV2x10 / OV3610 / OV3620 */
2464static int ov_hires_configure(struct sd *sd)
2465{
2466 int high, low;
2467
2468 if (sd->bridge != BRIDGE_OVFX2) {
2469 PDEBUG(D_ERR, "error hires sensors only supported with ovfx2");
2470 return -1;
2471 }
2472
2473 PDEBUG(D_PROBE, "starting ov hires configuration");
2474
2475 /* Detect sensor (sub)type */
2476 high = i2c_r(sd, 0x0a);
2477 low = i2c_r(sd, 0x0b);
2478 /* info("%x, %x", high, low); */
2479 if (high == 0x96 && low == 0x40) {
2480 PDEBUG(D_PROBE, "Sensor is an OV2610");
2481 sd->sensor = SEN_OV2610;
2482 } else if (high == 0x36 && (low & 0x0f) == 0x00) {
2483 PDEBUG(D_PROBE, "Sensor is an OV3610");
2484 sd->sensor = SEN_OV3610;
2485 } else {
2486 PDEBUG(D_ERR, "Error unknown sensor type: 0x%02x%02x",
2487 high, low);
2488 return -1;
2489 }
2490
2491 /* Set sensor-specific vars */
2492 return 0;
2493}
2494
2495
1511/* This initializes the OV8110, OV8610 sensor. The OV8110 uses 2496/* This initializes the OV8110, OV8610 sensor. The OV8110 uses
1512 * the same register settings as the OV8610, since they are very similar. 2497 * the same register settings as the OV8610, since they are very similar.
1513 */ 2498 */
@@ -1966,12 +2951,29 @@ static int ov519_configure(struct sd *sd)
1966 return write_regvals(sd, init_519, ARRAY_SIZE(init_519)); 2951 return write_regvals(sd, init_519, ARRAY_SIZE(init_519));
1967} 2952}
1968 2953
2954static int ovfx2_configure(struct sd *sd)
2955{
2956 static const struct ov_regvals init_fx2[] = {
2957 { 0x00, 0x60 },
2958 { 0x02, 0x01 },
2959 { 0x0f, 0x1d },
2960 { 0xe9, 0x82 },
2961 { 0xea, 0xc7 },
2962 { 0xeb, 0x10 },
2963 { 0xec, 0xf6 },
2964 };
2965
2966 sd->stopped = 1;
2967
2968 return write_regvals(sd, init_fx2, ARRAY_SIZE(init_fx2));
2969}
2970
1969/* this function is called at probe time */ 2971/* this function is called at probe time */
1970static int sd_config(struct gspca_dev *gspca_dev, 2972static int sd_config(struct gspca_dev *gspca_dev,
1971 const struct usb_device_id *id) 2973 const struct usb_device_id *id)
1972{ 2974{
1973 struct sd *sd = (struct sd *) gspca_dev; 2975 struct sd *sd = (struct sd *) gspca_dev;
1974 struct cam *cam; 2976 struct cam *cam = &gspca_dev->cam;
1975 int ret = 0; 2977 int ret = 0;
1976 2978
1977 sd->bridge = id->driver_info & BRIDGE_MASK; 2979 sd->bridge = id->driver_info & BRIDGE_MASK;
@@ -1989,6 +2991,16 @@ static int sd_config(struct gspca_dev *gspca_dev,
1989 case BRIDGE_OV519: 2991 case BRIDGE_OV519:
1990 ret = ov519_configure(sd); 2992 ret = ov519_configure(sd);
1991 break; 2993 break;
2994 case BRIDGE_OVFX2:
2995 ret = ovfx2_configure(sd);
2996 cam->bulk_size = OVFX2_BULK_SIZE;
2997 cam->bulk_nurbs = MAX_NURBS;
2998 cam->bulk = 1;
2999 break;
3000 case BRIDGE_W9968CF:
3001 ret = w9968cf_configure(sd);
3002 cam->reverse_alts = 1;
3003 break;
1992 } 3004 }
1993 3005
1994 if (ret) 3006 if (ret)
@@ -1996,49 +3008,39 @@ static int sd_config(struct gspca_dev *gspca_dev,
1996 3008
1997 ov51x_led_control(sd, 0); /* turn LED off */ 3009 ov51x_led_control(sd, 0); /* turn LED off */
1998 3010
1999 /* Test for 76xx */
2000 if (ov51x_set_slave_ids(sd, OV7xx0_SID) < 0)
2001 goto error;
2002
2003 /* The OV519 must be more aggressive about sensor detection since 3011 /* The OV519 must be more aggressive about sensor detection since
2004 * I2C write will never fail if the sensor is not present. We have 3012 * I2C write will never fail if the sensor is not present. We have
2005 * to try to initialize the sensor to detect its presence */ 3013 * to try to initialize the sensor to detect its presence */
2006 if (init_ov_sensor(sd) >= 0) { 3014
3015 /* Test for 76xx */
3016 if (init_ov_sensor(sd, OV7xx0_SID) >= 0) {
2007 if (ov7xx0_configure(sd) < 0) { 3017 if (ov7xx0_configure(sd) < 0) {
2008 PDEBUG(D_ERR, "Failed to configure OV7xx0"); 3018 PDEBUG(D_ERR, "Failed to configure OV7xx0");
2009 goto error; 3019 goto error;
2010 } 3020 }
2011 } else { 3021 /* Test for 6xx0 */
2012 3022 } else if (init_ov_sensor(sd, OV6xx0_SID) >= 0) {
2013 /* Test for 6xx0 */ 3023 if (ov6xx0_configure(sd) < 0) {
2014 if (ov51x_set_slave_ids(sd, OV6xx0_SID) < 0) 3024 PDEBUG(D_ERR, "Failed to configure OV6xx0");
3025 goto error;
3026 }
3027 /* Test for 8xx0 */
3028 } else if (init_ov_sensor(sd, OV8xx0_SID) >= 0) {
3029 if (ov8xx0_configure(sd) < 0) {
3030 PDEBUG(D_ERR, "Failed to configure OV8xx0");
2015 goto error; 3031 goto error;
2016
2017 if (init_ov_sensor(sd) >= 0) {
2018 if (ov6xx0_configure(sd) < 0) {
2019 PDEBUG(D_ERR, "Failed to configure OV6xx0");
2020 goto error;
2021 }
2022 } else {
2023
2024 /* Test for 8xx0 */
2025 if (ov51x_set_slave_ids(sd, OV8xx0_SID) < 0)
2026 goto error;
2027
2028 if (init_ov_sensor(sd) < 0) {
2029 PDEBUG(D_ERR,
2030 "Can't determine sensor slave IDs");
2031 goto error;
2032 }
2033 if (ov8xx0_configure(sd) < 0) {
2034 PDEBUG(D_ERR,
2035 "Failed to configure OV8xx0 sensor");
2036 goto error;
2037 }
2038 } 3032 }
3033 /* Test for 3xxx / 2xxx */
3034 } else if (init_ov_sensor(sd, OV_HIRES_SID) >= 0) {
3035 if (ov_hires_configure(sd) < 0) {
3036 PDEBUG(D_ERR, "Failed to configure high res OV");
3037 goto error;
3038 }
3039 } else {
3040 PDEBUG(D_ERR, "Can't determine sensor slave IDs");
3041 goto error;
2039 } 3042 }
2040 3043
2041 cam = &gspca_dev->cam;
2042 switch (sd->bridge) { 3044 switch (sd->bridge) {
2043 case BRIDGE_OV511: 3045 case BRIDGE_OV511:
2044 case BRIDGE_OV511PLUS: 3046 case BRIDGE_OV511PLUS:
@@ -2069,6 +3071,31 @@ static int sd_config(struct gspca_dev *gspca_dev,
2069 cam->nmodes = ARRAY_SIZE(ov519_sif_mode); 3071 cam->nmodes = ARRAY_SIZE(ov519_sif_mode);
2070 } 3072 }
2071 break; 3073 break;
3074 case BRIDGE_OVFX2:
3075 if (sd->sensor == SEN_OV2610) {
3076 cam->cam_mode = ovfx2_ov2610_mode;
3077 cam->nmodes = ARRAY_SIZE(ovfx2_ov2610_mode);
3078 } else if (sd->sensor == SEN_OV3610) {
3079 cam->cam_mode = ovfx2_ov3610_mode;
3080 cam->nmodes = ARRAY_SIZE(ovfx2_ov3610_mode);
3081 } else if (!sd->sif) {
3082 cam->cam_mode = ov519_vga_mode;
3083 cam->nmodes = ARRAY_SIZE(ov519_vga_mode);
3084 } else {
3085 cam->cam_mode = ov519_sif_mode;
3086 cam->nmodes = ARRAY_SIZE(ov519_sif_mode);
3087 }
3088 break;
3089 case BRIDGE_W9968CF:
3090 cam->cam_mode = w9968cf_vga_mode;
3091 cam->nmodes = ARRAY_SIZE(w9968cf_vga_mode);
3092 if (sd->sif)
3093 cam->nmodes--;
3094
3095 /* w9968cf needs initialisation once the sensor is known */
3096 if (w9968cf_init(sd) < 0)
3097 goto error;
3098 break;
2072 } 3099 }
2073 sd->brightness = BRIGHTNESS_DEF; 3100 sd->brightness = BRIGHTNESS_DEF;
2074 if (sd->sensor == SEN_OV6630 || sd->sensor == SEN_OV66308AF) 3101 if (sd->sensor == SEN_OV6630 || sd->sensor == SEN_OV66308AF)
@@ -2087,11 +3114,15 @@ static int sd_config(struct gspca_dev *gspca_dev,
2087 gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX) | 3114 gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX) |
2088 (1 << OV7670_FREQ_IDX); 3115 (1 << OV7670_FREQ_IDX);
2089 } 3116 }
3117 sd->quality = QUALITY_DEF;
2090 if (sd->sensor == SEN_OV7640 || sd->sensor == SEN_OV7670) 3118 if (sd->sensor == SEN_OV7640 || sd->sensor == SEN_OV7670)
2091 gspca_dev->ctrl_dis |= 1 << AUTOBRIGHT_IDX; 3119 gspca_dev->ctrl_dis |= 1 << AUTOBRIGHT_IDX;
2092 /* OV8610 Frequency filter control should work but needs testing */ 3120 /* OV8610 Frequency filter control should work but needs testing */
2093 if (sd->sensor == SEN_OV8610) 3121 if (sd->sensor == SEN_OV8610)
2094 gspca_dev->ctrl_dis |= 1 << FREQ_IDX; 3122 gspca_dev->ctrl_dis |= 1 << FREQ_IDX;
3123 /* No controls for the OV2610/OV3610 */
3124 if (sd->sensor == SEN_OV2610 || sd->sensor == SEN_OV3610)
3125 gspca_dev->ctrl_dis |= 0xFF;
2095 3126
2096 return 0; 3127 return 0;
2097error: 3128error:
@@ -2106,6 +3137,20 @@ static int sd_init(struct gspca_dev *gspca_dev)
2106 3137
2107 /* initialize the sensor */ 3138 /* initialize the sensor */
2108 switch (sd->sensor) { 3139 switch (sd->sensor) {
3140 case SEN_OV2610:
3141 if (write_i2c_regvals(sd, norm_2610, ARRAY_SIZE(norm_2610)))
3142 return -EIO;
3143 /* Enable autogain, autoexpo, awb, bandfilter */
3144 if (i2c_w_mask(sd, 0x13, 0x27, 0x27) < 0)
3145 return -EIO;
3146 break;
3147 case SEN_OV3610:
3148 if (write_i2c_regvals(sd, norm_3620b, ARRAY_SIZE(norm_3620b)))
3149 return -EIO;
3150 /* Enable autogain, autoexpo, awb, bandfilter */
3151 if (i2c_w_mask(sd, 0x13, 0x27, 0x27) < 0)
3152 return -EIO;
3153 break;
2109 case SEN_OV6620: 3154 case SEN_OV6620:
2110 if (write_i2c_regvals(sd, norm_6x20, ARRAY_SIZE(norm_6x20))) 3155 if (write_i2c_regvals(sd, norm_6x20, ARRAY_SIZE(norm_6x20)))
2111 return -EIO; 3156 return -EIO;
@@ -2548,19 +3593,60 @@ static int ov519_mode_init_regs(struct sd *sd)
2548static int mode_init_ov_sensor_regs(struct sd *sd) 3593static int mode_init_ov_sensor_regs(struct sd *sd)
2549{ 3594{
2550 struct gspca_dev *gspca_dev; 3595 struct gspca_dev *gspca_dev;
2551 int qvga; 3596 int qvga, xstart, xend, ystart, yend;
3597 __u8 v;
2552 3598
2553 gspca_dev = &sd->gspca_dev; 3599 gspca_dev = &sd->gspca_dev;
2554 qvga = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv & 1; 3600 qvga = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv & 1;
2555 3601
2556 /******** Mode (VGA/QVGA) and sensor specific regs ********/ 3602 /******** Mode (VGA/QVGA) and sensor specific regs ********/
2557 switch (sd->sensor) { 3603 switch (sd->sensor) {
3604 case SEN_OV2610:
3605 i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
3606 i2c_w_mask(sd, 0x28, qvga ? 0x00 : 0x20, 0x20);
3607 i2c_w(sd, 0x24, qvga ? 0x20 : 0x3a);
3608 i2c_w(sd, 0x25, qvga ? 0x30 : 0x60);
3609 i2c_w_mask(sd, 0x2d, qvga ? 0x40 : 0x00, 0x40);
3610 i2c_w_mask(sd, 0x67, qvga ? 0xf0 : 0x90, 0xf0);
3611 i2c_w_mask(sd, 0x74, qvga ? 0x20 : 0x00, 0x20);
3612 return 0;
3613 case SEN_OV3610:
3614 if (qvga) {
3615 xstart = (1040 - gspca_dev->width) / 2 + (0x1f << 4);
3616 ystart = (776 - gspca_dev->height) / 2;
3617 } else {
3618 xstart = (2076 - gspca_dev->width) / 2 + (0x10 << 4);
3619 ystart = (1544 - gspca_dev->height) / 2;
3620 }
3621 xend = xstart + gspca_dev->width;
3622 yend = ystart + gspca_dev->height;
3623 /* Writing to the COMH register resets the other windowing regs
3624 to their default values, so we must do this first. */
3625 i2c_w_mask(sd, 0x12, qvga ? 0x40 : 0x00, 0xf0);
3626 i2c_w_mask(sd, 0x32,
3627 (((xend >> 1) & 7) << 3) | ((xstart >> 1) & 7),
3628 0x3f);
3629 i2c_w_mask(sd, 0x03,
3630 (((yend >> 1) & 3) << 2) | ((ystart >> 1) & 3),
3631 0x0f);
3632 i2c_w(sd, 0x17, xstart >> 4);
3633 i2c_w(sd, 0x18, xend >> 4);
3634 i2c_w(sd, 0x19, ystart >> 3);
3635 i2c_w(sd, 0x1a, yend >> 3);
3636 return 0;
2558 case SEN_OV8610: 3637 case SEN_OV8610:
2559 /* For OV8610 qvga means qsvga */ 3638 /* For OV8610 qvga means qsvga */
2560 i2c_w_mask(sd, OV7610_REG_COM_C, qvga ? (1 << 5) : 0, 1 << 5); 3639 i2c_w_mask(sd, OV7610_REG_COM_C, qvga ? (1 << 5) : 0, 1 << 5);
3640 i2c_w_mask(sd, 0x13, 0x00, 0x20); /* Select 16 bit data bus */
3641 i2c_w_mask(sd, 0x12, 0x04, 0x06); /* AWB: 1 Test pattern: 0 */
3642 i2c_w_mask(sd, 0x2d, 0x00, 0x40); /* from windrv 090403 */
3643 i2c_w_mask(sd, 0x28, 0x20, 0x20); /* progressive mode on */
2561 break; 3644 break;
2562 case SEN_OV7610: 3645 case SEN_OV7610:
2563 i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20); 3646 i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
3647 i2c_w(sd, 0x35, qvga?0x1e:0x9e);
3648 i2c_w_mask(sd, 0x13, 0x00, 0x20); /* Select 16 bit data bus */
3649 i2c_w_mask(sd, 0x12, 0x04, 0x06); /* AWB: 1 Test pattern: 0 */
2564 break; 3650 break;
2565 case SEN_OV7620: 3651 case SEN_OV7620:
2566 case SEN_OV76BE: 3652 case SEN_OV76BE:
@@ -2571,6 +3657,10 @@ static int mode_init_ov_sensor_regs(struct sd *sd)
2571 i2c_w_mask(sd, 0x2d, qvga ? 0x40 : 0x00, 0x40); 3657 i2c_w_mask(sd, 0x2d, qvga ? 0x40 : 0x00, 0x40);
2572 i2c_w_mask(sd, 0x67, qvga ? 0xb0 : 0x90, 0xf0); 3658 i2c_w_mask(sd, 0x67, qvga ? 0xb0 : 0x90, 0xf0);
2573 i2c_w_mask(sd, 0x74, qvga ? 0x20 : 0x00, 0x20); 3659 i2c_w_mask(sd, 0x74, qvga ? 0x20 : 0x00, 0x20);
3660 i2c_w_mask(sd, 0x13, 0x00, 0x20); /* Select 16 bit data bus */
3661 i2c_w_mask(sd, 0x12, 0x04, 0x06); /* AWB: 1 Test pattern: 0 */
3662 if (sd->sensor == SEN_OV76BE)
3663 i2c_w(sd, 0x35, qvga ? 0x1e : 0x9e);
2574 break; 3664 break;
2575 case SEN_OV7640: 3665 case SEN_OV7640:
2576 i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20); 3666 i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
@@ -2580,6 +3670,7 @@ static int mode_init_ov_sensor_regs(struct sd *sd)
2580/* i2c_w_mask(sd, 0x2d, qvga ? 0x40 : 0x00, 0x40); */ 3670/* i2c_w_mask(sd, 0x2d, qvga ? 0x40 : 0x00, 0x40); */
2581/* i2c_w_mask(sd, 0x67, qvga ? 0xf0 : 0x90, 0xf0); */ 3671/* i2c_w_mask(sd, 0x67, qvga ? 0xf0 : 0x90, 0xf0); */
2582/* i2c_w_mask(sd, 0x74, qvga ? 0x20 : 0x00, 0x20); */ 3672/* i2c_w_mask(sd, 0x74, qvga ? 0x20 : 0x00, 0x20); */
3673 i2c_w_mask(sd, 0x12, 0x04, 0x04); /* AWB: 1 */
2583 break; 3674 break;
2584 case SEN_OV7670: 3675 case SEN_OV7670:
2585 /* set COM7_FMT_VGA or COM7_FMT_QVGA 3676 /* set COM7_FMT_VGA or COM7_FMT_QVGA
@@ -2588,55 +3679,56 @@ static int mode_init_ov_sensor_regs(struct sd *sd)
2588 i2c_w_mask(sd, OV7670_REG_COM7, 3679 i2c_w_mask(sd, OV7670_REG_COM7,
2589 qvga ? OV7670_COM7_FMT_QVGA : OV7670_COM7_FMT_VGA, 3680 qvga ? OV7670_COM7_FMT_QVGA : OV7670_COM7_FMT_VGA,
2590 OV7670_COM7_FMT_MASK); 3681 OV7670_COM7_FMT_MASK);
3682 i2c_w_mask(sd, 0x13, 0x00, 0x20); /* Select 16 bit data bus */
3683 i2c_w_mask(sd, OV7670_REG_COM8, OV7670_COM8_AWB,
3684 OV7670_COM8_AWB);
3685 if (qvga) { /* QVGA from ov7670.c by
3686 * Jonathan Corbet */
3687 xstart = 164;
3688 xend = 28;
3689 ystart = 14;
3690 yend = 494;
3691 } else { /* VGA */
3692 xstart = 158;
3693 xend = 14;
3694 ystart = 10;
3695 yend = 490;
3696 }
3697 /* OV7670 hardware window registers are split across
3698 * multiple locations */
3699 i2c_w(sd, OV7670_REG_HSTART, xstart >> 3);
3700 i2c_w(sd, OV7670_REG_HSTOP, xend >> 3);
3701 v = i2c_r(sd, OV7670_REG_HREF);
3702 v = (v & 0xc0) | ((xend & 0x7) << 3) | (xstart & 0x07);
3703 msleep(10); /* need to sleep between read and write to
3704 * same reg! */
3705 i2c_w(sd, OV7670_REG_HREF, v);
3706
3707 i2c_w(sd, OV7670_REG_VSTART, ystart >> 2);
3708 i2c_w(sd, OV7670_REG_VSTOP, yend >> 2);
3709 v = i2c_r(sd, OV7670_REG_VREF);
3710 v = (v & 0xc0) | ((yend & 0x3) << 2) | (ystart & 0x03);
3711 msleep(10); /* need to sleep between read and write to
3712 * same reg! */
3713 i2c_w(sd, OV7670_REG_VREF, v);
2591 break; 3714 break;
2592 case SEN_OV6620: 3715 case SEN_OV6620:
3716 i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
3717 i2c_w_mask(sd, 0x13, 0x00, 0x20); /* Select 16 bit data bus */
3718 i2c_w_mask(sd, 0x12, 0x04, 0x06); /* AWB: 1 Test pattern: 0 */
3719 break;
2593 case SEN_OV6630: 3720 case SEN_OV6630:
2594 case SEN_OV66308AF: 3721 case SEN_OV66308AF:
2595 i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20); 3722 i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
3723 i2c_w_mask(sd, 0x12, 0x04, 0x06); /* AWB: 1 Test pattern: 0 */
2596 break; 3724 break;
2597 default: 3725 default:
2598 return -EINVAL; 3726 return -EINVAL;
2599 } 3727 }
2600 3728
2601 /******** Palette-specific regs ********/
2602
2603 /* The OV518 needs special treatment. Although both the OV518
2604 * and the OV6630 support a 16-bit video bus, only the 8 bit Y
2605 * bus is actually used. The UV bus is tied to ground.
2606 * Therefore, the OV6630 needs to be in 8-bit multiplexed
2607 * output mode */
2608
2609 /* OV7640 is 8-bit only */
2610
2611 if (sd->sensor != SEN_OV6630 && sd->sensor != SEN_OV66308AF &&
2612 sd->sensor != SEN_OV7640)
2613 i2c_w_mask(sd, 0x13, 0x00, 0x20);
2614
2615 /******** Clock programming ********/ 3729 /******** Clock programming ********/
2616 i2c_w(sd, 0x11, sd->clockdiv); 3730 i2c_w(sd, 0x11, sd->clockdiv);
2617 3731
2618 /******** Special Features ********/
2619/* no evidence this is possible with OV7670, either */
2620 /* Test Pattern */
2621 if (sd->sensor != SEN_OV7640 && sd->sensor != SEN_OV7670)
2622 i2c_w_mask(sd, 0x12, 0x00, 0x02);
2623
2624 /* Enable auto white balance */
2625 if (sd->sensor == SEN_OV7670)
2626 i2c_w_mask(sd, OV7670_REG_COM8, OV7670_COM8_AWB,
2627 OV7670_COM8_AWB);
2628 else
2629 i2c_w_mask(sd, 0x12, 0x04, 0x04);
2630
2631 /* This will go away as soon as ov51x_mode_init_sensor_regs() */
2632 /* is fully tested. */
2633 /* 7620/6620/6630? don't have register 0x35, so play it safe */
2634 if (sd->sensor == SEN_OV7610 || sd->sensor == SEN_OV76BE) {
2635 if (!qvga)
2636 i2c_w(sd, 0x35, 0x9e);
2637 else
2638 i2c_w(sd, 0x35, 0x1e);
2639 }
2640 return 0; 3732 return 0;
2641} 3733}
2642 3734
@@ -2659,8 +3751,12 @@ static int set_ov_sensor_window(struct sd *sd)
2659 struct gspca_dev *gspca_dev; 3751 struct gspca_dev *gspca_dev;
2660 int qvga, crop; 3752 int qvga, crop;
2661 int hwsbase, hwebase, vwsbase, vwebase, hwscale, vwscale; 3753 int hwsbase, hwebase, vwsbase, vwebase, hwscale, vwscale;
2662 int ret, hstart, hstop, vstop, vstart; 3754 int ret;
2663 __u8 v; 3755
3756 /* mode setup is fully handled in mode_init_ov_sensor_regs for these */
3757 if (sd->sensor == SEN_OV2610 || sd->sensor == SEN_OV3610 ||
3758 sd->sensor == SEN_OV7670)
3759 return mode_init_ov_sensor_regs(sd);
2664 3760
2665 gspca_dev = &sd->gspca_dev; 3761 gspca_dev = &sd->gspca_dev;
2666 qvga = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv & 1; 3762 qvga = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv & 1;
@@ -2708,11 +3804,6 @@ static int set_ov_sensor_window(struct sd *sd)
2708 hwebase = 0x1a; 3804 hwebase = 0x1a;
2709 vwsbase = vwebase = 0x03; 3805 vwsbase = vwebase = 0x03;
2710 break; 3806 break;
2711 case SEN_OV7670:
2712 /*handling of OV7670 hardware sensor start and stop values
2713 * is very odd, compared to the other OV sensors */
2714 vwsbase = vwebase = hwebase = hwsbase = 0x00;
2715 break;
2716 default: 3807 default:
2717 return -EINVAL; 3808 return -EINVAL;
2718 } 3809 }
@@ -2753,58 +3844,11 @@ static int set_ov_sensor_window(struct sd *sd)
2753 if (ret < 0) 3844 if (ret < 0)
2754 return ret; 3845 return ret;
2755 3846
2756 if (sd->sensor == SEN_OV8610) { 3847 i2c_w(sd, 0x17, hwsbase);
2757 i2c_w_mask(sd, 0x2d, 0x05, 0x40); 3848 i2c_w(sd, 0x18, hwebase + (sd->sensor_width >> hwscale));
2758 /* old 0x95, new 0x05 from windrv 090403 */ 3849 i2c_w(sd, 0x19, vwsbase);
2759 /* bits 5-7: reserved */ 3850 i2c_w(sd, 0x1a, vwebase + (sd->sensor_height >> vwscale));
2760 i2c_w_mask(sd, 0x28, 0x20, 0x20);
2761 /* bit 5: progressive mode on */
2762 }
2763
2764 /* The below is wrong for OV7670s because their window registers
2765 * only store the high bits in 0x17 to 0x1a */
2766
2767 /* SRH Use sd->max values instead of requested win values */
2768 /* SCS Since we're sticking with only the max hardware widths
2769 * for a given mode */
2770 /* I can hard code this for OV7670s */
2771 /* Yes, these numbers do look odd, but they're tested and work! */
2772 if (sd->sensor == SEN_OV7670) {
2773 if (qvga) { /* QVGA from ov7670.c by
2774 * Jonathan Corbet */
2775 hstart = 164;
2776 hstop = 28;
2777 vstart = 14;
2778 vstop = 494;
2779 } else { /* VGA */
2780 hstart = 158;
2781 hstop = 14;
2782 vstart = 10;
2783 vstop = 490;
2784 }
2785 /* OV7670 hardware window registers are split across
2786 * multiple locations */
2787 i2c_w(sd, OV7670_REG_HSTART, hstart >> 3);
2788 i2c_w(sd, OV7670_REG_HSTOP, hstop >> 3);
2789 v = i2c_r(sd, OV7670_REG_HREF);
2790 v = (v & 0xc0) | ((hstop & 0x7) << 3) | (hstart & 0x07);
2791 msleep(10); /* need to sleep between read and write to
2792 * same reg! */
2793 i2c_w(sd, OV7670_REG_HREF, v);
2794 3851
2795 i2c_w(sd, OV7670_REG_VSTART, vstart >> 2);
2796 i2c_w(sd, OV7670_REG_VSTOP, vstop >> 2);
2797 v = i2c_r(sd, OV7670_REG_VREF);
2798 v = (v & 0xc0) | ((vstop & 0x3) << 2) | (vstart & 0x03);
2799 msleep(10); /* need to sleep between read and write to
2800 * same reg! */
2801 i2c_w(sd, OV7670_REG_VREF, v);
2802 } else {
2803 i2c_w(sd, 0x17, hwsbase);
2804 i2c_w(sd, 0x18, hwebase + (sd->gspca_dev.width >> hwscale));
2805 i2c_w(sd, 0x19, vwsbase);
2806 i2c_w(sd, 0x1a, vwebase + (sd->gspca_dev.height >> vwscale));
2807 }
2808 return 0; 3852 return 0;
2809} 3853}
2810 3854
@@ -2814,6 +3858,10 @@ static int sd_start(struct gspca_dev *gspca_dev)
2814 struct sd *sd = (struct sd *) gspca_dev; 3858 struct sd *sd = (struct sd *) gspca_dev;
2815 int ret = 0; 3859 int ret = 0;
2816 3860
3861 /* Default for most bridges, allow bridge_mode_init_regs to override */
3862 sd->sensor_width = sd->gspca_dev.width;
3863 sd->sensor_height = sd->gspca_dev.height;
3864
2817 switch (sd->bridge) { 3865 switch (sd->bridge) {
2818 case BRIDGE_OV511: 3866 case BRIDGE_OV511:
2819 case BRIDGE_OV511PLUS: 3867 case BRIDGE_OV511PLUS:
@@ -2826,6 +3874,10 @@ static int sd_start(struct gspca_dev *gspca_dev)
2826 case BRIDGE_OV519: 3874 case BRIDGE_OV519:
2827 ret = ov519_mode_init_regs(sd); 3875 ret = ov519_mode_init_regs(sd);
2828 break; 3876 break;
3877 /* case BRIDGE_OVFX2: nothing to do */
3878 case BRIDGE_W9968CF:
3879 ret = w9968cf_mode_init_regs(sd);
3880 break;
2829 } 3881 }
2830 if (ret < 0) 3882 if (ret < 0)
2831 goto out; 3883 goto out;
@@ -2859,10 +3911,17 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
2859 ov51x_led_control(sd, 0); 3911 ov51x_led_control(sd, 0);
2860} 3912}
2861 3913
3914static void sd_stop0(struct gspca_dev *gspca_dev)
3915{
3916 struct sd *sd = (struct sd *) gspca_dev;
3917
3918 if (sd->bridge == BRIDGE_W9968CF)
3919 w9968cf_stop0(sd);
3920}
3921
2862static void ov511_pkt_scan(struct gspca_dev *gspca_dev, 3922static void ov511_pkt_scan(struct gspca_dev *gspca_dev,
2863 struct gspca_frame *frame, /* target */ 3923 u8 *in, /* isoc packet */
2864 __u8 *in, /* isoc packet */ 3924 int len) /* iso packet length */
2865 int len) /* iso packet length */
2866{ 3925{
2867 struct sd *sd = (struct sd *) gspca_dev; 3926 struct sd *sd = (struct sd *) gspca_dev;
2868 3927
@@ -2893,11 +3952,11 @@ static void ov511_pkt_scan(struct gspca_dev *gspca_dev,
2893 return; 3952 return;
2894 } 3953 }
2895 /* Add 11 byte footer to frame, might be usefull */ 3954 /* Add 11 byte footer to frame, might be usefull */
2896 gspca_frame_add(gspca_dev, LAST_PACKET, frame, in, 11); 3955 gspca_frame_add(gspca_dev, LAST_PACKET, in, 11);
2897 return; 3956 return;
2898 } else { 3957 } else {
2899 /* Frame start */ 3958 /* Frame start */
2900 gspca_frame_add(gspca_dev, FIRST_PACKET, frame, in, 0); 3959 gspca_frame_add(gspca_dev, FIRST_PACKET, in, 0);
2901 sd->packet_nr = 0; 3960 sd->packet_nr = 0;
2902 } 3961 }
2903 } 3962 }
@@ -2906,12 +3965,11 @@ static void ov511_pkt_scan(struct gspca_dev *gspca_dev,
2906 len--; 3965 len--;
2907 3966
2908 /* intermediate packet */ 3967 /* intermediate packet */
2909 gspca_frame_add(gspca_dev, INTER_PACKET, frame, in, len); 3968 gspca_frame_add(gspca_dev, INTER_PACKET, in, len);
2910} 3969}
2911 3970
2912static void ov518_pkt_scan(struct gspca_dev *gspca_dev, 3971static void ov518_pkt_scan(struct gspca_dev *gspca_dev,
2913 struct gspca_frame *frame, /* target */ 3972 u8 *data, /* isoc packet */
2914 __u8 *data, /* isoc packet */
2915 int len) /* iso packet length */ 3973 int len) /* iso packet length */
2916{ 3974{
2917 struct sd *sd = (struct sd *) gspca_dev; 3975 struct sd *sd = (struct sd *) gspca_dev;
@@ -2919,8 +3977,8 @@ static void ov518_pkt_scan(struct gspca_dev *gspca_dev,
2919 /* A false positive here is likely, until OVT gives me 3977 /* A false positive here is likely, until OVT gives me
2920 * the definitive SOF/EOF format */ 3978 * the definitive SOF/EOF format */
2921 if ((!(data[0] | data[1] | data[2] | data[3] | data[5])) && data[6]) { 3979 if ((!(data[0] | data[1] | data[2] | data[3] | data[5])) && data[6]) {
2922 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, data, 0); 3980 gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
2923 gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, 0); 3981 gspca_frame_add(gspca_dev, FIRST_PACKET, NULL, 0);
2924 sd->packet_nr = 0; 3982 sd->packet_nr = 0;
2925 } 3983 }
2926 3984
@@ -2944,12 +4002,11 @@ static void ov518_pkt_scan(struct gspca_dev *gspca_dev,
2944 } 4002 }
2945 4003
2946 /* intermediate packet */ 4004 /* intermediate packet */
2947 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); 4005 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
2948} 4006}
2949 4007
2950static void ov519_pkt_scan(struct gspca_dev *gspca_dev, 4008static void ov519_pkt_scan(struct gspca_dev *gspca_dev,
2951 struct gspca_frame *frame, /* target */ 4009 u8 *data, /* isoc packet */
2952 __u8 *data, /* isoc packet */
2953 int len) /* iso packet length */ 4010 int len) /* iso packet length */
2954{ 4011{
2955 /* Header of ov519 is 16 bytes: 4012 /* Header of ov519 is 16 bytes:
@@ -2972,7 +4029,7 @@ static void ov519_pkt_scan(struct gspca_dev *gspca_dev,
2972 len -= HDRSZ; 4029 len -= HDRSZ;
2973#undef HDRSZ 4030#undef HDRSZ
2974 if (data[0] == 0xff || data[1] == 0xd8) 4031 if (data[0] == 0xff || data[1] == 0xd8)
2975 gspca_frame_add(gspca_dev, FIRST_PACKET, frame, 4032 gspca_frame_add(gspca_dev, FIRST_PACKET,
2976 data, len); 4033 data, len);
2977 else 4034 else
2978 gspca_dev->last_packet_type = DISCARD_PACKET; 4035 gspca_dev->last_packet_type = DISCARD_PACKET;
@@ -2980,20 +4037,31 @@ static void ov519_pkt_scan(struct gspca_dev *gspca_dev,
2980 case 0x51: /* end of frame */ 4037 case 0x51: /* end of frame */
2981 if (data[9] != 0) 4038 if (data[9] != 0)
2982 gspca_dev->last_packet_type = DISCARD_PACKET; 4039 gspca_dev->last_packet_type = DISCARD_PACKET;
2983 gspca_frame_add(gspca_dev, LAST_PACKET, frame, 4040 gspca_frame_add(gspca_dev, LAST_PACKET,
2984 data, 0); 4041 NULL, 0);
2985 return; 4042 return;
2986 } 4043 }
2987 } 4044 }
2988 4045
2989 /* intermediate packet */ 4046 /* intermediate packet */
2990 gspca_frame_add(gspca_dev, INTER_PACKET, frame, 4047 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
2991 data, len); 4048}
4049
4050static void ovfx2_pkt_scan(struct gspca_dev *gspca_dev,
4051 u8 *data, /* isoc packet */
4052 int len) /* iso packet length */
4053{
4054 /* A short read signals EOF */
4055 if (len < OVFX2_BULK_SIZE) {
4056 gspca_frame_add(gspca_dev, LAST_PACKET, data, len);
4057 gspca_frame_add(gspca_dev, FIRST_PACKET, NULL, 0);
4058 return;
4059 }
4060 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
2992} 4061}
2993 4062
2994static void sd_pkt_scan(struct gspca_dev *gspca_dev, 4063static void sd_pkt_scan(struct gspca_dev *gspca_dev,
2995 struct gspca_frame *frame, /* target */ 4064 u8 *data, /* isoc packet */
2996 __u8 *data, /* isoc packet */
2997 int len) /* iso packet length */ 4065 int len) /* iso packet length */
2998{ 4066{
2999 struct sd *sd = (struct sd *) gspca_dev; 4067 struct sd *sd = (struct sd *) gspca_dev;
@@ -3001,14 +4069,20 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
3001 switch (sd->bridge) { 4069 switch (sd->bridge) {
3002 case BRIDGE_OV511: 4070 case BRIDGE_OV511:
3003 case BRIDGE_OV511PLUS: 4071 case BRIDGE_OV511PLUS:
3004 ov511_pkt_scan(gspca_dev, frame, data, len); 4072 ov511_pkt_scan(gspca_dev, data, len);
3005 break; 4073 break;
3006 case BRIDGE_OV518: 4074 case BRIDGE_OV518:
3007 case BRIDGE_OV518PLUS: 4075 case BRIDGE_OV518PLUS:
3008 ov518_pkt_scan(gspca_dev, frame, data, len); 4076 ov518_pkt_scan(gspca_dev, data, len);
3009 break; 4077 break;
3010 case BRIDGE_OV519: 4078 case BRIDGE_OV519:
3011 ov519_pkt_scan(gspca_dev, frame, data, len); 4079 ov519_pkt_scan(gspca_dev, data, len);
4080 break;
4081 case BRIDGE_OVFX2:
4082 ovfx2_pkt_scan(gspca_dev, data, len);
4083 break;
4084 case BRIDGE_W9968CF:
4085 w9968cf_pkt_scan(gspca_dev, data, len);
3012 break; 4086 break;
3013 } 4087 }
3014} 4088}
@@ -3124,7 +4198,8 @@ static void setcolors(struct gspca_dev *gspca_dev)
3124 4198
3125static void setautobrightness(struct sd *sd) 4199static void setautobrightness(struct sd *sd)
3126{ 4200{
3127 if (sd->sensor == SEN_OV7640 || sd->sensor == SEN_OV7670) 4201 if (sd->sensor == SEN_OV7640 || sd->sensor == SEN_OV7670 ||
4202 sd->sensor == SEN_OV2610 || sd->sensor == SEN_OV3610)
3128 return; 4203 return;
3129 4204
3130 i2c_w_mask(sd, 0x2d, sd->autobrightness ? 0x10 : 0x00, 0x10); 4205 i2c_w_mask(sd, 0x2d, sd->autobrightness ? 0x10 : 0x00, 0x10);
@@ -3132,6 +4207,9 @@ static void setautobrightness(struct sd *sd)
3132 4207
3133static void setfreq(struct sd *sd) 4208static void setfreq(struct sd *sd)
3134{ 4209{
4210 if (sd->sensor == SEN_OV2610 || sd->sensor == SEN_OV3610)
4211 return;
4212
3135 if (sd->sensor == SEN_OV7670) { 4213 if (sd->sensor == SEN_OV7670) {
3136 switch (sd->freq) { 4214 switch (sd->freq) {
3137 case 0: /* Banding filter disabled */ 4215 case 0: /* Banding filter disabled */
@@ -3301,8 +4379,12 @@ static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val)
3301 struct sd *sd = (struct sd *) gspca_dev; 4379 struct sd *sd = (struct sd *) gspca_dev;
3302 4380
3303 sd->freq = val; 4381 sd->freq = val;
3304 if (gspca_dev->streaming) 4382 if (gspca_dev->streaming) {
3305 setfreq(sd); 4383 setfreq(sd);
4384 /* Ugly but necessary */
4385 if (sd->bridge == BRIDGE_W9968CF)
4386 w9968cf_set_crop_window(sd);
4387 }
3306 return 0; 4388 return 0;
3307} 4389}
3308 4390
@@ -3343,6 +4425,45 @@ static int sd_querymenu(struct gspca_dev *gspca_dev,
3343 return -EINVAL; 4425 return -EINVAL;
3344} 4426}
3345 4427
4428static int sd_get_jcomp(struct gspca_dev *gspca_dev,
4429 struct v4l2_jpegcompression *jcomp)
4430{
4431 struct sd *sd = (struct sd *) gspca_dev;
4432
4433 if (sd->bridge != BRIDGE_W9968CF)
4434 return -EINVAL;
4435
4436 memset(jcomp, 0, sizeof *jcomp);
4437 jcomp->quality = sd->quality;
4438 jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT | V4L2_JPEG_MARKER_DQT |
4439 V4L2_JPEG_MARKER_DRI;
4440 return 0;
4441}
4442
4443static int sd_set_jcomp(struct gspca_dev *gspca_dev,
4444 struct v4l2_jpegcompression *jcomp)
4445{
4446 struct sd *sd = (struct sd *) gspca_dev;
4447
4448 if (sd->bridge != BRIDGE_W9968CF)
4449 return -EINVAL;
4450
4451 if (gspca_dev->streaming)
4452 return -EBUSY;
4453
4454 if (jcomp->quality < QUALITY_MIN)
4455 sd->quality = QUALITY_MIN;
4456 else if (jcomp->quality > QUALITY_MAX)
4457 sd->quality = QUALITY_MAX;
4458 else
4459 sd->quality = jcomp->quality;
4460
4461 /* Return resulting jcomp params to app */
4462 sd_get_jcomp(gspca_dev, jcomp);
4463
4464 return 0;
4465}
4466
3346/* sub-driver description */ 4467/* sub-driver description */
3347static const struct sd_desc sd_desc = { 4468static const struct sd_desc sd_desc = {
3348 .name = MODULE_NAME, 4469 .name = MODULE_NAME,
@@ -3352,18 +4473,23 @@ static const struct sd_desc sd_desc = {
3352 .init = sd_init, 4473 .init = sd_init,
3353 .start = sd_start, 4474 .start = sd_start,
3354 .stopN = sd_stopN, 4475 .stopN = sd_stopN,
4476 .stop0 = sd_stop0,
3355 .pkt_scan = sd_pkt_scan, 4477 .pkt_scan = sd_pkt_scan,
3356 .querymenu = sd_querymenu, 4478 .querymenu = sd_querymenu,
4479 .get_jcomp = sd_get_jcomp,
4480 .set_jcomp = sd_set_jcomp,
3357}; 4481};
3358 4482
3359/* -- module initialisation -- */ 4483/* -- module initialisation -- */
3360static const __devinitdata struct usb_device_id device_table[] = { 4484static const __devinitdata struct usb_device_id device_table[] = {
4485 {USB_DEVICE(0x041e, 0x4003), .driver_info = BRIDGE_W9968CF },
3361 {USB_DEVICE(0x041e, 0x4052), .driver_info = BRIDGE_OV519 }, 4486 {USB_DEVICE(0x041e, 0x4052), .driver_info = BRIDGE_OV519 },
3362 {USB_DEVICE(0x041e, 0x405f), .driver_info = BRIDGE_OV519 }, 4487 {USB_DEVICE(0x041e, 0x405f), .driver_info = BRIDGE_OV519 },
3363 {USB_DEVICE(0x041e, 0x4060), .driver_info = BRIDGE_OV519 }, 4488 {USB_DEVICE(0x041e, 0x4060), .driver_info = BRIDGE_OV519 },
3364 {USB_DEVICE(0x041e, 0x4061), .driver_info = BRIDGE_OV519 }, 4489 {USB_DEVICE(0x041e, 0x4061), .driver_info = BRIDGE_OV519 },
3365 {USB_DEVICE(0x041e, 0x4064), 4490 {USB_DEVICE(0x041e, 0x4064),
3366 .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED }, 4491 .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED },
4492 {USB_DEVICE(0x041e, 0x4067), .driver_info = BRIDGE_OV519 },
3367 {USB_DEVICE(0x041e, 0x4068), 4493 {USB_DEVICE(0x041e, 0x4068),
3368 .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED }, 4494 .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED },
3369 {USB_DEVICE(0x045e, 0x028c), .driver_info = BRIDGE_OV519 }, 4495 {USB_DEVICE(0x045e, 0x028c), .driver_info = BRIDGE_OV519 },
@@ -3373,11 +4499,16 @@ static const __devinitdata struct usb_device_id device_table[] = {
3373 {USB_DEVICE(0x05a9, 0x0518), .driver_info = BRIDGE_OV518 }, 4499 {USB_DEVICE(0x05a9, 0x0518), .driver_info = BRIDGE_OV518 },
3374 {USB_DEVICE(0x05a9, 0x0519), .driver_info = BRIDGE_OV519 }, 4500 {USB_DEVICE(0x05a9, 0x0519), .driver_info = BRIDGE_OV519 },
3375 {USB_DEVICE(0x05a9, 0x0530), .driver_info = BRIDGE_OV519 }, 4501 {USB_DEVICE(0x05a9, 0x0530), .driver_info = BRIDGE_OV519 },
4502 {USB_DEVICE(0x05a9, 0x2800), .driver_info = BRIDGE_OVFX2 },
3376 {USB_DEVICE(0x05a9, 0x4519), .driver_info = BRIDGE_OV519 }, 4503 {USB_DEVICE(0x05a9, 0x4519), .driver_info = BRIDGE_OV519 },
3377 {USB_DEVICE(0x05a9, 0x8519), .driver_info = BRIDGE_OV519 }, 4504 {USB_DEVICE(0x05a9, 0x8519), .driver_info = BRIDGE_OV519 },
3378 {USB_DEVICE(0x05a9, 0xa511), .driver_info = BRIDGE_OV511PLUS }, 4505 {USB_DEVICE(0x05a9, 0xa511), .driver_info = BRIDGE_OV511PLUS },
3379 {USB_DEVICE(0x05a9, 0xa518), .driver_info = BRIDGE_OV518PLUS }, 4506 {USB_DEVICE(0x05a9, 0xa518), .driver_info = BRIDGE_OV518PLUS },
3380 {USB_DEVICE(0x0813, 0x0002), .driver_info = BRIDGE_OV511PLUS }, 4507 {USB_DEVICE(0x0813, 0x0002), .driver_info = BRIDGE_OV511PLUS },
4508 {USB_DEVICE(0x0b62, 0x0059), .driver_info = BRIDGE_OVFX2 },
4509 {USB_DEVICE(0x0e96, 0xc001), .driver_info = BRIDGE_OVFX2 },
4510 {USB_DEVICE(0x1046, 0x9967), .driver_info = BRIDGE_W9968CF },
4511 {USB_DEVICE(0x8020, 0xEF04), .driver_info = BRIDGE_OVFX2 },
3381 {} 4512 {}
3382}; 4513};
3383 4514
diff --git a/drivers/media/video/gspca/ov534.c b/drivers/media/video/gspca/ov534.c
index 4b528b372911..4dbb882c83dc 100644
--- a/drivers/media/video/gspca/ov534.c
+++ b/drivers/media/video/gspca/ov534.c
@@ -1,5 +1,6 @@
1/* 1/*
2 * ov534 gspca driver 2 * ov534 gspca driver
3 *
3 * Copyright (C) 2008 Antonio Ospite <ospite@studenti.unina.it> 4 * Copyright (C) 2008 Antonio Ospite <ospite@studenti.unina.it>
4 * Copyright (C) 2008 Jim Paris <jim@jtan.com> 5 * Copyright (C) 2008 Jim Paris <jim@jtan.com>
5 * Copyright (C) 2009 Jean-Francois Moine http://moinejf.free.fr 6 * Copyright (C) 2009 Jean-Francois Moine http://moinejf.free.fr
@@ -8,6 +9,10 @@
8 * USB protocol reverse engineered by Jim Paris <jim@jtan.com> 9 * USB protocol reverse engineered by Jim Paris <jim@jtan.com>
9 * https://jim.sh/svn/jim/devl/playstation/ps3/eye/test/ 10 * https://jim.sh/svn/jim/devl/playstation/ps3/eye/test/
10 * 11 *
12 * PS3 Eye camera enhanced by Richard Kaswy http://kaswy.free.fr
13 * PS3 Eye camera, brightness, contrast, hue, AWB control added
14 * by Max Thrun <bear24rw@gmail.com>
15 *
11 * This program is free software; you can redistribute it and/or modify 16 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by 17 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or 18 * the Free Software Foundation; either version 2 of the License, or
@@ -51,16 +56,335 @@ struct sd {
51 u16 last_fid; 56 u16 last_fid;
52 u8 frame_rate; 57 u8 frame_rate;
53 58
59 u8 brightness;
60 u8 contrast;
61 u8 gain;
62 u8 exposure;
63 u8 redblc;
64 u8 blueblc;
65 u8 hue;
66 u8 autogain;
67 u8 awb;
68 s8 sharpness;
69 u8 hflip;
70 u8 vflip;
71 u8 satur;
72 u8 lightfreq;
73
54 u8 sensor; 74 u8 sensor;
55#define SENSOR_OV772X 0 75#define SENSOR_OV772X 0
56#define SENSOR_OV965X 1 76#define SENSOR_OV965X 1
57}; 77};
58 78
59/* V4L2 controls supported by the driver */ 79/* V4L2 controls supported by the driver */
60static struct ctrl sd_ctrls[] = { 80static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val);
81static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val);
82static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val);
83static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val);
84static int sd_setredblc(struct gspca_dev *gspca_dev, __s32 val);
85static int sd_getredblc(struct gspca_dev *gspca_dev, __s32 *val);
86static int sd_setblueblc(struct gspca_dev *gspca_dev, __s32 val);
87static int sd_getblueblc(struct gspca_dev *gspca_dev, __s32 *val);
88static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
89static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
90static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val);
91static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val);
92static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val);
93static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val);
94static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val);
95static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val);
96static int sd_sethue(struct gspca_dev *gspca_dev, __s32 val);
97static int sd_gethue(struct gspca_dev *gspca_dev, __s32 *val);
98static int sd_setawb(struct gspca_dev *gspca_dev, __s32 val);
99static int sd_getawb(struct gspca_dev *gspca_dev, __s32 *val);
100static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
101static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
102static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
103static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
104static int sd_setsatur(struct gspca_dev *gspca_dev, __s32 val);
105static int sd_getsatur(struct gspca_dev *gspca_dev, __s32 *val);
106static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val);
107static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val);
108
109static struct ctrl sd_ctrls_ov772x[] = {
110 { /* 0 */
111 {
112 .id = V4L2_CID_BRIGHTNESS,
113 .type = V4L2_CTRL_TYPE_INTEGER,
114 .name = "Brightness",
115 .minimum = 0,
116 .maximum = 255,
117 .step = 1,
118#define BRIGHTNESS_77_DEF 20
119 .default_value = BRIGHTNESS_77_DEF,
120 },
121 .set = sd_setbrightness,
122 .get = sd_getbrightness,
123 },
124 { /* 1 */
125 {
126 .id = V4L2_CID_CONTRAST,
127 .type = V4L2_CTRL_TYPE_INTEGER,
128 .name = "Contrast",
129 .minimum = 0,
130 .maximum = 255,
131 .step = 1,
132#define CONTRAST_77_DEF 37
133 .default_value = CONTRAST_77_DEF,
134 },
135 .set = sd_setcontrast,
136 .get = sd_getcontrast,
137 },
138 { /* 2 */
139 {
140 .id = V4L2_CID_GAIN,
141 .type = V4L2_CTRL_TYPE_INTEGER,
142 .name = "Main Gain",
143 .minimum = 0,
144 .maximum = 63,
145 .step = 1,
146#define GAIN_DEF 20
147 .default_value = GAIN_DEF,
148 },
149 .set = sd_setgain,
150 .get = sd_getgain,
151 },
152 { /* 3 */
153 {
154 .id = V4L2_CID_EXPOSURE,
155 .type = V4L2_CTRL_TYPE_INTEGER,
156 .name = "Exposure",
157 .minimum = 0,
158 .maximum = 255,
159 .step = 1,
160#define EXPO_77_DEF 120
161 .default_value = EXPO_77_DEF,
162 },
163 .set = sd_setexposure,
164 .get = sd_getexposure,
165 },
166 { /* 4 */
167 {
168 .id = V4L2_CID_RED_BALANCE,
169 .type = V4L2_CTRL_TYPE_INTEGER,
170 .name = "Red Balance",
171 .minimum = 0,
172 .maximum = 255,
173 .step = 1,
174#define RED_BALANCE_DEF 128
175 .default_value = RED_BALANCE_DEF,
176 },
177 .set = sd_setredblc,
178 .get = sd_getredblc,
179 },
180 { /* 5 */
181 {
182 .id = V4L2_CID_BLUE_BALANCE,
183 .type = V4L2_CTRL_TYPE_INTEGER,
184 .name = "Blue Balance",
185 .minimum = 0,
186 .maximum = 255,
187 .step = 1,
188#define BLUE_BALANCE_DEF 128
189 .default_value = BLUE_BALANCE_DEF,
190 },
191 .set = sd_setblueblc,
192 .get = sd_getblueblc,
193 },
194 { /* 6 */
195 {
196 .id = V4L2_CID_HUE,
197 .type = V4L2_CTRL_TYPE_INTEGER,
198 .name = "Hue",
199 .minimum = 0,
200 .maximum = 255,
201 .step = 1,
202#define HUE_DEF 143
203 .default_value = HUE_DEF,
204 },
205 .set = sd_sethue,
206 .get = sd_gethue,
207 },
208 { /* 7 */
209 {
210 .id = V4L2_CID_AUTOGAIN,
211 .type = V4L2_CTRL_TYPE_BOOLEAN,
212 .name = "Autogain",
213 .minimum = 0,
214 .maximum = 1,
215 .step = 1,
216#define AUTOGAIN_77_DEF 0
217 .default_value = AUTOGAIN_77_DEF,
218 },
219 .set = sd_setautogain,
220 .get = sd_getautogain,
221 },
222#define AWB_77_IDX 8
223 { /* 8 */
224 {
225 .id = V4L2_CID_AUTO_WHITE_BALANCE,
226 .type = V4L2_CTRL_TYPE_BOOLEAN,
227 .name = "Auto White Balance",
228 .minimum = 0,
229 .maximum = 1,
230 .step = 1,
231#define AWB_DEF 0
232 .default_value = AWB_DEF,
233 },
234 .set = sd_setawb,
235 .get = sd_getawb,
236 },
237 { /* 9 */
238 {
239 .id = V4L2_CID_SHARPNESS,
240 .type = V4L2_CTRL_TYPE_INTEGER,
241 .name = "Sharpness",
242 .minimum = 0,
243 .maximum = 63,
244 .step = 1,
245#define SHARPNESS_77_DEF 0
246 .default_value = SHARPNESS_77_DEF,
247 },
248 .set = sd_setsharpness,
249 .get = sd_getsharpness,
250 },
251 { /* 10 */
252 {
253 .id = V4L2_CID_HFLIP,
254 .type = V4L2_CTRL_TYPE_BOOLEAN,
255 .name = "HFlip",
256 .minimum = 0,
257 .maximum = 1,
258 .step = 1,
259#define HFLIP_DEF 0
260 .default_value = HFLIP_DEF,
261 },
262 .set = sd_sethflip,
263 .get = sd_gethflip,
264 },
265 { /* 11 */
266 {
267 .id = V4L2_CID_VFLIP,
268 .type = V4L2_CTRL_TYPE_BOOLEAN,
269 .name = "VFlip",
270 .minimum = 0,
271 .maximum = 1,
272 .step = 1,
273#define VFLIP_DEF 0
274 .default_value = VFLIP_DEF,
275 },
276 .set = sd_setvflip,
277 .get = sd_getvflip,
278 },
279};
280static struct ctrl sd_ctrls_ov965x[] = {
281 { /* 0 */
282 {
283 .id = V4L2_CID_BRIGHTNESS,
284 .type = V4L2_CTRL_TYPE_INTEGER,
285 .name = "Brightness",
286 .minimum = 0,
287 .maximum = 15,
288 .step = 1,
289#define BRIGHTNESS_96_DEF 7
290 .default_value = BRIGHTNESS_96_DEF,
291 },
292 .set = sd_setbrightness,
293 .get = sd_getbrightness,
294 },
295 { /* 1 */
296 {
297 .id = V4L2_CID_CONTRAST,
298 .type = V4L2_CTRL_TYPE_INTEGER,
299 .name = "Contrast",
300 .minimum = 0,
301 .maximum = 15,
302 .step = 1,
303#define CONTRAST_96_DEF 3
304 .default_value = CONTRAST_96_DEF,
305 },
306 .set = sd_setcontrast,
307 .get = sd_getcontrast,
308 },
309 { /* 2 */
310 {
311 .id = V4L2_CID_AUTOGAIN,
312 .type = V4L2_CTRL_TYPE_BOOLEAN,
313 .name = "Autogain",
314 .minimum = 0,
315 .maximum = 1,
316 .step = 1,
317#define AUTOGAIN_96_DEF 1
318 .default_value = AUTOGAIN_96_DEF,
319 },
320 .set = sd_setautogain,
321 .get = sd_getautogain,
322 },
323#define EXPO_96_IDX 3
324 { /* 3 */
325 {
326 .id = V4L2_CID_EXPOSURE,
327 .type = V4L2_CTRL_TYPE_INTEGER,
328 .name = "Exposure",
329 .minimum = 0,
330 .maximum = 3,
331 .step = 1,
332#define EXPO_96_DEF 0
333 .default_value = EXPO_96_DEF,
334 },
335 .set = sd_setexposure,
336 .get = sd_getexposure,
337 },
338 { /* 4 */
339 {
340 .id = V4L2_CID_SHARPNESS,
341 .type = V4L2_CTRL_TYPE_INTEGER,
342 .name = "Sharpness",
343 .minimum = -1, /* -1 = auto */
344 .maximum = 4,
345 .step = 1,
346#define SHARPNESS_96_DEF -1
347 .default_value = SHARPNESS_96_DEF,
348 },
349 .set = sd_setsharpness,
350 .get = sd_getsharpness,
351 },
352 { /* 5 */
353 {
354 .id = V4L2_CID_SATURATION,
355 .type = V4L2_CTRL_TYPE_INTEGER,
356 .name = "Saturation",
357 .minimum = 0,
358 .maximum = 4,
359 .step = 1,
360#define SATUR_DEF 2
361 .default_value = SATUR_DEF,
362 },
363 .set = sd_setsatur,
364 .get = sd_getsatur,
365 },
366 {
367 {
368 .id = V4L2_CID_POWER_LINE_FREQUENCY,
369 .type = V4L2_CTRL_TYPE_MENU,
370 .name = "Light frequency filter",
371 .minimum = 0,
372 .maximum = 2, /* 0: 0, 1: 50Hz, 2:60Hz */
373 .step = 1,
374#define FREQ_DEF 0
375 .default_value = FREQ_DEF,
376 },
377 .set = sd_setfreq,
378 .get = sd_getfreq,
379 },
61}; 380};
62 381
63static const struct v4l2_pix_format vga_yuyv_mode[] = { 382static const struct v4l2_pix_format ov772x_mode[] = {
383 {320, 240, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE,
384 .bytesperline = 320 * 2,
385 .sizeimage = 320 * 240 * 2,
386 .colorspace = V4L2_COLORSPACE_SRGB,
387 .priv = 1},
64 {640, 480, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, 388 {640, 480, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE,
65 .bytesperline = 640 * 2, 389 .bytesperline = 640 * 2,
66 .sizeimage = 640 * 480 * 2, 390 .sizeimage = 640 * 480 * 2,
@@ -68,20 +392,35 @@ static const struct v4l2_pix_format vga_yuyv_mode[] = {
68 .priv = 0}, 392 .priv = 0},
69}; 393};
70 394
71static const struct v4l2_pix_format vga_jpeg_mode[] = { 395static const struct v4l2_pix_format ov965x_mode[] = {
72 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 396 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
73 .bytesperline = 320, 397 .bytesperline = 320,
74 .sizeimage = 320 * 240 * 3 / 8 + 590, 398 .sizeimage = 320 * 240 * 3 / 8 + 590,
75 .colorspace = V4L2_COLORSPACE_JPEG, 399 .colorspace = V4L2_COLORSPACE_JPEG,
76 .priv = 1}, 400 .priv = 4},
77 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 401 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
78 .bytesperline = 640, 402 .bytesperline = 640,
79 .sizeimage = 640 * 480 * 3 / 8 + 590, 403 .sizeimage = 640 * 480 * 3 / 8 + 590,
80 .colorspace = V4L2_COLORSPACE_JPEG, 404 .colorspace = V4L2_COLORSPACE_JPEG,
405 .priv = 3},
406 {800, 600, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
407 .bytesperline = 800,
408 .sizeimage = 800 * 600 * 3 / 8 + 590,
409 .colorspace = V4L2_COLORSPACE_JPEG,
410 .priv = 2},
411 {1024, 768, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
412 .bytesperline = 1024,
413 .sizeimage = 1024 * 768 * 3 / 8 + 590,
414 .colorspace = V4L2_COLORSPACE_JPEG,
415 .priv = 1},
416 {1280, 1024, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
417 .bytesperline = 1280,
418 .sizeimage = 1280 * 1024 * 3 / 8 + 590,
419 .colorspace = V4L2_COLORSPACE_JPEG,
81 .priv = 0}, 420 .priv = 0},
82}; 421};
83 422
84static const u8 bridge_init_ov722x[][2] = { 423static const u8 bridge_init_ov772x[][2] = {
85 { 0xc2, 0x0c }, 424 { 0xc2, 0x0c },
86 { 0x88, 0xf8 }, 425 { 0x88, 0xf8 },
87 { 0xc3, 0x69 }, 426 { 0xc3, 0x69 },
@@ -122,6 +461,7 @@ static const u8 bridge_init_ov722x[][2] = {
122 { 0x1d, 0x40 }, 461 { 0x1d, 0x40 },
123 { 0x1d, 0x02 }, /* payload size 0x0200 * 4 = 2048 bytes */ 462 { 0x1d, 0x02 }, /* payload size 0x0200 * 4 = 2048 bytes */
124 { 0x1d, 0x00 }, /* payload size */ 463 { 0x1d, 0x00 }, /* payload size */
464
125 { 0x1d, 0x02 }, /* frame size 0x025800 * 4 = 614400 */ 465 { 0x1d, 0x02 }, /* frame size 0x025800 * 4 = 614400 */
126 { 0x1d, 0x58 }, /* frame size */ 466 { 0x1d, 0x58 }, /* frame size */
127 { 0x1d, 0x00 }, /* frame size */ 467 { 0x1d, 0x00 }, /* frame size */
@@ -138,10 +478,20 @@ static const u8 bridge_init_ov722x[][2] = {
138 { 0xc1, 0x3c }, 478 { 0xc1, 0x3c },
139 { 0xc2, 0x0c }, 479 { 0xc2, 0x0c },
140}; 480};
141 481static const u8 sensor_init_ov772x[][2] = {
142static const u8 sensor_init_ov722x[][2] = {
143 { 0x12, 0x80 }, 482 { 0x12, 0x80 },
144 { 0x11, 0x01 }, 483 { 0x11, 0x01 },
484/*fixme: better have a delay?*/
485 { 0x11, 0x01 },
486 { 0x11, 0x01 },
487 { 0x11, 0x01 },
488 { 0x11, 0x01 },
489 { 0x11, 0x01 },
490 { 0x11, 0x01 },
491 { 0x11, 0x01 },
492 { 0x11, 0x01 },
493 { 0x11, 0x01 },
494 { 0x11, 0x01 },
145 495
146 { 0x3d, 0x03 }, 496 { 0x3d, 0x03 },
147 { 0x17, 0x26 }, 497 { 0x17, 0x26 },
@@ -154,10 +504,10 @@ static const u8 sensor_init_ov722x[][2] = {
154 { 0x65, 0x20 }, 504 { 0x65, 0x20 },
155 { 0x11, 0x01 }, 505 { 0x11, 0x01 },
156 { 0x42, 0x7f }, 506 { 0x42, 0x7f },
157 { 0x63, 0xe0 }, 507 { 0x63, 0xaa }, /* AWB - was e0 */
158 { 0x64, 0xff }, 508 { 0x64, 0xff },
159 { 0x66, 0x00 }, 509 { 0x66, 0x00 },
160 { 0x13, 0xf0 }, 510 { 0x13, 0xf0 }, /* com8 */
161 { 0x0d, 0x41 }, 511 { 0x0d, 0x41 },
162 { 0x0f, 0xc5 }, 512 { 0x0f, 0xc5 },
163 { 0x14, 0x11 }, 513 { 0x14, 0x11 },
@@ -170,7 +520,7 @@ static const u8 sensor_init_ov722x[][2] = {
170 { 0x2a, 0x00 }, 520 { 0x2a, 0x00 },
171 { 0x2b, 0x00 }, 521 { 0x2b, 0x00 },
172 { 0x6b, 0xaa }, 522 { 0x6b, 0xaa },
173 { 0x13, 0xff }, 523 { 0x13, 0xff }, /* AWB */
174 524
175 { 0x90, 0x05 }, 525 { 0x90, 0x05 },
176 { 0x91, 0x01 }, 526 { 0x91, 0x01 },
@@ -218,9 +568,51 @@ static const u8 sensor_init_ov722x[][2] = {
218 { 0x14, 0x41 }, 568 { 0x14, 0x41 },
219 { 0x0e, 0xcd }, 569 { 0x0e, 0xcd },
220 { 0xac, 0xbf }, 570 { 0xac, 0xbf },
221 { 0x8e, 0x00 }, 571 { 0x8e, 0x00 }, /* De-noise threshold */
222 { 0x0c, 0xd0 } 572 { 0x0c, 0xd0 }
223}; 573};
574static const u8 bridge_start_ov772x_vga[][2] = {
575 {0x1c, 0x00},
576 {0x1d, 0x40},
577 {0x1d, 0x02},
578 {0x1d, 0x00},
579 {0x1d, 0x02},
580 {0x1d, 0x58},
581 {0x1d, 0x00},
582 {0xc0, 0x50},
583 {0xc1, 0x3c},
584};
585static const u8 sensor_start_ov772x_vga[][2] = {
586 {0x12, 0x00},
587 {0x17, 0x26},
588 {0x18, 0xa0},
589 {0x19, 0x07},
590 {0x1a, 0xf0},
591 {0x29, 0xa0},
592 {0x2c, 0xf0},
593 {0x65, 0x20},
594};
595static const u8 bridge_start_ov772x_qvga[][2] = {
596 {0x1c, 0x00},
597 {0x1d, 0x40},
598 {0x1d, 0x02},
599 {0x1d, 0x00},
600 {0x1d, 0x01},
601 {0x1d, 0x4b},
602 {0x1d, 0x00},
603 {0xc0, 0x28},
604 {0xc1, 0x1e},
605};
606static const u8 sensor_start_ov772x_qvga[][2] = {
607 {0x12, 0x40},
608 {0x17, 0x3f},
609 {0x18, 0x50},
610 {0x19, 0x03},
611 {0x1a, 0x78},
612 {0x29, 0x50},
613 {0x2c, 0x78},
614 {0x65, 0x2f},
615};
224 616
225static const u8 bridge_init_ov965x[][2] = { 617static const u8 bridge_init_ov965x[][2] = {
226 {0x88, 0xf8}, 618 {0x88, 0xf8},
@@ -403,7 +795,7 @@ static const u8 sensor_init_ov965x[][2] = {
403 {0xcb, 0xf0}, 795 {0xcb, 0xf0},
404 {0xcc, 0xd8}, 796 {0xcc, 0xd8},
405 {0xcd, 0xf1}, 797 {0xcd, 0xf1},
406 {0x4f, 0x98}, 798 {0x4f, 0x98}, /* matrix */
407 {0x50, 0x98}, 799 {0x50, 0x98},
408 {0x51, 0x00}, 800 {0x51, 0x00},
409 {0x52, 0x28}, 801 {0x52, 0x28},
@@ -412,6 +804,7 @@ static const u8 sensor_init_ov965x[][2] = {
412 {0x58, 0x1a}, 804 {0x58, 0x1a},
413 {0xff, 0x41}, /* read 41, write ff 00 */ 805 {0xff, 0x41}, /* read 41, write ff 00 */
414 {0x41, 0x40}, /* com16 */ 806 {0x41, 0x40}, /* com16 */
807
415 {0xc5, 0x03}, /* 60 Hz banding filter */ 808 {0xc5, 0x03}, /* 60 Hz banding filter */
416 {0x6a, 0x02}, /* 50 Hz banding filter */ 809 {0x6a, 0x02}, /* 50 Hz banding filter */
417 810
@@ -455,8 +848,8 @@ static const u8 bridge_init_ov965x_2[][2] = {
455 {0x52, 0x3c}, 848 {0x52, 0x3c},
456 {0x53, 0x00}, 849 {0x53, 0x00},
457 {0x54, 0x00}, 850 {0x54, 0x00},
458 {0x55, 0x00}, /* brightness */ 851 {0x55, 0x00},
459 {0x57, 0x00}, /* contrast 2 */ 852 {0x57, 0x00},
460 {0x5c, 0x00}, 853 {0x5c, 0x00},
461 {0x5a, 0xa0}, 854 {0x5a, 0xa0},
462 {0x5b, 0x78}, 855 {0x5b, 0x78},
@@ -479,14 +872,16 @@ static const u8 sensor_init_ov965x_2[][2] = {
479 {0xa3, 0x3e}, 872 {0xa3, 0x3e},
480 {0x2d, 0x00}, 873 {0x2d, 0x00},
481 {0xff, 0x42}, /* read 42, write ff 00 */ 874 {0xff, 0x42}, /* read 42, write ff 00 */
482 {0x42, 0xc0}, 875 {0x42, 0xc0}, /* com17 */
483 {0x2d, 0x00}, 876 {0x2d, 0x00},
484 {0xff, 0x42}, /* read 42, write ff 00 */ 877 {0xff, 0x42}, /* read 42, write ff 00 */
485 {0x42, 0xc1}, 878 {0x42, 0xc1}, /* com17 */
879/* sharpness */
486 {0x3f, 0x01}, 880 {0x3f, 0x01},
487 {0xff, 0x42}, /* read 42, write ff 00 */ 881 {0xff, 0x42}, /* read 42, write ff 00 */
488 {0x42, 0xc1}, 882 {0x42, 0xc1}, /* com17 */
489 {0x4f, 0x98}, 883/* saturation */
884 {0x4f, 0x98}, /* matrix */
490 {0x50, 0x98}, 885 {0x50, 0x98},
491 {0x51, 0x00}, 886 {0x51, 0x00},
492 {0x52, 0x28}, 887 {0x52, 0x28},
@@ -495,14 +890,17 @@ static const u8 sensor_init_ov965x_2[][2] = {
495 {0x58, 0x1a}, 890 {0x58, 0x1a},
496 {0xff, 0x41}, /* read 41, write ff 00 */ 891 {0xff, 0x41}, /* read 41, write ff 00 */
497 {0x41, 0x40}, /* com16 */ 892 {0x41, 0x40}, /* com16 */
893/* contrast */
498 {0x56, 0x40}, 894 {0x56, 0x40},
895/* brightness */
499 {0x55, 0x8f}, 896 {0x55, 0x8f},
897/* expo */
500 {0x10, 0x25}, /* aech - exposure high bits */ 898 {0x10, 0x25}, /* aech - exposure high bits */
501 {0xff, 0x13}, /* read 13, write ff 00 */ 899 {0xff, 0x13}, /* read 13, write ff 00 */
502 {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */ 900 {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */
503}; 901};
504 902
505static const u8 sensor_start_ov965x[][2] = { 903static const u8 sensor_start_ov965x_1_vga[][2] = { /* same for qvga */
506 {0x12, 0x62}, /* com7 - 30fps VGA YUV */ 904 {0x12, 0x62}, /* com7 - 30fps VGA YUV */
507 {0x36, 0xfa}, /* aref3 */ 905 {0x36, 0xfa}, /* aref3 */
508 {0x69, 0x0a}, /* hv */ 906 {0x69, 0x0a}, /* hv */
@@ -523,10 +921,77 @@ static const u8 sensor_start_ov965x[][2] = {
523 {0x1a, 0x3d}, /* vstop */ 921 {0x1a, 0x3d}, /* vstop */
524 {0x32, 0xff}, /* href */ 922 {0x32, 0xff}, /* href */
525 {0xc0, 0xaa}, 923 {0xc0, 0xaa},
526 {}
527}; 924};
528 925
529static const u8 bridge_start_ov965x[][2] = { 926static const u8 sensor_start_ov965x_1_svga[][2] = {
927 {0x12, 0x02}, /* com7 - YUYV - VGA 15 full resolution */
928 {0x36, 0xf8}, /* aref3 */
929 {0x69, 0x02}, /* hv */
930 {0x8c, 0x0d}, /* com22 */
931 {0x3e, 0x0c}, /* com14 */
932 {0x41, 0x40}, /* com16 */
933 {0x72, 0x00},
934 {0x73, 0x01},
935 {0x74, 0x3a},
936 {0x75, 0x35},
937 {0x76, 0x01},
938 {0xc7, 0x80}, /* com24 */
939 {0x03, 0x1b}, /* vref */
940 {0x17, 0x1d}, /* hstart */
941 {0x18, 0xbd}, /* hstop */
942 {0x19, 0x01}, /* vstrt */
943 {0x1a, 0x81}, /* vstop */
944 {0x32, 0xff}, /* href */
945 {0xc0, 0xe2},
946};
947
948static const u8 sensor_start_ov965x_1_xga[][2] = {
949 {0x12, 0x02}, /* com7 */
950 {0x36, 0xf8}, /* aref3 */
951 {0x69, 0x02}, /* hv */
952 {0x8c, 0x89}, /* com22 */
953 {0x14, 0x28}, /* com9 */
954 {0x3e, 0x0c}, /* com14 */
955 {0x41, 0x40}, /* com16 */
956 {0x72, 0x00},
957 {0x73, 0x01},
958 {0x74, 0x3a},
959 {0x75, 0x35},
960 {0x76, 0x01},
961 {0xc7, 0x80}, /* com24 */
962 {0x03, 0x1b}, /* vref */
963 {0x17, 0x1d}, /* hstart */
964 {0x18, 0xbd}, /* hstop */
965 {0x19, 0x01}, /* vstrt */
966 {0x1a, 0x81}, /* vstop */
967 {0x32, 0xff}, /* href */
968 {0xc0, 0xe2},
969};
970
971static const u8 sensor_start_ov965x_1_sxga[][2] = {
972 {0x12, 0x02}, /* com7 */
973 {0x36, 0xf8}, /* aref3 */
974 {0x69, 0x02}, /* hv */
975 {0x8c, 0x89}, /* com22 */
976 {0x14, 0x28}, /* com9 */
977 {0x3e, 0x0c}, /* com14 */
978 {0x41, 0x40}, /* com16 */
979 {0x72, 0x00},
980 {0x73, 0x01},
981 {0x74, 0x3a},
982 {0x75, 0x35},
983 {0x76, 0x01},
984 {0xc7, 0x80}, /* com24 */
985 {0x03, 0x1b}, /* vref */
986 {0x17, 0x1d}, /* hstart */
987 {0x18, 0x02}, /* hstop */
988 {0x19, 0x01}, /* vstrt */
989 {0x1a, 0x81}, /* vstop */
990 {0x32, 0xff}, /* href */
991 {0xc0, 0xe2},
992};
993
994static const u8 bridge_start_ov965x_qvga[][2] = {
530 {0x94, 0xaa}, 995 {0x94, 0xaa},
531 {0xf1, 0x60}, 996 {0xf1, 0x60},
532 {0xe5, 0x04}, 997 {0xe5, 0x04},
@@ -535,10 +1000,34 @@ static const u8 bridge_start_ov965x[][2] = {
535 {0x8c, 0x00}, 1000 {0x8c, 0x00},
536 {0x8d, 0x1c}, 1001 {0x8d, 0x1c},
537 {0x34, 0x05}, 1002 {0x34, 0x05},
538 {} 1003
1004 {0xc2, 0x4c},
1005 {0xc3, 0xf9},
1006 {0xda, 0x00},
1007 {0x50, 0x00},
1008 {0x51, 0xa0},
1009 {0x52, 0x78},
1010 {0x53, 0x00},
1011 {0x54, 0x00},
1012 {0x55, 0x00},
1013 {0x57, 0x00},
1014 {0x5c, 0x00},
1015 {0x5a, 0x50},
1016 {0x5b, 0x3c},
1017 {0x35, 0x02},
1018 {0xd9, 0x10},
1019 {0x94, 0x11},
539}; 1020};
540 1021
541static const u8 bridge_start_ov965x_vga[][2] = { 1022static const u8 bridge_start_ov965x_vga[][2] = {
1023 {0x94, 0xaa},
1024 {0xf1, 0x60},
1025 {0xe5, 0x04},
1026 {0xc0, 0x50},
1027 {0xc1, 0x3c},
1028 {0x8c, 0x00},
1029 {0x8d, 0x1c},
1030 {0x34, 0x05},
542 {0xc2, 0x0c}, 1031 {0xc2, 0x0c},
543 {0xc3, 0xf9}, 1032 {0xc3, 0xf9},
544 {0xda, 0x01}, 1033 {0xda, 0x01},
@@ -555,30 +1044,98 @@ static const u8 bridge_start_ov965x_vga[][2] = {
555 {0x35, 0x02}, 1044 {0x35, 0x02},
556 {0xd9, 0x10}, 1045 {0xd9, 0x10},
557 {0x94, 0x11}, 1046 {0x94, 0x11},
558 {}
559}; 1047};
560 1048
561static const u8 bridge_start_ov965x_cif[][2] = { 1049static const u8 bridge_start_ov965x_svga[][2] = {
1050 {0x94, 0xaa},
1051 {0xf1, 0x60},
1052 {0xe5, 0x04},
1053 {0xc0, 0xa0},
1054 {0xc1, 0x80},
1055 {0x8c, 0x00},
1056 {0x8d, 0x1c},
1057 {0x34, 0x05},
562 {0xc2, 0x4c}, 1058 {0xc2, 0x4c},
563 {0xc3, 0xf9}, 1059 {0xc3, 0xf9},
564 {0xda, 0x00},
565 {0x50, 0x00}, 1060 {0x50, 0x00},
566 {0x51, 0xa0}, 1061 {0x51, 0x40},
567 {0x52, 0x78}, 1062 {0x52, 0x00},
568 {0x53, 0x00}, 1063 {0x53, 0x00},
569 {0x54, 0x00}, 1064 {0x54, 0x00},
570 {0x55, 0x00}, 1065 {0x55, 0x88},
571 {0x57, 0x00}, 1066 {0x57, 0x00},
572 {0x5c, 0x00}, 1067 {0x5c, 0x00},
573 {0x5a, 0x50}, 1068 {0x5a, 0xc8},
574 {0x5b, 0x3c}, 1069 {0x5b, 0x96},
575 {0x35, 0x02}, 1070 {0x35, 0x02},
576 {0xd9, 0x10}, 1071 {0xd9, 0x10},
1072 {0xda, 0x00},
577 {0x94, 0x11}, 1073 {0x94, 0x11},
578 {}
579}; 1074};
580 1075
581static const u8 sensor_start_ov965x_vga[][2] = { 1076static const u8 bridge_start_ov965x_xga[][2] = {
1077 {0x94, 0xaa},
1078 {0xf1, 0x60},
1079 {0xe5, 0x04},
1080 {0xc0, 0xa0},
1081 {0xc1, 0x80},
1082 {0x8c, 0x00},
1083 {0x8d, 0x1c},
1084 {0x34, 0x05},
1085 {0xc2, 0x4c},
1086 {0xc3, 0xf9},
1087 {0x50, 0x00},
1088 {0x51, 0x40},
1089 {0x52, 0x00},
1090 {0x53, 0x00},
1091 {0x54, 0x00},
1092 {0x55, 0x88},
1093 {0x57, 0x00},
1094 {0x5c, 0x01},
1095 {0x5a, 0x00},
1096 {0x5b, 0xc0},
1097 {0x35, 0x02},
1098 {0xd9, 0x10},
1099 {0xda, 0x01},
1100 {0x94, 0x11},
1101};
1102
1103static const u8 bridge_start_ov965x_sxga[][2] = {
1104 {0x94, 0xaa},
1105 {0xf1, 0x60},
1106 {0xe5, 0x04},
1107 {0xc0, 0xa0},
1108 {0xc1, 0x80},
1109 {0x8c, 0x00},
1110 {0x8d, 0x1c},
1111 {0x34, 0x05},
1112 {0xc2, 0x0c},
1113 {0xc3, 0xf9},
1114 {0xda, 0x00},
1115 {0x35, 0x02},
1116 {0xd9, 0x10},
1117 {0x94, 0x11},
1118};
1119
1120static const u8 sensor_start_ov965x_2_qvga[][2] = {
1121 {0x3b, 0xe4}, /* com11 - night mode 1/4 frame rate */
1122 {0x1e, 0x04}, /* mvfp */
1123 {0x13, 0xe0}, /* com8 */
1124 {0x00, 0x00},
1125 {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */
1126 {0x11, 0x01}, /* clkrc */
1127 {0x6b, 0x5a}, /* dblv */
1128 {0x6a, 0x02}, /* 50 Hz banding filter */
1129 {0xc5, 0x03}, /* 60 Hz banding filter */
1130 {0xa2, 0x96}, /* bd50 */
1131 {0xa3, 0x7d}, /* bd60 */
1132
1133 {0xff, 0x13}, /* read 13, write ff 00 */
1134 {0x13, 0xe7},
1135 {0x3a, 0x80}, /* tslb - yuyv */
1136};
1137
1138static const u8 sensor_start_ov965x_2_vga[][2] = {
582 {0x3b, 0xc4}, /* com11 - night mode 1/4 frame rate */ 1139 {0x3b, 0xc4}, /* com11 - night mode 1/4 frame rate */
583 {0x1e, 0x04}, /* mvfp */ 1140 {0x1e, 0x04}, /* mvfp */
584 {0x13, 0xe0}, /* com8 */ 1141 {0x13, 0xe0}, /* com8 */
@@ -592,35 +1149,36 @@ static const u8 sensor_start_ov965x_vga[][2] = {
592 {0xa3, 0x3e}, /* bd60 */ 1149 {0xa3, 0x3e}, /* bd60 */
593 1150
594 {0x2d, 0x00}, /* advfl */ 1151 {0x2d, 0x00}, /* advfl */
595 {}
596}; 1152};
597 1153
598static const u8 sensor_start_ov965x_cif[][2] = { 1154static const u8 sensor_start_ov965x_2_svga[][2] = { /* same for xga */
599 {0x3b, 0xe4}, /* com11 - night mode 1/4 frame rate */ 1155 {0x3b, 0xc4}, /* com11 - night mode 1/4 frame rate */
600 {0x1e, 0x04}, /* mvfp */ 1156 {0x1e, 0x04}, /* mvfp */
601 {0x13, 0xe0}, /* com8 */ 1157 {0x13, 0xe0}, /* com8 */
602 {0x00, 0x00}, 1158 {0x00, 0x00},
603 {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */ 1159 {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */
604 {0x11, 0x01}, /* clkrc */ 1160 {0x11, 0x01}, /* clkrc */
605 {0x6b, 0x5a}, /* dblv */ 1161 {0x6b, 0x5a}, /* dblv */
606 {0x6a, 0x02}, /* 50 Hz banding filter */ 1162 {0x6a, 0x0c}, /* 50 Hz banding filter */
607 {0xc5, 0x03}, /* 60 Hz banding filter */ 1163 {0xc5, 0x0f}, /* 60 Hz banding filter */
608 {0xa2, 0x96}, /* bd50 */ 1164 {0xa2, 0x4e}, /* bd50 */
609 {0xa3, 0x7d}, /* bd60 */ 1165 {0xa3, 0x41}, /* bd60 */
610
611 {0xff, 0x13}, /* read 13, write ff 00 */
612 {0x13, 0xe7},
613 {0x3a, 0x80}, /* tslb - yuyv */
614 {}
615}; 1166};
616 1167
617static const u8 sensor_start_ov965x_2[][2] = { 1168static const u8 sensor_start_ov965x_2_sxga[][2] = {
618 {0xff, 0x42}, /* read 42, write ff 00 */ 1169 {0x13, 0xe0}, /* com8 */
619 {0x42, 0xc1}, /* com17 - 50 Hz filter */ 1170 {0x00, 0x00},
620 {} 1171 {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */
1172 {0x3b, 0xc4}, /* com11 - night mode 1/4 frame rate */
1173 {0x1e, 0x04}, /* mvfp */
1174 {0x11, 0x01}, /* clkrc */
1175 {0x6b, 0x5a}, /* dblv */
1176 {0x6a, 0x0c}, /* 50 Hz banding filter */
1177 {0xc5, 0x0f}, /* 60 Hz banding filter */
1178 {0xa2, 0x4e}, /* bd50 */
1179 {0xa3, 0x41}, /* bd60 */
621}; 1180};
622 1181
623
624static void ov534_reg_write(struct gspca_dev *gspca_dev, u16 reg, u8 val) 1182static void ov534_reg_write(struct gspca_dev *gspca_dev, u16 reg, u8 val)
625{ 1183{
626 struct usb_device *udev = gspca_dev->dev; 1184 struct usb_device *udev = gspca_dev->dev;
@@ -753,39 +1311,310 @@ static void sccb_w_array(struct gspca_dev *gspca_dev,
753 } 1311 }
754} 1312}
755 1313
756/* set framerate */ 1314/* ov772x specific controls */
757static void ov534_set_frame_rate(struct gspca_dev *gspca_dev) 1315static void set_frame_rate(struct gspca_dev *gspca_dev)
1316{
1317 struct sd *sd = (struct sd *) gspca_dev;
1318 int i;
1319 struct rate_s {
1320 u8 fps;
1321 u8 r11;
1322 u8 r0d;
1323 u8 re5;
1324 };
1325 const struct rate_s *r;
1326 static const struct rate_s rate_0[] = { /* 640x480 */
1327 {60, 0x01, 0xc1, 0x04},
1328 {50, 0x01, 0x41, 0x02},
1329 {40, 0x02, 0xc1, 0x04},
1330 {30, 0x04, 0x81, 0x02},
1331 {15, 0x03, 0x41, 0x04},
1332 };
1333 static const struct rate_s rate_1[] = { /* 320x240 */
1334 {125, 0x02, 0x81, 0x02},
1335 {100, 0x02, 0xc1, 0x04},
1336 {75, 0x03, 0xc1, 0x04},
1337 {60, 0x04, 0xc1, 0x04},
1338 {50, 0x02, 0x41, 0x04},
1339 {40, 0x03, 0x41, 0x04},
1340 {30, 0x04, 0x41, 0x04},
1341 };
1342
1343 if (gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv == 0) {
1344 r = rate_0;
1345 i = ARRAY_SIZE(rate_0);
1346 } else {
1347 r = rate_1;
1348 i = ARRAY_SIZE(rate_1);
1349 }
1350 while (--i > 0) {
1351 if (sd->frame_rate >= r->fps)
1352 break;
1353 r++;
1354 }
1355
1356 sccb_reg_write(gspca_dev, 0x11, r->r11);
1357 sccb_reg_write(gspca_dev, 0x0d, r->r0d);
1358 ov534_reg_write(gspca_dev, 0xe5, r->re5);
1359
1360 PDEBUG(D_PROBE, "frame_rate: %d", r->fps);
1361}
1362
1363static void setbrightness_77(struct gspca_dev *gspca_dev)
1364{
1365 struct sd *sd = (struct sd *) gspca_dev;
1366
1367 sccb_reg_write(gspca_dev, 0x9B, sd->brightness);
1368}
1369
1370static void setcontrast_77(struct gspca_dev *gspca_dev)
758{ 1371{
759 struct sd *sd = (struct sd *) gspca_dev; 1372 struct sd *sd = (struct sd *) gspca_dev;
760 int fr = sd->frame_rate;
761 1373
762 switch (fr) { 1374 sccb_reg_write(gspca_dev, 0x9C, sd->contrast);
763 case 50: 1375}
764 sccb_reg_write(gspca_dev, 0x11, 0x01); 1376
765 sccb_reg_write(gspca_dev, 0x0d, 0x41); 1377static void setgain(struct gspca_dev *gspca_dev)
766 ov534_reg_write(gspca_dev, 0xe5, 0x02); 1378{
1379 struct sd *sd = (struct sd *) gspca_dev;
1380 u8 val;
1381
1382 val = sd->gain;
1383 switch (val & 0x30) {
1384 case 0x00:
1385 val &= 0x0f;
767 break; 1386 break;
768 case 40: 1387 case 0x10:
769 sccb_reg_write(gspca_dev, 0x11, 0x02); 1388 val &= 0x0f;
770 sccb_reg_write(gspca_dev, 0x0d, 0xc1); 1389 val |= 0x30;
771 ov534_reg_write(gspca_dev, 0xe5, 0x04);
772 break; 1390 break;
773/* case 30: */ 1391 case 0x20:
774 default: 1392 val &= 0x0f;
775 fr = 30; 1393 val |= 0x70;
776 sccb_reg_write(gspca_dev, 0x11, 0x04);
777 sccb_reg_write(gspca_dev, 0x0d, 0x81);
778 ov534_reg_write(gspca_dev, 0xe5, 0x02);
779 break; 1394 break;
780 case 15: 1395 default:
781 sccb_reg_write(gspca_dev, 0x11, 0x03); 1396/* case 0x30: */
782 sccb_reg_write(gspca_dev, 0x0d, 0x41); 1397 val &= 0x0f;
783 ov534_reg_write(gspca_dev, 0xe5, 0x04); 1398 val |= 0xf0;
784 break; 1399 break;
785 } 1400 }
1401 sccb_reg_write(gspca_dev, 0x00, val);
1402}
1403
1404static void setexposure_77(struct gspca_dev *gspca_dev)
1405{
1406 struct sd *sd = (struct sd *) gspca_dev;
1407 u8 val;
1408
1409 val = sd->exposure;
1410 sccb_reg_write(gspca_dev, 0x08, val >> 7);
1411 sccb_reg_write(gspca_dev, 0x10, val << 1);
1412}
1413
1414static void setredblc(struct gspca_dev *gspca_dev)
1415{
1416 struct sd *sd = (struct sd *) gspca_dev;
1417
1418 sccb_reg_write(gspca_dev, 0x43, sd->redblc);
1419}
1420
1421static void setblueblc(struct gspca_dev *gspca_dev)
1422{
1423 struct sd *sd = (struct sd *) gspca_dev;
1424
1425 sccb_reg_write(gspca_dev, 0x42, sd->blueblc);
1426}
1427
1428static void sethue(struct gspca_dev *gspca_dev)
1429{
1430 struct sd *sd = (struct sd *) gspca_dev;
1431
1432 sccb_reg_write(gspca_dev, 0x01, sd->hue);
1433}
1434
1435static void setautogain_77(struct gspca_dev *gspca_dev)
1436{
1437 struct sd *sd = (struct sd *) gspca_dev;
1438
1439 if (sd->autogain) {
1440 sccb_reg_write(gspca_dev, 0x13, 0xf7); /* AGC,AEC,AWB ON */
1441 sccb_reg_write(gspca_dev, 0x64,
1442 sccb_reg_read(gspca_dev, 0x64) | 0x03);
1443 } else {
1444 sccb_reg_write(gspca_dev, 0x13, 0xf0); /* AGC,AEC,AWB OFF */
1445 sccb_reg_write(gspca_dev, 0x64,
1446 sccb_reg_read(gspca_dev, 0x64) & 0xfc);
1447 }
1448}
1449
1450static void setawb(struct gspca_dev *gspca_dev)
1451{
1452 struct sd *sd = (struct sd *) gspca_dev;
1453
1454 if (sd->awb)
1455 sccb_reg_write(gspca_dev, 0x63, 0xe0); /* AWB on */
1456 else
1457 sccb_reg_write(gspca_dev, 0x63, 0xaa); /* AWB off */
1458}
1459
1460static void setsharpness_77(struct gspca_dev *gspca_dev)
1461{
1462 struct sd *sd = (struct sd *) gspca_dev;
1463 u8 val;
1464
1465 val = sd->sharpness;
1466 sccb_reg_write(gspca_dev, 0x91, val); /* vga noise */
1467 sccb_reg_write(gspca_dev, 0x8e, val); /* qvga noise */
1468}
1469
1470static void sethflip(struct gspca_dev *gspca_dev)
1471{
1472 struct sd *sd = (struct sd *) gspca_dev;
1473
1474 if (sd->hflip == 0)
1475 sccb_reg_write(gspca_dev, 0x0c,
1476 sccb_reg_read(gspca_dev, 0x0c) | 0x40);
1477 else
1478 sccb_reg_write(gspca_dev, 0x0c,
1479 sccb_reg_read(gspca_dev, 0x0c) & 0xbf);
1480}
1481
1482static void setvflip(struct gspca_dev *gspca_dev)
1483{
1484 struct sd *sd = (struct sd *) gspca_dev;
1485
1486 if (sd->vflip == 0)
1487 sccb_reg_write(gspca_dev, 0x0c,
1488 sccb_reg_read(gspca_dev, 0x0c) | 0x80);
1489 else
1490 sccb_reg_write(gspca_dev, 0x0c,
1491 sccb_reg_read(gspca_dev, 0x0c) & 0x7f);
1492}
1493
1494/* ov965x specific controls */
1495static void setbrightness_96(struct gspca_dev *gspca_dev)
1496{
1497 struct sd *sd = (struct sd *) gspca_dev;
1498 u8 val;
1499
1500 val = sd->brightness;
1501 if (val < 8)
1502 val = 15 - val; /* f .. 8 */
1503 else
1504 val = val - 8; /* 0 .. 7 */
1505 sccb_reg_write(gspca_dev, 0x55, /* brtn - brightness adjustment */
1506 0x0f | (val << 4));
1507}
1508
1509static void setcontrast_96(struct gspca_dev *gspca_dev)
1510{
1511 struct sd *sd = (struct sd *) gspca_dev;
1512
1513 sccb_reg_write(gspca_dev, 0x56, /* cnst1 - contrast 1 ctrl coeff */
1514 sd->contrast << 4);
1515}
1516
1517static void setexposure_96(struct gspca_dev *gspca_dev)
1518{
1519 struct sd *sd = (struct sd *) gspca_dev;
1520 u8 val;
1521 static const u8 expo[4] = {0x00, 0x25, 0x38, 0x5e};
1522
1523 sccb_reg_write(gspca_dev, 0x10, /* aec[9:2] */
1524 expo[sd->exposure]);
1525 val = sccb_reg_read(gspca_dev, 0x13); /* com8 */
1526 sccb_reg_write(gspca_dev, 0xff, 0x00);
1527 sccb_reg_write(gspca_dev, 0x13, val);
1528 val = sccb_reg_read(gspca_dev, 0xa1); /* aech */
1529 sccb_reg_write(gspca_dev, 0xff, 0x00);
1530 sccb_reg_write(gspca_dev, 0xa1, val & 0xe0); /* aec[15:10] = 0 */
1531}
1532
1533static void setsharpness_96(struct gspca_dev *gspca_dev)
1534{
1535 struct sd *sd = (struct sd *) gspca_dev;
1536 u8 val;
1537
1538 val = sd->sharpness;
1539 if (val < 0) { /* auto */
1540 val = sccb_reg_read(gspca_dev, 0x42); /* com17 */
1541 sccb_reg_write(gspca_dev, 0xff, 0x00);
1542 sccb_reg_write(gspca_dev, 0x42, val | 0x40);
1543 /* Edge enhancement strength auto adjust */
1544 return;
1545 }
1546 if (val != 0)
1547 val = 1 << (val - 1);
1548 sccb_reg_write(gspca_dev, 0x3f, /* edge - edge enhance. factor */
1549 val);
1550 val = sccb_reg_read(gspca_dev, 0x42); /* com17 */
1551 sccb_reg_write(gspca_dev, 0xff, 0x00);
1552 sccb_reg_write(gspca_dev, 0x42, val & 0xbf);
1553}
1554
1555static void setautogain_96(struct gspca_dev *gspca_dev)
1556{
1557 struct sd *sd = (struct sd *) gspca_dev;
1558 u8 val;
1559
1560/*fixme: should adjust agc/awb/aec by different controls */
1561 val = sd->autogain;
1562 val = sccb_reg_read(gspca_dev, 0x13); /* com8 */
1563 sccb_reg_write(gspca_dev, 0xff, 0x00);
1564 if (sd->autogain)
1565 val |= 0x05; /* agc & aec */
1566 else
1567 val &= 0xfa;
1568 sccb_reg_write(gspca_dev, 0x13, val);
1569}
1570
1571static void setsatur(struct gspca_dev *gspca_dev)
1572{
1573 struct sd *sd = (struct sd *) gspca_dev;
1574 u8 val1, val2, val3;
1575 static const u8 matrix[5][2] = {
1576 {0x14, 0x38},
1577 {0x1e, 0x54},
1578 {0x28, 0x70},
1579 {0x32, 0x8c},
1580 {0x48, 0x90}
1581 };
1582
1583 val1 = matrix[sd->satur][0];
1584 val2 = matrix[sd->satur][1];
1585 val3 = val1 + val2;
1586 sccb_reg_write(gspca_dev, 0x4f, val3); /* matrix coeff */
1587 sccb_reg_write(gspca_dev, 0x50, val3);
1588 sccb_reg_write(gspca_dev, 0x51, 0x00);
1589 sccb_reg_write(gspca_dev, 0x52, val1);
1590 sccb_reg_write(gspca_dev, 0x53, val2);
1591 sccb_reg_write(gspca_dev, 0x54, val3);
1592 sccb_reg_write(gspca_dev, 0x58, 0x1a); /* mtxs - coeff signs */
1593 val1 = sccb_reg_read(gspca_dev, 0x41); /* com16 */
1594 sccb_reg_write(gspca_dev, 0xff, 0x00);
1595 sccb_reg_write(gspca_dev, 0x41, val1);
1596}
1597
1598static void setfreq(struct gspca_dev *gspca_dev)
1599{
1600 struct sd *sd = (struct sd *) gspca_dev;
1601 u8 val;
1602
1603 val = sccb_reg_read(gspca_dev, 0x13); /* com8 */
1604 sccb_reg_write(gspca_dev, 0xff, 0x00);
1605 if (sd->lightfreq == 0) {
1606 sccb_reg_write(gspca_dev, 0x13, val & 0xdf);
1607 return;
1608 }
1609 sccb_reg_write(gspca_dev, 0x13, val | 0x20);
786 1610
787 sd->frame_rate = fr; 1611 val = sccb_reg_read(gspca_dev, 0x42); /* com17 */
788 PDEBUG(D_PROBE, "frame_rate: %d", fr); 1612 sccb_reg_write(gspca_dev, 0xff, 0x00);
1613 if (sd->lightfreq == 1)
1614 val |= 0x01;
1615 else
1616 val &= 0xfe;
1617 sccb_reg_write(gspca_dev, 0x42, val);
789} 1618}
790 1619
791/* this function is called at probe time */ 1620/* this function is called at probe time */
@@ -800,17 +1629,60 @@ static int sd_config(struct gspca_dev *gspca_dev,
800 cam = &gspca_dev->cam; 1629 cam = &gspca_dev->cam;
801 1630
802 if (sd->sensor == SENSOR_OV772X) { 1631 if (sd->sensor == SENSOR_OV772X) {
803 cam->cam_mode = vga_yuyv_mode; 1632 cam->cam_mode = ov772x_mode;
804 cam->nmodes = ARRAY_SIZE(vga_yuyv_mode); 1633 cam->nmodes = ARRAY_SIZE(ov772x_mode);
805 1634
806 cam->bulk = 1; 1635 cam->bulk = 1;
807 cam->bulk_size = 16384; 1636 cam->bulk_size = 16384;
808 cam->bulk_nurbs = 2; 1637 cam->bulk_nurbs = 2;
809 } else { /* ov965x */ 1638 } else { /* ov965x */
810 cam->cam_mode = vga_jpeg_mode; 1639 cam->cam_mode = ov965x_mode;
811 cam->nmodes = ARRAY_SIZE(vga_jpeg_mode); 1640 cam->nmodes = ARRAY_SIZE(ov965x_mode);
812 } 1641 }
813 1642
1643 sd->frame_rate = 30;
1644
1645 if (sd->sensor == SENSOR_OV772X) {
1646 sd->brightness = BRIGHTNESS_77_DEF;
1647 sd->contrast = CONTRAST_77_DEF;
1648 sd->gain = GAIN_DEF;
1649 sd->exposure = EXPO_77_DEF;
1650 sd->redblc = RED_BALANCE_DEF;
1651 sd->blueblc = BLUE_BALANCE_DEF;
1652 sd->hue = HUE_DEF;
1653#if AUTOGAIN_77_DEF != 0
1654 sd->autogain = AUTOGAIN_77_DEF;
1655#else
1656 gspca_dev->ctrl_inac |= (1 << AWB_77_IDX);
1657#endif
1658#if AWB_DEF != 0
1659 sd->awb = AWB_DEF
1660#endif
1661#if SHARPNESS_77_DEF != 0
1662 sd->sharpness = SHARPNESS_77_DEF;
1663#endif
1664#if HFLIP_DEF != 0
1665 sd->hflip = HFLIP_DEF;
1666#endif
1667#if VFLIP_DEF != 0
1668 sd->vflip = VFLIP_DEF;
1669#endif
1670 } else {
1671 sd->brightness = BRIGHTNESS_96_DEF;
1672 sd->contrast = CONTRAST_96_DEF;
1673#if AUTOGAIN_96_DEF != 0
1674 sd->autogain = AUTOGAIN_96_DEF;
1675 gspca_dev->ctrl_inac |= (1 << EXPO_96_IDX);
1676#endif
1677#if EXPO_96_DEF != 0
1678 sd->exposure = EXPO_96_DEF;
1679#endif
1680#if SHARPNESS_96_DEF != 0
1681 sd->sharpness = SHARPNESS_96_DEF;
1682#endif
1683 sd->satur = SATUR_DEF;
1684 sd->lightfreq = FREQ_DEF;
1685 }
814 return 0; 1686 return 0;
815} 1687}
816 1688
@@ -847,14 +1719,14 @@ static int sd_init(struct gspca_dev *gspca_dev)
847 /* initialize */ 1719 /* initialize */
848 switch (sd->sensor) { 1720 switch (sd->sensor) {
849 case SENSOR_OV772X: 1721 case SENSOR_OV772X:
850 reg_w_array(gspca_dev, bridge_init_ov722x, 1722 reg_w_array(gspca_dev, bridge_init_ov772x,
851 ARRAY_SIZE(bridge_init_ov722x)); 1723 ARRAY_SIZE(bridge_init_ov772x));
852 ov534_set_led(gspca_dev, 1); 1724 ov534_set_led(gspca_dev, 1);
853 sccb_w_array(gspca_dev, sensor_init_ov722x, 1725 sccb_w_array(gspca_dev, sensor_init_ov772x,
854 ARRAY_SIZE(sensor_init_ov722x)); 1726 ARRAY_SIZE(sensor_init_ov772x));
855 ov534_reg_write(gspca_dev, 0xe0, 0x09); 1727 ov534_reg_write(gspca_dev, 0xe0, 0x09);
856 ov534_set_led(gspca_dev, 0); 1728 ov534_set_led(gspca_dev, 0);
857 ov534_set_frame_rate(gspca_dev); 1729 set_frame_rate(gspca_dev);
858 break; 1730 break;
859 default: 1731 default:
860/* case SENSOR_OV965X: */ 1732/* case SENSOR_OV965X: */
@@ -875,60 +1747,115 @@ static int sd_init(struct gspca_dev *gspca_dev)
875 return 0; 1747 return 0;
876} 1748}
877 1749
878static int sd_start(struct gspca_dev *gspca_dev) 1750static int sd_start_ov772x(struct gspca_dev *gspca_dev)
879{ 1751{
880 struct sd *sd = (struct sd *) gspca_dev;
881 int mode; 1752 int mode;
882 1753
883 switch (sd->sensor) { 1754 mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
884 case SENSOR_OV772X: 1755 if (mode != 0) { /* 320x240 */
885 ov534_set_led(gspca_dev, 1); 1756 reg_w_array(gspca_dev, bridge_start_ov772x_qvga,
886 ov534_reg_write(gspca_dev, 0xe0, 0x00); 1757 ARRAY_SIZE(bridge_start_ov772x_qvga));
887 break; 1758 sccb_w_array(gspca_dev, sensor_start_ov772x_qvga,
888 default: 1759 ARRAY_SIZE(sensor_start_ov772x_qvga));
889/* case SENSOR_OV965X: */ 1760 } else { /* 640x480 */
890 1761 reg_w_array(gspca_dev, bridge_start_ov772x_vga,
891 sccb_w_array(gspca_dev, sensor_start_ov965x, 1762 ARRAY_SIZE(bridge_start_ov772x_vga));
892 ARRAY_SIZE(sensor_start_ov965x)); 1763 sccb_w_array(gspca_dev, sensor_start_ov772x_vga,
893 reg_w_array(gspca_dev, bridge_start_ov965x, 1764 ARRAY_SIZE(sensor_start_ov772x_vga));
894 ARRAY_SIZE(bridge_start_ov965x));
895 mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
896 if (mode != 0) { /* 320x240 */
897 reg_w_array(gspca_dev, bridge_start_ov965x_cif,
898 ARRAY_SIZE(bridge_start_ov965x_cif));
899 sccb_w_array(gspca_dev, sensor_start_ov965x_cif,
900 ARRAY_SIZE(sensor_start_ov965x_cif));
901 } else { /* 640x480 */
902 reg_w_array(gspca_dev, bridge_start_ov965x_vga,
903 ARRAY_SIZE(bridge_start_ov965x_vga));
904 sccb_w_array(gspca_dev, sensor_start_ov965x_vga,
905 ARRAY_SIZE(sensor_start_ov965x_vga));
906 }
907 sccb_w_array(gspca_dev, sensor_start_ov965x_2,
908 ARRAY_SIZE(sensor_start_ov965x_2));
909 ov534_reg_write(gspca_dev, 0xe0, 0x00);
910 ov534_reg_write(gspca_dev, 0xe0, 0x00);
911 ov534_set_led(gspca_dev, 1);
912 } 1765 }
1766 set_frame_rate(gspca_dev);
1767
1768 setautogain_77(gspca_dev);
1769 setawb(gspca_dev);
1770 setgain(gspca_dev);
1771 setredblc(gspca_dev);
1772 setblueblc(gspca_dev);
1773 sethue(gspca_dev);
1774 setexposure_77(gspca_dev);
1775 setbrightness_77(gspca_dev);
1776 setcontrast_77(gspca_dev);
1777 setsharpness_77(gspca_dev);
1778 setvflip(gspca_dev);
1779 sethflip(gspca_dev);
1780
1781 ov534_set_led(gspca_dev, 1);
1782 ov534_reg_write(gspca_dev, 0xe0, 0x00);
913 return 0; 1783 return 0;
914} 1784}
915 1785
916static void sd_stopN(struct gspca_dev *gspca_dev) 1786static int sd_start_ov965x(struct gspca_dev *gspca_dev)
917{ 1787{
918 struct sd *sd = (struct sd *) gspca_dev; 1788 int mode;
919 1789
920 switch (sd->sensor) { 1790 mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
921 case SENSOR_OV772X: 1791 switch (mode) {
922 ov534_reg_write(gspca_dev, 0xe0, 0x09);
923 ov534_set_led(gspca_dev, 0);
924 break;
925 default: 1792 default:
926/* case SENSOR_OV965X: */ 1793/* case 4: * 320x240 */
927 ov534_reg_write(gspca_dev, 0xe0, 0x01); 1794 sccb_w_array(gspca_dev, sensor_start_ov965x_1_vga,
928 ov534_set_led(gspca_dev, 0); 1795 ARRAY_SIZE(sensor_start_ov965x_1_vga));
929 ov534_reg_write(gspca_dev, 0xe0, 0x00); 1796 reg_w_array(gspca_dev, bridge_start_ov965x_qvga,
1797 ARRAY_SIZE(bridge_start_ov965x_qvga));
1798 sccb_w_array(gspca_dev, sensor_start_ov965x_2_qvga,
1799 ARRAY_SIZE(sensor_start_ov965x_2_qvga));
1800 break;
1801 case 3: /* 640x480 */
1802 sccb_w_array(gspca_dev, sensor_start_ov965x_1_vga,
1803 ARRAY_SIZE(sensor_start_ov965x_1_vga));
1804 reg_w_array(gspca_dev, bridge_start_ov965x_vga,
1805 ARRAY_SIZE(bridge_start_ov965x_vga));
1806 sccb_w_array(gspca_dev, sensor_start_ov965x_2_vga,
1807 ARRAY_SIZE(sensor_start_ov965x_2_vga));
1808 break;
1809 case 2: /* 800x600 */
1810 sccb_w_array(gspca_dev, sensor_start_ov965x_1_svga,
1811 ARRAY_SIZE(sensor_start_ov965x_1_svga));
1812 reg_w_array(gspca_dev, bridge_start_ov965x_svga,
1813 ARRAY_SIZE(bridge_start_ov965x_svga));
1814 sccb_w_array(gspca_dev, sensor_start_ov965x_2_svga,
1815 ARRAY_SIZE(sensor_start_ov965x_2_svga));
1816 break;
1817 case 1: /* 1024x768 */
1818 sccb_w_array(gspca_dev, sensor_start_ov965x_1_xga,
1819 ARRAY_SIZE(sensor_start_ov965x_1_xga));
1820 reg_w_array(gspca_dev, bridge_start_ov965x_xga,
1821 ARRAY_SIZE(bridge_start_ov965x_xga));
1822 sccb_w_array(gspca_dev, sensor_start_ov965x_2_svga,
1823 ARRAY_SIZE(sensor_start_ov965x_2_svga));
1824 break;
1825 case 0: /* 1280x1024 */
1826 sccb_w_array(gspca_dev, sensor_start_ov965x_1_sxga,
1827 ARRAY_SIZE(sensor_start_ov965x_1_sxga));
1828 reg_w_array(gspca_dev, bridge_start_ov965x_sxga,
1829 ARRAY_SIZE(bridge_start_ov965x_sxga));
1830 sccb_w_array(gspca_dev, sensor_start_ov965x_2_sxga,
1831 ARRAY_SIZE(sensor_start_ov965x_2_sxga));
930 break; 1832 break;
931 } 1833 }
1834 setfreq(gspca_dev);
1835 setautogain_96(gspca_dev);
1836 setbrightness_96(gspca_dev);
1837 setcontrast_96(gspca_dev);
1838 setexposure_96(gspca_dev);
1839 setsharpness_96(gspca_dev);
1840 setsatur(gspca_dev);
1841
1842 ov534_reg_write(gspca_dev, 0xe0, 0x00);
1843 ov534_reg_write(gspca_dev, 0xe0, 0x00);
1844 ov534_set_led(gspca_dev, 1);
1845 return 0;
1846}
1847
1848static void sd_stopN_ov772x(struct gspca_dev *gspca_dev)
1849{
1850 ov534_reg_write(gspca_dev, 0xe0, 0x09);
1851 ov534_set_led(gspca_dev, 0);
1852}
1853
1854static void sd_stopN_ov965x(struct gspca_dev *gspca_dev)
1855{
1856 ov534_reg_write(gspca_dev, 0xe0, 0x01);
1857 ov534_set_led(gspca_dev, 0);
1858 ov534_reg_write(gspca_dev, 0xe0, 0x00);
932} 1859}
933 1860
934/* Values for bmHeaderInfo (Video and Still Image Payload Headers, 2.4.3.3) */ 1861/* Values for bmHeaderInfo (Video and Still Image Payload Headers, 2.4.3.3) */
@@ -941,8 +1868,8 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
941#define UVC_STREAM_EOF (1 << 1) 1868#define UVC_STREAM_EOF (1 << 1)
942#define UVC_STREAM_FID (1 << 0) 1869#define UVC_STREAM_FID (1 << 0)
943 1870
944static void sd_pkt_scan(struct gspca_dev *gspca_dev, struct gspca_frame *frame, 1871static void sd_pkt_scan(struct gspca_dev *gspca_dev,
945 __u8 *data, int len) 1872 u8 *data, int len)
946{ 1873{
947 struct sd *sd = (struct sd *) gspca_dev; 1874 struct sd *sd = (struct sd *) gspca_dev;
948 __u32 this_pts; 1875 __u32 this_pts;
@@ -983,32 +1910,30 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, struct gspca_frame *frame,
983 /* If PTS or FID has changed, start a new frame. */ 1910 /* If PTS or FID has changed, start a new frame. */
984 if (this_pts != sd->last_pts || this_fid != sd->last_fid) { 1911 if (this_pts != sd->last_pts || this_fid != sd->last_fid) {
985 if (gspca_dev->last_packet_type == INTER_PACKET) 1912 if (gspca_dev->last_packet_type == INTER_PACKET)
986 frame = gspca_frame_add(gspca_dev, 1913 gspca_frame_add(gspca_dev, LAST_PACKET,
987 LAST_PACKET, frame, 1914 NULL, 0);
988 NULL, 0);
989 sd->last_pts = this_pts; 1915 sd->last_pts = this_pts;
990 sd->last_fid = this_fid; 1916 sd->last_fid = this_fid;
991 gspca_frame_add(gspca_dev, FIRST_PACKET, frame, 1917 gspca_frame_add(gspca_dev, FIRST_PACKET,
992 data + 12, len - 12); 1918 data + 12, len - 12);
993 /* If this packet is marked as EOF, end the frame */ 1919 /* If this packet is marked as EOF, end the frame */
994 } else if (data[1] & UVC_STREAM_EOF) { 1920 } else if (data[1] & UVC_STREAM_EOF) {
995 sd->last_pts = 0; 1921 sd->last_pts = 0;
996 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, 1922 gspca_frame_add(gspca_dev, LAST_PACKET,
997 data + 12, len - 12); 1923 data + 12, len - 12);
998 } else { 1924 } else {
999 1925
1000 /* Add the data from this payload */ 1926 /* Add the data from this payload */
1001 gspca_frame_add(gspca_dev, INTER_PACKET, frame, 1927 gspca_frame_add(gspca_dev, INTER_PACKET,
1002 data + 12, len - 12); 1928 data + 12, len - 12);
1003 } 1929 }
1004 1930
1005
1006 /* Done this payload */ 1931 /* Done this payload */
1007 goto scan_next; 1932 goto scan_next;
1008 1933
1009discard: 1934discard:
1010 /* Discard data until a new frame starts. */ 1935 /* Discard data until a new frame starts. */
1011 gspca_frame_add(gspca_dev, DISCARD_PACKET, frame, NULL, 0); 1936 gspca_dev->last_packet_type = DISCARD_PACKET;
1012 1937
1013scan_next: 1938scan_next:
1014 remaining_len -= len; 1939 remaining_len -= len;
@@ -1016,6 +1941,291 @@ scan_next:
1016 } while (remaining_len > 0); 1941 } while (remaining_len > 0);
1017} 1942}
1018 1943
1944/* controls */
1945static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val)
1946{
1947 struct sd *sd = (struct sd *) gspca_dev;
1948
1949 sd->gain = val;
1950 if (gspca_dev->streaming)
1951 setgain(gspca_dev);
1952 return 0;
1953}
1954
1955static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
1956{
1957 struct sd *sd = (struct sd *) gspca_dev;
1958
1959 *val = sd->gain;
1960 return 0;
1961}
1962
1963static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val)
1964{
1965 struct sd *sd = (struct sd *) gspca_dev;
1966
1967 sd->exposure = val;
1968 if (gspca_dev->streaming) {
1969 if (sd->sensor == SENSOR_OV772X)
1970 setexposure_77(gspca_dev);
1971 else
1972 setexposure_96(gspca_dev);
1973 }
1974 return 0;
1975}
1976
1977static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val)
1978{
1979 struct sd *sd = (struct sd *) gspca_dev;
1980
1981 *val = sd->exposure;
1982 return 0;
1983}
1984
1985static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1986{
1987 struct sd *sd = (struct sd *) gspca_dev;
1988
1989 sd->brightness = val;
1990 if (gspca_dev->streaming) {
1991 if (sd->sensor == SENSOR_OV772X)
1992 setbrightness_77(gspca_dev);
1993 else
1994 setbrightness_96(gspca_dev);
1995 }
1996 return 0;
1997}
1998
1999static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
2000{
2001 struct sd *sd = (struct sd *) gspca_dev;
2002
2003 *val = sd->brightness;
2004 return 0;
2005}
2006
2007static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
2008{
2009 struct sd *sd = (struct sd *) gspca_dev;
2010
2011 sd->contrast = val;
2012 if (gspca_dev->streaming) {
2013 if (sd->sensor == SENSOR_OV772X)
2014 setcontrast_77(gspca_dev);
2015 else
2016 setcontrast_96(gspca_dev);
2017 }
2018 return 0;
2019}
2020
2021static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
2022{
2023 struct sd *sd = (struct sd *) gspca_dev;
2024
2025 *val = sd->contrast;
2026 return 0;
2027}
2028
2029static int sd_setsatur(struct gspca_dev *gspca_dev, __s32 val)
2030{
2031 struct sd *sd = (struct sd *) gspca_dev;
2032
2033 sd->satur = val;
2034 if (gspca_dev->streaming)
2035 setsatur(gspca_dev);
2036 return 0;
2037}
2038
2039static int sd_getsatur(struct gspca_dev *gspca_dev, __s32 *val)
2040{
2041 struct sd *sd = (struct sd *) gspca_dev;
2042
2043 *val = sd->satur;
2044 return 0;
2045}
2046static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val)
2047{
2048 struct sd *sd = (struct sd *) gspca_dev;
2049
2050 sd->lightfreq = val;
2051 if (gspca_dev->streaming)
2052 setfreq(gspca_dev);
2053 return 0;
2054}
2055
2056static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val)
2057{
2058 struct sd *sd = (struct sd *) gspca_dev;
2059
2060 *val = sd->lightfreq;
2061 return 0;
2062}
2063
2064static int sd_setredblc(struct gspca_dev *gspca_dev, __s32 val)
2065{
2066 struct sd *sd = (struct sd *) gspca_dev;
2067
2068 sd->redblc = val;
2069 if (gspca_dev->streaming)
2070 setredblc(gspca_dev);
2071 return 0;
2072}
2073
2074static int sd_getredblc(struct gspca_dev *gspca_dev, __s32 *val)
2075{
2076 struct sd *sd = (struct sd *) gspca_dev;
2077
2078 *val = sd->redblc;
2079 return 0;
2080}
2081
2082static int sd_setblueblc(struct gspca_dev *gspca_dev, __s32 val)
2083{
2084 struct sd *sd = (struct sd *) gspca_dev;
2085
2086 sd->blueblc = val;
2087 if (gspca_dev->streaming)
2088 setblueblc(gspca_dev);
2089 return 0;
2090}
2091
2092static int sd_getblueblc(struct gspca_dev *gspca_dev, __s32 *val)
2093{
2094 struct sd *sd = (struct sd *) gspca_dev;
2095
2096 *val = sd->blueblc;
2097 return 0;
2098}
2099
2100static int sd_sethue(struct gspca_dev *gspca_dev, __s32 val)
2101{
2102 struct sd *sd = (struct sd *) gspca_dev;
2103
2104 sd->hue = val;
2105 if (gspca_dev->streaming)
2106 sethue(gspca_dev);
2107 return 0;
2108}
2109
2110static int sd_gethue(struct gspca_dev *gspca_dev, __s32 *val)
2111{
2112 struct sd *sd = (struct sd *) gspca_dev;
2113
2114 *val = sd->hue;
2115 return 0;
2116}
2117
2118static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
2119{
2120 struct sd *sd = (struct sd *) gspca_dev;
2121
2122 sd->autogain = val;
2123
2124 if (gspca_dev->streaming) {
2125 if (sd->sensor == SENSOR_OV772X) {
2126
2127 /* the auto white balance control works only
2128 * when auto gain is set */
2129 if (val)
2130 gspca_dev->ctrl_inac &= ~(1 << AWB_77_IDX);
2131 else
2132 gspca_dev->ctrl_inac |= (1 << AWB_77_IDX);
2133 setautogain_77(gspca_dev);
2134 } else {
2135 if (val)
2136 gspca_dev->ctrl_inac |= (1 << EXPO_96_IDX);
2137 else
2138 gspca_dev->ctrl_inac &= ~(1 << EXPO_96_IDX);
2139 setautogain_96(gspca_dev);
2140 }
2141 }
2142 return 0;
2143}
2144
2145static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
2146{
2147 struct sd *sd = (struct sd *) gspca_dev;
2148
2149 *val = sd->autogain;
2150 return 0;
2151}
2152
2153static int sd_setawb(struct gspca_dev *gspca_dev, __s32 val)
2154{
2155 struct sd *sd = (struct sd *) gspca_dev;
2156
2157 sd->awb = val;
2158 if (gspca_dev->streaming)
2159 setawb(gspca_dev);
2160 return 0;
2161}
2162
2163static int sd_getawb(struct gspca_dev *gspca_dev, __s32 *val)
2164{
2165 struct sd *sd = (struct sd *) gspca_dev;
2166
2167 *val = sd->awb;
2168 return 0;
2169}
2170
2171static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val)
2172{
2173 struct sd *sd = (struct sd *) gspca_dev;
2174
2175 sd->sharpness = val;
2176 if (gspca_dev->streaming) {
2177 if (sd->sensor == SENSOR_OV772X)
2178 setsharpness_77(gspca_dev);
2179 else
2180 setsharpness_96(gspca_dev);
2181 }
2182 return 0;
2183}
2184
2185static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val)
2186{
2187 struct sd *sd = (struct sd *) gspca_dev;
2188
2189 *val = sd->sharpness;
2190 return 0;
2191}
2192
2193static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val)
2194{
2195 struct sd *sd = (struct sd *) gspca_dev;
2196
2197 sd->hflip = val;
2198 if (gspca_dev->streaming)
2199 sethflip(gspca_dev);
2200 return 0;
2201}
2202
2203static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val)
2204{
2205 struct sd *sd = (struct sd *) gspca_dev;
2206
2207 *val = sd->hflip;
2208 return 0;
2209}
2210
2211static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val)
2212{
2213 struct sd *sd = (struct sd *) gspca_dev;
2214
2215 sd->vflip = val;
2216 if (gspca_dev->streaming)
2217 setvflip(gspca_dev);
2218 return 0;
2219}
2220
2221static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val)
2222{
2223 struct sd *sd = (struct sd *) gspca_dev;
2224
2225 *val = sd->vflip;
2226 return 0;
2227}
2228
1019/* get stream parameters (framerate) */ 2229/* get stream parameters (framerate) */
1020static int sd_get_streamparm(struct gspca_dev *gspca_dev, 2230static int sd_get_streamparm(struct gspca_dev *gspca_dev,
1021 struct v4l2_streamparm *parm) 2231 struct v4l2_streamparm *parm)
@@ -1047,7 +2257,8 @@ static int sd_set_streamparm(struct gspca_dev *gspca_dev,
1047 2257
1048 /* Set requested framerate */ 2258 /* Set requested framerate */
1049 sd->frame_rate = tpf->denominator / tpf->numerator; 2259 sd->frame_rate = tpf->denominator / tpf->numerator;
1050 ov534_set_frame_rate(gspca_dev); 2260 if (gspca_dev->streaming && sd->sensor == SENSOR_OV772X)
2261 set_frame_rate(gspca_dev);
1051 2262
1052 /* Return the actual framerate */ 2263 /* Return the actual framerate */
1053 tpf->numerator = 1; 2264 tpf->numerator = 1;
@@ -1056,20 +2267,53 @@ static int sd_set_streamparm(struct gspca_dev *gspca_dev,
1056 return 0; 2267 return 0;
1057} 2268}
1058 2269
2270static int sd_querymenu(struct gspca_dev *gspca_dev,
2271 struct v4l2_querymenu *menu)
2272{
2273 switch (menu->id) {
2274 case V4L2_CID_POWER_LINE_FREQUENCY:
2275 switch (menu->index) {
2276 case 0: /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */
2277 strcpy((char *) menu->name, "NoFliker");
2278 return 0;
2279 case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
2280 strcpy((char *) menu->name, "50 Hz");
2281 return 0;
2282 case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
2283 strcpy((char *) menu->name, "60 Hz");
2284 return 0;
2285 }
2286 break;
2287 }
2288 return -EINVAL;
2289}
2290
1059/* sub-driver description */ 2291/* sub-driver description */
1060static const struct sd_desc sd_desc = { 2292static const struct sd_desc sd_desc_ov772x = {
1061 .name = MODULE_NAME, 2293 .name = MODULE_NAME,
1062 .ctrls = sd_ctrls, 2294 .ctrls = sd_ctrls_ov772x,
1063 .nctrls = ARRAY_SIZE(sd_ctrls), 2295 .nctrls = ARRAY_SIZE(sd_ctrls_ov772x),
1064 .config = sd_config, 2296 .config = sd_config,
1065 .init = sd_init, 2297 .init = sd_init,
1066 .start = sd_start, 2298 .start = sd_start_ov772x,
1067 .stopN = sd_stopN, 2299 .stopN = sd_stopN_ov772x,
1068 .pkt_scan = sd_pkt_scan, 2300 .pkt_scan = sd_pkt_scan,
1069 .get_streamparm = sd_get_streamparm, 2301 .get_streamparm = sd_get_streamparm,
1070 .set_streamparm = sd_set_streamparm, 2302 .set_streamparm = sd_set_streamparm,
1071}; 2303};
1072 2304
2305static const struct sd_desc sd_desc_ov965x = {
2306 .name = MODULE_NAME,
2307 .ctrls = sd_ctrls_ov965x,
2308 .nctrls = ARRAY_SIZE(sd_ctrls_ov965x),
2309 .config = sd_config,
2310 .init = sd_init,
2311 .start = sd_start_ov965x,
2312 .stopN = sd_stopN_ov965x,
2313 .pkt_scan = sd_pkt_scan,
2314 .querymenu = sd_querymenu,
2315};
2316
1073/* -- module initialisation -- */ 2317/* -- module initialisation -- */
1074static const __devinitdata struct usb_device_id device_table[] = { 2318static const __devinitdata struct usb_device_id device_table[] = {
1075 {USB_DEVICE(0x06f8, 0x3003), .driver_info = SENSOR_OV965X}, 2319 {USB_DEVICE(0x06f8, 0x3003), .driver_info = SENSOR_OV965X},
@@ -1082,8 +2326,12 @@ MODULE_DEVICE_TABLE(usb, device_table);
1082/* -- device connect -- */ 2326/* -- device connect -- */
1083static int sd_probe(struct usb_interface *intf, const struct usb_device_id *id) 2327static int sd_probe(struct usb_interface *intf, const struct usb_device_id *id)
1084{ 2328{
1085 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), 2329 return gspca_dev_probe(intf, id,
1086 THIS_MODULE); 2330 id->driver_info == SENSOR_OV772X
2331 ? &sd_desc_ov772x
2332 : &sd_desc_ov965x,
2333 sizeof(struct sd),
2334 THIS_MODULE);
1087} 2335}
1088 2336
1089static struct usb_driver sd_driver = { 2337static struct usb_driver sd_driver = {
@@ -1101,6 +2349,7 @@ static struct usb_driver sd_driver = {
1101static int __init sd_mod_init(void) 2349static int __init sd_mod_init(void)
1102{ 2350{
1103 int ret; 2351 int ret;
2352
1104 ret = usb_register(&sd_driver); 2353 ret = usb_register(&sd_driver);
1105 if (ret < 0) 2354 if (ret < 0)
1106 return ret; 2355 return ret;
diff --git a/drivers/media/video/gspca/pac207.c b/drivers/media/video/gspca/pac207.c
index 96659433d248..4706a823add0 100644
--- a/drivers/media/video/gspca/pac207.c
+++ b/drivers/media/video/gspca/pac207.c
@@ -337,14 +337,13 @@ static void pac207_do_auto_gain(struct gspca_dev *gspca_dev)
337} 337}
338 338
339static void sd_pkt_scan(struct gspca_dev *gspca_dev, 339static void sd_pkt_scan(struct gspca_dev *gspca_dev,
340 struct gspca_frame *frame, 340 u8 *data,
341 __u8 *data,
342 int len) 341 int len)
343{ 342{
344 struct sd *sd = (struct sd *) gspca_dev; 343 struct sd *sd = (struct sd *) gspca_dev;
345 unsigned char *sof; 344 unsigned char *sof;
346 345
347 sof = pac_find_sof(gspca_dev, data, len); 346 sof = pac_find_sof(&sd->sof_read, data, len);
348 if (sof) { 347 if (sof) {
349 int n; 348 int n;
350 349
@@ -354,10 +353,10 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
354 n -= sizeof pac_sof_marker; 353 n -= sizeof pac_sof_marker;
355 else 354 else
356 n = 0; 355 n = 0;
357 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, 356 gspca_frame_add(gspca_dev, LAST_PACKET,
358 data, n); 357 data, n);
359 sd->header_read = 0; 358 sd->header_read = 0;
360 gspca_frame_add(gspca_dev, FIRST_PACKET, frame, NULL, 0); 359 gspca_frame_add(gspca_dev, FIRST_PACKET, NULL, 0);
361 len -= sof - data; 360 len -= sof - data;
362 data = sof; 361 data = sof;
363 } 362 }
@@ -381,7 +380,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
381 sd->header_read = 11; 380 sd->header_read = 11;
382 } 381 }
383 382
384 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); 383 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
385} 384}
386 385
387static void setbrightness(struct gspca_dev *gspca_dev) 386static void setbrightness(struct gspca_dev *gspca_dev)
diff --git a/drivers/media/video/gspca/pac7302.c b/drivers/media/video/gspca/pac7302.c
new file mode 100644
index 000000000000..74acceea8094
--- /dev/null
+++ b/drivers/media/video/gspca/pac7302.c
@@ -0,0 +1,1272 @@
1/*
2 * Pixart PAC7302 library
3 * Copyright (C) 2005 Thomas Kaiser thomas@kaiser-linux.li
4 *
5 * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
6 *
7 * Separated from Pixart PAC7311 library by Márton Németh <nm127@freemail.hu>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */
23
24/* Some documentation about various registers as determined by trial and error.
25 When the register addresses differ between the 7202 and the 7311 the 2
26 different addresses are written as 7302addr/7311addr, when one of the 2
27 addresses is a - sign that register description is not valid for the
28 matching IC.
29
30 Register page 1:
31
32 Address Description
33 -/0x08 Unknown compressor related, must always be 8 except when not
34 in 640x480 resolution and page 4 reg 2 <= 3 then set it to 9 !
35 -/0x1b Auto white balance related, bit 0 is AWB enable (inverted)
36 bits 345 seem to toggle per color gains on/off (inverted)
37 0x78 Global control, bit 6 controls the LED (inverted)
38 -/0x80 JPEG compression ratio ? Best not touched
39
40 Register page 3/4:
41
42 Address Description
43 0x02 Clock divider 2-63, fps =~ 60 / val. Must be a multiple of 3 on
44 the 7302, so one of 3, 6, 9, ..., except when between 6 and 12?
45 -/0x0f Master gain 1-245, low value = high gain
46 0x10/- Master gain 0-31
47 -/0x10 Another gain 0-15, limited influence (1-2x gain I guess)
48 0x21 Bitfield: 0-1 unused, 2-3 vflip/hflip, 4-5 unknown, 6-7 unused
49 -/0x27 Seems to toggle various gains on / off, Setting bit 7 seems to
50 completely disable the analog amplification block. Set to 0x68
51 for max gain, 0x14 for minimal gain.
52
53 The registers are accessed in the following functions:
54
55 Page | Register | Function
56 -----+------------+---------------------------------------------------
57 0 | 0x0f..0x20 | setcolors()
58 0 | 0xa2..0xab | setbrightcont()
59 0 | 0xc5 | setredbalance()
60 0 | 0xc6 | setwhitebalance()
61 0 | 0xc7 | setbluebalance()
62 0 | 0xdc | setbrightcont(), setcolors()
63 3 | 0x02 | setexposure()
64 3 | 0x10 | setgain()
65 3 | 0x11 | setcolors(), setgain(), setexposure(), sethvflip()
66 3 | 0x21 | sethvflip()
67*/
68
69#define MODULE_NAME "pac7302"
70
71#include <media/v4l2-chip-ident.h>
72#include "gspca.h"
73
74MODULE_AUTHOR("Thomas Kaiser thomas@kaiser-linux.li");
75MODULE_DESCRIPTION("Pixart PAC7302");
76MODULE_LICENSE("GPL");
77
78/* specific webcam descriptor for pac7302 */
79struct sd {
80 struct gspca_dev gspca_dev; /* !! must be the first item */
81
82 unsigned char brightness;
83 unsigned char contrast;
84 unsigned char colors;
85 unsigned char white_balance;
86 unsigned char red_balance;
87 unsigned char blue_balance;
88 unsigned char gain;
89 unsigned char exposure;
90 unsigned char autogain;
91 __u8 hflip;
92 __u8 vflip;
93
94 u8 sof_read;
95 u8 autogain_ignore_frames;
96
97 atomic_t avg_lum;
98};
99
100/* V4L2 controls supported by the driver */
101static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
102static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
103static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
104static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
105static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
106static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
107static int sd_setwhitebalance(struct gspca_dev *gspca_dev, __s32 val);
108static int sd_getwhitebalance(struct gspca_dev *gspca_dev, __s32 *val);
109static int sd_setredbalance(struct gspca_dev *gspca_dev, __s32 val);
110static int sd_getredbalance(struct gspca_dev *gspca_dev, __s32 *val);
111static int sd_setbluebalance(struct gspca_dev *gspca_dev, __s32 val);
112static int sd_getbluebalance(struct gspca_dev *gspca_dev, __s32 *val);
113static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
114static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
115static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val);
116static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val);
117static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val);
118static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val);
119static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val);
120static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val);
121static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val);
122static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val);
123
124static struct ctrl sd_ctrls[] = {
125/* This control is pac7302 only */
126 {
127 {
128 .id = V4L2_CID_BRIGHTNESS,
129 .type = V4L2_CTRL_TYPE_INTEGER,
130 .name = "Brightness",
131 .minimum = 0,
132#define BRIGHTNESS_MAX 0x20
133 .maximum = BRIGHTNESS_MAX,
134 .step = 1,
135#define BRIGHTNESS_DEF 0x10
136 .default_value = BRIGHTNESS_DEF,
137 },
138 .set = sd_setbrightness,
139 .get = sd_getbrightness,
140 },
141/* This control is for both the 7302 and the 7311 */
142 {
143 {
144 .id = V4L2_CID_CONTRAST,
145 .type = V4L2_CTRL_TYPE_INTEGER,
146 .name = "Contrast",
147 .minimum = 0,
148#define CONTRAST_MAX 255
149 .maximum = CONTRAST_MAX,
150 .step = 1,
151#define CONTRAST_DEF 127
152 .default_value = CONTRAST_DEF,
153 },
154 .set = sd_setcontrast,
155 .get = sd_getcontrast,
156 },
157/* This control is pac7302 only */
158 {
159 {
160 .id = V4L2_CID_SATURATION,
161 .type = V4L2_CTRL_TYPE_INTEGER,
162 .name = "Saturation",
163 .minimum = 0,
164#define COLOR_MAX 255
165 .maximum = COLOR_MAX,
166 .step = 1,
167#define COLOR_DEF 127
168 .default_value = COLOR_DEF,
169 },
170 .set = sd_setcolors,
171 .get = sd_getcolors,
172 },
173 {
174 {
175 .id = V4L2_CID_WHITE_BALANCE_TEMPERATURE,
176 .type = V4L2_CTRL_TYPE_INTEGER,
177 .name = "White Balance",
178 .minimum = 0,
179 .maximum = 255,
180 .step = 1,
181#define WHITEBALANCE_DEF 4
182 .default_value = WHITEBALANCE_DEF,
183 },
184 .set = sd_setwhitebalance,
185 .get = sd_getwhitebalance,
186 },
187 {
188 {
189 .id = V4L2_CID_RED_BALANCE,
190 .type = V4L2_CTRL_TYPE_INTEGER,
191 .name = "Red",
192 .minimum = 0,
193 .maximum = 3,
194 .step = 1,
195#define REDBALANCE_DEF 1
196 .default_value = REDBALANCE_DEF,
197 },
198 .set = sd_setredbalance,
199 .get = sd_getredbalance,
200 },
201 {
202 {
203 .id = V4L2_CID_BLUE_BALANCE,
204 .type = V4L2_CTRL_TYPE_INTEGER,
205 .name = "Blue",
206 .minimum = 0,
207 .maximum = 3,
208 .step = 1,
209#define BLUEBALANCE_DEF 1
210 .default_value = BLUEBALANCE_DEF,
211 },
212 .set = sd_setbluebalance,
213 .get = sd_getbluebalance,
214 },
215/* All controls below are for both the 7302 and the 7311 */
216 {
217 {
218 .id = V4L2_CID_GAIN,
219 .type = V4L2_CTRL_TYPE_INTEGER,
220 .name = "Gain",
221 .minimum = 0,
222#define GAIN_MAX 255
223 .maximum = GAIN_MAX,
224 .step = 1,
225#define GAIN_DEF 127
226#define GAIN_KNEE 255 /* Gain seems to cause little noise on the pac73xx */
227 .default_value = GAIN_DEF,
228 },
229 .set = sd_setgain,
230 .get = sd_getgain,
231 },
232 {
233 {
234 .id = V4L2_CID_EXPOSURE,
235 .type = V4L2_CTRL_TYPE_INTEGER,
236 .name = "Exposure",
237 .minimum = 0,
238#define EXPOSURE_MAX 255
239 .maximum = EXPOSURE_MAX,
240 .step = 1,
241#define EXPOSURE_DEF 16 /* 32 ms / 30 fps */
242#define EXPOSURE_KNEE 50 /* 100 ms / 10 fps */
243 .default_value = EXPOSURE_DEF,
244 },
245 .set = sd_setexposure,
246 .get = sd_getexposure,
247 },
248 {
249 {
250 .id = V4L2_CID_AUTOGAIN,
251 .type = V4L2_CTRL_TYPE_BOOLEAN,
252 .name = "Auto Gain",
253 .minimum = 0,
254 .maximum = 1,
255 .step = 1,
256#define AUTOGAIN_DEF 1
257 .default_value = AUTOGAIN_DEF,
258 },
259 .set = sd_setautogain,
260 .get = sd_getautogain,
261 },
262 {
263 {
264 .id = V4L2_CID_HFLIP,
265 .type = V4L2_CTRL_TYPE_BOOLEAN,
266 .name = "Mirror",
267 .minimum = 0,
268 .maximum = 1,
269 .step = 1,
270#define HFLIP_DEF 0
271 .default_value = HFLIP_DEF,
272 },
273 .set = sd_sethflip,
274 .get = sd_gethflip,
275 },
276 {
277 {
278 .id = V4L2_CID_VFLIP,
279 .type = V4L2_CTRL_TYPE_BOOLEAN,
280 .name = "Vflip",
281 .minimum = 0,
282 .maximum = 1,
283 .step = 1,
284#define VFLIP_DEF 0
285 .default_value = VFLIP_DEF,
286 },
287 .set = sd_setvflip,
288 .get = sd_getvflip,
289 },
290};
291
292static const struct v4l2_pix_format vga_mode[] = {
293 {640, 480, V4L2_PIX_FMT_PJPG, V4L2_FIELD_NONE,
294 .bytesperline = 640,
295 .sizeimage = 640 * 480 * 3 / 8 + 590,
296 .colorspace = V4L2_COLORSPACE_JPEG,
297 .priv = 0},
298};
299
300#define LOAD_PAGE3 255
301#define LOAD_PAGE4 254
302#define END_OF_SEQUENCE 0
303
304/* pac 7302 */
305static const __u8 init_7302[] = {
306/* index,value */
307 0xff, 0x01, /* page 1 */
308 0x78, 0x00, /* deactivate */
309 0xff, 0x01,
310 0x78, 0x40, /* led off */
311};
312static const __u8 start_7302[] = {
313/* index, len, [value]* */
314 0xff, 1, 0x00, /* page 0 */
315 0x00, 12, 0x01, 0x40, 0x40, 0x40, 0x01, 0xe0, 0x02, 0x80,
316 0x00, 0x00, 0x00, 0x00,
317 0x0d, 24, 0x03, 0x01, 0x00, 0xb5, 0x07, 0xcb, 0x00, 0x00,
318 0x07, 0xc8, 0x00, 0xea, 0x07, 0xcf, 0x07, 0xf7,
319 0x07, 0x7e, 0x01, 0x0b, 0x00, 0x00, 0x00, 0x11,
320 0x26, 2, 0xaa, 0xaa,
321 0x2e, 1, 0x31,
322 0x38, 1, 0x01,
323 0x3a, 3, 0x14, 0xff, 0x5a,
324 0x43, 11, 0x00, 0x0a, 0x18, 0x11, 0x01, 0x2c, 0x88, 0x11,
325 0x00, 0x54, 0x11,
326 0x55, 1, 0x00,
327 0x62, 4, 0x10, 0x1e, 0x1e, 0x18,
328 0x6b, 1, 0x00,
329 0x6e, 3, 0x08, 0x06, 0x00,
330 0x72, 3, 0x00, 0xff, 0x00,
331 0x7d, 23, 0x01, 0x01, 0x58, 0x46, 0x50, 0x3c, 0x50, 0x3c,
332 0x54, 0x46, 0x54, 0x56, 0x52, 0x50, 0x52, 0x50,
333 0x56, 0x64, 0xa4, 0x00, 0xda, 0x00, 0x00,
334 0xa2, 10, 0x22, 0x2c, 0x3c, 0x54, 0x69, 0x7c, 0x9c, 0xb9,
335 0xd2, 0xeb,
336 0xaf, 1, 0x02,
337 0xb5, 2, 0x08, 0x08,
338 0xb8, 2, 0x08, 0x88,
339 0xc4, 4, 0xae, 0x01, 0x04, 0x01,
340 0xcc, 1, 0x00,
341 0xd1, 11, 0x01, 0x30, 0x49, 0x5e, 0x6f, 0x7f, 0x8e, 0xa9,
342 0xc1, 0xd7, 0xec,
343 0xdc, 1, 0x01,
344 0xff, 1, 0x01, /* page 1 */
345 0x12, 3, 0x02, 0x00, 0x01,
346 0x3e, 2, 0x00, 0x00,
347 0x76, 5, 0x01, 0x20, 0x40, 0x00, 0xf2,
348 0x7c, 1, 0x00,
349 0x7f, 10, 0x4b, 0x0f, 0x01, 0x2c, 0x02, 0x58, 0x03, 0x20,
350 0x02, 0x00,
351 0x96, 5, 0x01, 0x10, 0x04, 0x01, 0x04,
352 0xc8, 14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00,
353 0x07, 0x00, 0x01, 0x07, 0x04, 0x01,
354 0xd8, 1, 0x01,
355 0xdb, 2, 0x00, 0x01,
356 0xde, 7, 0x00, 0x01, 0x04, 0x04, 0x00, 0x00, 0x00,
357 0xe6, 4, 0x00, 0x00, 0x00, 0x01,
358 0xeb, 1, 0x00,
359 0xff, 1, 0x02, /* page 2 */
360 0x22, 1, 0x00,
361 0xff, 1, 0x03, /* page 3 */
362 0, LOAD_PAGE3, /* load the page 3 */
363 0x11, 1, 0x01,
364 0xff, 1, 0x02, /* page 2 */
365 0x13, 1, 0x00,
366 0x22, 4, 0x1f, 0xa4, 0xf0, 0x96,
367 0x27, 2, 0x14, 0x0c,
368 0x2a, 5, 0xc8, 0x00, 0x18, 0x12, 0x22,
369 0x64, 8, 0x00, 0x00, 0xf0, 0x01, 0x14, 0x44, 0x44, 0x44,
370 0x6e, 1, 0x08,
371 0xff, 1, 0x01, /* page 1 */
372 0x78, 1, 0x00,
373 0, END_OF_SEQUENCE /* end of sequence */
374};
375
376#define SKIP 0xaa
377/* page 3 - the value SKIP says skip the index - see reg_w_page() */
378static const __u8 page3_7302[] = {
379 0x90, 0x40, 0x03, 0x50, 0xc2, 0x01, 0x14, 0x16,
380 0x14, 0x12, 0x00, 0x00, 0x00, 0x02, 0x33, 0x00,
381 0x0f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
382 0x00, 0x00, 0x00, 0x47, 0x01, 0xb3, 0x01, 0x00,
383 0x00, 0x08, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x21,
384 0x00, 0x00, 0x00, 0x54, 0xf4, 0x02, 0x52, 0x54,
385 0xa4, 0xb8, 0xe0, 0x2a, 0xf6, 0x00, 0x00, 0x00,
386 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
387 0x00, 0xfc, 0x00, 0xf2, 0x1f, 0x04, 0x00, 0x00,
388 0x00, 0x00, 0x00, 0xc0, 0xc0, 0x10, 0x00, 0x00,
389 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
390 0x00, 0x40, 0xff, 0x03, 0x19, 0x00, 0x00, 0x00,
391 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
392 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0xc8, 0xc8,
393 0xc8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
394 0x08, 0x10, 0x24, 0x40, 0x00, 0x00, 0x00, 0x00,
395 0x01, 0x00, 0x02, 0x47, 0x00, 0x00, 0x00, 0x00,
396 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
397 0x00, 0x02, 0xfa, 0x00, 0x64, 0x5a, 0x28, 0x00,
398 0x00
399};
400
401static int reg_w_buf(struct gspca_dev *gspca_dev,
402 __u8 index,
403 const char *buffer, int len)
404{
405 int ret;
406
407 memcpy(gspca_dev->usb_buf, buffer, len);
408 ret = usb_control_msg(gspca_dev->dev,
409 usb_sndctrlpipe(gspca_dev->dev, 0),
410 1, /* request */
411 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
412 0, /* value */
413 index, gspca_dev->usb_buf, len,
414 500);
415 if (ret < 0)
416 PDEBUG(D_ERR, "reg_w_buf(): "
417 "Failed to write registers to index 0x%x, error %i",
418 index, ret);
419 return ret;
420}
421
422
423static int reg_w(struct gspca_dev *gspca_dev,
424 __u8 index,
425 __u8 value)
426{
427 int ret;
428
429 gspca_dev->usb_buf[0] = value;
430 ret = usb_control_msg(gspca_dev->dev,
431 usb_sndctrlpipe(gspca_dev->dev, 0),
432 0, /* request */
433 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
434 0, index, gspca_dev->usb_buf, 1,
435 500);
436 if (ret < 0)
437 PDEBUG(D_ERR, "reg_w(): "
438 "Failed to write register to index 0x%x, value 0x%x, error %i",
439 index, value, ret);
440 return ret;
441}
442
443static int reg_w_seq(struct gspca_dev *gspca_dev,
444 const __u8 *seq, int len)
445{
446 int ret = 0;
447 while (--len >= 0) {
448 if (0 <= ret)
449 ret = reg_w(gspca_dev, seq[0], seq[1]);
450 seq += 2;
451 }
452 return ret;
453}
454
455/* load the beginning of a page */
456static int reg_w_page(struct gspca_dev *gspca_dev,
457 const __u8 *page, int len)
458{
459 int index;
460 int ret = 0;
461
462 for (index = 0; index < len; index++) {
463 if (page[index] == SKIP) /* skip this index */
464 continue;
465 gspca_dev->usb_buf[0] = page[index];
466 ret = usb_control_msg(gspca_dev->dev,
467 usb_sndctrlpipe(gspca_dev->dev, 0),
468 0, /* request */
469 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
470 0, index, gspca_dev->usb_buf, 1,
471 500);
472 if (ret < 0) {
473 PDEBUG(D_ERR, "reg_w_page(): "
474 "Failed to write register to index 0x%x, "
475 "value 0x%x, error %i",
476 index, page[index], ret);
477 break;
478 }
479 }
480 return ret;
481}
482
483/* output a variable sequence */
484static int reg_w_var(struct gspca_dev *gspca_dev,
485 const __u8 *seq,
486 const __u8 *page3, unsigned int page3_len,
487 const __u8 *page4, unsigned int page4_len)
488{
489 int index, len;
490 int ret = 0;
491
492 for (;;) {
493 index = *seq++;
494 len = *seq++;
495 switch (len) {
496 case END_OF_SEQUENCE:
497 return ret;
498 case LOAD_PAGE4:
499 ret = reg_w_page(gspca_dev, page4, page4_len);
500 break;
501 case LOAD_PAGE3:
502 ret = reg_w_page(gspca_dev, page3, page3_len);
503 break;
504 default:
505 if (len > USB_BUF_SZ) {
506 PDEBUG(D_ERR|D_STREAM,
507 "Incorrect variable sequence");
508 return -EINVAL;
509 }
510 while (len > 0) {
511 if (len < 8) {
512 ret = reg_w_buf(gspca_dev,
513 index, seq, len);
514 if (ret < 0)
515 return ret;
516 seq += len;
517 break;
518 }
519 ret = reg_w_buf(gspca_dev, index, seq, 8);
520 seq += 8;
521 index += 8;
522 len -= 8;
523 }
524 }
525 if (ret < 0)
526 return ret;
527 }
528 /* not reached */
529}
530
531/* this function is called at probe time for pac7302 */
532static int sd_config(struct gspca_dev *gspca_dev,
533 const struct usb_device_id *id)
534{
535 struct sd *sd = (struct sd *) gspca_dev;
536 struct cam *cam;
537
538 cam = &gspca_dev->cam;
539
540 PDEBUG(D_CONF, "Find Sensor PAC7302");
541 cam->cam_mode = vga_mode; /* only 640x480 */
542 cam->nmodes = ARRAY_SIZE(vga_mode);
543
544 sd->brightness = BRIGHTNESS_DEF;
545 sd->contrast = CONTRAST_DEF;
546 sd->colors = COLOR_DEF;
547 sd->white_balance = WHITEBALANCE_DEF;
548 sd->red_balance = REDBALANCE_DEF;
549 sd->blue_balance = BLUEBALANCE_DEF;
550 sd->gain = GAIN_DEF;
551 sd->exposure = EXPOSURE_DEF;
552 sd->autogain = AUTOGAIN_DEF;
553 sd->hflip = HFLIP_DEF;
554 sd->vflip = VFLIP_DEF;
555 return 0;
556}
557
558/* This function is used by pac7302 only */
559static int setbrightcont(struct gspca_dev *gspca_dev)
560{
561 struct sd *sd = (struct sd *) gspca_dev;
562 int i, v;
563 int ret;
564 static const __u8 max[10] =
565 {0x29, 0x33, 0x42, 0x5a, 0x6e, 0x80, 0x9f, 0xbb,
566 0xd4, 0xec};
567 static const __u8 delta[10] =
568 {0x35, 0x33, 0x33, 0x2f, 0x2a, 0x25, 0x1e, 0x17,
569 0x11, 0x0b};
570
571 ret = reg_w(gspca_dev, 0xff, 0x00); /* page 0 */
572 for (i = 0; i < 10; i++) {
573 v = max[i];
574 v += (sd->brightness - BRIGHTNESS_MAX)
575 * 150 / BRIGHTNESS_MAX; /* 200 ? */
576 v -= delta[i] * sd->contrast / CONTRAST_MAX;
577 if (v < 0)
578 v = 0;
579 else if (v > 0xff)
580 v = 0xff;
581 if (0 <= ret)
582 ret = reg_w(gspca_dev, 0xa2 + i, v);
583 }
584 if (0 <= ret)
585 ret = reg_w(gspca_dev, 0xdc, 0x01);
586 return ret;
587}
588
589/* This function is used by pac7302 only */
590static int setcolors(struct gspca_dev *gspca_dev)
591{
592 struct sd *sd = (struct sd *) gspca_dev;
593 int i, v;
594 int ret;
595 static const int a[9] =
596 {217, -212, 0, -101, 170, -67, -38, -315, 355};
597 static const int b[9] =
598 {19, 106, 0, 19, 106, 1, 19, 106, 1};
599
600 ret = reg_w(gspca_dev, 0xff, 0x03); /* page 3 */
601 if (0 <= ret)
602 ret = reg_w(gspca_dev, 0x11, 0x01);
603 if (0 <= ret)
604 ret = reg_w(gspca_dev, 0xff, 0x00); /* page 0 */
605 for (i = 0; i < 9; i++) {
606 v = a[i] * sd->colors / COLOR_MAX + b[i];
607 if (0 <= ret)
608 ret = reg_w(gspca_dev, 0x0f + 2 * i, (v >> 8) & 0x07);
609 if (0 <= ret)
610 ret = reg_w(gspca_dev, 0x0f + 2 * i + 1, v);
611 }
612 if (0 <= ret)
613 ret = reg_w(gspca_dev, 0xdc, 0x01);
614 PDEBUG(D_CONF|D_STREAM, "color: %i", sd->colors);
615 return ret;
616}
617
618static int setwhitebalance(struct gspca_dev *gspca_dev)
619{
620 struct sd *sd = (struct sd *) gspca_dev;
621 int ret;
622
623 ret = reg_w(gspca_dev, 0xff, 0x00); /* page 0 */
624 if (0 <= ret)
625 ret = reg_w(gspca_dev, 0xc6, sd->white_balance);
626
627 if (0 <= ret)
628 ret = reg_w(gspca_dev, 0xdc, 0x01);
629 PDEBUG(D_CONF|D_STREAM, "white_balance: %i", sd->white_balance);
630 return ret;
631}
632
633static int setredbalance(struct gspca_dev *gspca_dev)
634{
635 struct sd *sd = (struct sd *) gspca_dev;
636 int ret;
637
638 ret = reg_w(gspca_dev, 0xff, 0x00); /* page 0 */
639 if (0 <= ret)
640 ret = reg_w(gspca_dev, 0xc5, sd->red_balance);
641
642 if (0 <= ret)
643 ret = reg_w(gspca_dev, 0xdc, 0x01);
644 PDEBUG(D_CONF|D_STREAM, "red_balance: %i", sd->red_balance);
645 return ret;
646}
647
648static int setbluebalance(struct gspca_dev *gspca_dev)
649{
650 struct sd *sd = (struct sd *) gspca_dev;
651 int ret;
652
653 ret = reg_w(gspca_dev, 0xff, 0x00); /* page 0 */
654 if (0 <= ret)
655 ret = reg_w(gspca_dev, 0xc7, sd->blue_balance);
656
657 if (0 <= ret)
658 ret = reg_w(gspca_dev, 0xdc, 0x01);
659 PDEBUG(D_CONF|D_STREAM, "blue_balance: %i", sd->blue_balance);
660 return ret;
661}
662
663static int setgain(struct gspca_dev *gspca_dev)
664{
665 struct sd *sd = (struct sd *) gspca_dev;
666 int ret;
667
668 ret = reg_w(gspca_dev, 0xff, 0x03); /* page 3 */
669 if (0 <= ret)
670 ret = reg_w(gspca_dev, 0x10, sd->gain >> 3);
671
672 /* load registers to sensor (Bit 0, auto clear) */
673 if (0 <= ret)
674 ret = reg_w(gspca_dev, 0x11, 0x01);
675 return ret;
676}
677
678static int setexposure(struct gspca_dev *gspca_dev)
679{
680 struct sd *sd = (struct sd *) gspca_dev;
681 int ret;
682 __u8 reg;
683
684 /* register 2 of frame 3/4 contains the clock divider configuring the
685 no fps according to the formula: 60 / reg. sd->exposure is the
686 desired exposure time in ms. */
687 reg = 120 * sd->exposure / 1000;
688 if (reg < 2)
689 reg = 2;
690 else if (reg > 63)
691 reg = 63;
692
693 /* On the pac7302 reg2 MUST be a multiple of 3, so round it to
694 the nearest multiple of 3, except when between 6 and 12? */
695 if (reg < 6 || reg > 12)
696 reg = ((reg + 1) / 3) * 3;
697 ret = reg_w(gspca_dev, 0xff, 0x03); /* page 3 */
698 if (0 <= ret)
699 ret = reg_w(gspca_dev, 0x02, reg);
700
701 /* load registers to sensor (Bit 0, auto clear) */
702 if (0 <= ret)
703 ret = reg_w(gspca_dev, 0x11, 0x01);
704 return ret;
705}
706
707static int sethvflip(struct gspca_dev *gspca_dev)
708{
709 struct sd *sd = (struct sd *) gspca_dev;
710 int ret;
711 __u8 data;
712
713 ret = reg_w(gspca_dev, 0xff, 0x03); /* page 3 */
714 data = (sd->hflip ? 0x08 : 0x00) | (sd->vflip ? 0x04 : 0x00);
715 if (0 <= ret)
716 ret = reg_w(gspca_dev, 0x21, data);
717 /* load registers to sensor (Bit 0, auto clear) */
718 if (0 <= ret)
719 ret = reg_w(gspca_dev, 0x11, 0x01);
720 return ret;
721}
722
723/* this function is called at probe and resume time for pac7302 */
724static int sd_init(struct gspca_dev *gspca_dev)
725{
726 return reg_w_seq(gspca_dev, init_7302, sizeof(init_7302)/2);
727}
728
729static int sd_start(struct gspca_dev *gspca_dev)
730{
731 struct sd *sd = (struct sd *) gspca_dev;
732 int ret = 0;
733
734 sd->sof_read = 0;
735
736 ret = reg_w_var(gspca_dev, start_7302,
737 page3_7302, sizeof(page3_7302),
738 NULL, 0);
739 if (0 <= ret)
740 ret = setbrightcont(gspca_dev);
741 if (0 <= ret)
742 ret = setcolors(gspca_dev);
743 if (0 <= ret)
744 ret = setwhitebalance(gspca_dev);
745 if (0 <= ret)
746 ret = setredbalance(gspca_dev);
747 if (0 <= ret)
748 ret = setbluebalance(gspca_dev);
749 if (0 <= ret)
750 ret = setgain(gspca_dev);
751 if (0 <= ret)
752 ret = setexposure(gspca_dev);
753 if (0 <= ret)
754 ret = sethvflip(gspca_dev);
755
756 /* only resolution 640x480 is supported for pac7302 */
757
758 sd->sof_read = 0;
759 sd->autogain_ignore_frames = 0;
760 atomic_set(&sd->avg_lum, -1);
761
762 /* start stream */
763 if (0 <= ret)
764 ret = reg_w(gspca_dev, 0xff, 0x01);
765 if (0 <= ret)
766 ret = reg_w(gspca_dev, 0x78, 0x01);
767
768 return ret;
769}
770
771static void sd_stopN(struct gspca_dev *gspca_dev)
772{
773 int ret;
774
775 /* stop stream */
776 ret = reg_w(gspca_dev, 0xff, 0x01);
777 if (0 <= ret)
778 ret = reg_w(gspca_dev, 0x78, 0x00);
779}
780
781/* called on streamoff with alt 0 and on disconnect for pac7302 */
782static void sd_stop0(struct gspca_dev *gspca_dev)
783{
784 int ret;
785
786 if (!gspca_dev->present)
787 return;
788 ret = reg_w(gspca_dev, 0xff, 0x01);
789 if (0 <= ret)
790 ret = reg_w(gspca_dev, 0x78, 0x40);
791}
792
793/* Include pac common sof detection functions */
794#include "pac_common.h"
795
796static void do_autogain(struct gspca_dev *gspca_dev)
797{
798 struct sd *sd = (struct sd *) gspca_dev;
799 int avg_lum = atomic_read(&sd->avg_lum);
800 int desired_lum, deadzone;
801
802 if (avg_lum == -1)
803 return;
804
805 desired_lum = 270 + sd->brightness * 4;
806 /* Hack hack, with the 7202 the first exposure step is
807 pretty large, so if we're about to make the first
808 exposure increase make the deadzone large to avoid
809 oscilating */
810 if (desired_lum > avg_lum && sd->gain == GAIN_DEF &&
811 sd->exposure > EXPOSURE_DEF &&
812 sd->exposure < 42)
813 deadzone = 90;
814 else
815 deadzone = 30;
816
817 if (sd->autogain_ignore_frames > 0)
818 sd->autogain_ignore_frames--;
819 else if (gspca_auto_gain_n_exposure(gspca_dev, avg_lum, desired_lum,
820 deadzone, GAIN_KNEE, EXPOSURE_KNEE))
821 sd->autogain_ignore_frames = PAC_AUTOGAIN_IGNORE_FRAMES;
822}
823
824/* JPEG header, part 1 */
825static const unsigned char pac_jpeg_header1[] = {
826 0xff, 0xd8, /* SOI: Start of Image */
827
828 0xff, 0xc0, /* SOF0: Start of Frame (Baseline DCT) */
829 0x00, 0x11, /* length = 17 bytes (including this length field) */
830 0x08 /* Precision: 8 */
831 /* 2 bytes is placed here: number of image lines */
832 /* 2 bytes is placed here: samples per line */
833};
834
835/* JPEG header, continued */
836static const unsigned char pac_jpeg_header2[] = {
837 0x03, /* Number of image components: 3 */
838 0x01, 0x21, 0x00, /* ID=1, Subsampling 1x1, Quantization table: 0 */
839 0x02, 0x11, 0x01, /* ID=2, Subsampling 2x1, Quantization table: 1 */
840 0x03, 0x11, 0x01, /* ID=3, Subsampling 2x1, Quantization table: 1 */
841
842 0xff, 0xda, /* SOS: Start Of Scan */
843 0x00, 0x0c, /* length = 12 bytes (including this length field) */
844 0x03, /* number of components: 3 */
845 0x01, 0x00, /* selector 1, table 0x00 */
846 0x02, 0x11, /* selector 2, table 0x11 */
847 0x03, 0x11, /* selector 3, table 0x11 */
848 0x00, 0x3f, /* Spectral selection: 0 .. 63 */
849 0x00 /* Successive approximation: 0 */
850};
851
852static void pac_start_frame(struct gspca_dev *gspca_dev,
853 struct gspca_frame *frame,
854 __u16 lines, __u16 samples_per_line)
855{
856 unsigned char tmpbuf[4];
857
858 gspca_frame_add(gspca_dev, FIRST_PACKET,
859 pac_jpeg_header1, sizeof(pac_jpeg_header1));
860
861 tmpbuf[0] = lines >> 8;
862 tmpbuf[1] = lines & 0xff;
863 tmpbuf[2] = samples_per_line >> 8;
864 tmpbuf[3] = samples_per_line & 0xff;
865
866 gspca_frame_add(gspca_dev, INTER_PACKET,
867 tmpbuf, sizeof(tmpbuf));
868 gspca_frame_add(gspca_dev, INTER_PACKET,
869 pac_jpeg_header2, sizeof(pac_jpeg_header2));
870}
871
872/* this function is run at interrupt level */
873static void sd_pkt_scan(struct gspca_dev *gspca_dev,
874 u8 *data, /* isoc packet */
875 int len) /* iso packet length */
876{
877 struct sd *sd = (struct sd *) gspca_dev;
878 struct gspca_frame *frame;
879 unsigned char *sof;
880
881 sof = pac_find_sof(&sd->sof_read, data, len);
882 if (sof) {
883 int n, lum_offset, footer_length;
884
885 frame = gspca_get_i_frame(gspca_dev);
886 if (frame == NULL) {
887 gspca_dev->last_packet_type = DISCARD_PACKET;
888 return;
889 }
890
891 /* 6 bytes after the FF D9 EOF marker a number of lumination
892 bytes are send corresponding to different parts of the
893 image, the 14th and 15th byte after the EOF seem to
894 correspond to the center of the image */
895 lum_offset = 61 + sizeof pac_sof_marker;
896 footer_length = 74;
897
898 /* Finish decoding current frame */
899 n = (sof - data) - (footer_length + sizeof pac_sof_marker);
900 if (n < 0) {
901 frame->data_end += n;
902 n = 0;
903 }
904 gspca_frame_add(gspca_dev, INTER_PACKET,
905 data, n);
906 if (gspca_dev->last_packet_type != DISCARD_PACKET &&
907 frame->data_end[-2] == 0xff &&
908 frame->data_end[-1] == 0xd9)
909 gspca_frame_add(gspca_dev, LAST_PACKET,
910 NULL, 0);
911
912 n = sof - data;
913 len -= n;
914 data = sof;
915
916 /* Get average lumination */
917 if (gspca_dev->last_packet_type == LAST_PACKET &&
918 n >= lum_offset)
919 atomic_set(&sd->avg_lum, data[-lum_offset] +
920 data[-lum_offset + 1]);
921 else
922 atomic_set(&sd->avg_lum, -1);
923
924 /* Start the new frame with the jpeg header */
925 /* The PAC7302 has the image rotated 90 degrees */
926 pac_start_frame(gspca_dev, frame,
927 gspca_dev->width, gspca_dev->height);
928 }
929 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
930}
931
932static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
933{
934 struct sd *sd = (struct sd *) gspca_dev;
935
936 sd->brightness = val;
937 if (gspca_dev->streaming)
938 setbrightcont(gspca_dev);
939 return 0;
940}
941
942static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
943{
944 struct sd *sd = (struct sd *) gspca_dev;
945
946 *val = sd->brightness;
947 return 0;
948}
949
950static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
951{
952 struct sd *sd = (struct sd *) gspca_dev;
953
954 sd->contrast = val;
955 if (gspca_dev->streaming) {
956 setbrightcont(gspca_dev);
957 }
958 return 0;
959}
960
961static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
962{
963 struct sd *sd = (struct sd *) gspca_dev;
964
965 *val = sd->contrast;
966 return 0;
967}
968
969static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
970{
971 struct sd *sd = (struct sd *) gspca_dev;
972
973 sd->colors = val;
974 if (gspca_dev->streaming)
975 setcolors(gspca_dev);
976 return 0;
977}
978
979static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
980{
981 struct sd *sd = (struct sd *) gspca_dev;
982
983 *val = sd->colors;
984 return 0;
985}
986
987static int sd_setwhitebalance(struct gspca_dev *gspca_dev, __s32 val)
988{
989 struct sd *sd = (struct sd *) gspca_dev;
990 int ret = 0;
991
992 sd->white_balance = val;
993 if (gspca_dev->streaming)
994 ret = setwhitebalance(gspca_dev);
995 if (0 <= ret)
996 ret = 0;
997 return ret;
998}
999
1000static int sd_getwhitebalance(struct gspca_dev *gspca_dev, __s32 *val)
1001{
1002 struct sd *sd = (struct sd *) gspca_dev;
1003
1004 *val = sd->white_balance;
1005 return 0;
1006}
1007
1008static int sd_setredbalance(struct gspca_dev *gspca_dev, __s32 val)
1009{
1010 struct sd *sd = (struct sd *) gspca_dev;
1011 int ret = 0;
1012
1013 sd->red_balance = val;
1014 if (gspca_dev->streaming)
1015 ret = setredbalance(gspca_dev);
1016 if (0 <= ret)
1017 ret = 0;
1018 return ret;
1019}
1020
1021static int sd_getredbalance(struct gspca_dev *gspca_dev, __s32 *val)
1022{
1023 struct sd *sd = (struct sd *) gspca_dev;
1024
1025 *val = sd->red_balance;
1026 return 0;
1027}
1028
1029static int sd_setbluebalance(struct gspca_dev *gspca_dev, __s32 val)
1030{
1031 struct sd *sd = (struct sd *) gspca_dev;
1032 int ret = 0;
1033
1034 sd->blue_balance = val;
1035 if (gspca_dev->streaming)
1036 ret = setbluebalance(gspca_dev);
1037 if (0 <= ret)
1038 ret = 0;
1039 return ret;
1040}
1041
1042static int sd_getbluebalance(struct gspca_dev *gspca_dev, __s32 *val)
1043{
1044 struct sd *sd = (struct sd *) gspca_dev;
1045
1046 *val = sd->blue_balance;
1047 return 0;
1048}
1049
1050static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val)
1051{
1052 struct sd *sd = (struct sd *) gspca_dev;
1053
1054 sd->gain = val;
1055 if (gspca_dev->streaming)
1056 setgain(gspca_dev);
1057 return 0;
1058}
1059
1060static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
1061{
1062 struct sd *sd = (struct sd *) gspca_dev;
1063
1064 *val = sd->gain;
1065 return 0;
1066}
1067
1068static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val)
1069{
1070 struct sd *sd = (struct sd *) gspca_dev;
1071
1072 sd->exposure = val;
1073 if (gspca_dev->streaming)
1074 setexposure(gspca_dev);
1075 return 0;
1076}
1077
1078static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val)
1079{
1080 struct sd *sd = (struct sd *) gspca_dev;
1081
1082 *val = sd->exposure;
1083 return 0;
1084}
1085
1086static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
1087{
1088 struct sd *sd = (struct sd *) gspca_dev;
1089
1090 sd->autogain = val;
1091 /* when switching to autogain set defaults to make sure
1092 we are on a valid point of the autogain gain /
1093 exposure knee graph, and give this change time to
1094 take effect before doing autogain. */
1095 if (sd->autogain) {
1096 sd->exposure = EXPOSURE_DEF;
1097 sd->gain = GAIN_DEF;
1098 if (gspca_dev->streaming) {
1099 sd->autogain_ignore_frames =
1100 PAC_AUTOGAIN_IGNORE_FRAMES;
1101 setexposure(gspca_dev);
1102 setgain(gspca_dev);
1103 }
1104 }
1105
1106 return 0;
1107}
1108
1109static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
1110{
1111 struct sd *sd = (struct sd *) gspca_dev;
1112
1113 *val = sd->autogain;
1114 return 0;
1115}
1116
1117static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val)
1118{
1119 struct sd *sd = (struct sd *) gspca_dev;
1120
1121 sd->hflip = val;
1122 if (gspca_dev->streaming)
1123 sethvflip(gspca_dev);
1124 return 0;
1125}
1126
1127static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val)
1128{
1129 struct sd *sd = (struct sd *) gspca_dev;
1130
1131 *val = sd->hflip;
1132 return 0;
1133}
1134
1135static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val)
1136{
1137 struct sd *sd = (struct sd *) gspca_dev;
1138
1139 sd->vflip = val;
1140 if (gspca_dev->streaming)
1141 sethvflip(gspca_dev);
1142 return 0;
1143}
1144
1145static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val)
1146{
1147 struct sd *sd = (struct sd *) gspca_dev;
1148
1149 *val = sd->vflip;
1150 return 0;
1151}
1152
1153#ifdef CONFIG_VIDEO_ADV_DEBUG
1154static int sd_dbg_s_register(struct gspca_dev *gspca_dev,
1155 struct v4l2_dbg_register *reg)
1156{
1157 int ret = -EINVAL;
1158 __u8 index;
1159 __u8 value;
1160
1161 /* reg->reg: bit0..15: reserved for register index (wIndex is 16bit
1162 long on the USB bus)
1163 */
1164 if (reg->match.type == V4L2_CHIP_MATCH_HOST &&
1165 reg->match.addr == 0 &&
1166 (reg->reg < 0x000000ff) &&
1167 (reg->val <= 0x000000ff)
1168 ) {
1169 /* Currently writing to page 0 is only supported. */
1170 /* reg_w() only supports 8bit index */
1171 index = reg->reg & 0x000000ff;
1172 value = reg->val & 0x000000ff;
1173
1174 /* Note that there shall be no access to other page
1175 by any other function between the page swith and
1176 the actual register write */
1177 ret = reg_w(gspca_dev, 0xff, 0x00); /* page 0 */
1178 if (0 <= ret)
1179 ret = reg_w(gspca_dev, index, value);
1180
1181 if (0 <= ret)
1182 ret = reg_w(gspca_dev, 0xdc, 0x01);
1183 }
1184 return ret;
1185}
1186
1187static int sd_chip_ident(struct gspca_dev *gspca_dev,
1188 struct v4l2_dbg_chip_ident *chip)
1189{
1190 int ret = -EINVAL;
1191
1192 if (chip->match.type == V4L2_CHIP_MATCH_HOST &&
1193 chip->match.addr == 0) {
1194 chip->revision = 0;
1195 chip->ident = V4L2_IDENT_UNKNOWN;
1196 ret = 0;
1197 }
1198 return ret;
1199}
1200#endif
1201
1202/* sub-driver description for pac7302 */
1203static struct sd_desc sd_desc = {
1204 .name = MODULE_NAME,
1205 .ctrls = sd_ctrls,
1206 .nctrls = ARRAY_SIZE(sd_ctrls),
1207 .config = sd_config,
1208 .init = sd_init,
1209 .start = sd_start,
1210 .stopN = sd_stopN,
1211 .stop0 = sd_stop0,
1212 .pkt_scan = sd_pkt_scan,
1213 .dq_callback = do_autogain,
1214#ifdef CONFIG_VIDEO_ADV_DEBUG
1215 .set_register = sd_dbg_s_register,
1216 .get_chip_ident = sd_chip_ident,
1217#endif
1218};
1219
1220/* -- module initialisation -- */
1221static __devinitdata struct usb_device_id device_table[] = {
1222 {USB_DEVICE(0x06f8, 0x3009)},
1223 {USB_DEVICE(0x093a, 0x2620)},
1224 {USB_DEVICE(0x093a, 0x2621)},
1225 {USB_DEVICE(0x093a, 0x2622)},
1226 {USB_DEVICE(0x093a, 0x2624)},
1227 {USB_DEVICE(0x093a, 0x2626)},
1228 {USB_DEVICE(0x093a, 0x2628)},
1229 {USB_DEVICE(0x093a, 0x2629)},
1230 {USB_DEVICE(0x093a, 0x262a)},
1231 {USB_DEVICE(0x093a, 0x262c)},
1232 {}
1233};
1234MODULE_DEVICE_TABLE(usb, device_table);
1235
1236/* -- device connect -- */
1237static int sd_probe(struct usb_interface *intf,
1238 const struct usb_device_id *id)
1239{
1240 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1241 THIS_MODULE);
1242}
1243
1244static struct usb_driver sd_driver = {
1245 .name = MODULE_NAME,
1246 .id_table = device_table,
1247 .probe = sd_probe,
1248 .disconnect = gspca_disconnect,
1249#ifdef CONFIG_PM
1250 .suspend = gspca_suspend,
1251 .resume = gspca_resume,
1252#endif
1253};
1254
1255/* -- module insert / remove -- */
1256static int __init sd_mod_init(void)
1257{
1258 int ret;
1259 ret = usb_register(&sd_driver);
1260 if (ret < 0)
1261 return ret;
1262 PDEBUG(D_PROBE, "registered");
1263 return 0;
1264}
1265static void __exit sd_mod_exit(void)
1266{
1267 usb_deregister(&sd_driver);
1268 PDEBUG(D_PROBE, "deregistered");
1269}
1270
1271module_init(sd_mod_init);
1272module_exit(sd_mod_exit);
diff --git a/drivers/media/video/gspca/pac7311.c b/drivers/media/video/gspca/pac7311.c
index 052714484e83..e5697a6345e8 100644
--- a/drivers/media/video/gspca/pac7311.c
+++ b/drivers/media/video/gspca/pac7311.c
@@ -57,23 +57,17 @@ MODULE_AUTHOR("Thomas Kaiser thomas@kaiser-linux.li");
57MODULE_DESCRIPTION("Pixart PAC7311"); 57MODULE_DESCRIPTION("Pixart PAC7311");
58MODULE_LICENSE("GPL"); 58MODULE_LICENSE("GPL");
59 59
60/* specific webcam descriptor */ 60/* specific webcam descriptor for pac7311 */
61struct sd { 61struct sd {
62 struct gspca_dev gspca_dev; /* !! must be the first item */ 62 struct gspca_dev gspca_dev; /* !! must be the first item */
63 63
64 unsigned char brightness;
65 unsigned char contrast; 64 unsigned char contrast;
66 unsigned char colors;
67 unsigned char gain; 65 unsigned char gain;
68 unsigned char exposure; 66 unsigned char exposure;
69 unsigned char autogain; 67 unsigned char autogain;
70 __u8 hflip; 68 __u8 hflip;
71 __u8 vflip; 69 __u8 vflip;
72 70
73 __u8 sensor;
74#define SENSOR_PAC7302 0
75#define SENSOR_PAC7311 1
76
77 u8 sof_read; 71 u8 sof_read;
78 u8 autogain_ignore_frames; 72 u8 autogain_ignore_frames;
79 73
@@ -81,12 +75,8 @@ struct sd {
81}; 75};
82 76
83/* V4L2 controls supported by the driver */ 77/* V4L2 controls supported by the driver */
84static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
85static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
86static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); 78static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
87static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); 79static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
88static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
89static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
90static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); 80static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
91static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val); 81static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
92static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val); 82static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val);
@@ -99,23 +89,6 @@ static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val);
99static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val); 89static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val);
100 90
101static struct ctrl sd_ctrls[] = { 91static struct ctrl sd_ctrls[] = {
102/* This control is pac7302 only */
103#define BRIGHTNESS_IDX 0
104 {
105 {
106 .id = V4L2_CID_BRIGHTNESS,
107 .type = V4L2_CTRL_TYPE_INTEGER,
108 .name = "Brightness",
109 .minimum = 0,
110#define BRIGHTNESS_MAX 0x20
111 .maximum = BRIGHTNESS_MAX,
112 .step = 1,
113#define BRIGHTNESS_DEF 0x10
114 .default_value = BRIGHTNESS_DEF,
115 },
116 .set = sd_setbrightness,
117 .get = sd_getbrightness,
118 },
119/* This control is for both the 7302 and the 7311 */ 92/* This control is for both the 7302 and the 7311 */
120 { 93 {
121 { 94 {
@@ -132,23 +105,6 @@ static struct ctrl sd_ctrls[] = {
132 .set = sd_setcontrast, 105 .set = sd_setcontrast,
133 .get = sd_getcontrast, 106 .get = sd_getcontrast,
134 }, 107 },
135/* This control is pac7302 only */
136#define SATURATION_IDX 2
137 {
138 {
139 .id = V4L2_CID_SATURATION,
140 .type = V4L2_CTRL_TYPE_INTEGER,
141 .name = "Saturation",
142 .minimum = 0,
143#define COLOR_MAX 255
144 .maximum = COLOR_MAX,
145 .step = 1,
146#define COLOR_DEF 127
147 .default_value = COLOR_DEF,
148 },
149 .set = sd_setcolors,
150 .get = sd_getcolors,
151 },
152/* All controls below are for both the 7302 and the 7311 */ 108/* All controls below are for both the 7302 and the 7311 */
153 { 109 {
154 { 110 {
@@ -244,101 +200,9 @@ static const struct v4l2_pix_format vga_mode[] = {
244 .priv = 0}, 200 .priv = 0},
245}; 201};
246 202
247/* pac 7302 */ 203#define LOAD_PAGE3 255
248static const __u8 init_7302[] = { 204#define LOAD_PAGE4 254
249/* index,value */ 205#define END_OF_SEQUENCE 0
250 0xff, 0x01, /* page 1 */
251 0x78, 0x00, /* deactivate */
252 0xff, 0x01,
253 0x78, 0x40, /* led off */
254};
255static const __u8 start_7302[] = {
256/* index, len, [value]* */
257 0xff, 1, 0x00, /* page 0 */
258 0x00, 12, 0x01, 0x40, 0x40, 0x40, 0x01, 0xe0, 0x02, 0x80,
259 0x00, 0x00, 0x00, 0x00,
260 0x0d, 24, 0x03, 0x01, 0x00, 0xb5, 0x07, 0xcb, 0x00, 0x00,
261 0x07, 0xc8, 0x00, 0xea, 0x07, 0xcf, 0x07, 0xf7,
262 0x07, 0x7e, 0x01, 0x0b, 0x00, 0x00, 0x00, 0x11,
263 0x26, 2, 0xaa, 0xaa,
264 0x2e, 1, 0x31,
265 0x38, 1, 0x01,
266 0x3a, 3, 0x14, 0xff, 0x5a,
267 0x43, 11, 0x00, 0x0a, 0x18, 0x11, 0x01, 0x2c, 0x88, 0x11,
268 0x00, 0x54, 0x11,
269 0x55, 1, 0x00,
270 0x62, 4, 0x10, 0x1e, 0x1e, 0x18,
271 0x6b, 1, 0x00,
272 0x6e, 3, 0x08, 0x06, 0x00,
273 0x72, 3, 0x00, 0xff, 0x00,
274 0x7d, 23, 0x01, 0x01, 0x58, 0x46, 0x50, 0x3c, 0x50, 0x3c,
275 0x54, 0x46, 0x54, 0x56, 0x52, 0x50, 0x52, 0x50,
276 0x56, 0x64, 0xa4, 0x00, 0xda, 0x00, 0x00,
277 0xa2, 10, 0x22, 0x2c, 0x3c, 0x54, 0x69, 0x7c, 0x9c, 0xb9,
278 0xd2, 0xeb,
279 0xaf, 1, 0x02,
280 0xb5, 2, 0x08, 0x08,
281 0xb8, 2, 0x08, 0x88,
282 0xc4, 4, 0xae, 0x01, 0x04, 0x01,
283 0xcc, 1, 0x00,
284 0xd1, 11, 0x01, 0x30, 0x49, 0x5e, 0x6f, 0x7f, 0x8e, 0xa9,
285 0xc1, 0xd7, 0xec,
286 0xdc, 1, 0x01,
287 0xff, 1, 0x01, /* page 1 */
288 0x12, 3, 0x02, 0x00, 0x01,
289 0x3e, 2, 0x00, 0x00,
290 0x76, 5, 0x01, 0x20, 0x40, 0x00, 0xf2,
291 0x7c, 1, 0x00,
292 0x7f, 10, 0x4b, 0x0f, 0x01, 0x2c, 0x02, 0x58, 0x03, 0x20,
293 0x02, 0x00,
294 0x96, 5, 0x01, 0x10, 0x04, 0x01, 0x04,
295 0xc8, 14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00,
296 0x07, 0x00, 0x01, 0x07, 0x04, 0x01,
297 0xd8, 1, 0x01,
298 0xdb, 2, 0x00, 0x01,
299 0xde, 7, 0x00, 0x01, 0x04, 0x04, 0x00, 0x00, 0x00,
300 0xe6, 4, 0x00, 0x00, 0x00, 0x01,
301 0xeb, 1, 0x00,
302 0xff, 1, 0x02, /* page 2 */
303 0x22, 1, 0x00,
304 0xff, 1, 0x03, /* page 3 */
305 0x00, 255, /* load the page 3 */
306 0x11, 1, 0x01,
307 0xff, 1, 0x02, /* page 2 */
308 0x13, 1, 0x00,
309 0x22, 4, 0x1f, 0xa4, 0xf0, 0x96,
310 0x27, 2, 0x14, 0x0c,
311 0x2a, 5, 0xc8, 0x00, 0x18, 0x12, 0x22,
312 0x64, 8, 0x00, 0x00, 0xf0, 0x01, 0x14, 0x44, 0x44, 0x44,
313 0x6e, 1, 0x08,
314 0xff, 1, 0x01, /* page 1 */
315 0x78, 1, 0x00,
316 0, 0 /* end of sequence */
317};
318
319/* page 3 - the value 0xaa says skip the index - see reg_w_page() */
320static const __u8 page3_7302[] = {
321 0x90, 0x40, 0x03, 0x50, 0xc2, 0x01, 0x14, 0x16,
322 0x14, 0x12, 0x00, 0x00, 0x00, 0x02, 0x33, 0x00,
323 0x0f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
324 0x00, 0x00, 0x00, 0x47, 0x01, 0xb3, 0x01, 0x00,
325 0x00, 0x08, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x21,
326 0x00, 0x00, 0x00, 0x54, 0xf4, 0x02, 0x52, 0x54,
327 0xa4, 0xb8, 0xe0, 0x2a, 0xf6, 0x00, 0x00, 0x00,
328 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
329 0x00, 0xfc, 0x00, 0xf2, 0x1f, 0x04, 0x00, 0x00,
330 0x00, 0x00, 0x00, 0xc0, 0xc0, 0x10, 0x00, 0x00,
331 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
332 0x00, 0x40, 0xff, 0x03, 0x19, 0x00, 0x00, 0x00,
333 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
334 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0xc8, 0xc8,
335 0xc8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
336 0x08, 0x10, 0x24, 0x40, 0x00, 0x00, 0x00, 0x00,
337 0x01, 0x00, 0x02, 0x47, 0x00, 0x00, 0x00, 0x00,
338 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
339 0x00, 0x02, 0xfa, 0x00, 0x64, 0x5a, 0x28, 0x00,
340 0x00
341};
342 206
343/* pac 7311 */ 207/* pac 7311 */
344static const __u8 init_7311[] = { 208static const __u8 init_7311[] = {
@@ -378,119 +242,154 @@ static const __u8 start_7311[] = {
378 0xf0, 13, 0x01, 0x00, 0x00, 0x00, 0x22, 0x00, 0x20, 0x00, 242 0xf0, 13, 0x01, 0x00, 0x00, 0x00, 0x22, 0x00, 0x20, 0x00,
379 0x3f, 0x00, 0x0a, 0x01, 0x00, 243 0x3f, 0x00, 0x0a, 0x01, 0x00,
380 0xff, 1, 0x04, /* page 4 */ 244 0xff, 1, 0x04, /* page 4 */
381 0x00, 254, /* load the page 4 */ 245 0, LOAD_PAGE4, /* load the page 4 */
382 0x11, 1, 0x01, 246 0x11, 1, 0x01,
383 0, 0 /* end of sequence */ 247 0, END_OF_SEQUENCE /* end of sequence */
384}; 248};
385 249
386/* page 4 - the value 0xaa says skip the index - see reg_w_page() */ 250#define SKIP 0xaa
251/* page 4 - the value SKIP says skip the index - see reg_w_page() */
387static const __u8 page4_7311[] = { 252static const __u8 page4_7311[] = {
388 0xaa, 0xaa, 0x04, 0x54, 0x07, 0x2b, 0x09, 0x0f, 253 SKIP, SKIP, 0x04, 0x54, 0x07, 0x2b, 0x09, 0x0f,
389 0x09, 0x00, 0xaa, 0xaa, 0x07, 0x00, 0x00, 0x62, 254 0x09, 0x00, SKIP, SKIP, 0x07, 0x00, 0x00, 0x62,
390 0x08, 0xaa, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 255 0x08, SKIP, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
391 0x00, 0x00, 0x00, 0x03, 0xa0, 0x01, 0xf4, 0xaa, 256 0x00, 0x00, 0x00, 0x03, 0xa0, 0x01, 0xf4, SKIP,
392 0xaa, 0x00, 0x08, 0xaa, 0x03, 0xaa, 0x00, 0x68, 257 SKIP, 0x00, 0x08, SKIP, 0x03, SKIP, 0x00, 0x68,
393 0xca, 0x10, 0x06, 0x78, 0x00, 0x00, 0x00, 0x00, 258 0xca, 0x10, 0x06, 0x78, 0x00, 0x00, 0x00, 0x00,
394 0x23, 0x28, 0x04, 0x11, 0x00, 0x00 259 0x23, 0x28, 0x04, 0x11, 0x00, 0x00
395}; 260};
396 261
397static void reg_w_buf(struct gspca_dev *gspca_dev, 262static int reg_w_buf(struct gspca_dev *gspca_dev,
398 __u8 index, 263 __u8 index,
399 const char *buffer, int len) 264 const char *buffer, int len)
400{ 265{
266 int ret;
267
401 memcpy(gspca_dev->usb_buf, buffer, len); 268 memcpy(gspca_dev->usb_buf, buffer, len);
402 usb_control_msg(gspca_dev->dev, 269 ret = usb_control_msg(gspca_dev->dev,
403 usb_sndctrlpipe(gspca_dev->dev, 0), 270 usb_sndctrlpipe(gspca_dev->dev, 0),
404 1, /* request */ 271 1, /* request */
405 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 272 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
406 0, /* value */ 273 0, /* value */
407 index, gspca_dev->usb_buf, len, 274 index, gspca_dev->usb_buf, len,
408 500); 275 500);
276 if (ret < 0)
277 PDEBUG(D_ERR, "reg_w_buf(): "
278 "Failed to write registers to index 0x%x, error %i",
279 index, ret);
280 return ret;
409} 281}
410 282
411 283
412static void reg_w(struct gspca_dev *gspca_dev, 284static int reg_w(struct gspca_dev *gspca_dev,
413 __u8 index, 285 __u8 index,
414 __u8 value) 286 __u8 value)
415{ 287{
288 int ret;
289
416 gspca_dev->usb_buf[0] = value; 290 gspca_dev->usb_buf[0] = value;
417 usb_control_msg(gspca_dev->dev, 291 ret = usb_control_msg(gspca_dev->dev,
418 usb_sndctrlpipe(gspca_dev->dev, 0), 292 usb_sndctrlpipe(gspca_dev->dev, 0),
419 0, /* request */ 293 0, /* request */
420 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 294 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
421 0, index, gspca_dev->usb_buf, 1, 295 0, index, gspca_dev->usb_buf, 1,
422 500); 296 500);
297 if (ret < 0)
298 PDEBUG(D_ERR, "reg_w(): "
299 "Failed to write register to index 0x%x, value 0x%x, error %i",
300 index, value, ret);
301 return ret;
423} 302}
424 303
425static void reg_w_seq(struct gspca_dev *gspca_dev, 304static int reg_w_seq(struct gspca_dev *gspca_dev,
426 const __u8 *seq, int len) 305 const __u8 *seq, int len)
427{ 306{
307 int ret = 0;
428 while (--len >= 0) { 308 while (--len >= 0) {
429 reg_w(gspca_dev, seq[0], seq[1]); 309 if (0 <= ret)
310 ret = reg_w(gspca_dev, seq[0], seq[1]);
430 seq += 2; 311 seq += 2;
431 } 312 }
313 return ret;
432} 314}
433 315
434/* load the beginning of a page */ 316/* load the beginning of a page */
435static void reg_w_page(struct gspca_dev *gspca_dev, 317static int reg_w_page(struct gspca_dev *gspca_dev,
436 const __u8 *page, int len) 318 const __u8 *page, int len)
437{ 319{
438 int index; 320 int index;
321 int ret = 0;
439 322
440 for (index = 0; index < len; index++) { 323 for (index = 0; index < len; index++) {
441 if (page[index] == 0xaa) /* skip this index */ 324 if (page[index] == SKIP) /* skip this index */
442 continue; 325 continue;
443 gspca_dev->usb_buf[0] = page[index]; 326 gspca_dev->usb_buf[0] = page[index];
444 usb_control_msg(gspca_dev->dev, 327 ret = usb_control_msg(gspca_dev->dev,
445 usb_sndctrlpipe(gspca_dev->dev, 0), 328 usb_sndctrlpipe(gspca_dev->dev, 0),
446 0, /* request */ 329 0, /* request */
447 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 330 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
448 0, index, gspca_dev->usb_buf, 1, 331 0, index, gspca_dev->usb_buf, 1,
449 500); 332 500);
333 if (ret < 0) {
334 PDEBUG(D_ERR, "reg_w_page(): "
335 "Failed to write register to index 0x%x, "
336 "value 0x%x, error %i",
337 index, page[index], ret);
338 break;
339 }
450 } 340 }
341 return ret;
451} 342}
452 343
453/* output a variable sequence */ 344/* output a variable sequence */
454static void reg_w_var(struct gspca_dev *gspca_dev, 345static int reg_w_var(struct gspca_dev *gspca_dev,
455 const __u8 *seq) 346 const __u8 *seq,
347 const __u8 *page3, unsigned int page3_len,
348 const __u8 *page4, unsigned int page4_len)
456{ 349{
457 int index, len; 350 int index, len;
351 int ret = 0;
458 352
459 for (;;) { 353 for (;;) {
460 index = *seq++; 354 index = *seq++;
461 len = *seq++; 355 len = *seq++;
462 switch (len) { 356 switch (len) {
463 case 0: 357 case END_OF_SEQUENCE:
464 return; 358 return ret;
465 case 254: 359 case LOAD_PAGE4:
466 reg_w_page(gspca_dev, page4_7311, sizeof page4_7311); 360 ret = reg_w_page(gspca_dev, page4, page4_len);
467 break; 361 break;
468 case 255: 362 case LOAD_PAGE3:
469 reg_w_page(gspca_dev, page3_7302, sizeof page3_7302); 363 ret = reg_w_page(gspca_dev, page3, page3_len);
470 break; 364 break;
471 default: 365 default:
472 if (len > 64) { 366 if (len > USB_BUF_SZ) {
473 PDEBUG(D_ERR|D_STREAM, 367 PDEBUG(D_ERR|D_STREAM,
474 "Incorrect variable sequence"); 368 "Incorrect variable sequence");
475 return; 369 return -EINVAL;
476 } 370 }
477 while (len > 0) { 371 while (len > 0) {
478 if (len < 8) { 372 if (len < 8) {
479 reg_w_buf(gspca_dev, index, seq, len); 373 ret = reg_w_buf(gspca_dev,
374 index, seq, len);
375 if (ret < 0)
376 return ret;
480 seq += len; 377 seq += len;
481 break; 378 break;
482 } 379 }
483 reg_w_buf(gspca_dev, index, seq, 8); 380 ret = reg_w_buf(gspca_dev, index, seq, 8);
484 seq += 8; 381 seq += 8;
485 index += 8; 382 index += 8;
486 len -= 8; 383 len -= 8;
487 } 384 }
488 } 385 }
386 if (ret < 0)
387 return ret;
489 } 388 }
490 /* not reached */ 389 /* not reached */
491} 390}
492 391
493/* this function is called at probe time */ 392/* this function is called at probe time for pac7311 */
494static int sd_config(struct gspca_dev *gspca_dev, 393static int sd_config(struct gspca_dev *gspca_dev,
495 const struct usb_device_id *id) 394 const struct usb_device_id *id)
496{ 395{
@@ -499,22 +398,11 @@ static int sd_config(struct gspca_dev *gspca_dev,
499 398
500 cam = &gspca_dev->cam; 399 cam = &gspca_dev->cam;
501 400
502 sd->sensor = id->driver_info; 401 PDEBUG(D_CONF, "Find Sensor PAC7311");
503 if (sd->sensor == SENSOR_PAC7302) { 402 cam->cam_mode = vga_mode;
504 PDEBUG(D_CONF, "Find Sensor PAC7302"); 403 cam->nmodes = ARRAY_SIZE(vga_mode);
505 cam->cam_mode = &vga_mode[2]; /* only 640x480 */
506 cam->nmodes = 1;
507 } else {
508 PDEBUG(D_CONF, "Find Sensor PAC7311");
509 cam->cam_mode = vga_mode;
510 cam->nmodes = ARRAY_SIZE(vga_mode);
511 gspca_dev->ctrl_dis = (1 << BRIGHTNESS_IDX)
512 | (1 << SATURATION_IDX);
513 }
514 404
515 sd->brightness = BRIGHTNESS_DEF;
516 sd->contrast = CONTRAST_DEF; 405 sd->contrast = CONTRAST_DEF;
517 sd->colors = COLOR_DEF;
518 sd->gain = GAIN_DEF; 406 sd->gain = GAIN_DEF;
519 sd->exposure = EXPOSURE_DEF; 407 sd->exposure = EXPOSURE_DEF;
520 sd->autogain = AUTOGAIN_DEF; 408 sd->autogain = AUTOGAIN_DEF;
@@ -523,91 +411,47 @@ static int sd_config(struct gspca_dev *gspca_dev,
523 return 0; 411 return 0;
524} 412}
525 413
526/* This function is used by pac7302 only */
527static void setbrightcont(struct gspca_dev *gspca_dev)
528{
529 struct sd *sd = (struct sd *) gspca_dev;
530 int i, v;
531 static const __u8 max[10] =
532 {0x29, 0x33, 0x42, 0x5a, 0x6e, 0x80, 0x9f, 0xbb,
533 0xd4, 0xec};
534 static const __u8 delta[10] =
535 {0x35, 0x33, 0x33, 0x2f, 0x2a, 0x25, 0x1e, 0x17,
536 0x11, 0x0b};
537
538 reg_w(gspca_dev, 0xff, 0x00); /* page 0 */
539 for (i = 0; i < 10; i++) {
540 v = max[i];
541 v += (sd->brightness - BRIGHTNESS_MAX)
542 * 150 / BRIGHTNESS_MAX; /* 200 ? */
543 v -= delta[i] * sd->contrast / CONTRAST_MAX;
544 if (v < 0)
545 v = 0;
546 else if (v > 0xff)
547 v = 0xff;
548 reg_w(gspca_dev, 0xa2 + i, v);
549 }
550 reg_w(gspca_dev, 0xdc, 0x01);
551}
552
553/* This function is used by pac7311 only */ 414/* This function is used by pac7311 only */
554static void setcontrast(struct gspca_dev *gspca_dev) 415static int setcontrast(struct gspca_dev *gspca_dev)
555{ 416{
556 struct sd *sd = (struct sd *) gspca_dev; 417 struct sd *sd = (struct sd *) gspca_dev;
418 int ret;
557 419
558 reg_w(gspca_dev, 0xff, 0x04); 420 ret = reg_w(gspca_dev, 0xff, 0x04);
559 reg_w(gspca_dev, 0x10, sd->contrast >> 4); 421 if (0 <= ret)
422 ret = reg_w(gspca_dev, 0x10, sd->contrast >> 4);
560 /* load registers to sensor (Bit 0, auto clear) */ 423 /* load registers to sensor (Bit 0, auto clear) */
561 reg_w(gspca_dev, 0x11, 0x01); 424 if (0 <= ret)
425 ret = reg_w(gspca_dev, 0x11, 0x01);
426 return ret;
562} 427}
563 428
564/* This function is used by pac7302 only */ 429static int setgain(struct gspca_dev *gspca_dev)
565static void setcolors(struct gspca_dev *gspca_dev)
566{ 430{
567 struct sd *sd = (struct sd *) gspca_dev; 431 struct sd *sd = (struct sd *) gspca_dev;
568 int i, v; 432 int gain = GAIN_MAX - sd->gain;
569 static const int a[9] = 433 int ret;
570 {217, -212, 0, -101, 170, -67, -38, -315, 355};
571 static const int b[9] =
572 {19, 106, 0, 19, 106, 1, 19, 106, 1};
573
574 reg_w(gspca_dev, 0xff, 0x03); /* page 3 */
575 reg_w(gspca_dev, 0x11, 0x01);
576 reg_w(gspca_dev, 0xff, 0x00); /* page 0 */
577 reg_w(gspca_dev, 0xff, 0x00); /* page 0 */
578 for (i = 0; i < 9; i++) {
579 v = a[i] * sd->colors / COLOR_MAX + b[i];
580 reg_w(gspca_dev, 0x0f + 2 * i, (v >> 8) & 0x07);
581 reg_w(gspca_dev, 0x0f + 2 * i + 1, v);
582 }
583 reg_w(gspca_dev, 0xdc, 0x01);
584 PDEBUG(D_CONF|D_STREAM, "color: %i", sd->colors);
585}
586 434
587static void setgain(struct gspca_dev *gspca_dev) 435 if (gain < 1)
588{ 436 gain = 1;
589 struct sd *sd = (struct sd *) gspca_dev; 437 else if (gain > 245)
438 gain = 245;
439 ret = reg_w(gspca_dev, 0xff, 0x04); /* page 4 */
440 if (0 <= ret)
441 ret = reg_w(gspca_dev, 0x0e, 0x00);
442 if (0 <= ret)
443 ret = reg_w(gspca_dev, 0x0f, gain);
590 444
591 if (sd->sensor == SENSOR_PAC7302) {
592 reg_w(gspca_dev, 0xff, 0x03); /* page 3 */
593 reg_w(gspca_dev, 0x10, sd->gain >> 3);
594 } else {
595 int gain = GAIN_MAX - sd->gain;
596 if (gain < 1)
597 gain = 1;
598 else if (gain > 245)
599 gain = 245;
600 reg_w(gspca_dev, 0xff, 0x04); /* page 4 */
601 reg_w(gspca_dev, 0x0e, 0x00);
602 reg_w(gspca_dev, 0x0f, gain);
603 }
604 /* load registers to sensor (Bit 0, auto clear) */ 445 /* load registers to sensor (Bit 0, auto clear) */
605 reg_w(gspca_dev, 0x11, 0x01); 446 if (0 <= ret)
447 ret = reg_w(gspca_dev, 0x11, 0x01);
448 return ret;
606} 449}
607 450
608static void setexposure(struct gspca_dev *gspca_dev) 451static int setexposure(struct gspca_dev *gspca_dev)
609{ 452{
610 struct sd *sd = (struct sd *) gspca_dev; 453 struct sd *sd = (struct sd *) gspca_dev;
454 int ret;
611 __u8 reg; 455 __u8 reg;
612 456
613 /* register 2 of frame 3/4 contains the clock divider configuring the 457 /* register 2 of frame 3/4 contains the clock divider configuring the
@@ -619,97 +463,94 @@ static void setexposure(struct gspca_dev *gspca_dev)
619 else if (reg > 63) 463 else if (reg > 63)
620 reg = 63; 464 reg = 63;
621 465
622 if (sd->sensor == SENSOR_PAC7302) { 466 ret = reg_w(gspca_dev, 0xff, 0x04); /* page 4 */
623 /* On the pac7302 reg2 MUST be a multiple of 3, so round it to 467 if (0 <= ret)
624 the nearest multiple of 3, except when between 6 and 12? */ 468 ret = reg_w(gspca_dev, 0x02, reg);
625 if (reg < 6 || reg > 12) 469 /* Page 1 register 8 must always be 0x08 except when not in
626 reg = ((reg + 1) / 3) * 3; 470 640x480 mode and Page3/4 reg 2 <= 3 then it must be 9 */
627 reg_w(gspca_dev, 0xff, 0x03); /* page 3 */ 471 if (0 <= ret)
628 reg_w(gspca_dev, 0x02, reg); 472 ret = reg_w(gspca_dev, 0xff, 0x01);
473 if (gspca_dev->cam.cam_mode[(int)gspca_dev->curr_mode].priv &&
474 reg <= 3) {
475 if (0 <= ret)
476 ret = reg_w(gspca_dev, 0x08, 0x09);
629 } else { 477 } else {
630 reg_w(gspca_dev, 0xff, 0x04); /* page 4 */ 478 if (0 <= ret)
631 reg_w(gspca_dev, 0x02, reg); 479 ret = reg_w(gspca_dev, 0x08, 0x08);
632 /* Page 1 register 8 must always be 0x08 except when not in
633 640x480 mode and Page3/4 reg 2 <= 3 then it must be 9 */
634 reg_w(gspca_dev, 0xff, 0x01);
635 if (gspca_dev->cam.cam_mode[(int)gspca_dev->curr_mode].priv &&
636 reg <= 3)
637 reg_w(gspca_dev, 0x08, 0x09);
638 else
639 reg_w(gspca_dev, 0x08, 0x08);
640 } 480 }
481
641 /* load registers to sensor (Bit 0, auto clear) */ 482 /* load registers to sensor (Bit 0, auto clear) */
642 reg_w(gspca_dev, 0x11, 0x01); 483 if (0 <= ret)
484 ret = reg_w(gspca_dev, 0x11, 0x01);
485 return ret;
643} 486}
644 487
645static void sethvflip(struct gspca_dev *gspca_dev) 488static int sethvflip(struct gspca_dev *gspca_dev)
646{ 489{
647 struct sd *sd = (struct sd *) gspca_dev; 490 struct sd *sd = (struct sd *) gspca_dev;
491 int ret;
648 __u8 data; 492 __u8 data;
649 493
650 if (sd->sensor == SENSOR_PAC7302) { 494 ret = reg_w(gspca_dev, 0xff, 0x04); /* page 4 */
651 reg_w(gspca_dev, 0xff, 0x03); /* page 3 */ 495 data = (sd->hflip ? 0x04 : 0x00) | (sd->vflip ? 0x08 : 0x00);
652 data = (sd->hflip ? 0x08 : 0x00) 496 if (0 <= ret)
653 | (sd->vflip ? 0x04 : 0x00); 497 ret = reg_w(gspca_dev, 0x21, data);
654 } else {
655 reg_w(gspca_dev, 0xff, 0x04); /* page 4 */
656 data = (sd->hflip ? 0x04 : 0x00)
657 | (sd->vflip ? 0x08 : 0x00);
658 }
659 reg_w(gspca_dev, 0x21, data);
660 /* load registers to sensor (Bit 0, auto clear) */ 498 /* load registers to sensor (Bit 0, auto clear) */
661 reg_w(gspca_dev, 0x11, 0x01); 499 if (0 <= ret)
500 ret = reg_w(gspca_dev, 0x11, 0x01);
501 return ret;
662} 502}
663 503
664/* this function is called at probe and resume time */ 504/* this function is called at probe and resume time for pac7311 */
665static int sd_init(struct gspca_dev *gspca_dev) 505static int sd_init(struct gspca_dev *gspca_dev)
666{ 506{
667 struct sd *sd = (struct sd *) gspca_dev; 507 return reg_w_seq(gspca_dev, init_7311, sizeof(init_7311)/2);
668
669 if (sd->sensor == SENSOR_PAC7302)
670 reg_w_seq(gspca_dev, init_7302, sizeof init_7302);
671 else
672 reg_w_seq(gspca_dev, init_7311, sizeof init_7311);
673
674 return 0;
675} 508}
676 509
677static int sd_start(struct gspca_dev *gspca_dev) 510static int sd_start(struct gspca_dev *gspca_dev)
678{ 511{
679 struct sd *sd = (struct sd *) gspca_dev; 512 struct sd *sd = (struct sd *) gspca_dev;
513 int ret;
680 514
681 sd->sof_read = 0; 515 sd->sof_read = 0;
682 516
683 if (sd->sensor == SENSOR_PAC7302) { 517 ret = reg_w_var(gspca_dev, start_7311,
684 reg_w_var(gspca_dev, start_7302); 518 NULL, 0,
685 setbrightcont(gspca_dev); 519 page4_7311, sizeof(page4_7311));
686 setcolors(gspca_dev); 520 if (0 <= ret)
687 } else { 521 ret = setcontrast(gspca_dev);
688 reg_w_var(gspca_dev, start_7311); 522 if (0 <= ret)
689 setcontrast(gspca_dev); 523 ret = setgain(gspca_dev);
690 } 524 if (0 <= ret)
691 setgain(gspca_dev); 525 ret = setexposure(gspca_dev);
692 setexposure(gspca_dev); 526 if (0 <= ret)
693 sethvflip(gspca_dev); 527 ret = sethvflip(gspca_dev);
694 528
695 /* set correct resolution */ 529 /* set correct resolution */
696 switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) { 530 switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) {
697 case 2: /* 160x120 pac7311 */ 531 case 2: /* 160x120 pac7311 */
698 reg_w(gspca_dev, 0xff, 0x01); 532 if (0 <= ret)
699 reg_w(gspca_dev, 0x17, 0x20); 533 ret = reg_w(gspca_dev, 0xff, 0x01);
700 reg_w(gspca_dev, 0x87, 0x10); 534 if (0 <= ret)
535 ret = reg_w(gspca_dev, 0x17, 0x20);
536 if (0 <= ret)
537 ret = reg_w(gspca_dev, 0x87, 0x10);
701 break; 538 break;
702 case 1: /* 320x240 pac7311 */ 539 case 1: /* 320x240 pac7311 */
703 reg_w(gspca_dev, 0xff, 0x01); 540 if (0 <= ret)
704 reg_w(gspca_dev, 0x17, 0x30); 541 ret = reg_w(gspca_dev, 0xff, 0x01);
705 reg_w(gspca_dev, 0x87, 0x11); 542 if (0 <= ret)
543 ret = reg_w(gspca_dev, 0x17, 0x30);
544 if (0 <= ret)
545 ret = reg_w(gspca_dev, 0x87, 0x11);
706 break; 546 break;
707 case 0: /* 640x480 */ 547 case 0: /* 640x480 */
708 if (sd->sensor == SENSOR_PAC7302) 548 if (0 <= ret)
709 break; 549 ret = reg_w(gspca_dev, 0xff, 0x01);
710 reg_w(gspca_dev, 0xff, 0x01); 550 if (0 <= ret)
711 reg_w(gspca_dev, 0x17, 0x00); 551 ret = reg_w(gspca_dev, 0x17, 0x00);
712 reg_w(gspca_dev, 0x87, 0x12); 552 if (0 <= ret)
553 ret = reg_w(gspca_dev, 0x87, 0x12);
713 break; 554 break;
714 } 555 }
715 556
@@ -718,47 +559,42 @@ static int sd_start(struct gspca_dev *gspca_dev)
718 atomic_set(&sd->avg_lum, -1); 559 atomic_set(&sd->avg_lum, -1);
719 560
720 /* start stream */ 561 /* start stream */
721 reg_w(gspca_dev, 0xff, 0x01); 562 if (0 <= ret)
722 if (sd->sensor == SENSOR_PAC7302) 563 ret = reg_w(gspca_dev, 0xff, 0x01);
723 reg_w(gspca_dev, 0x78, 0x01); 564 if (0 <= ret)
724 else 565 ret = reg_w(gspca_dev, 0x78, 0x05);
725 reg_w(gspca_dev, 0x78, 0x05); 566
726 return 0; 567 return ret;
727} 568}
728 569
729static void sd_stopN(struct gspca_dev *gspca_dev) 570static void sd_stopN(struct gspca_dev *gspca_dev)
730{ 571{
731 struct sd *sd = (struct sd *) gspca_dev; 572 int ret;
732
733 if (sd->sensor == SENSOR_PAC7302) {
734 reg_w(gspca_dev, 0xff, 0x01);
735 reg_w(gspca_dev, 0x78, 0x00);
736 reg_w(gspca_dev, 0x78, 0x00);
737 return;
738 }
739 reg_w(gspca_dev, 0xff, 0x04);
740 reg_w(gspca_dev, 0x27, 0x80);
741 reg_w(gspca_dev, 0x28, 0xca);
742 reg_w(gspca_dev, 0x29, 0x53);
743 reg_w(gspca_dev, 0x2a, 0x0e);
744 reg_w(gspca_dev, 0xff, 0x01);
745 reg_w(gspca_dev, 0x3e, 0x20);
746 reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
747 reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
748 reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
749}
750 573
751/* called on streamoff with alt 0 and on disconnect */ 574 ret = reg_w(gspca_dev, 0xff, 0x04);
575 if (0 <= ret)
576 ret = reg_w(gspca_dev, 0x27, 0x80);
577 if (0 <= ret)
578 ret = reg_w(gspca_dev, 0x28, 0xca);
579 if (0 <= ret)
580 ret = reg_w(gspca_dev, 0x29, 0x53);
581 if (0 <= ret)
582 ret = reg_w(gspca_dev, 0x2a, 0x0e);
583 if (0 <= ret)
584 ret = reg_w(gspca_dev, 0xff, 0x01);
585 if (0 <= ret)
586 ret = reg_w(gspca_dev, 0x3e, 0x20);
587 if (0 <= ret)
588 ret = reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
589 if (0 <= ret)
590 ret = reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
591 if (0 <= ret)
592 ret = reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
593}
594
595/* called on streamoff with alt 0 and on disconnect for 7311 */
752static void sd_stop0(struct gspca_dev *gspca_dev) 596static void sd_stop0(struct gspca_dev *gspca_dev)
753{ 597{
754 struct sd *sd = (struct sd *) gspca_dev;
755
756 if (!gspca_dev->present)
757 return;
758 if (sd->sensor == SENSOR_PAC7302) {
759 reg_w(gspca_dev, 0xff, 0x01);
760 reg_w(gspca_dev, 0x78, 0x40);
761 }
762} 598}
763 599
764/* Include pac common sof detection functions */ 600/* Include pac common sof detection functions */
@@ -773,22 +609,8 @@ static void do_autogain(struct gspca_dev *gspca_dev)
773 if (avg_lum == -1) 609 if (avg_lum == -1)
774 return; 610 return;
775 611
776 if (sd->sensor == SENSOR_PAC7302) { 612 desired_lum = 200;
777 desired_lum = 270 + sd->brightness * 4; 613 deadzone = 20;
778 /* Hack hack, with the 7202 the first exposure step is
779 pretty large, so if we're about to make the first
780 exposure increase make the deadzone large to avoid
781 oscilating */
782 if (desired_lum > avg_lum && sd->gain == GAIN_DEF &&
783 sd->exposure > EXPOSURE_DEF &&
784 sd->exposure < 42)
785 deadzone = 90;
786 else
787 deadzone = 30;
788 } else {
789 desired_lum = 200;
790 deadzone = 20;
791 }
792 614
793 if (sd->autogain_ignore_frames > 0) 615 if (sd->autogain_ignore_frames > 0)
794 sd->autogain_ignore_frames--; 616 sd->autogain_ignore_frames--;
@@ -797,53 +619,92 @@ static void do_autogain(struct gspca_dev *gspca_dev)
797 sd->autogain_ignore_frames = PAC_AUTOGAIN_IGNORE_FRAMES; 619 sd->autogain_ignore_frames = PAC_AUTOGAIN_IGNORE_FRAMES;
798} 620}
799 621
800static const unsigned char pac7311_jpeg_header1[] = { 622/* JPEG header, part 1 */
801 0xff, 0xd8, 0xff, 0xc0, 0x00, 0x11, 0x08 623static const unsigned char pac_jpeg_header1[] = {
624 0xff, 0xd8, /* SOI: Start of Image */
625
626 0xff, 0xc0, /* SOF0: Start of Frame (Baseline DCT) */
627 0x00, 0x11, /* length = 17 bytes (including this length field) */
628 0x08 /* Precision: 8 */
629 /* 2 bytes is placed here: number of image lines */
630 /* 2 bytes is placed here: samples per line */
802}; 631};
803 632
804static const unsigned char pac7311_jpeg_header2[] = { 633/* JPEG header, continued */
805 0x03, 0x01, 0x21, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, 0xff, 0xda, 634static const unsigned char pac_jpeg_header2[] = {
806 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00 635 0x03, /* Number of image components: 3 */
636 0x01, 0x21, 0x00, /* ID=1, Subsampling 1x1, Quantization table: 0 */
637 0x02, 0x11, 0x01, /* ID=2, Subsampling 2x1, Quantization table: 1 */
638 0x03, 0x11, 0x01, /* ID=3, Subsampling 2x1, Quantization table: 1 */
639
640 0xff, 0xda, /* SOS: Start Of Scan */
641 0x00, 0x0c, /* length = 12 bytes (including this length field) */
642 0x03, /* number of components: 3 */
643 0x01, 0x00, /* selector 1, table 0x00 */
644 0x02, 0x11, /* selector 2, table 0x11 */
645 0x03, 0x11, /* selector 3, table 0x11 */
646 0x00, 0x3f, /* Spectral selection: 0 .. 63 */
647 0x00 /* Successive approximation: 0 */
807}; 648};
808 649
650static void pac_start_frame(struct gspca_dev *gspca_dev,
651 struct gspca_frame *frame,
652 __u16 lines, __u16 samples_per_line)
653{
654 unsigned char tmpbuf[4];
655
656 gspca_frame_add(gspca_dev, FIRST_PACKET,
657 pac_jpeg_header1, sizeof(pac_jpeg_header1));
658
659 tmpbuf[0] = lines >> 8;
660 tmpbuf[1] = lines & 0xff;
661 tmpbuf[2] = samples_per_line >> 8;
662 tmpbuf[3] = samples_per_line & 0xff;
663
664 gspca_frame_add(gspca_dev, INTER_PACKET,
665 tmpbuf, sizeof(tmpbuf));
666 gspca_frame_add(gspca_dev, INTER_PACKET,
667 pac_jpeg_header2, sizeof(pac_jpeg_header2));
668}
669
809/* this function is run at interrupt level */ 670/* this function is run at interrupt level */
810static void sd_pkt_scan(struct gspca_dev *gspca_dev, 671static void sd_pkt_scan(struct gspca_dev *gspca_dev,
811 struct gspca_frame *frame, /* target */ 672 u8 *data, /* isoc packet */
812 __u8 *data, /* isoc packet */
813 int len) /* iso packet length */ 673 int len) /* iso packet length */
814{ 674{
815 struct sd *sd = (struct sd *) gspca_dev; 675 struct sd *sd = (struct sd *) gspca_dev;
816 unsigned char *sof; 676 unsigned char *sof;
677 struct gspca_frame *frame;
817 678
818 sof = pac_find_sof(gspca_dev, data, len); 679 sof = pac_find_sof(&sd->sof_read, data, len);
819 if (sof) { 680 if (sof) {
820 unsigned char tmpbuf[4];
821 int n, lum_offset, footer_length; 681 int n, lum_offset, footer_length;
822 682
823 if (sd->sensor == SENSOR_PAC7302) { 683 frame = gspca_get_i_frame(gspca_dev);
824 /* 6 bytes after the FF D9 EOF marker a number of lumination 684 if (frame == NULL) {
825 bytes are send corresponding to different parts of the 685 gspca_dev->last_packet_type = DISCARD_PACKET;
826 image, the 14th and 15th byte after the EOF seem to 686 return;
827 correspond to the center of the image */
828 lum_offset = 61 + sizeof pac_sof_marker;
829 footer_length = 74;
830 } else {
831 lum_offset = 24 + sizeof pac_sof_marker;
832 footer_length = 26;
833 } 687 }
834 688
689 /* 6 bytes after the FF D9 EOF marker a number of lumination
690 bytes are send corresponding to different parts of the
691 image, the 14th and 15th byte after the EOF seem to
692 correspond to the center of the image */
693 lum_offset = 24 + sizeof pac_sof_marker;
694 footer_length = 26;
695
835 /* Finish decoding current frame */ 696 /* Finish decoding current frame */
836 n = (sof - data) - (footer_length + sizeof pac_sof_marker); 697 n = (sof - data) - (footer_length + sizeof pac_sof_marker);
837 if (n < 0) { 698 if (n < 0) {
838 frame->data_end += n; 699 frame->data_end += n;
839 n = 0; 700 n = 0;
840 } 701 }
841 frame = gspca_frame_add(gspca_dev, INTER_PACKET, frame, 702 gspca_frame_add(gspca_dev, INTER_PACKET,
842 data, n); 703 data, n);
843 if (gspca_dev->last_packet_type != DISCARD_PACKET && 704 if (gspca_dev->last_packet_type != DISCARD_PACKET &&
844 frame->data_end[-2] == 0xff && 705 frame->data_end[-2] == 0xff &&
845 frame->data_end[-1] == 0xd9) 706 frame->data_end[-1] == 0xd9)
846 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, 707 gspca_frame_add(gspca_dev, LAST_PACKET,
847 NULL, 0); 708 NULL, 0);
848 709
849 n = sof - data; 710 n = sof - data;
@@ -859,43 +720,10 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
859 atomic_set(&sd->avg_lum, -1); 720 atomic_set(&sd->avg_lum, -1);
860 721
861 /* Start the new frame with the jpeg header */ 722 /* Start the new frame with the jpeg header */
862 gspca_frame_add(gspca_dev, FIRST_PACKET, frame, 723 pac_start_frame(gspca_dev, frame,
863 pac7311_jpeg_header1, sizeof(pac7311_jpeg_header1)); 724 gspca_dev->height, gspca_dev->width);
864 if (sd->sensor == SENSOR_PAC7302) {
865 /* The PAC7302 has the image rotated 90 degrees */
866 tmpbuf[0] = gspca_dev->width >> 8;
867 tmpbuf[1] = gspca_dev->width & 0xff;
868 tmpbuf[2] = gspca_dev->height >> 8;
869 tmpbuf[3] = gspca_dev->height & 0xff;
870 } else {
871 tmpbuf[0] = gspca_dev->height >> 8;
872 tmpbuf[1] = gspca_dev->height & 0xff;
873 tmpbuf[2] = gspca_dev->width >> 8;
874 tmpbuf[3] = gspca_dev->width & 0xff;
875 }
876 gspca_frame_add(gspca_dev, INTER_PACKET, frame, tmpbuf, 4);
877 gspca_frame_add(gspca_dev, INTER_PACKET, frame,
878 pac7311_jpeg_header2, sizeof(pac7311_jpeg_header2));
879 } 725 }
880 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); 726 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
881}
882
883static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
884{
885 struct sd *sd = (struct sd *) gspca_dev;
886
887 sd->brightness = val;
888 if (gspca_dev->streaming)
889 setbrightcont(gspca_dev);
890 return 0;
891}
892
893static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
894{
895 struct sd *sd = (struct sd *) gspca_dev;
896
897 *val = sd->brightness;
898 return 0;
899} 727}
900 728
901static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val) 729static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
@@ -904,10 +732,7 @@ static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
904 732
905 sd->contrast = val; 733 sd->contrast = val;
906 if (gspca_dev->streaming) { 734 if (gspca_dev->streaming) {
907 if (sd->sensor == SENSOR_PAC7302) 735 setcontrast(gspca_dev);
908 setbrightcont(gspca_dev);
909 else
910 setcontrast(gspca_dev);
911 } 736 }
912 return 0; 737 return 0;
913} 738}
@@ -920,24 +745,6 @@ static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
920 return 0; 745 return 0;
921} 746}
922 747
923static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
924{
925 struct sd *sd = (struct sd *) gspca_dev;
926
927 sd->colors = val;
928 if (gspca_dev->streaming)
929 setcolors(gspca_dev);
930 return 0;
931}
932
933static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
934{
935 struct sd *sd = (struct sd *) gspca_dev;
936
937 *val = sd->colors;
938 return 0;
939}
940
941static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val) 748static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val)
942{ 749{
943 struct sd *sd = (struct sd *) gspca_dev; 750 struct sd *sd = (struct sd *) gspca_dev;
@@ -1041,7 +848,7 @@ static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val)
1041 return 0; 848 return 0;
1042} 849}
1043 850
1044/* sub-driver description */ 851/* sub-driver description for pac7311 */
1045static struct sd_desc sd_desc = { 852static struct sd_desc sd_desc = {
1046 .name = MODULE_NAME, 853 .name = MODULE_NAME,
1047 .ctrls = sd_ctrls, 854 .ctrls = sd_ctrls,
@@ -1057,21 +864,12 @@ static struct sd_desc sd_desc = {
1057 864
1058/* -- module initialisation -- */ 865/* -- module initialisation -- */
1059static __devinitdata struct usb_device_id device_table[] = { 866static __devinitdata struct usb_device_id device_table[] = {
1060 {USB_DEVICE(0x06f8, 0x3009), .driver_info = SENSOR_PAC7302}, 867 {USB_DEVICE(0x093a, 0x2600)},
1061 {USB_DEVICE(0x093a, 0x2600), .driver_info = SENSOR_PAC7311}, 868 {USB_DEVICE(0x093a, 0x2601)},
1062 {USB_DEVICE(0x093a, 0x2601), .driver_info = SENSOR_PAC7311}, 869 {USB_DEVICE(0x093a, 0x2603)},
1063 {USB_DEVICE(0x093a, 0x2603), .driver_info = SENSOR_PAC7311}, 870 {USB_DEVICE(0x093a, 0x2608)},
1064 {USB_DEVICE(0x093a, 0x2608), .driver_info = SENSOR_PAC7311}, 871 {USB_DEVICE(0x093a, 0x260e)},
1065 {USB_DEVICE(0x093a, 0x260e), .driver_info = SENSOR_PAC7311}, 872 {USB_DEVICE(0x093a, 0x260f)},
1066 {USB_DEVICE(0x093a, 0x260f), .driver_info = SENSOR_PAC7311},
1067 {USB_DEVICE(0x093a, 0x2620), .driver_info = SENSOR_PAC7302},
1068 {USB_DEVICE(0x093a, 0x2621), .driver_info = SENSOR_PAC7302},
1069 {USB_DEVICE(0x093a, 0x2622), .driver_info = SENSOR_PAC7302},
1070 {USB_DEVICE(0x093a, 0x2624), .driver_info = SENSOR_PAC7302},
1071 {USB_DEVICE(0x093a, 0x2626), .driver_info = SENSOR_PAC7302},
1072 {USB_DEVICE(0x093a, 0x2629), .driver_info = SENSOR_PAC7302},
1073 {USB_DEVICE(0x093a, 0x262a), .driver_info = SENSOR_PAC7302},
1074 {USB_DEVICE(0x093a, 0x262c), .driver_info = SENSOR_PAC7302},
1075 {} 873 {}
1076}; 874};
1077MODULE_DEVICE_TABLE(usb, device_table); 875MODULE_DEVICE_TABLE(usb, device_table);
diff --git a/drivers/media/video/gspca/pac_common.h b/drivers/media/video/gspca/pac_common.h
index 34d4b1494cd5..20f67d9b8c06 100644
--- a/drivers/media/video/gspca/pac_common.h
+++ b/drivers/media/video/gspca/pac_common.h
@@ -33,26 +33,101 @@
33static const unsigned char pac_sof_marker[5] = 33static const unsigned char pac_sof_marker[5] =
34 { 0xff, 0xff, 0x00, 0xff, 0x96 }; 34 { 0xff, 0xff, 0x00, 0xff, 0x96 };
35 35
36static unsigned char *pac_find_sof(struct gspca_dev *gspca_dev, 36/*
37 The following state machine finds the SOF marker sequence
38 0xff, 0xff, 0x00, 0xff, 0x96 in a byte stream.
39
40 +----------+
41 | 0: START |<---------------\
42 +----------+<-\ |
43 | \---/otherwise |
44 v 0xff |
45 +----------+ otherwise |
46 | 1 |--------------->*
47 | | ^
48 +----------+ |
49 | |
50 v 0xff |
51 +----------+<-\0xff |
52 /->| |--/ |
53 | | 2 |--------------->*
54 | | | otherwise ^
55 | +----------+ |
56 | | |
57 | v 0x00 |
58 | +----------+ |
59 | | 3 | |
60 | | |--------------->*
61 | +----------+ otherwise ^
62 | | |
63 0xff | v 0xff |
64 | +----------+ |
65 \--| 4 | |
66 | |----------------/
67 +----------+ otherwise
68 |
69 v 0x96
70 +----------+
71 | FOUND |
72 +----------+
73*/
74
75static unsigned char *pac_find_sof(u8 *sof_read,
37 unsigned char *m, int len) 76 unsigned char *m, int len)
38{ 77{
39 struct sd *sd = (struct sd *) gspca_dev;
40 int i; 78 int i;
41 79
42 /* Search for the SOF marker (fixed part) in the header */ 80 /* Search for the SOF marker (fixed part) in the header */
43 for (i = 0; i < len; i++) { 81 for (i = 0; i < len; i++) {
44 if (m[i] == pac_sof_marker[sd->sof_read]) { 82 switch (*sof_read) {
45 sd->sof_read++; 83 case 0:
46 if (sd->sof_read == sizeof(pac_sof_marker)) { 84 if (m[i] == 0xff)
85 *sof_read = 1;
86 break;
87 case 1:
88 if (m[i] == 0xff)
89 *sof_read = 2;
90 else
91 *sof_read = 0;
92 break;
93 case 2:
94 switch (m[i]) {
95 case 0x00:
96 *sof_read = 3;
97 break;
98 case 0xff:
99 /* stay in this state */
100 break;
101 default:
102 *sof_read = 0;
103 }
104 break;
105 case 3:
106 if (m[i] == 0xff)
107 *sof_read = 4;
108 else
109 *sof_read = 0;
110 break;
111 case 4:
112 switch (m[i]) {
113 case 0x96:
114 /* Pattern found */
47 PDEBUG(D_FRAM, 115 PDEBUG(D_FRAM,
48 "SOF found, bytes to analyze: %u." 116 "SOF found, bytes to analyze: %u."
49 " Frame starts at byte #%u", 117 " Frame starts at byte #%u",
50 len, i + 1); 118 len, i + 1);
51 sd->sof_read = 0; 119 *sof_read = 0;
52 return m + i + 1; 120 return m + i + 1;
121 break;
122 case 0xff:
123 *sof_read = 2;
124 break;
125 default:
126 *sof_read = 0;
53 } 127 }
54 } else { 128 break;
55 sd->sof_read = 0; 129 default:
130 *sof_read = 0;
56 } 131 }
57 } 132 }
58 133
diff --git a/drivers/media/video/gspca/sn9c20x.c b/drivers/media/video/gspca/sn9c20x.c
index cdad3db33367..b1944a7cbb0f 100644
--- a/drivers/media/video/gspca/sn9c20x.c
+++ b/drivers/media/video/gspca/sn9c20x.c
@@ -2342,7 +2342,6 @@ static void sd_dqcallback(struct gspca_dev *gspca_dev)
2342} 2342}
2343 2343
2344static void sd_pkt_scan(struct gspca_dev *gspca_dev, 2344static void sd_pkt_scan(struct gspca_dev *gspca_dev,
2345 struct gspca_frame *frame, /* target */
2346 u8 *data, /* isoc packet */ 2345 u8 *data, /* isoc packet */
2347 int len) /* iso packet length */ 2346 int len) /* iso packet length */
2348{ 2347{
@@ -2378,22 +2377,22 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
2378 avg_lum >>= 9; 2377 avg_lum >>= 9;
2379 atomic_set(&sd->avg_lum, avg_lum); 2378 atomic_set(&sd->avg_lum, avg_lum);
2380 gspca_frame_add(gspca_dev, LAST_PACKET, 2379 gspca_frame_add(gspca_dev, LAST_PACKET,
2381 frame, data, len); 2380 data, len);
2382 return; 2381 return;
2383 } 2382 }
2384 if (gspca_dev->last_packet_type == LAST_PACKET) { 2383 if (gspca_dev->last_packet_type == LAST_PACKET) {
2385 if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv 2384 if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv
2386 & MODE_JPEG) { 2385 & MODE_JPEG) {
2387 gspca_frame_add(gspca_dev, FIRST_PACKET, frame, 2386 gspca_frame_add(gspca_dev, FIRST_PACKET,
2388 sd->jpeg_hdr, JPEG_HDR_SZ); 2387 sd->jpeg_hdr, JPEG_HDR_SZ);
2389 gspca_frame_add(gspca_dev, INTER_PACKET, frame, 2388 gspca_frame_add(gspca_dev, INTER_PACKET,
2390 data, len); 2389 data, len);
2391 } else { 2390 } else {
2392 gspca_frame_add(gspca_dev, FIRST_PACKET, frame, 2391 gspca_frame_add(gspca_dev, FIRST_PACKET,
2393 data, len); 2392 data, len);
2394 } 2393 }
2395 } else { 2394 } else {
2396 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); 2395 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
2397 } 2396 }
2398} 2397}
2399 2398
diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c
index e39efb45fa1c..5be95bc65138 100644
--- a/drivers/media/video/gspca/sonixb.c
+++ b/drivers/media/video/gspca/sonixb.c
@@ -995,8 +995,7 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
995} 995}
996 996
997static void sd_pkt_scan(struct gspca_dev *gspca_dev, 997static void sd_pkt_scan(struct gspca_dev *gspca_dev,
998 struct gspca_frame *frame, /* target */ 998 u8 *data, /* isoc packet */
999 unsigned char *data, /* isoc packet */
1000 int len) /* iso packet length */ 999 int len) /* iso packet length */
1001{ 1000{
1002 int i; 1001 int i;
@@ -1054,12 +1053,12 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1054 pkt_type = DISCARD_PACKET; 1053 pkt_type = DISCARD_PACKET;
1055 } 1054 }
1056 1055
1057 frame = gspca_frame_add(gspca_dev, pkt_type, 1056 gspca_frame_add(gspca_dev, pkt_type,
1058 frame, data, 0); 1057 NULL, 0);
1059 data += i + fr_h_sz; 1058 data += i + fr_h_sz;
1060 len -= i + fr_h_sz; 1059 len -= i + fr_h_sz;
1061 gspca_frame_add(gspca_dev, FIRST_PACKET, 1060 gspca_frame_add(gspca_dev, FIRST_PACKET,
1062 frame, data, len); 1061 data, len);
1063 return; 1062 return;
1064 } 1063 }
1065 } 1064 }
@@ -1068,15 +1067,21 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1068 if (cam->cam_mode[gspca_dev->curr_mode].priv & MODE_RAW) { 1067 if (cam->cam_mode[gspca_dev->curr_mode].priv & MODE_RAW) {
1069 /* In raw mode we sometimes get some garbage after the frame 1068 /* In raw mode we sometimes get some garbage after the frame
1070 ignore this */ 1069 ignore this */
1071 int used = frame->data_end - frame->data; 1070 struct gspca_frame *frame;
1071 int used;
1072 int size = cam->cam_mode[gspca_dev->curr_mode].sizeimage; 1072 int size = cam->cam_mode[gspca_dev->curr_mode].sizeimage;
1073 1073
1074 frame = gspca_get_i_frame(gspca_dev);
1075 if (frame == NULL) {
1076 gspca_dev->last_packet_type = DISCARD_PACKET;
1077 return;
1078 }
1079 used = frame->data_end - frame->data;
1074 if (used + len > size) 1080 if (used + len > size)
1075 len = size - used; 1081 len = size - used;
1076 } 1082 }
1077 1083
1078 gspca_frame_add(gspca_dev, INTER_PACKET, 1084 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
1079 frame, data, len);
1080} 1085}
1081 1086
1082static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) 1087static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c
index 33f4d0a1f6fd..0bd36a00dd2a 100644
--- a/drivers/media/video/gspca/sonixj.c
+++ b/drivers/media/video/gspca/sonixj.c
@@ -1,8 +1,8 @@
1/* 1/*
2 * Sonix sn9c102p sn9c105 sn9c120 (jpeg) library 2 * Sonix sn9c102p sn9c105 sn9c120 (jpeg) subdriver
3 * Copyright (C) 2005 Michel Xhaard mxhaard@magic.fr
4 * 3 *
5 * V4L2 by Jean-Francois Moine <http://moinejf.free.fr> 4 * Copyright (C) 2009 Jean-Francois Moine <http://moinejf.free.fr>
5 * Copyright (C) 2005 Michel Xhaard mxhaard@magic.fr
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by 8 * it under the terms of the GNU General Public License as published by
@@ -72,8 +72,9 @@ struct sd {
72#define SENSOR_OV7630 5 72#define SENSOR_OV7630 5
73#define SENSOR_OV7648 6 73#define SENSOR_OV7648 6
74#define SENSOR_OV7660 7 74#define SENSOR_OV7660 7
75#define SENSOR_SP80708 8 75#define SENSOR_PO1030 8
76 u8 i2c_base; 76#define SENSOR_SP80708 9
77 u8 i2c_addr;
77 78
78 u8 *jpeg_hdr; 79 u8 *jpeg_hdr;
79}; 80};
@@ -250,7 +251,7 @@ static struct ctrl sd_ctrls[] = {
250 .minimum = 0, 251 .minimum = 0,
251 .maximum = 2, /* 0: 0, 1: 50Hz, 2:60Hz */ 252 .maximum = 2, /* 0: 0, 1: 50Hz, 2:60Hz */
252 .step = 1, 253 .step = 1,
253#define FREQ_DEF 2 254#define FREQ_DEF 1
254 .default_value = FREQ_DEF, 255 .default_value = FREQ_DEF,
255 }, 256 },
256 .set = sd_setfreq, 257 .set = sd_setfreq,
@@ -277,7 +278,9 @@ static __u32 ctrl_dis[] = {
277 (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX), 278 (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX),
278 /* SENSOR_OV7660 7 */ 279 /* SENSOR_OV7660 7 */
279 (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX) | 280 (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX) |
280 (1 << FREQ_IDX), /* SENSOR_SP80708 8 */ 281 (1 << FREQ_IDX), /* SENSOR_PO1030 8 */
282 (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX) |
283 (1 << FREQ_IDX), /* SENSOR_SP80708 9 */
281}; 284};
282 285
283static const struct v4l2_pix_format vga_mode[] = { 286static const struct v4l2_pix_format vga_mode[] = {
@@ -304,7 +307,7 @@ static const u8 sn_hv7131[0x1c] = {
304/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ 307/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
305 0x00, 0x03, 0x64, 0x00, 0x1a, 0x20, 0x20, 0x20, 308 0x00, 0x03, 0x64, 0x00, 0x1a, 0x20, 0x20, 0x20,
306/* reg8 reg9 rega regb regc regd rege regf */ 309/* reg8 reg9 rega regb regc regd rege regf */
307 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10, 310 0x81, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
308/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */ 311/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
309 0x03, 0x00, 0x00, 0x01, 0x03, 0x28, 0x1e, 0x41, 312 0x03, 0x00, 0x00, 0x01, 0x03, 0x28, 0x1e, 0x41,
310/* reg18 reg19 reg1a reg1b */ 313/* reg18 reg19 reg1a reg1b */
@@ -315,7 +318,7 @@ static const u8 sn_mi0360[0x1c] = {
315/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ 318/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
316 0x00, 0x61, 0x44, 0x00, 0x1a, 0x20, 0x20, 0x20, 319 0x00, 0x61, 0x44, 0x00, 0x1a, 0x20, 0x20, 0x20,
317/* reg8 reg9 rega regb regc regd rege regf */ 320/* reg8 reg9 rega regb regc regd rege regf */
318 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10, 321 0x81, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
319/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */ 322/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
320 0x03, 0x00, 0x00, 0x02, 0x0a, 0x28, 0x1e, 0x61, 323 0x03, 0x00, 0x00, 0x02, 0x0a, 0x28, 0x1e, 0x61,
321/* reg18 reg19 reg1a reg1b */ 324/* reg18 reg19 reg1a reg1b */
@@ -337,7 +340,7 @@ static const u8 sn_mt9v111[0x1c] = {
337/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ 340/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
338 0x00, 0x61, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20, 341 0x00, 0x61, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20,
339/* reg8 reg9 rega regb regc regd rege regf */ 342/* reg8 reg9 rega regb regc regd rege regf */
340 0x81, 0x5c, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 343 0x81, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
341/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */ 344/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
342 0x03, 0x00, 0x00, 0x02, 0x1c, 0x28, 0x1e, 0x40, 345 0x03, 0x00, 0x00, 0x02, 0x1c, 0x28, 0x1e, 0x40,
343/* reg18 reg19 reg1a reg1b */ 346/* reg18 reg19 reg1a reg1b */
@@ -346,7 +349,7 @@ static const u8 sn_mt9v111[0x1c] = {
346 349
347static const u8 sn_om6802[0x1c] = { 350static const u8 sn_om6802[0x1c] = {
348/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ 351/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
349 0x00, 0x23, 0x72, 0x00, 0x1a, 0x34, 0x27, 0x20, 352 0x00, 0x23, 0x72, 0x00, 0x1a, 0x20, 0x20, 0x19,
350/* reg8 reg9 rega regb regc regd rege regf */ 353/* reg8 reg9 rega regb regc regd rege regf */
351 0x80, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 354 0x80, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
352/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */ 355/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
@@ -359,7 +362,7 @@ static const u8 sn_ov7630[0x1c] = {
359/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ 362/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
360 0x00, 0x21, 0x40, 0x00, 0x1a, 0x20, 0x1f, 0x20, 363 0x00, 0x21, 0x40, 0x00, 0x1a, 0x20, 0x1f, 0x20,
361/* reg8 reg9 rega regb regc regd rege regf */ 364/* reg8 reg9 rega regb regc regd rege regf */
362 0xa1, 0x21, 0x76, 0x21, 0x00, 0x00, 0x00, 0x10, 365 0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
363/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */ 366/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
364 0x03, 0x00, 0x04, 0x01, 0x0a, 0x28, 0x1e, 0xc2, 367 0x03, 0x00, 0x04, 0x01, 0x0a, 0x28, 0x1e, 0xc2,
365/* reg18 reg19 reg1a reg1b */ 368/* reg18 reg19 reg1a reg1b */
@@ -370,7 +373,7 @@ static const u8 sn_ov7648[0x1c] = {
370/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ 373/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
371 0x00, 0x63, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20, 374 0x00, 0x63, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20,
372/* reg8 reg9 rega regb regc regd rege regf */ 375/* reg8 reg9 rega regb regc regd rege regf */
373 0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 376 0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
374/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */ 377/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
375 0x03, 0x00, 0x00, 0x01, 0x00, 0x28, 0x1e, 0x00, 378 0x03, 0x00, 0x00, 0x01, 0x00, 0x28, 0x1e, 0x00,
376/* reg18 reg19 reg1a reg1b */ 379/* reg18 reg19 reg1a reg1b */
@@ -388,11 +391,22 @@ static const u8 sn_ov7660[0x1c] = {
388 0x07, 0x00, 0x00, 0x00 391 0x07, 0x00, 0x00, 0x00
389}; 392};
390 393
394static const u8 sn_po1030[0x1c] = {
395/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
396 0x00, 0x21, 0x62, 0x00, 0x1a, 0x20, 0x20, 0x20,
397/* reg8 reg9 rega regb regc regd rege regf */
398 0x81, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
399/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
400 0x03, 0x00, 0x00, 0x06, 0x06, 0x28, 0x1e, 0x00,
401/* reg18 reg19 reg1a reg1b */
402 0x07, 0x00, 0x00, 0x00
403};
404
391static const u8 sn_sp80708[0x1c] = { 405static const u8 sn_sp80708[0x1c] = {
392/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ 406/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
393 0x00, 0x63, 0x60, 0x00, 0x1a, 0x20, 0x20, 0x20, 407 0x00, 0x63, 0x60, 0x00, 0x1a, 0x20, 0x20, 0x20,
394/* reg8 reg9 rega regb regc regd rege regf */ 408/* reg8 reg9 rega regb regc regd rege regf */
395 0x81, 0x18, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 409 0x81, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
396/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */ 410/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
397 0x03, 0x00, 0x00, 0x03, 0x04, 0x28, 0x1e, 0x00, 411 0x03, 0x00, 0x00, 0x03, 0x04, 0x28, 0x1e, 0x00,
398/* reg18 reg19 reg1a reg1b */ 412/* reg18 reg19 reg1a reg1b */
@@ -409,6 +423,7 @@ static const u8 *sn_tb[] = {
409 sn_ov7630, 423 sn_ov7630,
410 sn_ov7648, 424 sn_ov7648,
411 sn_ov7660, 425 sn_ov7660,
426 sn_po1030,
412 sn_sp80708 427 sn_sp80708
413}; 428};
414 429
@@ -455,7 +470,7 @@ static const u8 hv7131r_sensor_init[][8] = {
455 470
456 {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10}, 471 {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
457 {0xa1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10}, 472 {0xa1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
458 {0xa1, 0x11, 0x21, 0xD0, 0x00, 0x00, 0x00, 0x10}, 473 {0xa1, 0x11, 0x21, 0xd0, 0x00, 0x00, 0x00, 0x10},
459 {0xa1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10}, 474 {0xa1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
460 {0xa1, 0x11, 0x23, 0x09, 0x00, 0x00, 0x00, 0x10}, 475 {0xa1, 0x11, 0x23, 0x09, 0x00, 0x00, 0x00, 0x10},
461 476
@@ -464,6 +479,8 @@ static const u8 hv7131r_sensor_init[][8] = {
464 {0xa1, 0x11, 0x21, 0xd0, 0x00, 0x00, 0x00, 0x10}, 479 {0xa1, 0x11, 0x21, 0xd0, 0x00, 0x00, 0x00, 0x10},
465 {0xa1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10}, 480 {0xa1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
466 {0xa1, 0x11, 0x23, 0x10, 0x00, 0x00, 0x00, 0x10}, 481 {0xa1, 0x11, 0x23, 0x10, 0x00, 0x00, 0x00, 0x10},
482 {0xa1, 0x11, 0x01, 0x18, 0x00, 0x00, 0x00, 0x10},
483 /* set sensor clock */
467 {} 484 {}
468}; 485};
469static const u8 mi0360_sensor_init[][8] = { 486static const u8 mi0360_sensor_init[][8] = {
@@ -545,7 +562,7 @@ static const u8 mo4000_sensor_init[][8] = {
545}; 562};
546static const u8 mt9v111_sensor_init[][8] = { 563static const u8 mt9v111_sensor_init[][8] = {
547 {0xb1, 0x5c, 0x0d, 0x00, 0x01, 0x00, 0x00, 0x10}, /* reset? */ 564 {0xb1, 0x5c, 0x0d, 0x00, 0x01, 0x00, 0x00, 0x10}, /* reset? */
548 /* delay 20 ms */ 565 {0xdd, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */
549 {0xb1, 0x5c, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x10}, 566 {0xb1, 0x5c, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x10},
550 {0xb1, 0x5c, 0x01, 0x00, 0x01, 0x00, 0x00, 0x10}, /* IFP select */ 567 {0xb1, 0x5c, 0x01, 0x00, 0x01, 0x00, 0x00, 0x10}, /* IFP select */
551 {0xb1, 0x5c, 0x08, 0x04, 0x80, 0x00, 0x00, 0x10}, /* output fmt ctrl */ 568 {0xb1, 0x5c, 0x08, 0x04, 0x80, 0x00, 0x00, 0x10}, /* output fmt ctrl */
@@ -572,7 +589,9 @@ static const u8 mt9v111_sensor_init[][8] = {
572 {0xb1, 0x5c, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x10}, /* digital zoom */ 589 {0xb1, 0x5c, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x10}, /* digital zoom */
573 {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10}, /* read mode */ 590 {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10}, /* read mode */
574 {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10}, 591 {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
575 /*******/ 592 {}
593};
594static const u8 mt9v111_sensor_param1[][8] = {
576 {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10}, 595 {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
577 {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10}, 596 {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
578 {0xb1, 0x5c, 0x09, 0x01, 0x2c, 0x00, 0x00, 0x10}, 597 {0xb1, 0x5c, 0x09, 0x01, 0x2c, 0x00, 0x00, 0x10},
@@ -585,14 +604,20 @@ static const u8 mt9v111_sensor_init[][8] = {
585 {0xb1, 0x5c, 0x35, 0x01, 0xc0, 0x00, 0x00, 0x10}, /* global gain */ 604 {0xb1, 0x5c, 0x35, 0x01, 0xc0, 0x00, 0x00, 0x10}, /* global gain */
586 {} 605 {}
587}; 606};
607static const u8 om6802_init0[2][8] = {
608/*fixme: variable*/
609 {0xa0, 0x34, 0x29, 0x0e, 0x00, 0x00, 0x00, 0x10},
610 {0xa0, 0x34, 0x23, 0xb0, 0x00, 0x00, 0x00, 0x10},
611};
588static const u8 om6802_sensor_init[][8] = { 612static const u8 om6802_sensor_init[][8] = {
589 {0xa0, 0x34, 0x90, 0x05, 0x00, 0x00, 0x00, 0x10}, 613 {0xa0, 0x34, 0xdf, 0x6d, 0x00, 0x00, 0x00, 0x10},
590 {0xa0, 0x34, 0x49, 0x85, 0x00, 0x00, 0x00, 0x10}, 614 /* factory mode */
591 {0xa0, 0x34, 0x5a, 0xc0, 0x00, 0x00, 0x00, 0x10},
592 {0xa0, 0x34, 0xdd, 0x18, 0x00, 0x00, 0x00, 0x10}, 615 {0xa0, 0x34, 0xdd, 0x18, 0x00, 0x00, 0x00, 0x10},
616 /* output raw RGB */
617 {0xa0, 0x34, 0x5a, 0xc0, 0x00, 0x00, 0x00, 0x10},
593/* {0xa0, 0x34, 0xfb, 0x11, 0x00, 0x00, 0x00, 0x10}, */ 618/* {0xa0, 0x34, 0xfb, 0x11, 0x00, 0x00, 0x00, 0x10}, */
594 {0xa0, 0x34, 0xf0, 0x04, 0x00, 0x00, 0x00, 0x10}, 619 {0xa0, 0x34, 0xf0, 0x04, 0x00, 0x00, 0x00, 0x10},
595 /* white balance & auto-exposure */ 620 /* auto-exposure speed (0) / white balance mode (auto RGB) */
596/* {0xa0, 0x34, 0xf1, 0x02, 0x00, 0x00, 0x00, 0x10}, 621/* {0xa0, 0x34, 0xf1, 0x02, 0x00, 0x00, 0x00, 0x10},
597 * set color mode */ 622 * set color mode */
598/* {0xa0, 0x34, 0xfe, 0x5b, 0x00, 0x00, 0x00, 0x10}, 623/* {0xa0, 0x34, 0xfe, 0x5b, 0x00, 0x00, 0x00, 0x10},
@@ -606,26 +631,29 @@ static const u8 om6802_sensor_init[][8] = {
606/* {0xa0, 0x34, 0xe8, 0x31, 0x00, 0x00, 0x00, 0x10}, 631/* {0xa0, 0x34, 0xe8, 0x31, 0x00, 0x00, 0x00, 0x10},
607 * preset gamma */ 632 * preset gamma */
608 {0xa0, 0x34, 0xe9, 0x0f, 0x00, 0x00, 0x00, 0x10}, 633 {0xa0, 0x34, 0xe9, 0x0f, 0x00, 0x00, 0x00, 0x10},
609 /* luminance mode (0x4f = AE) */ 634 /* luminance mode (0x4f -> AutoExpo on) */
610 {0xa0, 0x34, 0xe4, 0xff, 0x00, 0x00, 0x00, 0x10}, 635 {0xa0, 0x34, 0xe4, 0xff, 0x00, 0x00, 0x00, 0x10},
611 /* preset shutter */ 636 /* preset shutter */
612/* {0xa0, 0x34, 0xef, 0x00, 0x00, 0x00, 0x00, 0x10}, 637/* {0xa0, 0x34, 0xef, 0x00, 0x00, 0x00, 0x00, 0x10},
613 * auto frame rate */ 638 * auto frame rate */
614/* {0xa0, 0x34, 0xfb, 0xee, 0x00, 0x00, 0x00, 0x10}, */ 639/* {0xa0, 0x34, 0xfb, 0xee, 0x00, 0x00, 0x00, 0x10}, */
615 640 {0xa0, 0x34, 0x5d, 0x80, 0x00, 0x00, 0x00, 0x10},
616/* {0xa0, 0x34, 0x71, 0x84, 0x00, 0x00, 0x00, 0x10}, */ 641 {}
617/* {0xa0, 0x34, 0x72, 0x05, 0x00, 0x00, 0x00, 0x10}, */ 642};
618/* {0xa0, 0x34, 0x68, 0x80, 0x00, 0x00, 0x00, 0x10}, */ 643static const u8 om6802_sensor_param1[][8] = {
619/* {0xa0, 0x34, 0x69, 0x01, 0x00, 0x00, 0x00, 0x10}, */ 644 {0xa0, 0x34, 0x71, 0x84, 0x00, 0x00, 0x00, 0x10},
645 {0xa0, 0x34, 0x72, 0x05, 0x00, 0x00, 0x00, 0x10},
646 {0xa0, 0x34, 0x68, 0x80, 0x00, 0x00, 0x00, 0x10},
647 {0xa0, 0x34, 0x69, 0x01, 0x00, 0x00, 0x00, 0x10},
620 {} 648 {}
621}; 649};
622static const u8 ov7630_sensor_init[][8] = { 650static const u8 ov7630_sensor_init[][8] = {
623 {0xa1, 0x21, 0x76, 0x01, 0x00, 0x00, 0x00, 0x10}, 651 {0xa1, 0x21, 0x76, 0x01, 0x00, 0x00, 0x00, 0x10},
624 {0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10}, 652 {0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10},
625/* win: delay 20ms */ 653 {0xdd, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */
626 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10}, 654 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
627 {0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10}, 655 {0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10},
628/* win: delay 20ms */ 656 {0xdd, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */
629 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10}, 657 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
630/* win: i2c_r from 00 to 80 */ 658/* win: i2c_r from 00 to 80 */
631 {0xd1, 0x21, 0x03, 0x80, 0x10, 0x20, 0x80, 0x10}, 659 {0xd1, 0x21, 0x03, 0x80, 0x10, 0x20, 0x80, 0x10},
@@ -677,6 +705,7 @@ static const u8 ov7630_sensor_init[][8] = {
677static const u8 ov7648_sensor_init[][8] = { 705static const u8 ov7648_sensor_init[][8] = {
678 {0xa1, 0x21, 0x76, 0x00, 0x00, 0x00, 0x00, 0x10}, 706 {0xa1, 0x21, 0x76, 0x00, 0x00, 0x00, 0x00, 0x10},
679 {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset */ 707 {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset */
708 {0xdd, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */
680 {0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10}, 709 {0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
681 {0xd1, 0x21, 0x03, 0xa4, 0x30, 0x88, 0x00, 0x10}, 710 {0xd1, 0x21, 0x03, 0xa4, 0x30, 0x88, 0x00, 0x10},
682 {0xb1, 0x21, 0x11, 0x80, 0x08, 0x00, 0x00, 0x10}, 711 {0xb1, 0x21, 0x11, 0x80, 0x08, 0x00, 0x00, 0x10},
@@ -701,7 +730,9 @@ static const u8 ov7648_sensor_init[][8] = {
701/* {0xd1, 0x21, 0x25, 0x80, 0x32, 0xfe, 0xa0, 0x10}, jfm done */ 730/* {0xd1, 0x21, 0x25, 0x80, 0x32, 0xfe, 0xa0, 0x10}, jfm done */
702/* {0xd1, 0x21, 0x29, 0x00, 0x91, 0x00, 0x88, 0x10}, jfm done */ 731/* {0xd1, 0x21, 0x29, 0x00, 0x91, 0x00, 0x88, 0x10}, jfm done */
703/* {0xb1, 0x21, 0x2d, 0x85, 0x00, 0x00, 0x00, 0x10}, set by setfreq */ 732/* {0xb1, 0x21, 0x2d, 0x85, 0x00, 0x00, 0x00, 0x10}, set by setfreq */
704/*...*/ 733 {}
734};
735static const u8 ov7648_sensor_param1[][8] = {
705/* {0xa1, 0x21, 0x12, 0x08, 0x00, 0x00, 0x00, 0x10}, jfm done */ 736/* {0xa1, 0x21, 0x12, 0x08, 0x00, 0x00, 0x00, 0x10}, jfm done */
706/* {0xa1, 0x21, 0x75, 0x06, 0x00, 0x00, 0x00, 0x10}, * COMN 737/* {0xa1, 0x21, 0x75, 0x06, 0x00, 0x00, 0x00, 0x10}, * COMN
707 * set by setvflip */ 738 * set by setvflip */
@@ -723,7 +754,7 @@ static const u8 ov7648_sensor_init[][8] = {
723 754
724static const u8 ov7660_sensor_init[][8] = { 755static const u8 ov7660_sensor_init[][8] = {
725 {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset SCCB */ 756 {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset SCCB */
726/* (delay 20ms) */ 757 {0xdd, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */
727 {0xa1, 0x21, 0x12, 0x05, 0x00, 0x00, 0x00, 0x10}, 758 {0xa1, 0x21, 0x12, 0x05, 0x00, 0x00, 0x00, 0x10},
728 /* Outformat = rawRGB */ 759 /* Outformat = rawRGB */
729 {0xa1, 0x21, 0x13, 0xb8, 0x00, 0x00, 0x00, 0x10}, /* init COM8 */ 760 {0xa1, 0x21, 0x13, 0xb8, 0x00, 0x00, 0x00, 0x10}, /* init COM8 */
@@ -783,8 +814,11 @@ static const u8 ov7660_sensor_init[][8] = {
783 {0xc1, 0x21, 0x88, 0xaf, 0xc7, 0xdf, 0x00, 0x10}, /* gamma curve */ 814 {0xc1, 0x21, 0x88, 0xaf, 0xc7, 0xdf, 0x00, 0x10}, /* gamma curve */
784 {0xc1, 0x21, 0x8b, 0x99, 0x99, 0xcf, 0x00, 0x10}, /* reserved */ 815 {0xc1, 0x21, 0x8b, 0x99, 0x99, 0xcf, 0x00, 0x10}, /* reserved */
785 {0xb1, 0x21, 0x92, 0x00, 0x00, 0x00, 0x00, 0x10}, /* DM_LNL/H */ 816 {0xb1, 0x21, 0x92, 0x00, 0x00, 0x00, 0x00, 0x10}, /* DM_LNL/H */
817/* not in all ms-win traces*/
786 {0xa1, 0x21, 0xa1, 0x00, 0x00, 0x00, 0x00, 0x10}, 818 {0xa1, 0x21, 0xa1, 0x00, 0x00, 0x00, 0x00, 0x10},
787/****** (some exchanges in the win trace) ******/ 819 {}
820};
821static const u8 ov7660_sensor_param1[][8] = {
788 {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10}, /* MVFP */ 822 {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10}, /* MVFP */
789 /* bits[3..0]reserved */ 823 /* bits[3..0]reserved */
790 {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10}, 824 {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10},
@@ -797,6 +831,7 @@ static const u8 ov7660_sensor_init[][8] = {
797 {0xa1, 0x21, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x10}, /* GAIN */ 831 {0xa1, 0x21, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x10}, /* GAIN */
798/* {0xb1, 0x21, 0x01, 0x78, 0x78, 0x00, 0x00, 0x10}, * BLUE */ 832/* {0xb1, 0x21, 0x01, 0x78, 0x78, 0x00, 0x00, 0x10}, * BLUE */
799/****** (some exchanges in the win trace) ******/ 833/****** (some exchanges in the win trace) ******/
834/*fixme:param2*/
800 {0xa1, 0x21, 0x93, 0x00, 0x00, 0x00, 0x00, 0x10},/* dummy line hight */ 835 {0xa1, 0x21, 0x93, 0x00, 0x00, 0x00, 0x00, 0x10},/* dummy line hight */
801 {0xa1, 0x21, 0x92, 0x25, 0x00, 0x00, 0x00, 0x10}, /* dummy line low */ 836 {0xa1, 0x21, 0x92, 0x25, 0x00, 0x00, 0x00, 0x10}, /* dummy line low */
802 {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCH */ 837 {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCH */
@@ -804,6 +839,7 @@ static const u8 ov7660_sensor_init[][8] = {
804/* {0xa1, 0x21, 0x02, 0x90, 0x00, 0x00, 0x00, 0x10}, * RED */ 839/* {0xa1, 0x21, 0x02, 0x90, 0x00, 0x00, 0x00, 0x10}, * RED */
805/****** (some exchanges in the win trace) ******/ 840/****** (some exchanges in the win trace) ******/
806/******!! startsensor KO if changed !!****/ 841/******!! startsensor KO if changed !!****/
842/*fixme: param3*/
807 {0xa1, 0x21, 0x93, 0x01, 0x00, 0x00, 0x00, 0x10}, 843 {0xa1, 0x21, 0x93, 0x01, 0x00, 0x00, 0x00, 0x10},
808 {0xa1, 0x21, 0x92, 0xff, 0x00, 0x00, 0x00, 0x10}, 844 {0xa1, 0x21, 0x92, 0xff, 0x00, 0x00, 0x00, 0x10},
809 {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10}, 845 {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10},
@@ -811,6 +847,60 @@ static const u8 ov7660_sensor_init[][8] = {
811 {} 847 {}
812}; 848};
813 849
850static const u8 po1030_sensor_init[][8] = {
851/* the sensor registers are described in m5602/m5602_po1030.h */
852 {0xa1, 0x6e, 0x3f, 0x20, 0x00, 0x00, 0x00, 0x10}, /* sensor reset */
853 {0xdd, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */
854 {0xa1, 0x6e, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x10},
855 {0xa1, 0x6e, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x10},
856 {0xd1, 0x6e, 0x04, 0x02, 0xb1, 0x02, 0x39, 0x10},
857 {0xd1, 0x6e, 0x08, 0x00, 0x01, 0x00, 0x00, 0x10},
858 {0xd1, 0x6e, 0x0c, 0x02, 0x7f, 0x01, 0xe0, 0x10},
859 {0xd1, 0x6e, 0x12, 0x03, 0x02, 0x00, 0x03, 0x10},
860 {0xd1, 0x6e, 0x16, 0x85, 0x40, 0x4a, 0x40, 0x10}, /* r/g1/b/g2 gains */
861 {0xc1, 0x6e, 0x1a, 0x00, 0x80, 0x00, 0x00, 0x10},
862 {0xd1, 0x6e, 0x1d, 0x08, 0x03, 0x00, 0x00, 0x10},
863 {0xd1, 0x6e, 0x23, 0x00, 0xb0, 0x00, 0x94, 0x10},
864 {0xd1, 0x6e, 0x27, 0x58, 0x00, 0x00, 0x00, 0x10},
865 {0xb1, 0x6e, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10},
866 {0xd1, 0x6e, 0x2d, 0x14, 0x35, 0x61, 0x84, 0x10}, /* gamma corr */
867 {0xd1, 0x6e, 0x31, 0xa2, 0xbd, 0xd8, 0xff, 0x10},
868 {0xd1, 0x6e, 0x35, 0x06, 0x1e, 0x12, 0x02, 0x10}, /* color matrix */
869 {0xd1, 0x6e, 0x39, 0xaa, 0x53, 0x37, 0xd5, 0x10},
870 {0xa1, 0x6e, 0x3d, 0xf2, 0x00, 0x00, 0x00, 0x10},
871 {0xd1, 0x6e, 0x3e, 0x00, 0x00, 0x80, 0x03, 0x10},
872 {0xd1, 0x6e, 0x42, 0x03, 0x00, 0x00, 0x00, 0x10},
873 {0xc1, 0x6e, 0x46, 0x00, 0x80, 0x80, 0x00, 0x10},
874 {0xd1, 0x6e, 0x4b, 0x02, 0xef, 0x08, 0xcd, 0x10},
875 {0xd1, 0x6e, 0x4f, 0x00, 0xd0, 0x00, 0xa0, 0x10},
876 {0xd1, 0x6e, 0x53, 0x01, 0xaa, 0x01, 0x40, 0x10},
877 {0xd1, 0x6e, 0x5a, 0x50, 0x04, 0x30, 0x03, 0x10}, /* raw rgb bayer */
878 {0xa1, 0x6e, 0x5e, 0x00, 0x00, 0x00, 0x00, 0x10},
879 {0xd1, 0x6e, 0x5f, 0x10, 0x40, 0xff, 0x00, 0x10},
880
881 {0xd1, 0x6e, 0x63, 0x40, 0x40, 0x00, 0x00, 0x10},
882 {0xd1, 0x6e, 0x67, 0x00, 0x00, 0x00, 0x00, 0x10},
883 {0xd1, 0x6e, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x10},
884 {0xd1, 0x6e, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x10},
885 {0xc1, 0x6e, 0x73, 0x10, 0x80, 0xeb, 0x00, 0x10},
886 {}
887};
888static const u8 po1030_sensor_param1[][8] = {
889/* from ms-win traces - these values change with auto gain/expo/wb.. */
890 {0xa1, 0x6e, 0x1e, 0x03, 0x00, 0x00, 0x00, 0x10},
891 {0xa1, 0x6e, 0x1e, 0x03, 0x00, 0x00, 0x00, 0x10},
892/* mean values */
893 {0xc1, 0x6e, 0x1a, 0x02, 0xd4, 0xa4, 0x00, 0x10}, /* integlines */
894 {0xa1, 0x6e, 0x15, 0x04, 0x00, 0x00, 0x00, 0x10}, /* global gain */
895 {0xc1, 0x6e, 0x16, 0x40, 0x40, 0x40, 0x00, 0x10}, /* r/g1/b gains */
896
897 {0xa1, 0x6e, 0x1d, 0x08, 0x00, 0x00, 0x00, 0x10}, /* control1 */
898 {0xa1, 0x6e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x10}, /* frameheight */
899 {0xa1, 0x6e, 0x07, 0xd5, 0x00, 0x00, 0x00, 0x10},
900/* {0xc1, 0x6e, 0x16, 0x49, 0x40, 0x45, 0x00, 0x10}, */
901 {}
902};
903
814static const u8 sp80708_sensor_init[][8] = { 904static const u8 sp80708_sensor_init[][8] = {
815 {0xa1, 0x18, 0x06, 0xf9, 0x00, 0x00, 0x00, 0x10}, 905 {0xa1, 0x18, 0x06, 0xf9, 0x00, 0x00, 0x00, 0x10},
816 {0xa1, 0x18, 0x09, 0x1f, 0x00, 0x00, 0x00, 0x10}, 906 {0xa1, 0x18, 0x09, 0x1f, 0x00, 0x00, 0x00, 0x10},
@@ -883,7 +973,9 @@ static const u8 sp80708_sensor_init[][8] = {
883 {0xa1, 0x18, 0x67, 0x24, 0x00, 0x00, 0x00, 0x10}, 973 {0xa1, 0x18, 0x67, 0x24, 0x00, 0x00, 0x00, 0x10},
884 {0xa1, 0x18, 0x68, 0x08, 0x00, 0x00, 0x00, 0x10}, 974 {0xa1, 0x18, 0x68, 0x08, 0x00, 0x00, 0x00, 0x10},
885 {0xa1, 0x18, 0x2f, 0xc9, 0x00, 0x00, 0x00, 0x10}, 975 {0xa1, 0x18, 0x2f, 0xc9, 0x00, 0x00, 0x00, 0x10},
886 /********/ 976 {}
977};
978static const u8 sp80708_sensor_param1[][8] = {
887 {0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10}, 979 {0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10},
888 {0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10}, 980 {0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10},
889 {0xa1, 0x18, 0x03, 0x01, 0x00, 0x00, 0x00, 0x10}, 981 {0xa1, 0x18, 0x03, 0x01, 0x00, 0x00, 0x00, 0x10},
@@ -894,6 +986,19 @@ static const u8 sp80708_sensor_init[][8] = {
894 {} 986 {}
895}; 987};
896 988
989static const u8 (*sensor_init[10])[8] = {
990 hv7131r_sensor_init, /* HV7131R 0 */
991 mi0360_sensor_init, /* MI0360 1 */
992 mo4000_sensor_init, /* MO4000 2 */
993 mt9v111_sensor_init, /* MT9V111 3 */
994 om6802_sensor_init, /* OM6802 4 */
995 ov7630_sensor_init, /* OV7630 5 */
996 ov7648_sensor_init, /* OV7648 6 */
997 ov7660_sensor_init, /* OV7660 7 */
998 po1030_sensor_init, /* PO1030 8 */
999 sp80708_sensor_init, /* SP80708 9 */
1000};
1001
897/* read <len> bytes to gspca_dev->usb_buf */ 1002/* read <len> bytes to gspca_dev->usb_buf */
898static void reg_r(struct gspca_dev *gspca_dev, 1003static void reg_r(struct gspca_dev *gspca_dev,
899 u16 value, int len) 1004 u16 value, int len)
@@ -958,8 +1063,15 @@ static void i2c_w1(struct gspca_dev *gspca_dev, u8 reg, u8 val)
958 struct sd *sd = (struct sd *) gspca_dev; 1063 struct sd *sd = (struct sd *) gspca_dev;
959 1064
960 PDEBUG(D_USBO, "i2c_w2 [%02x] = %02x", reg, val); 1065 PDEBUG(D_USBO, "i2c_w2 [%02x] = %02x", reg, val);
961 gspca_dev->usb_buf[0] = 0x81 | (2 << 4); /* = a1 */ 1066 switch (sd->sensor) {
962 gspca_dev->usb_buf[1] = sd->i2c_base; 1067 case SENSOR_OM6802: /* i2c command = a0 (100 kHz) */
1068 gspca_dev->usb_buf[0] = 0x80 | (2 << 4);
1069 break;
1070 default: /* i2c command = a1 (400 kHz) */
1071 gspca_dev->usb_buf[0] = 0x81 | (2 << 4);
1072 break;
1073 }
1074 gspca_dev->usb_buf[1] = sd->i2c_addr;
963 gspca_dev->usb_buf[2] = reg; 1075 gspca_dev->usb_buf[2] = reg;
964 gspca_dev->usb_buf[3] = val; 1076 gspca_dev->usb_buf[3] = val;
965 gspca_dev->usb_buf[4] = 0; 1077 gspca_dev->usb_buf[4] = 0;
@@ -991,14 +1103,21 @@ static void i2c_w8(struct gspca_dev *gspca_dev,
991 msleep(2); 1103 msleep(2);
992} 1104}
993 1105
994/* read 5 bytes in gspca_dev->usb_buf */ 1106/* sensor read 'len' (1..5) bytes in gspca_dev->usb_buf */
995static void i2c_r5(struct gspca_dev *gspca_dev, u8 reg) 1107static void i2c_r(struct gspca_dev *gspca_dev, u8 reg, int len)
996{ 1108{
997 struct sd *sd = (struct sd *) gspca_dev; 1109 struct sd *sd = (struct sd *) gspca_dev;
998 u8 mode[8]; 1110 u8 mode[8];
999 1111
1000 mode[0] = 0x81 | 0x10; 1112 switch (sd->sensor) {
1001 mode[1] = sd->i2c_base; 1113 case SENSOR_OM6802: /* i2c command = 90 (100 kHz) */
1114 mode[0] = 0x80 | 0x10;
1115 break;
1116 default: /* i2c command = 91 (400 kHz) */
1117 mode[0] = 0x81 | 0x10;
1118 break;
1119 }
1120 mode[1] = sd->i2c_addr;
1002 mode[2] = reg; 1121 mode[2] = reg;
1003 mode[3] = 0; 1122 mode[3] = 0;
1004 mode[4] = 0; 1123 mode[4] = 0;
@@ -1007,33 +1126,43 @@ static void i2c_r5(struct gspca_dev *gspca_dev, u8 reg)
1007 mode[7] = 0x10; 1126 mode[7] = 0x10;
1008 i2c_w8(gspca_dev, mode); 1127 i2c_w8(gspca_dev, mode);
1009 msleep(2); 1128 msleep(2);
1010 mode[0] = 0x81 | (5 << 4) | 0x02; 1129 mode[0] = (mode[0] & 0x81) | (len << 4) | 0x02;
1011 mode[2] = 0; 1130 mode[2] = 0;
1012 i2c_w8(gspca_dev, mode); 1131 i2c_w8(gspca_dev, mode);
1013 msleep(2); 1132 msleep(2);
1014 reg_r(gspca_dev, 0x0a, 5); 1133 reg_r(gspca_dev, 0x0a, 5);
1015} 1134}
1016 1135
1017static int hv7131r_probe(struct gspca_dev *gspca_dev) 1136static void i2c_w_seq(struct gspca_dev *gspca_dev,
1137 const u8 (*data)[8])
1138{
1139 while ((*data)[0] != 0) {
1140 if ((*data)[0] != 0xdd)
1141 i2c_w8(gspca_dev, *data);
1142 else
1143 msleep((*data)[1]);
1144 data++;
1145 }
1146}
1147
1148static void hv7131r_probe(struct gspca_dev *gspca_dev)
1018{ 1149{
1019 i2c_w1(gspca_dev, 0x02, 0); /* sensor wakeup */ 1150 i2c_w1(gspca_dev, 0x02, 0); /* sensor wakeup */
1020 msleep(10); 1151 msleep(10);
1021 reg_w1(gspca_dev, 0x02, 0x66); /* Gpio on */ 1152 reg_w1(gspca_dev, 0x02, 0x66); /* Gpio on */
1022 msleep(10); 1153 msleep(10);
1023 i2c_r5(gspca_dev, 0); /* read sensor id */ 1154 i2c_r(gspca_dev, 0, 5); /* read sensor id */
1024 if (gspca_dev->usb_buf[0] == 0x02 1155 if (gspca_dev->usb_buf[0] == 0x02
1025 && gspca_dev->usb_buf[1] == 0x09 1156 && gspca_dev->usb_buf[1] == 0x09
1026 && gspca_dev->usb_buf[2] == 0x01 1157 && gspca_dev->usb_buf[2] == 0x01
1027 && gspca_dev->usb_buf[3] == 0x00 1158 && gspca_dev->usb_buf[3] == 0x00
1028 && gspca_dev->usb_buf[4] == 0x00) { 1159 && gspca_dev->usb_buf[4] == 0x00) {
1029 PDEBUG(D_PROBE, "Find Sensor sn9c102P HV7131R"); 1160 PDEBUG(D_PROBE, "Sensor sn9c102P HV7131R found");
1030 return 0; 1161 return;
1031 } 1162 }
1032 PDEBUG(D_PROBE, "Find Sensor 0x%02x 0x%02x 0x%02x", 1163 PDEBUG(D_PROBE, "Sensor 0x%02x 0x%02x 0x%02x - sn9c102P not found",
1033 gspca_dev->usb_buf[0], gspca_dev->usb_buf[1], 1164 gspca_dev->usb_buf[0], gspca_dev->usb_buf[1],
1034 gspca_dev->usb_buf[2]); 1165 gspca_dev->usb_buf[2]);
1035 PDEBUG(D_PROBE, "Sensor sn9c102P Not found");
1036 return -ENODEV;
1037} 1166}
1038 1167
1039static void mi0360_probe(struct gspca_dev *gspca_dev) 1168static void mi0360_probe(struct gspca_dev *gspca_dev)
@@ -1075,7 +1204,6 @@ static void mi0360_probe(struct gspca_dev *gspca_dev)
1075 case 0x823a: 1204 case 0x823a:
1076 PDEBUG(D_PROBE, "Sensor mt9v111"); 1205 PDEBUG(D_PROBE, "Sensor mt9v111");
1077 sd->sensor = SENSOR_MT9V111; 1206 sd->sensor = SENSOR_MT9V111;
1078 sd->i2c_base = 0x5c;
1079 break; 1207 break;
1080 case 0x8243: 1208 case 0x8243:
1081 PDEBUG(D_PROBE, "Sensor mi0360"); 1209 PDEBUG(D_PROBE, "Sensor mi0360");
@@ -1086,7 +1214,42 @@ static void mi0360_probe(struct gspca_dev *gspca_dev)
1086 } 1214 }
1087} 1215}
1088 1216
1089static int configure_gpio(struct gspca_dev *gspca_dev, 1217static void ov7648_probe(struct gspca_dev *gspca_dev)
1218{
1219 struct sd *sd = (struct sd *) gspca_dev;
1220
1221 /* check ov76xx */
1222 reg_w1(gspca_dev, 0x17, 0x62);
1223 reg_w1(gspca_dev, 0x01, 0x08);
1224 sd->i2c_addr = 0x21;
1225 i2c_r(gspca_dev, 0x0a, 2);
1226 if (gspca_dev->usb_buf[3] == 0x76) { /* ov76xx */
1227 PDEBUG(D_PROBE, "Sensor ov%02x%02x",
1228 gspca_dev->usb_buf[3], gspca_dev->usb_buf[4]);
1229 return;
1230 }
1231
1232 /* reset */
1233 reg_w1(gspca_dev, 0x01, 0x29);
1234 reg_w1(gspca_dev, 0x17, 0x42);
1235
1236 /* check po1030 */
1237 reg_w1(gspca_dev, 0x17, 0x62);
1238 reg_w1(gspca_dev, 0x01, 0x08);
1239 sd->i2c_addr = 0x6e;
1240 i2c_r(gspca_dev, 0x00, 2);
1241 if (gspca_dev->usb_buf[3] == 0x10 /* po1030 */
1242 && gspca_dev->usb_buf[4] == 0x30) {
1243 PDEBUG(D_PROBE, "Sensor po1030");
1244 sd->sensor = SENSOR_PO1030;
1245 return;
1246 }
1247
1248 PDEBUG(D_PROBE, "Unknown sensor %02x%02x",
1249 gspca_dev->usb_buf[3], gspca_dev->usb_buf[4]);
1250}
1251
1252static void bridge_init(struct gspca_dev *gspca_dev,
1090 const u8 *sn9c1xx) 1253 const u8 *sn9c1xx)
1091{ 1254{
1092 struct sd *sd = (struct sd *) gspca_dev; 1255 struct sd *sd = (struct sd *) gspca_dev;
@@ -1103,9 +1266,10 @@ static int configure_gpio(struct gspca_dev *gspca_dev,
1103 /* configure gpio */ 1266 /* configure gpio */
1104 reg_w(gspca_dev, 0x01, &sn9c1xx[1], 2); 1267 reg_w(gspca_dev, 0x01, &sn9c1xx[1], 2);
1105 reg_w(gspca_dev, 0x08, &sn9c1xx[8], 2); 1268 reg_w(gspca_dev, 0x08, &sn9c1xx[8], 2);
1106 reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 5); /* jfm len was 3 */ 1269 reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 5);
1107 switch (sd->sensor) { 1270 switch (sd->sensor) {
1108 case SENSOR_OV7660: 1271 case SENSOR_OV7660:
1272 case SENSOR_PO1030:
1109 case SENSOR_SP80708: 1273 case SENSOR_SP80708:
1110 reg9a = reg9a_spec; 1274 reg9a = reg9a_spec;
1111 break; 1275 break;
@@ -1115,7 +1279,7 @@ static int configure_gpio(struct gspca_dev *gspca_dev,
1115 } 1279 }
1116 reg_w(gspca_dev, 0x9a, reg9a, 6); 1280 reg_w(gspca_dev, 0x9a, reg9a, 6);
1117 1281
1118 reg_w(gspca_dev, 0xd4, regd4, sizeof regd4); /*fixme:jfm was 60 only*/ 1282 reg_w(gspca_dev, 0xd4, regd4, sizeof regd4);
1119 1283
1120 reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f); 1284 reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f);
1121 1285
@@ -1127,10 +1291,22 @@ static int configure_gpio(struct gspca_dev *gspca_dev,
1127 reg_w1(gspca_dev, 0x01, 0x40); 1291 reg_w1(gspca_dev, 0x01, 0x40);
1128 break; 1292 break;
1129 case SENSOR_OM6802: 1293 case SENSOR_OM6802:
1130 reg_w1(gspca_dev, 0x02, 0x71); 1294 msleep(10);
1131 reg_w1(gspca_dev, 0x01, 0x42); 1295 reg_w1(gspca_dev, 0x02, 0x73);
1296 reg_w1(gspca_dev, 0x17, 0x60);
1297 reg_w1(gspca_dev, 0x01, 0x22);
1298 msleep(100);
1299 reg_w1(gspca_dev, 0x01, 0x62);
1300 reg_w1(gspca_dev, 0x17, 0x64);
1132 reg_w1(gspca_dev, 0x17, 0x64); 1301 reg_w1(gspca_dev, 0x17, 0x64);
1133 reg_w1(gspca_dev, 0x01, 0x42); 1302 reg_w1(gspca_dev, 0x01, 0x42);
1303 msleep(10);
1304 reg_w1(gspca_dev, 0x01, 0x42);
1305 i2c_w8(gspca_dev, om6802_init0[0]);
1306 i2c_w8(gspca_dev, om6802_init0[1]);
1307 msleep(15);
1308 reg_w1(gspca_dev, 0x02, 0x71);
1309 msleep(150);
1134 break; 1310 break;
1135 case SENSOR_OV7630: 1311 case SENSOR_OV7630:
1136 reg_w1(gspca_dev, 0x01, 0x61); 1312 reg_w1(gspca_dev, 0x01, 0x61);
@@ -1144,7 +1320,14 @@ static int configure_gpio(struct gspca_dev *gspca_dev,
1144 reg_w1(gspca_dev, 0x01, 0x62); 1320 reg_w1(gspca_dev, 0x01, 0x62);
1145 reg_w1(gspca_dev, 0x01, 0x42); 1321 reg_w1(gspca_dev, 0x01, 0x42);
1146 break; 1322 break;
1323 case SENSOR_PO1030:
1324 reg_w1(gspca_dev, 0x01, 0x61);
1325 reg_w1(gspca_dev, 0x17, 0x20);
1326 reg_w1(gspca_dev, 0x01, 0x60);
1327 reg_w1(gspca_dev, 0x01, 0x40);
1328 break;
1147 case SENSOR_OV7660: 1329 case SENSOR_OV7660:
1330 /* fall thru */
1148 case SENSOR_SP80708: 1331 case SENSOR_SP80708:
1149 reg_w1(gspca_dev, 0x01, 0x63); 1332 reg_w1(gspca_dev, 0x01, 0x63);
1150 reg_w1(gspca_dev, 0x17, 0x20); 1333 reg_w1(gspca_dev, 0x17, 0x20);
@@ -1153,143 +1336,18 @@ static int configure_gpio(struct gspca_dev *gspca_dev,
1153 msleep(100); 1336 msleep(100);
1154 reg_w1(gspca_dev, 0x02, 0x62); 1337 reg_w1(gspca_dev, 0x02, 0x62);
1155 break; 1338 break;
1339 default:
1156/* case SENSOR_HV7131R: */ 1340/* case SENSOR_HV7131R: */
1157/* case SENSOR_MI0360: */ 1341/* case SENSOR_MI0360: */
1158/* case SENSOR_MO4000: */ 1342/* case SENSOR_MO4000: */
1159 default:
1160 reg_w1(gspca_dev, 0x01, 0x43); 1343 reg_w1(gspca_dev, 0x01, 0x43);
1161 reg_w1(gspca_dev, 0x17, 0x61); 1344 reg_w1(gspca_dev, 0x17, 0x61);
1162 reg_w1(gspca_dev, 0x01, 0x42); 1345 reg_w1(gspca_dev, 0x01, 0x42);
1163 if (sd->sensor == SENSOR_HV7131R) { 1346 if (sd->sensor == SENSOR_HV7131R
1164 if (hv7131r_probe(gspca_dev) < 0) 1347 && sd->bridge == BRIDGE_SN9C102P)
1165 return -ENODEV; 1348 hv7131r_probe(gspca_dev);
1166 }
1167 break; 1349 break;
1168 } 1350 }
1169 return 0;
1170}
1171
1172static void hv7131R_InitSensor(struct gspca_dev *gspca_dev)
1173{
1174 int i = 0;
1175 static const u8 SetSensorClk[] = /* 0x08 Mclk */
1176 { 0xa1, 0x11, 0x01, 0x18, 0x00, 0x00, 0x00, 0x10 };
1177
1178 while (hv7131r_sensor_init[i][0]) {
1179 i2c_w8(gspca_dev, hv7131r_sensor_init[i]);
1180 i++;
1181 }
1182 i2c_w8(gspca_dev, SetSensorClk);
1183}
1184
1185static void mi0360_InitSensor(struct gspca_dev *gspca_dev)
1186{
1187 int i = 0;
1188
1189 while (mi0360_sensor_init[i][0]) {
1190 i2c_w8(gspca_dev, mi0360_sensor_init[i]);
1191 i++;
1192 }
1193}
1194
1195static void mo4000_InitSensor(struct gspca_dev *gspca_dev)
1196{
1197 int i = 0;
1198
1199 while (mo4000_sensor_init[i][0]) {
1200 i2c_w8(gspca_dev, mo4000_sensor_init[i]);
1201 i++;
1202 }
1203}
1204
1205static void mt9v111_InitSensor(struct gspca_dev *gspca_dev)
1206{
1207 int i = 0;
1208
1209 i2c_w8(gspca_dev, mt9v111_sensor_init[i]);
1210 i++;
1211 msleep(20);
1212 while (mt9v111_sensor_init[i][0]) {
1213 i2c_w8(gspca_dev, mt9v111_sensor_init[i]);
1214 i++;
1215 }
1216}
1217
1218static void om6802_InitSensor(struct gspca_dev *gspca_dev)
1219{
1220 int i = 0;
1221
1222 while (om6802_sensor_init[i][0]) {
1223 i2c_w8(gspca_dev, om6802_sensor_init[i]);
1224 i++;
1225 }
1226}
1227
1228static void ov7630_InitSensor(struct gspca_dev *gspca_dev)
1229{
1230 int i = 0;
1231
1232 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 76 01 */
1233 i++;
1234 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 c8 (RGB+SRST) */
1235 i++;
1236 msleep(20);
1237 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 48 */
1238 i++;
1239 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 c8 */
1240 i++;
1241 msleep(20);
1242 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 48 */
1243 i++;
1244/*jfm:win i2c_r from 00 to 80*/
1245
1246 while (ov7630_sensor_init[i][0]) {
1247 i2c_w8(gspca_dev, ov7630_sensor_init[i]);
1248 i++;
1249 }
1250}
1251
1252static void ov7648_InitSensor(struct gspca_dev *gspca_dev)
1253{
1254 int i = 0;
1255
1256 i2c_w8(gspca_dev, ov7648_sensor_init[i]);
1257 i++;
1258/* win: dble reset */
1259 i2c_w8(gspca_dev, ov7648_sensor_init[i]); /* reset */
1260 i++;
1261 msleep(20);
1262/* win: i2c reg read 00..7f */
1263 while (ov7648_sensor_init[i][0]) {
1264 i2c_w8(gspca_dev, ov7648_sensor_init[i]);
1265 i++;
1266 }
1267}
1268
1269static void ov7660_InitSensor(struct gspca_dev *gspca_dev)
1270{
1271 int i = 0;
1272
1273 i2c_w8(gspca_dev, ov7660_sensor_init[i]); /* reset SCCB */
1274 i++;
1275 msleep(20);
1276 while (ov7660_sensor_init[i][0]) {
1277 i2c_w8(gspca_dev, ov7660_sensor_init[i]);
1278 i++;
1279 }
1280}
1281
1282static void sp80708_InitSensor(struct gspca_dev *gspca_dev)
1283{
1284 int i = 0;
1285
1286 i2c_w8(gspca_dev, sp80708_sensor_init[i]); /* reset SCCB */
1287 i++;
1288 msleep(20);
1289 while (sp80708_sensor_init[i][0]) {
1290 i2c_w8(gspca_dev, sp80708_sensor_init[i]);
1291 i++;
1292 }
1293} 1351}
1294 1352
1295/* this function is called at probe time */ 1353/* this function is called at probe time */
@@ -1305,8 +1363,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
1305 cam->npkt = 24; /* 24 packets per ISOC message */ 1363 cam->npkt = 24; /* 24 packets per ISOC message */
1306 1364
1307 sd->bridge = id->driver_info >> 16; 1365 sd->bridge = id->driver_info >> 16;
1308 sd->sensor = id->driver_info >> 8; 1366 sd->sensor = id->driver_info;
1309 sd->i2c_base = id->driver_info;
1310 1367
1311 sd->brightness = BRIGHTNESS_DEF; 1368 sd->brightness = BRIGHTNESS_DEF;
1312 sd->contrast = CONTRAST_DEF; 1369 sd->contrast = CONTRAST_DEF;
@@ -1322,7 +1379,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
1322 sd->quality = QUALITY_DEF; 1379 sd->quality = QUALITY_DEF;
1323 sd->jpegqual = 80; 1380 sd->jpegqual = 80;
1324 1381
1325 gspca_dev->ctrl_dis = ctrl_dis[sd->sensor];
1326 return 0; 1382 return 0;
1327} 1383}
1328 1384
@@ -1330,6 +1386,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
1330static int sd_init(struct gspca_dev *gspca_dev) 1386static int sd_init(struct gspca_dev *gspca_dev)
1331{ 1387{
1332 struct sd *sd = (struct sd *) gspca_dev; 1388 struct sd *sd = (struct sd *) gspca_dev;
1389 const u8 *sn9c1xx;
1333 u8 regGpio[] = { 0x29, 0x74 }; 1390 u8 regGpio[] = { 0x29, 0x74 };
1334 u8 regF1; 1391 u8 regF1;
1335 1392
@@ -1356,8 +1413,14 @@ static int sd_init(struct gspca_dev *gspca_dev)
1356 case BRIDGE_SN9C120: 1413 case BRIDGE_SN9C120:
1357 if (regF1 != 0x12) 1414 if (regF1 != 0x12)
1358 return -ENODEV; 1415 return -ENODEV;
1359 if (sd->sensor == SENSOR_MI0360) 1416 switch (sd->sensor) {
1417 case SENSOR_MI0360:
1360 mi0360_probe(gspca_dev); 1418 mi0360_probe(gspca_dev);
1419 break;
1420 case SENSOR_OV7648:
1421 ov7648_probe(gspca_dev);
1422 break;
1423 }
1361 regGpio[1] = 0x70; 1424 regGpio[1] = 0x70;
1362 reg_w(gspca_dev, 0x01, regGpio, 2); 1425 reg_w(gspca_dev, 0x01, regGpio, 2);
1363 break; 1426 break;
@@ -1372,6 +1435,12 @@ static int sd_init(struct gspca_dev *gspca_dev)
1372 1435
1373 reg_w1(gspca_dev, 0xf1, 0x01); 1436 reg_w1(gspca_dev, 0xf1, 0x01);
1374 1437
1438 /* set the i2c address */
1439 sn9c1xx = sn_tb[sd->sensor];
1440 sd->i2c_addr = sn9c1xx[9];
1441
1442 gspca_dev->ctrl_dis = ctrl_dis[sd->sensor];
1443
1375 return 0; 1444 return 0;
1376} 1445}
1377 1446
@@ -1383,7 +1452,7 @@ static u32 setexposure(struct gspca_dev *gspca_dev,
1383 switch (sd->sensor) { 1452 switch (sd->sensor) {
1384 case SENSOR_HV7131R: { 1453 case SENSOR_HV7131R: {
1385 u8 Expodoit[] = 1454 u8 Expodoit[] =
1386 { 0xc1, 0x11, 0x25, 0x07, 0x27, 0xc0, 0x00, 0x16 }; 1455 { 0xc1, 0x11, 0x25, 0x00, 0x00, 0x00, 0x00, 0x16 };
1387 1456
1388 Expodoit[3] = expo >> 16; 1457 Expodoit[3] = expo >> 16;
1389 Expodoit[4] = expo >> 8; 1458 Expodoit[4] = expo >> 8;
@@ -1393,7 +1462,7 @@ static u32 setexposure(struct gspca_dev *gspca_dev,
1393 } 1462 }
1394 case SENSOR_MI0360: { 1463 case SENSOR_MI0360: {
1395 u8 expoMi[] = /* exposure 0x0635 -> 4 fp/s 0x10 */ 1464 u8 expoMi[] = /* exposure 0x0635 -> 4 fp/s 0x10 */
1396 { 0xb1, 0x5d, 0x09, 0x06, 0x35, 0x00, 0x00, 0x16 }; 1465 { 0xb1, 0x5d, 0x09, 0x00, 0x00, 0x00, 0x00, 0x16 };
1397 static const u8 doit[] = /* update sensor */ 1466 static const u8 doit[] = /* update sensor */
1398 { 0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10 }; 1467 { 0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10 };
1399 static const u8 sensorgo[] = /* sensor on */ 1468 static const u8 sensorgo[] = /* sensor on */
@@ -1412,9 +1481,9 @@ static u32 setexposure(struct gspca_dev *gspca_dev,
1412 } 1481 }
1413 case SENSOR_MO4000: { 1482 case SENSOR_MO4000: {
1414 u8 expoMof[] = 1483 u8 expoMof[] =
1415 { 0xa1, 0x21, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x10 }; 1484 { 0xa1, 0x21, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x10 };
1416 u8 expoMo10[] = 1485 u8 expoMo10[] =
1417 { 0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10 }; 1486 { 0xa1, 0x21, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10 };
1418 static const u8 gainMo[] = 1487 static const u8 gainMo[] =
1419 { 0xa1, 0x21, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1d }; 1488 { 0xa1, 0x21, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1d };
1420 1489
@@ -1450,6 +1519,7 @@ static u32 setexposure(struct gspca_dev *gspca_dev,
1450 case SENSOR_OM6802: { 1519 case SENSOR_OM6802: {
1451 u8 gainOm[] = 1520 u8 gainOm[] =
1452 { 0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10 }; 1521 { 0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10 };
1522 /* preset AGC - works when AutoExpo = off */
1453 1523
1454 if (expo > 0x03ff) 1524 if (expo > 0x03ff)
1455 expo = 0x03ff; 1525 expo = 0x03ff;
@@ -1457,7 +1527,7 @@ static u32 setexposure(struct gspca_dev *gspca_dev,
1457 expo = 0x0001; 1527 expo = 0x0001;
1458 gainOm[3] = expo >> 2; 1528 gainOm[3] = expo >> 2;
1459 i2c_w8(gspca_dev, gainOm); 1529 i2c_w8(gspca_dev, gainOm);
1460 reg_w1(gspca_dev, 0x96, (expo >> 5) & 0x1f); 1530 reg_w1(gspca_dev, 0x96, expo >> 5);
1461 PDEBUG(D_FRAM, "set exposure %d", gainOm[3]); 1531 PDEBUG(D_FRAM, "set exposure %d", gainOm[3]);
1462 break; 1532 break;
1463 } 1533 }
@@ -1489,7 +1559,7 @@ static void setbrightness(struct gspca_dev *gspca_dev)
1489 case SENSOR_MT9V111: 1559 case SENSOR_MT9V111:
1490 expo = sd->brightness >> 8; 1560 expo = sd->brightness >> 8;
1491 sd->exposure = setexposure(gspca_dev, expo); 1561 sd->exposure = setexposure(gspca_dev, expo);
1492 break; 1562 return; /* don't set the Y offset */
1493 case SENSOR_OM6802: 1563 case SENSOR_OM6802:
1494 expo = sd->brightness >> 6; 1564 expo = sd->brightness >> 6;
1495 sd->exposure = setexposure(gspca_dev, expo); 1565 sd->exposure = setexposure(gspca_dev, expo);
@@ -1497,8 +1567,7 @@ static void setbrightness(struct gspca_dev *gspca_dev)
1497 break; 1567 break;
1498 } 1568 }
1499 1569
1500 if (sd->sensor != SENSOR_MT9V111) 1570 reg_w1(gspca_dev, 0x96, k2); /* color matrix Y offset */
1501 reg_w1(gspca_dev, 0x96, k2); /* color matrix Y offset */
1502} 1571}
1503 1572
1504static void setcontrast(struct gspca_dev *gspca_dev) 1573static void setcontrast(struct gspca_dev *gspca_dev)
@@ -1526,6 +1595,7 @@ static void setcolors(struct gspca_dev *gspca_dev)
1526 -24, -38, 64, /* UR UG UB */ 1595 -24, -38, 64, /* UR UG UB */
1527 62, -51, -9 /* VR VG VB */ 1596 62, -51, -9 /* VR VG VB */
1528 }; 1597 };
1598
1529 for (i = 0; i < 6; i++) { 1599 for (i = 0; i < 6; i++) {
1530 v = uv[i] * sd->colors / COLOR_DEF; 1600 v = uv[i] * sd->colors / COLOR_DEF;
1531 reg8a[i * 2] = v; 1601 reg8a[i * 2] = v;
@@ -1605,6 +1675,8 @@ static void setvflip(struct sd *sd)
1605{ 1675{
1606 u8 comn; 1676 u8 comn;
1607 1677
1678 if (sd->gspca_dev.ctrl_dis & (1 << VFLIP_IDX))
1679 return;
1608 if (sd->sensor == SENSOR_OV7630) { 1680 if (sd->sensor == SENSOR_OV7630) {
1609 comn = 0x02; 1681 comn = 0x02;
1610 if (!sd->vflip) 1682 if (!sd->vflip)
@@ -1726,8 +1798,9 @@ static int sd_start(struct gspca_dev *gspca_dev)
1726{ 1798{
1727 struct sd *sd = (struct sd *) gspca_dev; 1799 struct sd *sd = (struct sd *) gspca_dev;
1728 int i; 1800 int i;
1729 u8 reg1, reg17; 1801 u8 reg1, reg2, reg17;
1730 const u8 *sn9c1xx; 1802 const u8 *sn9c1xx;
1803 const u8 (*init)[8];
1731 int mode; 1804 int mode;
1732 static const u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f }; 1805 static const u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f };
1733 static const u8 CA[] = { 0x28, 0xd8, 0x14, 0xec }; 1806 static const u8 CA[] = { 0x28, 0xd8, 0x14, 0xec };
@@ -1743,8 +1816,26 @@ static int sd_start(struct gspca_dev *gspca_dev)
1743 0x21); /* JPEG 422 */ 1816 0x21); /* JPEG 422 */
1744 jpeg_set_qual(sd->jpeg_hdr, sd->quality); 1817 jpeg_set_qual(sd->jpeg_hdr, sd->quality);
1745 1818
1746 sn9c1xx = sn_tb[(int) sd->sensor]; 1819 /* initialize the bridge */
1747 configure_gpio(gspca_dev, sn9c1xx); 1820 sn9c1xx = sn_tb[sd->sensor];
1821 bridge_init(gspca_dev, sn9c1xx);
1822
1823 /* initialize the sensor */
1824 i2c_w_seq(gspca_dev, sensor_init[sd->sensor]);
1825
1826 switch (sd->sensor) {
1827 case SENSOR_OM6802:
1828 reg2 = 0x71;
1829 break;
1830 case SENSOR_SP80708:
1831 reg2 = 0x62;
1832 break;
1833 default:
1834 reg2 = 0x40;
1835 break;
1836 }
1837 reg_w1(gspca_dev, 0x02, reg2);
1838 reg_w1(gspca_dev, 0x02, reg2);
1748 1839
1749 reg_w1(gspca_dev, 0x15, sn9c1xx[0x15]); 1840 reg_w1(gspca_dev, 0x15, sn9c1xx[0x15]);
1750 reg_w1(gspca_dev, 0x16, sn9c1xx[0x16]); 1841 reg_w1(gspca_dev, 0x16, sn9c1xx[0x16]);
@@ -1771,6 +1862,9 @@ static int sd_start(struct gspca_dev *gspca_dev)
1771 case SENSOR_OV7660: 1862 case SENSOR_OV7660:
1772 reg17 = 0xa0; 1863 reg17 = 0xa0;
1773 break; 1864 break;
1865 case SENSOR_PO1030:
1866 reg17 = 0xa0;
1867 break;
1774 default: 1868 default:
1775 reg17 = 0x60; 1869 reg17 = 0x60;
1776 break; 1870 break;
@@ -1791,6 +1885,10 @@ static int sd_start(struct gspca_dev *gspca_dev)
1791 reg_w1(gspca_dev, 0x9a, 0x07); 1885 reg_w1(gspca_dev, 0x9a, 0x07);
1792 reg_w1(gspca_dev, 0x99, 0x59); 1886 reg_w1(gspca_dev, 0x99, 0x59);
1793 break; 1887 break;
1888 case SENSOR_OM6802:
1889 reg_w1(gspca_dev, 0x9a, 0x08);
1890 reg_w1(gspca_dev, 0x99, 0x10);
1891 break;
1794 case SENSOR_OV7648: 1892 case SENSOR_OV7648:
1795 reg_w1(gspca_dev, 0x9a, 0x0a); 1893 reg_w1(gspca_dev, 0x9a, 0x0a);
1796 reg_w1(gspca_dev, 0x99, 0x60); 1894 reg_w1(gspca_dev, 0x99, 0x60);
@@ -1806,21 +1904,20 @@ static int sd_start(struct gspca_dev *gspca_dev)
1806 break; 1904 break;
1807 } 1905 }
1808 1906
1809 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; 1907 reg_w(gspca_dev, 0x84, reg84, sizeof reg84);
1908 reg_w1(gspca_dev, 0x05, sn9c1xx[5]); /* red */
1909 reg_w1(gspca_dev, 0x07, sn9c1xx[7]); /* green */
1910 reg_w1(gspca_dev, 0x06, sn9c1xx[6]); /* blue */
1911
1912 init = NULL;
1913 mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
1810 if (mode) 1914 if (mode)
1811 reg1 = 0x46; /* 320x240: clk 48Mhz, video trf enable */ 1915 reg1 = 0x46; /* 320x240: clk 48Mhz, video trf enable */
1812 else 1916 else
1813 reg1 = 0x06; /* 640x480: clk 24Mhz, video trf enable */ 1917 reg1 = 0x06; /* 640x480: clk 24Mhz, video trf enable */
1814 reg17 = 0x61; /* 0x:20: enable sensor clock */ 1918 reg17 = 0x61; /* 0x:20: enable sensor clock */
1815 switch (sd->sensor) { 1919 switch (sd->sensor) {
1816 case SENSOR_HV7131R:
1817 hv7131R_InitSensor(gspca_dev);
1818 break;
1819 case SENSOR_MI0360:
1820 mi0360_InitSensor(gspca_dev);
1821 break;
1822 case SENSOR_MO4000: 1920 case SENSOR_MO4000:
1823 mo4000_InitSensor(gspca_dev);
1824 if (mode) { 1921 if (mode) {
1825/* reg1 = 0x46; * 320 clk 48Mhz 60fp/s */ 1922/* reg1 = 0x46; * 320 clk 48Mhz 60fp/s */
1826 reg1 = 0x06; /* clk 24Mz */ 1923 reg1 = 0x06; /* clk 24Mz */
@@ -1830,7 +1927,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
1830 } 1927 }
1831 break; 1928 break;
1832 case SENSOR_MT9V111: 1929 case SENSOR_MT9V111:
1833 mt9v111_InitSensor(gspca_dev); 1930 init = mt9v111_sensor_param1;
1834 if (mode) { 1931 if (mode) {
1835 reg1 = 0x04; /* 320 clk 48Mhz */ 1932 reg1 = 0x04; /* 320 clk 48Mhz */
1836 } else { 1933 } else {
@@ -1839,22 +1936,21 @@ static int sd_start(struct gspca_dev *gspca_dev)
1839 } 1936 }
1840 break; 1937 break;
1841 case SENSOR_OM6802: 1938 case SENSOR_OM6802:
1842 om6802_InitSensor(gspca_dev); 1939 init = om6802_sensor_param1;
1843 reg17 = 0x64; /* 640 MCKSIZE */ 1940 reg17 = 0x64; /* 640 MCKSIZE */
1844 break; 1941 break;
1845 case SENSOR_OV7630: 1942 case SENSOR_OV7630:
1846 ov7630_InitSensor(gspca_dev);
1847 setvflip(sd); 1943 setvflip(sd);
1848 reg17 = 0xe2; 1944 reg17 = 0xe2;
1849 reg1 = 0x44; 1945 reg1 = 0x44;
1850 break; 1946 break;
1851 case SENSOR_OV7648: 1947 case SENSOR_OV7648:
1852 ov7648_InitSensor(gspca_dev); 1948 init = ov7648_sensor_param1;
1853 reg17 = 0x21; 1949 reg17 = 0x21;
1854/* reg1 = 0x42; * 42 - 46? */ 1950/* reg1 = 0x42; * 42 - 46? */
1855 break; 1951 break;
1856 case SENSOR_OV7660: 1952 case SENSOR_OV7660:
1857 ov7660_InitSensor(gspca_dev); 1953 init = ov7660_sensor_param1;
1858 if (sd->bridge == BRIDGE_SN9C120) { 1954 if (sd->bridge == BRIDGE_SN9C120) {
1859 if (mode) { /* 320x240 - 160x120 */ 1955 if (mode) { /* 320x240 - 160x120 */
1860 reg17 = 0xa2; 1956 reg17 = 0xa2;
@@ -1866,9 +1962,14 @@ static int sd_start(struct gspca_dev *gspca_dev)
1866 * inverse power down */ 1962 * inverse power down */
1867 } 1963 }
1868 break; 1964 break;
1965 case SENSOR_PO1030:
1966 init = po1030_sensor_param1;
1967 reg17 = 0xa2;
1968 reg1 = 0x44;
1969 break;
1869 default: 1970 default:
1870/* case SENSOR_SP80708: */ 1971/* case SENSOR_SP80708: */
1871 sp80708_InitSensor(gspca_dev); 1972 init = sp80708_sensor_param1;
1872 if (mode) { 1973 if (mode) {
1873/*?? reg1 = 0x04; * 320 clk 48Mhz */ 1974/*?? reg1 = 0x04; * 320 clk 48Mhz */
1874 } else { 1975 } else {
@@ -1877,6 +1978,13 @@ static int sd_start(struct gspca_dev *gspca_dev)
1877 } 1978 }
1878 break; 1979 break;
1879 } 1980 }
1981
1982 /* more sensor initialization - param1 */
1983 if (init != NULL) {
1984 i2c_w_seq(gspca_dev, init);
1985/* init = NULL; */
1986 }
1987
1880 reg_w(gspca_dev, 0xc0, C0, 6); 1988 reg_w(gspca_dev, 0xc0, C0, 6);
1881 reg_w(gspca_dev, 0xca, CA, 4); 1989 reg_w(gspca_dev, 0xca, CA, 4);
1882 switch (sd->sensor) { 1990 switch (sd->sensor) {
@@ -1891,6 +1999,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
1891 break; 1999 break;
1892 } 2000 }
1893 2001
2002
1894 /* here change size mode 0 -> VGA; 1 -> CIF */ 2003 /* here change size mode 0 -> VGA; 1 -> CIF */
1895 sd->reg18 = sn9c1xx[0x18] | (mode << 4) | 0x40; 2004 sd->reg18 = sn9c1xx[0x18] | (mode << 4) | 0x40;
1896 reg_w1(gspca_dev, 0x18, sd->reg18); 2005 reg_w1(gspca_dev, 0x18, sd->reg18);
@@ -1898,6 +2007,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
1898 2007
1899 reg_w1(gspca_dev, 0x17, reg17); 2008 reg_w1(gspca_dev, 0x17, reg17);
1900 reg_w1(gspca_dev, 0x01, reg1); 2009 reg_w1(gspca_dev, 0x01, reg1);
2010
1901 switch (sd->sensor) { 2011 switch (sd->sensor) {
1902 case SENSOR_OV7630: 2012 case SENSOR_OV7630:
1903 setvflip(sd); 2013 setvflip(sd);
@@ -1937,14 +2047,11 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
1937 /* fall thru */ 2047 /* fall thru */
1938 case SENSOR_MT9V111: 2048 case SENSOR_MT9V111:
1939 case SENSOR_OV7630: 2049 case SENSOR_OV7630:
2050 case SENSOR_PO1030:
1940 data = 0x29; 2051 data = 0x29;
1941 break; 2052 break;
1942 default:
1943/* case SENSOR_MO4000: */
1944/* case SENSOR_OV7660: */
1945 break;
1946 } 2053 }
1947 sn9c1xx = sn_tb[(int) sd->sensor]; 2054 sn9c1xx = sn_tb[sd->sensor];
1948 reg_w1(gspca_dev, 0x01, sn9c1xx[1]); 2055 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
1949 reg_w1(gspca_dev, 0x17, sn9c1xx[0x17]); 2056 reg_w1(gspca_dev, 0x17, sn9c1xx[0x17]);
1950 reg_w1(gspca_dev, 0x01, sn9c1xx[1]); 2057 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
@@ -1987,11 +2094,19 @@ static void do_autogain(struct gspca_dev *gspca_dev)
1987 sd->exposure = setexposure(gspca_dev, 2094 sd->exposure = setexposure(gspca_dev,
1988 (unsigned int) (expotimes << 8)); 2095 (unsigned int) (expotimes << 8));
1989 break; 2096 break;
2097 case SENSOR_OM6802:
2098 expotimes = sd->exposure;
2099 expotimes += (luma_mean - delta) >> 2;
2100 if (expotimes < 0)
2101 expotimes = 0;
2102 sd->exposure = setexposure(gspca_dev,
2103 (unsigned int) expotimes);
2104 setredblue(gspca_dev);
2105 break;
1990 default: 2106 default:
1991/* case SENSOR_MO4000: */ 2107/* case SENSOR_MO4000: */
1992/* case SENSOR_MI0360: */ 2108/* case SENSOR_MI0360: */
1993/* case SENSOR_MT9V111: */ 2109/* case SENSOR_MT9V111: */
1994/* case SENSOR_OM6802: */
1995 expotimes = sd->exposure; 2110 expotimes = sd->exposure;
1996 expotimes += (luma_mean - delta) >> 6; 2111 expotimes += (luma_mean - delta) >> 6;
1997 if (expotimes < 0) 2112 if (expotimes < 0)
@@ -2007,7 +2122,6 @@ static void do_autogain(struct gspca_dev *gspca_dev)
2007/* scan the URB packets */ 2122/* scan the URB packets */
2008/* This function is run at interrupt level. */ 2123/* This function is run at interrupt level. */
2009static void sd_pkt_scan(struct gspca_dev *gspca_dev, 2124static void sd_pkt_scan(struct gspca_dev *gspca_dev,
2010 struct gspca_frame *frame, /* target */
2011 u8 *data, /* isoc packet */ 2125 u8 *data, /* isoc packet */
2012 int len) /* iso packet length */ 2126 int len) /* iso packet length */
2013{ 2127{
@@ -2019,7 +2133,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
2019 2133
2020 /* end of frame */ 2134 /* end of frame */
2021 gspca_frame_add(gspca_dev, LAST_PACKET, 2135 gspca_frame_add(gspca_dev, LAST_PACKET,
2022 frame, data, sof + 2); 2136 data, sof + 2);
2023 if (sd->ag_cnt < 0) 2137 if (sd->ag_cnt < 0)
2024 return; 2138 return;
2025/* w1 w2 w3 */ 2139/* w1 w2 w3 */
@@ -2042,10 +2156,10 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
2042 if (gspca_dev->last_packet_type == LAST_PACKET) { 2156 if (gspca_dev->last_packet_type == LAST_PACKET) {
2043 2157
2044 /* put the JPEG 422 header */ 2158 /* put the JPEG 422 header */
2045 gspca_frame_add(gspca_dev, FIRST_PACKET, frame, 2159 gspca_frame_add(gspca_dev, FIRST_PACKET,
2046 sd->jpeg_hdr, JPEG_HDR_SZ); 2160 sd->jpeg_hdr, JPEG_HDR_SZ);
2047 } 2161 }
2048 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); 2162 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
2049} 2163}
2050 2164
2051static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) 2165static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
@@ -2295,69 +2409,69 @@ static const struct sd_desc sd_desc = {
2295}; 2409};
2296 2410
2297/* -- module initialisation -- */ 2411/* -- module initialisation -- */
2298#define BSI(bridge, sensor, i2c_addr) \ 2412#define BS(bridge, sensor) \
2299 .driver_info = (BRIDGE_ ## bridge << 16) \ 2413 .driver_info = (BRIDGE_ ## bridge << 16) \
2300 | (SENSOR_ ## sensor << 8) \ 2414 | SENSOR_ ## sensor
2301 | (i2c_addr)
2302static const __devinitdata struct usb_device_id device_table[] = { 2415static const __devinitdata struct usb_device_id device_table[] = {
2303#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE 2416#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
2304 {USB_DEVICE(0x0458, 0x7025), BSI(SN9C120, MI0360, 0x5d)}, 2417 {USB_DEVICE(0x0458, 0x7025), BS(SN9C120, MI0360)},
2305 {USB_DEVICE(0x0458, 0x702e), BSI(SN9C120, OV7660, 0x21)}, 2418 {USB_DEVICE(0x0458, 0x702e), BS(SN9C120, OV7660)},
2306#endif 2419#endif
2307 {USB_DEVICE(0x045e, 0x00f5), BSI(SN9C105, OV7660, 0x21)}, 2420 {USB_DEVICE(0x045e, 0x00f5), BS(SN9C105, OV7660)},
2308 {USB_DEVICE(0x045e, 0x00f7), BSI(SN9C105, OV7660, 0x21)}, 2421 {USB_DEVICE(0x045e, 0x00f7), BS(SN9C105, OV7660)},
2309 {USB_DEVICE(0x0471, 0x0327), BSI(SN9C105, MI0360, 0x5d)}, 2422 {USB_DEVICE(0x0471, 0x0327), BS(SN9C105, MI0360)},
2310 {USB_DEVICE(0x0471, 0x0328), BSI(SN9C105, MI0360, 0x5d)}, 2423 {USB_DEVICE(0x0471, 0x0328), BS(SN9C105, MI0360)},
2311 {USB_DEVICE(0x0471, 0x0330), BSI(SN9C105, MI0360, 0x5d)}, 2424 {USB_DEVICE(0x0471, 0x0330), BS(SN9C105, MI0360)},
2312 {USB_DEVICE(0x06f8, 0x3004), BSI(SN9C105, OV7660, 0x21)}, 2425 {USB_DEVICE(0x06f8, 0x3004), BS(SN9C105, OV7660)},
2313 {USB_DEVICE(0x06f8, 0x3008), BSI(SN9C105, OV7660, 0x21)}, 2426 {USB_DEVICE(0x06f8, 0x3008), BS(SN9C105, OV7660)},
2314 {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, HV7131R, 0x11)}, 2427/* {USB_DEVICE(0x0c45, 0x603a), BS(SN9C102P, OV7648)}, */
2315/* bw600.inf: 2428 {USB_DEVICE(0x0c45, 0x6040), BS(SN9C102P, HV7131R)},
2316 {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, MI0360, 0x5d)}, */ 2429/* {USB_DEVICE(0x0c45, 0x607a), BS(SN9C102P, OV7648)}, */
2317/* {USB_DEVICE(0x0c45, 0x603a), BSI(SN9C102P, OV7648, 0x??)}, */ 2430/* {USB_DEVICE(0x0c45, 0x607b), BS(SN9C102P, OV7660)}, */
2318/* {USB_DEVICE(0x0c45, 0x607a), BSI(SN9C102P, OV7648, 0x??)}, */ 2431 {USB_DEVICE(0x0c45, 0x607c), BS(SN9C102P, HV7131R)},
2319 {USB_DEVICE(0x0c45, 0x607c), BSI(SN9C102P, HV7131R, 0x11)}, 2432/* {USB_DEVICE(0x0c45, 0x607e), BS(SN9C102P, OV7630)}, */
2320/* {USB_DEVICE(0x0c45, 0x607e), BSI(SN9C102P, OV7630, 0x??)}, */ 2433 {USB_DEVICE(0x0c45, 0x60c0), BS(SN9C105, MI0360)},
2321 {USB_DEVICE(0x0c45, 0x60c0), BSI(SN9C105, MI0360, 0x5d)}, 2434/* {USB_DEVICE(0x0c45, 0x60c2), BS(SN9C105, P1030xC)}, */
2322/* {USB_DEVICE(0x0c45, 0x60c8), BSI(SN9C105, OM6802, 0x??)}, */ 2435/* {USB_DEVICE(0x0c45, 0x60c8), BS(SN9C105, OM6802)}, */
2323/* {USB_DEVICE(0x0c45, 0x60cc), BSI(SN9C105, HV7131GP, 0x??)}, */ 2436/* {USB_DEVICE(0x0c45, 0x60cc), BS(SN9C105, HV7131GP)}, */
2324 {USB_DEVICE(0x0c45, 0x60ec), BSI(SN9C105, MO4000, 0x21)}, 2437 {USB_DEVICE(0x0c45, 0x60ec), BS(SN9C105, MO4000)},
2325/* {USB_DEVICE(0x0c45, 0x60ef), BSI(SN9C105, ICM105C, 0x??)}, */ 2438/* {USB_DEVICE(0x0c45, 0x60ef), BS(SN9C105, ICM105C)}, */
2326/* {USB_DEVICE(0x0c45, 0x60fa), BSI(SN9C105, OV7648, 0x??)}, */ 2439/* {USB_DEVICE(0x0c45, 0x60fa), BS(SN9C105, OV7648)}, */
2327 {USB_DEVICE(0x0c45, 0x60fb), BSI(SN9C105, OV7660, 0x21)}, 2440 {USB_DEVICE(0x0c45, 0x60fb), BS(SN9C105, OV7660)},
2328#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE 2441#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
2329 {USB_DEVICE(0x0c45, 0x60fc), BSI(SN9C105, HV7131R, 0x11)}, 2442 {USB_DEVICE(0x0c45, 0x60fc), BS(SN9C105, HV7131R)},
2330 {USB_DEVICE(0x0c45, 0x60fe), BSI(SN9C105, OV7630, 0x21)}, 2443 {USB_DEVICE(0x0c45, 0x60fe), BS(SN9C105, OV7630)},
2331#endif 2444#endif
2332 {USB_DEVICE(0x0c45, 0x6100), BSI(SN9C120, MI0360, 0x5d)}, /*sn9c128*/ 2445 {USB_DEVICE(0x0c45, 0x6100), BS(SN9C120, MI0360)}, /*sn9c128*/
2333/* {USB_DEVICE(0x0c45, 0x6102), BSI(SN9C120, PO2030N, ??)}, */ 2446/* {USB_DEVICE(0x0c45, 0x6102), BS(SN9C120, P1030xC)}, */
2334/* {USB_DEVICE(0x0c45, 0x6108), BSI(SN9C120, OM6802, 0x21)}, */ 2447/* {USB_DEVICE(0x0c45, 0x6108), BS(SN9C120, OM6802)}, */
2335 {USB_DEVICE(0x0c45, 0x610a), BSI(SN9C120, OV7648, 0x21)}, /*sn9c128*/ 2448 {USB_DEVICE(0x0c45, 0x610a), BS(SN9C120, OV7648)}, /*sn9c128*/
2336 {USB_DEVICE(0x0c45, 0x610b), BSI(SN9C120, OV7660, 0x21)}, /*sn9c128*/ 2449 {USB_DEVICE(0x0c45, 0x610b), BS(SN9C120, OV7660)}, /*sn9c128*/
2337 {USB_DEVICE(0x0c45, 0x610c), BSI(SN9C120, HV7131R, 0x11)}, /*sn9c128*/ 2450 {USB_DEVICE(0x0c45, 0x610c), BS(SN9C120, HV7131R)}, /*sn9c128*/
2338 {USB_DEVICE(0x0c45, 0x610e), BSI(SN9C120, OV7630, 0x21)}, /*sn9c128*/ 2451 {USB_DEVICE(0x0c45, 0x610e), BS(SN9C120, OV7630)}, /*sn9c128*/
2339/* {USB_DEVICE(0x0c45, 0x6122), BSI(SN9C110, ICM105C, 0x??)}, */ 2452/* {USB_DEVICE(0x0c45, 0x610f), BS(SN9C120, S5K53BEB)}, */
2340/* {USB_DEVICE(0x0c45, 0x6123), BSI(SN9C110, SanyoCCD, 0x??)}, */ 2453/* {USB_DEVICE(0x0c45, 0x6122), BS(SN9C110, ICM105C)}, */
2341 {USB_DEVICE(0x0c45, 0x6128), BSI(SN9C110, OM6802, 0x21)}, /*sn9c325?*/ 2454/* {USB_DEVICE(0x0c45, 0x6123), BS(SN9C110, SanyoCCD)}, */
2455 {USB_DEVICE(0x0c45, 0x6128), BS(SN9C120, OM6802)}, /*sn9c325?*/
2342/*bw600.inf:*/ 2456/*bw600.inf:*/
2343 {USB_DEVICE(0x0c45, 0x612a), BSI(SN9C120, OV7648, 0x21)}, /*sn9c110?*/ 2457 {USB_DEVICE(0x0c45, 0x612a), BS(SN9C120, OV7648)}, /*sn9c325?*/
2344 {USB_DEVICE(0x0c45, 0x612c), BSI(SN9C110, MO4000, 0x21)}, 2458 {USB_DEVICE(0x0c45, 0x612c), BS(SN9C110, MO4000)},
2345 {USB_DEVICE(0x0c45, 0x612e), BSI(SN9C110, OV7630, 0x21)}, 2459 {USB_DEVICE(0x0c45, 0x612e), BS(SN9C110, OV7630)},
2346/* {USB_DEVICE(0x0c45, 0x612f), BSI(SN9C110, ICM105C, 0x??)}, */ 2460/* {USB_DEVICE(0x0c45, 0x612f), BS(SN9C110, ICM105C)}, */
2347#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE 2461#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
2348 {USB_DEVICE(0x0c45, 0x6130), BSI(SN9C120, MI0360, 0x5d)}, 2462 {USB_DEVICE(0x0c45, 0x6130), BS(SN9C120, MI0360)},
2349#endif 2463#endif
2350/* {USB_DEVICE(0x0c45, 0x6132), BSI(SN9C120, OV7670, 0x21)}, */ 2464/* {USB_DEVICE(0x0c45, 0x6132), BS(SN9C120, OV7670)}, */
2351 {USB_DEVICE(0x0c45, 0x6138), BSI(SN9C120, MO4000, 0x21)}, 2465 {USB_DEVICE(0x0c45, 0x6138), BS(SN9C120, MO4000)},
2352 {USB_DEVICE(0x0c45, 0x613a), BSI(SN9C120, OV7648, 0x21)}, 2466 {USB_DEVICE(0x0c45, 0x613a), BS(SN9C120, OV7648)},
2353#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE 2467#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
2354 {USB_DEVICE(0x0c45, 0x613b), BSI(SN9C120, OV7660, 0x21)}, 2468 {USB_DEVICE(0x0c45, 0x613b), BS(SN9C120, OV7660)},
2355#endif 2469#endif
2356 {USB_DEVICE(0x0c45, 0x613c), BSI(SN9C120, HV7131R, 0x11)}, 2470 {USB_DEVICE(0x0c45, 0x613c), BS(SN9C120, HV7131R)},
2357 {USB_DEVICE(0x0c45, 0x613e), BSI(SN9C120, OV7630, 0x21)}, 2471 {USB_DEVICE(0x0c45, 0x613e), BS(SN9C120, OV7630)},
2358/* {USB_DEVICE(0x0c45, 0x6142), BSI(SN9C120, PO2030N, ??)}, *sn9c120b*/ 2472/* {USB_DEVICE(0x0c45, 0x6142), BS(SN9C120, PO2030N)}, *sn9c120b*/
2359 {USB_DEVICE(0x0c45, 0x6143), BSI(SN9C120, SP80708, 0x18)}, /*sn9c120b*/ 2473 {USB_DEVICE(0x0c45, 0x6143), BS(SN9C120, SP80708)}, /*sn9c120b*/
2360 {USB_DEVICE(0x0c45, 0x6148), BSI(SN9C120, OM6802, 0x21)}, /*sn9c120b*/ 2474 {USB_DEVICE(0x0c45, 0x6148), BS(SN9C120, OM6802)}, /*sn9c120b*/
2361 {} 2475 {}
2362}; 2476};
2363MODULE_DEVICE_TABLE(usb, device_table); 2477MODULE_DEVICE_TABLE(usb, device_table);
diff --git a/drivers/media/video/gspca/spca500.c b/drivers/media/video/gspca/spca500.c
index 7dbd5eea6cc0..fe46868a87f2 100644
--- a/drivers/media/video/gspca/spca500.c
+++ b/drivers/media/video/gspca/spca500.c
@@ -899,8 +899,7 @@ static void sd_stop0(struct gspca_dev *gspca_dev)
899} 899}
900 900
901static void sd_pkt_scan(struct gspca_dev *gspca_dev, 901static void sd_pkt_scan(struct gspca_dev *gspca_dev,
902 struct gspca_frame *frame, /* target */ 902 u8 *data, /* isoc packet */
903 __u8 *data, /* isoc packet */
904 int len) /* iso packet length */ 903 int len) /* iso packet length */
905{ 904{
906 struct sd *sd = (struct sd *) gspca_dev; 905 struct sd *sd = (struct sd *) gspca_dev;
@@ -913,11 +912,11 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
913/* gspca_dev->last_packet_type = DISCARD_PACKET; */ 912/* gspca_dev->last_packet_type = DISCARD_PACKET; */
914 return; 913 return;
915 } 914 }
916 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, 915 gspca_frame_add(gspca_dev, LAST_PACKET,
917 ffd9, 2); 916 ffd9, 2);
918 917
919 /* put the JPEG header in the new frame */ 918 /* put the JPEG header in the new frame */
920 gspca_frame_add(gspca_dev, FIRST_PACKET, frame, 919 gspca_frame_add(gspca_dev, FIRST_PACKET,
921 sd->jpeg_hdr, JPEG_HDR_SZ); 920 sd->jpeg_hdr, JPEG_HDR_SZ);
922 921
923 data += SPCA500_OFFSET_DATA; 922 data += SPCA500_OFFSET_DATA;
@@ -931,7 +930,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
931 i = 0; 930 i = 0;
932 do { 931 do {
933 if (data[i] == 0xff) { 932 if (data[i] == 0xff) {
934 gspca_frame_add(gspca_dev, INTER_PACKET, frame, 933 gspca_frame_add(gspca_dev, INTER_PACKET,
935 data, i + 1); 934 data, i + 1);
936 len -= i; 935 len -= i;
937 data += i; 936 data += i;
@@ -940,7 +939,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
940 } 939 }
941 i++; 940 i++;
942 } while (i < len); 941 } while (i < len);
943 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); 942 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
944} 943}
945 944
946static void setbrightness(struct gspca_dev *gspca_dev) 945static void setbrightness(struct gspca_dev *gspca_dev)
diff --git a/drivers/media/video/gspca/spca501.c b/drivers/media/video/gspca/spca501.c
index 66f9f0056146..6761a3048a98 100644
--- a/drivers/media/video/gspca/spca501.c
+++ b/drivers/media/video/gspca/spca501.c
@@ -2032,20 +2032,15 @@ static void sd_stop0(struct gspca_dev *gspca_dev)
2032} 2032}
2033 2033
2034static void sd_pkt_scan(struct gspca_dev *gspca_dev, 2034static void sd_pkt_scan(struct gspca_dev *gspca_dev,
2035 struct gspca_frame *frame, /* target */ 2035 u8 *data, /* isoc packet */
2036 __u8 *data, /* isoc packet */
2037 int len) /* iso packet length */ 2036 int len) /* iso packet length */
2038{ 2037{
2039 switch (data[0]) { 2038 switch (data[0]) {
2040 case 0: /* start of frame */ 2039 case 0: /* start of frame */
2041 frame = gspca_frame_add(gspca_dev, 2040 gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
2042 LAST_PACKET,
2043 frame,
2044 data, 0);
2045 data += SPCA501_OFFSET_DATA; 2041 data += SPCA501_OFFSET_DATA;
2046 len -= SPCA501_OFFSET_DATA; 2042 len -= SPCA501_OFFSET_DATA;
2047 gspca_frame_add(gspca_dev, FIRST_PACKET, frame, 2043 gspca_frame_add(gspca_dev, FIRST_PACKET, data, len);
2048 data, len);
2049 return; 2044 return;
2050 case 0xff: /* drop */ 2045 case 0xff: /* drop */
2051/* gspca_dev->last_packet_type = DISCARD_PACKET; */ 2046/* gspca_dev->last_packet_type = DISCARD_PACKET; */
@@ -2053,8 +2048,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
2053 } 2048 }
2054 data++; 2049 data++;
2055 len--; 2050 len--;
2056 gspca_frame_add(gspca_dev, INTER_PACKET, frame, 2051 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
2057 data, len);
2058} 2052}
2059 2053
2060static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) 2054static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
diff --git a/drivers/media/video/gspca/spca505.c b/drivers/media/video/gspca/spca505.c
index ea8c9fe2e961..0f9232ff1281 100644
--- a/drivers/media/video/gspca/spca505.c
+++ b/drivers/media/video/gspca/spca505.c
@@ -739,26 +739,22 @@ static void sd_stop0(struct gspca_dev *gspca_dev)
739} 739}
740 740
741static void sd_pkt_scan(struct gspca_dev *gspca_dev, 741static void sd_pkt_scan(struct gspca_dev *gspca_dev,
742 struct gspca_frame *frame, /* target */
743 u8 *data, /* isoc packet */ 742 u8 *data, /* isoc packet */
744 int len) /* iso packet length */ 743 int len) /* iso packet length */
745{ 744{
746 switch (data[0]) { 745 switch (data[0]) {
747 case 0: /* start of frame */ 746 case 0: /* start of frame */
748 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, 747 gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
749 data, 0);
750 data += SPCA50X_OFFSET_DATA; 748 data += SPCA50X_OFFSET_DATA;
751 len -= SPCA50X_OFFSET_DATA; 749 len -= SPCA50X_OFFSET_DATA;
752 gspca_frame_add(gspca_dev, FIRST_PACKET, frame, 750 gspca_frame_add(gspca_dev, FIRST_PACKET, data, len);
753 data, len);
754 break; 751 break;
755 case 0xff: /* drop */ 752 case 0xff: /* drop */
756 break; 753 break;
757 default: 754 default:
758 data += 1; 755 data += 1;
759 len -= 1; 756 len -= 1;
760 gspca_frame_add(gspca_dev, INTER_PACKET, frame, 757 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
761 data, len);
762 break; 758 break;
763 } 759 }
764} 760}
diff --git a/drivers/media/video/gspca/spca506.c b/drivers/media/video/gspca/spca506.c
index a199298a6419..ab28cc23e415 100644
--- a/drivers/media/video/gspca/spca506.c
+++ b/drivers/media/video/gspca/spca506.c
@@ -543,18 +543,15 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
543} 543}
544 544
545static void sd_pkt_scan(struct gspca_dev *gspca_dev, 545static void sd_pkt_scan(struct gspca_dev *gspca_dev,
546 struct gspca_frame *frame, /* target */ 546 u8 *data, /* isoc packet */
547 __u8 *data, /* isoc packet */
548 int len) /* iso packet length */ 547 int len) /* iso packet length */
549{ 548{
550 switch (data[0]) { 549 switch (data[0]) {
551 case 0: /* start of frame */ 550 case 0: /* start of frame */
552 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, 551 gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
553 data, 0);
554 data += SPCA50X_OFFSET_DATA; 552 data += SPCA50X_OFFSET_DATA;
555 len -= SPCA50X_OFFSET_DATA; 553 len -= SPCA50X_OFFSET_DATA;
556 gspca_frame_add(gspca_dev, FIRST_PACKET, frame, 554 gspca_frame_add(gspca_dev, FIRST_PACKET, data, len);
557 data, len);
558 break; 555 break;
559 case 0xff: /* drop */ 556 case 0xff: /* drop */
560/* gspca_dev->last_packet_type = DISCARD_PACKET; */ 557/* gspca_dev->last_packet_type = DISCARD_PACKET; */
@@ -562,8 +559,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
562 default: 559 default:
563 data += 1; 560 data += 1;
564 len -= 1; 561 len -= 1;
565 gspca_frame_add(gspca_dev, INTER_PACKET, frame, 562 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
566 data, len);
567 break; 563 break;
568 } 564 }
569} 565}
diff --git a/drivers/media/video/gspca/spca508.c b/drivers/media/video/gspca/spca508.c
index 9696c4caf5c9..4d8e6cf75d55 100644
--- a/drivers/media/video/gspca/spca508.c
+++ b/drivers/media/video/gspca/spca508.c
@@ -1447,26 +1447,22 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
1447} 1447}
1448 1448
1449static void sd_pkt_scan(struct gspca_dev *gspca_dev, 1449static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1450 struct gspca_frame *frame, /* target */
1451 u8 *data, /* isoc packet */ 1450 u8 *data, /* isoc packet */
1452 int len) /* iso packet length */ 1451 int len) /* iso packet length */
1453{ 1452{
1454 switch (data[0]) { 1453 switch (data[0]) {
1455 case 0: /* start of frame */ 1454 case 0: /* start of frame */
1456 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, 1455 gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
1457 data, 0);
1458 data += SPCA508_OFFSET_DATA; 1456 data += SPCA508_OFFSET_DATA;
1459 len -= SPCA508_OFFSET_DATA; 1457 len -= SPCA508_OFFSET_DATA;
1460 gspca_frame_add(gspca_dev, FIRST_PACKET, frame, 1458 gspca_frame_add(gspca_dev, FIRST_PACKET, data, len);
1461 data, len);
1462 break; 1459 break;
1463 case 0xff: /* drop */ 1460 case 0xff: /* drop */
1464 break; 1461 break;
1465 default: 1462 default:
1466 data += 1; 1463 data += 1;
1467 len -= 1; 1464 len -= 1;
1468 gspca_frame_add(gspca_dev, INTER_PACKET, frame, 1465 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
1469 data, len);
1470 break; 1466 break;
1471 } 1467 }
1472} 1468}
diff --git a/drivers/media/video/gspca/spca561.c b/drivers/media/video/gspca/spca561.c
index 27e82b35f3e7..58c2f0039af1 100644
--- a/drivers/media/video/gspca/spca561.c
+++ b/drivers/media/video/gspca/spca561.c
@@ -779,8 +779,7 @@ static void do_autogain(struct gspca_dev *gspca_dev)
779} 779}
780 780
781static void sd_pkt_scan(struct gspca_dev *gspca_dev, 781static void sd_pkt_scan(struct gspca_dev *gspca_dev,
782 struct gspca_frame *frame, /* target */ 782 u8 *data, /* isoc packet */
783 __u8 *data, /* isoc packet */
784 int len) /* iso packet length */ 783 int len) /* iso packet length */
785{ 784{
786 struct sd *sd = (struct sd *) gspca_dev; 785 struct sd *sd = (struct sd *) gspca_dev;
@@ -788,12 +787,10 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
788 len--; 787 len--;
789 switch (*data++) { /* sequence number */ 788 switch (*data++) { /* sequence number */
790 case 0: /* start of frame */ 789 case 0: /* start of frame */
791 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, 790 gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
792 data, 0);
793 if (data[1] & 0x10) { 791 if (data[1] & 0x10) {
794 /* compressed bayer */ 792 /* compressed bayer */
795 gspca_frame_add(gspca_dev, FIRST_PACKET, 793 gspca_frame_add(gspca_dev, FIRST_PACKET, data, len);
796 frame, data, len);
797 } else { 794 } else {
798 /* raw bayer (with a header, which we skip) */ 795 /* raw bayer (with a header, which we skip) */
799 if (sd->chip_revision == Rev012A) { 796 if (sd->chip_revision == Rev012A) {
@@ -803,14 +800,13 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
803 data += 16; 800 data += 16;
804 len -= 16; 801 len -= 16;
805 } 802 }
806 gspca_frame_add(gspca_dev, FIRST_PACKET, 803 gspca_frame_add(gspca_dev, FIRST_PACKET, data, len);
807 frame, data, len);
808 } 804 }
809 return; 805 return;
810 case 0xff: /* drop (empty mpackets) */ 806 case 0xff: /* drop (empty mpackets) */
811 return; 807 return;
812 } 808 }
813 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); 809 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
814} 810}
815 811
816/* rev 72a only */ 812/* rev 72a only */
diff --git a/drivers/media/video/gspca/sq905.c b/drivers/media/video/gspca/sq905.c
index 715a68f0156e..1fcaca6a87f7 100644
--- a/drivers/media/video/gspca/sq905.c
+++ b/drivers/media/video/gspca/sq905.c
@@ -168,18 +168,22 @@ static int sq905_ack_frame(struct gspca_dev *gspca_dev)
168 * request and read a block of data - see warning on sq905_command. 168 * request and read a block of data - see warning on sq905_command.
169 */ 169 */
170static int 170static int
171sq905_read_data(struct gspca_dev *gspca_dev, u8 *data, int size) 171sq905_read_data(struct gspca_dev *gspca_dev, u8 *data, int size, int need_lock)
172{ 172{
173 int ret; 173 int ret;
174 int act_len; 174 int act_len;
175 175
176 gspca_dev->usb_buf[0] = '\0'; 176 gspca_dev->usb_buf[0] = '\0';
177 if (need_lock)
178 mutex_lock(&gspca_dev->usb_lock);
177 ret = usb_control_msg(gspca_dev->dev, 179 ret = usb_control_msg(gspca_dev->dev,
178 usb_sndctrlpipe(gspca_dev->dev, 0), 180 usb_sndctrlpipe(gspca_dev->dev, 0),
179 USB_REQ_SYNCH_FRAME, /* request */ 181 USB_REQ_SYNCH_FRAME, /* request */
180 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 182 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
181 SQ905_BULK_READ, size, gspca_dev->usb_buf, 183 SQ905_BULK_READ, size, gspca_dev->usb_buf,
182 1, SQ905_CMD_TIMEOUT); 184 1, SQ905_CMD_TIMEOUT);
185 if (need_lock)
186 mutex_unlock(&gspca_dev->usb_lock);
183 if (ret < 0) { 187 if (ret < 0) {
184 PDEBUG(D_ERR, "%s: usb_control_msg failed (%d)", __func__, ret); 188 PDEBUG(D_ERR, "%s: usb_control_msg failed (%d)", __func__, ret);
185 return ret; 189 return ret;
@@ -210,11 +214,9 @@ static void sq905_dostream(struct work_struct *work)
210{ 214{
211 struct sd *dev = container_of(work, struct sd, work_struct); 215 struct sd *dev = container_of(work, struct sd, work_struct);
212 struct gspca_dev *gspca_dev = &dev->gspca_dev; 216 struct gspca_dev *gspca_dev = &dev->gspca_dev;
213 struct gspca_frame *frame;
214 int bytes_left; /* bytes remaining in current frame. */ 217 int bytes_left; /* bytes remaining in current frame. */
215 int data_len; /* size to use for the next read. */ 218 int data_len; /* size to use for the next read. */
216 int header_read; /* true if we have already read the frame header. */ 219 int header_read; /* true if we have already read the frame header. */
217 int discarding; /* true if we failed to get space for frame. */
218 int packet_type; 220 int packet_type;
219 int frame_sz; 221 int frame_sz;
220 int ret; 222 int ret;
@@ -222,7 +224,6 @@ static void sq905_dostream(struct work_struct *work)
222 u8 *buffer; 224 u8 *buffer;
223 225
224 buffer = kmalloc(SQ905_MAX_TRANSFER, GFP_KERNEL | GFP_DMA); 226 buffer = kmalloc(SQ905_MAX_TRANSFER, GFP_KERNEL | GFP_DMA);
225 mutex_lock(&gspca_dev->usb_lock);
226 if (!buffer) { 227 if (!buffer) {
227 PDEBUG(D_ERR, "Couldn't allocate USB buffer"); 228 PDEBUG(D_ERR, "Couldn't allocate USB buffer");
228 goto quit_stream; 229 goto quit_stream;
@@ -232,28 +233,22 @@ static void sq905_dostream(struct work_struct *work)
232 + FRAME_HEADER_LEN; 233 + FRAME_HEADER_LEN;
233 234
234 while (gspca_dev->present && gspca_dev->streaming) { 235 while (gspca_dev->present && gspca_dev->streaming) {
235 /* Need a short delay to ensure streaming flag was set by
236 * gspca and to make sure gspca can grab the mutex. */
237 mutex_unlock(&gspca_dev->usb_lock);
238 msleep(1);
239
240 /* request some data and then read it until we have 236 /* request some data and then read it until we have
241 * a complete frame. */ 237 * a complete frame. */
242 bytes_left = frame_sz; 238 bytes_left = frame_sz;
243 header_read = 0; 239 header_read = 0;
244 discarding = 0;
245 240
246 while (bytes_left > 0) { 241 /* Note we do not check for gspca_dev->streaming here, as
242 we must finish reading an entire frame, otherwise the
243 next time we stream we start reading in the middle of a
244 frame. */
245 while (bytes_left > 0 && gspca_dev->present) {
247 data_len = bytes_left > SQ905_MAX_TRANSFER ? 246 data_len = bytes_left > SQ905_MAX_TRANSFER ?
248 SQ905_MAX_TRANSFER : bytes_left; 247 SQ905_MAX_TRANSFER : bytes_left;
249 mutex_lock(&gspca_dev->usb_lock); 248 ret = sq905_read_data(gspca_dev, buffer, data_len, 1);
250 if (!gspca_dev->present)
251 goto quit_stream;
252 ret = sq905_read_data(gspca_dev, buffer, data_len);
253 if (ret < 0) 249 if (ret < 0)
254 goto quit_stream; 250 goto quit_stream;
255 mutex_unlock(&gspca_dev->usb_lock); 251 PDEBUG(D_PACK,
256 PDEBUG(D_STREAM,
257 "Got %d bytes out of %d for frame", 252 "Got %d bytes out of %d for frame",
258 data_len, bytes_left); 253 data_len, bytes_left);
259 bytes_left -= data_len; 254 bytes_left -= data_len;
@@ -270,34 +265,30 @@ static void sq905_dostream(struct work_struct *work)
270 } else { 265 } else {
271 packet_type = INTER_PACKET; 266 packet_type = INTER_PACKET;
272 } 267 }
273 frame = gspca_get_i_frame(gspca_dev); 268 gspca_frame_add(gspca_dev, packet_type,
274 if (frame && !discarding) { 269 data, data_len);
275 frame = gspca_frame_add(gspca_dev, packet_type, 270 /* If entire frame fits in one packet we still
276 frame, data, data_len); 271 need to add a LAST_PACKET */
277 /* If entire frame fits in one packet we still 272 if (packet_type == FIRST_PACKET &&
278 need to add a LAST_PACKET */ 273 bytes_left == 0)
279 if (packet_type == FIRST_PACKET && 274 gspca_frame_add(gspca_dev, LAST_PACKET,
280 bytes_left == 0) 275 NULL, 0);
281 frame = gspca_frame_add(gspca_dev, 276 }
282 LAST_PACKET, 277 if (gspca_dev->present) {
283 frame, data, 0); 278 /* acknowledge the frame */
284 } else { 279 mutex_lock(&gspca_dev->usb_lock);
285 discarding = 1; 280 ret = sq905_ack_frame(gspca_dev);
286 } 281 mutex_unlock(&gspca_dev->usb_lock);
282 if (ret < 0)
283 goto quit_stream;
287 } 284 }
288 /* acknowledge the frame */
289 mutex_lock(&gspca_dev->usb_lock);
290 if (!gspca_dev->present)
291 goto quit_stream;
292 ret = sq905_ack_frame(gspca_dev);
293 if (ret < 0)
294 goto quit_stream;
295 } 285 }
296quit_stream: 286quit_stream:
297 /* the usb_lock is already acquired */ 287 if (gspca_dev->present) {
298 if (gspca_dev->present) 288 mutex_lock(&gspca_dev->usb_lock);
299 sq905_command(gspca_dev, SQ905_CLEAR); 289 sq905_command(gspca_dev, SQ905_CLEAR);
300 mutex_unlock(&gspca_dev->usb_lock); 290 mutex_unlock(&gspca_dev->usb_lock);
291 }
301 kfree(buffer); 292 kfree(buffer);
302} 293}
303 294
@@ -346,7 +337,7 @@ static int sd_init(struct gspca_dev *gspca_dev)
346 ret = sq905_command(gspca_dev, SQ905_ID); 337 ret = sq905_command(gspca_dev, SQ905_ID);
347 if (ret < 0) 338 if (ret < 0)
348 return ret; 339 return ret;
349 ret = sq905_read_data(gspca_dev, gspca_dev->usb_buf, 4); 340 ret = sq905_read_data(gspca_dev, gspca_dev->usb_buf, 4, 0);
350 if (ret < 0) 341 if (ret < 0)
351 return ret; 342 return ret;
352 /* usb_buf is allocated with kmalloc so is aligned. 343 /* usb_buf is allocated with kmalloc so is aligned.
diff --git a/drivers/media/video/gspca/sq905c.c b/drivers/media/video/gspca/sq905c.c
index 916892505432..d70b156872d6 100644
--- a/drivers/media/video/gspca/sq905c.c
+++ b/drivers/media/video/gspca/sq905c.c
@@ -115,11 +115,9 @@ static void sq905c_dostream(struct work_struct *work)
115{ 115{
116 struct sd *dev = container_of(work, struct sd, work_struct); 116 struct sd *dev = container_of(work, struct sd, work_struct);
117 struct gspca_dev *gspca_dev = &dev->gspca_dev; 117 struct gspca_dev *gspca_dev = &dev->gspca_dev;
118 struct gspca_frame *frame;
119 int bytes_left; /* bytes remaining in current frame. */ 118 int bytes_left; /* bytes remaining in current frame. */
120 int data_len; /* size to use for the next read. */ 119 int data_len; /* size to use for the next read. */
121 int act_len; 120 int act_len;
122 int discarding = 0; /* true if we failed to get space for frame. */
123 int packet_type; 121 int packet_type;
124 int ret; 122 int ret;
125 u8 *buffer; 123 u8 *buffer;
@@ -131,8 +129,6 @@ static void sq905c_dostream(struct work_struct *work)
131 } 129 }
132 130
133 while (gspca_dev->present && gspca_dev->streaming) { 131 while (gspca_dev->present && gspca_dev->streaming) {
134 if (!gspca_dev->present)
135 goto quit_stream;
136 /* Request the header, which tells the size to download */ 132 /* Request the header, which tells the size to download */
137 ret = usb_bulk_msg(gspca_dev->dev, 133 ret = usb_bulk_msg(gspca_dev->dev,
138 usb_rcvbulkpipe(gspca_dev->dev, 0x81), 134 usb_rcvbulkpipe(gspca_dev->dev, 0x81),
@@ -149,17 +145,11 @@ static void sq905c_dostream(struct work_struct *work)
149 PDEBUG(D_STREAM, "bytes_left = 0x%x", bytes_left); 145 PDEBUG(D_STREAM, "bytes_left = 0x%x", bytes_left);
150 /* We keep the header. It has other information, too. */ 146 /* We keep the header. It has other information, too. */
151 packet_type = FIRST_PACKET; 147 packet_type = FIRST_PACKET;
152 frame = gspca_get_i_frame(gspca_dev); 148 gspca_frame_add(gspca_dev, packet_type,
153 if (frame && !discarding) { 149 buffer, FRAME_HEADER_LEN);
154 gspca_frame_add(gspca_dev, packet_type, 150 while (bytes_left > 0 && gspca_dev->present) {
155 frame, buffer, FRAME_HEADER_LEN);
156 } else
157 discarding = 1;
158 while (bytes_left > 0) {
159 data_len = bytes_left > SQ905C_MAX_TRANSFER ? 151 data_len = bytes_left > SQ905C_MAX_TRANSFER ?
160 SQ905C_MAX_TRANSFER : bytes_left; 152 SQ905C_MAX_TRANSFER : bytes_left;
161 if (!gspca_dev->present)
162 goto quit_stream;
163 ret = usb_bulk_msg(gspca_dev->dev, 153 ret = usb_bulk_msg(gspca_dev->dev,
164 usb_rcvbulkpipe(gspca_dev->dev, 0x81), 154 usb_rcvbulkpipe(gspca_dev->dev, 0x81),
165 buffer, data_len, &act_len, 155 buffer, data_len, &act_len,
@@ -174,19 +164,16 @@ static void sq905c_dostream(struct work_struct *work)
174 packet_type = LAST_PACKET; 164 packet_type = LAST_PACKET;
175 else 165 else
176 packet_type = INTER_PACKET; 166 packet_type = INTER_PACKET;
177 frame = gspca_get_i_frame(gspca_dev); 167 gspca_frame_add(gspca_dev, packet_type,
178 if (frame && !discarding) 168 buffer, data_len);
179 gspca_frame_add(gspca_dev, packet_type,
180 frame, buffer, data_len);
181 else
182 discarding = 1;
183 } 169 }
184 } 170 }
185quit_stream: 171quit_stream:
186 mutex_lock(&gspca_dev->usb_lock); 172 if (gspca_dev->present) {
187 if (gspca_dev->present) 173 mutex_lock(&gspca_dev->usb_lock);
188 sq905c_command(gspca_dev, SQ905C_CLEAR, 0); 174 sq905c_command(gspca_dev, SQ905C_CLEAR, 0);
189 mutex_unlock(&gspca_dev->usb_lock); 175 mutex_unlock(&gspca_dev->usb_lock);
176 }
190 kfree(buffer); 177 kfree(buffer);
191} 178}
192 179
diff --git a/drivers/media/video/gspca/stk014.c b/drivers/media/video/gspca/stk014.c
index 47628964801e..8e23320d7ab7 100644
--- a/drivers/media/video/gspca/stk014.c
+++ b/drivers/media/video/gspca/stk014.c
@@ -418,8 +418,7 @@ static void sd_stop0(struct gspca_dev *gspca_dev)
418} 418}
419 419
420static void sd_pkt_scan(struct gspca_dev *gspca_dev, 420static void sd_pkt_scan(struct gspca_dev *gspca_dev,
421 struct gspca_frame *frame, /* target */ 421 u8 *data, /* isoc packet */
422 __u8 *data, /* isoc packet */
423 int len) /* iso packet length */ 422 int len) /* iso packet length */
424{ 423{
425 struct sd *sd = (struct sd *) gspca_dev; 424 struct sd *sd = (struct sd *) gspca_dev;
@@ -435,11 +434,11 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
435 * (without ending - ff d9) 434 * (without ending - ff d9)
436 */ 435 */
437 if (data[0] == 0xff && data[1] == 0xfe) { 436 if (data[0] == 0xff && data[1] == 0xfe) {
438 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, 437 gspca_frame_add(gspca_dev, LAST_PACKET,
439 ffd9, 2); 438 ffd9, 2);
440 439
441 /* put the JPEG 411 header */ 440 /* put the JPEG 411 header */
442 gspca_frame_add(gspca_dev, FIRST_PACKET, frame, 441 gspca_frame_add(gspca_dev, FIRST_PACKET,
443 sd->jpeg_hdr, JPEG_HDR_SZ); 442 sd->jpeg_hdr, JPEG_HDR_SZ);
444 443
445 /* beginning of the frame */ 444 /* beginning of the frame */
@@ -447,7 +446,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
447 data += STKHDRSZ; 446 data += STKHDRSZ;
448 len -= STKHDRSZ; 447 len -= STKHDRSZ;
449 } 448 }
450 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); 449 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
451} 450}
452 451
453static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) 452static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
diff --git a/drivers/media/video/gspca/stv0680.c b/drivers/media/video/gspca/stv0680.c
new file mode 100644
index 000000000000..2a69d7ccb50d
--- /dev/null
+++ b/drivers/media/video/gspca/stv0680.c
@@ -0,0 +1,364 @@
1/*
2 * STV0680 USB Camera Driver
3 *
4 * Copyright (C) 2009 Hans de Goede <hdgoede@redhat.com>
5 *
6 * This module is adapted from the in kernel v4l1 stv680 driver:
7 *
8 * STV0680 USB Camera Driver, by Kevin Sisson (kjsisson@bellsouth.net)
9 *
10 * Thanks to STMicroelectronics for information on the usb commands, and
11 * to Steve Miller at STM for his help and encouragement while I was
12 * writing this driver.
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 *
28 */
29
30#define MODULE_NAME "stv0680"
31
32#include "gspca.h"
33
34MODULE_AUTHOR("Hans de Goede <hdgoede@redhat.com>");
35MODULE_DESCRIPTION("STV0680 USB Camera Driver");
36MODULE_LICENSE("GPL");
37
38/* specific webcam descriptor */
39struct sd {
40 struct gspca_dev gspca_dev; /* !! must be the first item */
41 struct v4l2_pix_format mode;
42 u8 orig_mode;
43 u8 video_mode;
44 u8 current_mode;
45};
46
47/* V4L2 controls supported by the driver */
48static struct ctrl sd_ctrls[] = {
49};
50
51static int stv_sndctrl(struct gspca_dev *gspca_dev, int set, u8 req, u16 val,
52 int size)
53{
54 int ret = -1;
55 u8 req_type = 0;
56
57 switch (set) {
58 case 0: /* 0xc1 */
59 req_type = USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT;
60 break;
61 case 1: /* 0x41 */
62 req_type = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT;
63 break;
64 case 2: /* 0x80 */
65 req_type = USB_DIR_IN | USB_RECIP_DEVICE;
66 break;
67 case 3: /* 0x40 */
68 req_type = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE;
69 break;
70 }
71
72 ret = usb_control_msg(gspca_dev->dev,
73 usb_rcvctrlpipe(gspca_dev->dev, 0),
74 req, req_type,
75 val, 0, gspca_dev->usb_buf, size, 500);
76
77 if ((ret < 0) && (req != 0x0a))
78 PDEBUG(D_ERR,
79 "usb_control_msg error %i, request = 0x%x, error = %i",
80 set, req, ret);
81
82 return ret;
83}
84
85static int stv0680_handle_error(struct gspca_dev *gspca_dev, int ret)
86{
87 stv_sndctrl(gspca_dev, 0, 0x80, 0, 0x02); /* Get Last Error */
88 PDEBUG(D_ERR, "last error: %i, command = 0x%x",
89 gspca_dev->usb_buf[0], gspca_dev->usb_buf[1]);
90 return ret;
91}
92
93static int stv0680_get_video_mode(struct gspca_dev *gspca_dev)
94{
95 /* Note not sure if this init of usb_buf is really necessary */
96 memset(gspca_dev->usb_buf, 0, 8);
97 gspca_dev->usb_buf[0] = 0x0f;
98
99 if (stv_sndctrl(gspca_dev, 0, 0x87, 0, 0x08) != 0x08) {
100 PDEBUG(D_ERR, "Get_Camera_Mode failed");
101 return stv0680_handle_error(gspca_dev, -EIO);
102 }
103
104 return gspca_dev->usb_buf[0]; /* 01 = VGA, 03 = QVGA, 00 = CIF */
105}
106
107static int stv0680_set_video_mode(struct gspca_dev *gspca_dev, u8 mode)
108{
109 struct sd *sd = (struct sd *) gspca_dev;
110
111 if (sd->current_mode == mode)
112 return 0;
113
114 memset(gspca_dev->usb_buf, 0, 8);
115 gspca_dev->usb_buf[0] = mode;
116
117 if (stv_sndctrl(gspca_dev, 3, 0x07, 0x0100, 0x08) != 0x08) {
118 PDEBUG(D_ERR, "Set_Camera_Mode failed");
119 return stv0680_handle_error(gspca_dev, -EIO);
120 }
121
122 /* Verify we got what we've asked for */
123 if (stv0680_get_video_mode(gspca_dev) != mode) {
124 PDEBUG(D_ERR, "Error setting camera video mode!");
125 return -EIO;
126 }
127
128 sd->current_mode = mode;
129
130 return 0;
131}
132
133/* this function is called at probe time */
134static int sd_config(struct gspca_dev *gspca_dev,
135 const struct usb_device_id *id)
136{
137 int ret;
138 struct sd *sd = (struct sd *) gspca_dev;
139 struct cam *cam = &gspca_dev->cam;
140
141 /* ping camera to be sure STV0680 is present */
142 if (stv_sndctrl(gspca_dev, 0, 0x88, 0x5678, 0x02) != 0x02 ||
143 gspca_dev->usb_buf[0] != 0x56 || gspca_dev->usb_buf[1] != 0x78) {
144 PDEBUG(D_ERR, "STV(e): camera ping failed!!");
145 return stv0680_handle_error(gspca_dev, -ENODEV);
146 }
147
148 /* get camera descriptor */
149 if (stv_sndctrl(gspca_dev, 2, 0x06, 0x0200, 0x09) != 0x09)
150 return stv0680_handle_error(gspca_dev, -ENODEV);
151
152 if (stv_sndctrl(gspca_dev, 2, 0x06, 0x0200, 0x22) != 0x22 ||
153 gspca_dev->usb_buf[7] != 0xa0 || gspca_dev->usb_buf[8] != 0x23) {
154 PDEBUG(D_ERR, "Could not get descriptor 0200.");
155 return stv0680_handle_error(gspca_dev, -ENODEV);
156 }
157 if (stv_sndctrl(gspca_dev, 0, 0x8a, 0, 0x02) != 0x02)
158 return stv0680_handle_error(gspca_dev, -ENODEV);
159 if (stv_sndctrl(gspca_dev, 0, 0x8b, 0, 0x24) != 0x24)
160 return stv0680_handle_error(gspca_dev, -ENODEV);
161 if (stv_sndctrl(gspca_dev, 0, 0x85, 0, 0x10) != 0x10)
162 return stv0680_handle_error(gspca_dev, -ENODEV);
163
164 if (!(gspca_dev->usb_buf[7] & 0x09)) {
165 PDEBUG(D_ERR, "Camera supports neither CIF nor QVGA mode");
166 return -ENODEV;
167 }
168 if (gspca_dev->usb_buf[7] & 0x01)
169 PDEBUG(D_PROBE, "Camera supports CIF mode");
170 if (gspca_dev->usb_buf[7] & 0x02)
171 PDEBUG(D_PROBE, "Camera supports VGA mode");
172 if (gspca_dev->usb_buf[7] & 0x08)
173 PDEBUG(D_PROBE, "Camera supports QVGA mode");
174
175 if (gspca_dev->usb_buf[7] & 0x01)
176 sd->video_mode = 0x00; /* CIF */
177 else
178 sd->video_mode = 0x03; /* QVGA */
179
180 /* FW rev, ASIC rev, sensor ID */
181 PDEBUG(D_PROBE, "Firmware rev is %i.%i",
182 gspca_dev->usb_buf[0], gspca_dev->usb_buf[1]);
183 PDEBUG(D_PROBE, "ASIC rev is %i.%i",
184 gspca_dev->usb_buf[2], gspca_dev->usb_buf[3]);
185 PDEBUG(D_PROBE, "Sensor ID is %i",
186 (gspca_dev->usb_buf[4]*16) + (gspca_dev->usb_buf[5]>>4));
187
188
189 ret = stv0680_get_video_mode(gspca_dev);
190 if (ret < 0)
191 return ret;
192 sd->current_mode = sd->orig_mode = ret;
193
194 ret = stv0680_set_video_mode(gspca_dev, sd->video_mode);
195 if (ret < 0)
196 return ret;
197
198 /* Get mode details */
199 if (stv_sndctrl(gspca_dev, 0, 0x8f, 0, 0x10) != 0x10)
200 return stv0680_handle_error(gspca_dev, -EIO);
201
202 cam->bulk = 1;
203 cam->bulk_nurbs = 1; /* The cam cannot handle more */
204 cam->bulk_size = (gspca_dev->usb_buf[0] << 24) |
205 (gspca_dev->usb_buf[1] << 16) |
206 (gspca_dev->usb_buf[2] << 8) |
207 (gspca_dev->usb_buf[3]);
208 sd->mode.width = (gspca_dev->usb_buf[4] << 8) |
209 (gspca_dev->usb_buf[5]); /* 322, 356, 644 */
210 sd->mode.height = (gspca_dev->usb_buf[6] << 8) |
211 (gspca_dev->usb_buf[7]); /* 242, 292, 484 */
212 sd->mode.pixelformat = V4L2_PIX_FMT_STV0680;
213 sd->mode.field = V4L2_FIELD_NONE;
214 sd->mode.bytesperline = sd->mode.width;
215 sd->mode.sizeimage = cam->bulk_size;
216 sd->mode.colorspace = V4L2_COLORSPACE_SRGB;
217
218 /* origGain = gspca_dev->usb_buf[12]; */
219
220 cam->cam_mode = &sd->mode;
221 cam->nmodes = 1;
222
223
224 ret = stv0680_set_video_mode(gspca_dev, sd->orig_mode);
225 if (ret < 0)
226 return ret;
227
228 if (stv_sndctrl(gspca_dev, 2, 0x06, 0x0100, 0x12) != 0x12 ||
229 gspca_dev->usb_buf[8] != 0x53 || gspca_dev->usb_buf[9] != 0x05) {
230 PDEBUG(D_ERR, "Could not get descriptor 0100.");
231 return stv0680_handle_error(gspca_dev, -EIO);
232 }
233
234 return 0;
235}
236
237/* this function is called at probe and resume time */
238static int sd_init(struct gspca_dev *gspca_dev)
239{
240 return 0;
241}
242
243/* -- start the camera -- */
244static int sd_start(struct gspca_dev *gspca_dev)
245{
246 int ret;
247 struct sd *sd = (struct sd *) gspca_dev;
248
249 ret = stv0680_set_video_mode(gspca_dev, sd->video_mode);
250 if (ret < 0)
251 return ret;
252
253 if (stv_sndctrl(gspca_dev, 0, 0x85, 0, 0x10) != 0x10)
254 return stv0680_handle_error(gspca_dev, -EIO);
255
256 /* Start stream at:
257 0x0000 = CIF (352x288)
258 0x0100 = VGA (640x480)
259 0x0300 = QVGA (320x240) */
260 if (stv_sndctrl(gspca_dev, 1, 0x09, sd->video_mode << 8, 0x0) != 0x0)
261 return stv0680_handle_error(gspca_dev, -EIO);
262
263 return 0;
264}
265
266static void sd_stopN(struct gspca_dev *gspca_dev)
267{
268 /* This is a high priority command; it stops all lower order cmds */
269 if (stv_sndctrl(gspca_dev, 1, 0x04, 0x0000, 0x0) != 0x0)
270 stv0680_handle_error(gspca_dev, -EIO);
271}
272
273static void sd_stop0(struct gspca_dev *gspca_dev)
274{
275 struct sd *sd = (struct sd *) gspca_dev;
276
277 if (!sd->gspca_dev.present)
278 return;
279
280 stv0680_set_video_mode(gspca_dev, sd->orig_mode);
281}
282
283static void sd_pkt_scan(struct gspca_dev *gspca_dev,
284 u8 *data,
285 int len)
286{
287 struct sd *sd = (struct sd *) gspca_dev;
288
289 /* Every now and then the camera sends a 16 byte packet, no idea
290 what it contains, but it is not image data, when this
291 happens the frame received before this packet is corrupt,
292 so discard it. */
293 if (len != sd->mode.sizeimage) {
294 gspca_dev->last_packet_type = DISCARD_PACKET;
295 return;
296 }
297
298 /* Finish the previous frame, we do this upon reception of the next
299 packet, even though it is already complete so that the strange 16
300 byte packets send after a corrupt frame can discard it. */
301 gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
302
303 /* Store the just received frame */
304 gspca_frame_add(gspca_dev, FIRST_PACKET, data, len);
305}
306
307/* sub-driver description */
308static const struct sd_desc sd_desc = {
309 .name = MODULE_NAME,
310 .ctrls = sd_ctrls,
311 .nctrls = ARRAY_SIZE(sd_ctrls),
312 .config = sd_config,
313 .init = sd_init,
314 .start = sd_start,
315 .stopN = sd_stopN,
316 .stop0 = sd_stop0,
317 .pkt_scan = sd_pkt_scan,
318};
319
320/* -- module initialisation -- */
321static const __devinitdata struct usb_device_id device_table[] = {
322 {USB_DEVICE(0x0553, 0x0202)},
323 {USB_DEVICE(0x041e, 0x4007)},
324 {}
325};
326MODULE_DEVICE_TABLE(usb, device_table);
327
328/* -- device connect -- */
329static int sd_probe(struct usb_interface *intf,
330 const struct usb_device_id *id)
331{
332 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
333 THIS_MODULE);
334}
335
336static struct usb_driver sd_driver = {
337 .name = MODULE_NAME,
338 .id_table = device_table,
339 .probe = sd_probe,
340 .disconnect = gspca_disconnect,
341#ifdef CONFIG_PM
342 .suspend = gspca_suspend,
343 .resume = gspca_resume,
344#endif
345};
346
347/* -- module insert / remove -- */
348static int __init sd_mod_init(void)
349{
350 int ret;
351 ret = usb_register(&sd_driver);
352 if (ret < 0)
353 return ret;
354 PDEBUG(D_PROBE, "registered");
355 return 0;
356}
357static void __exit sd_mod_exit(void)
358{
359 usb_deregister(&sd_driver);
360 PDEBUG(D_PROBE, "deregistered");
361}
362
363module_init(sd_mod_init);
364module_exit(sd_mod_exit);
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx.c b/drivers/media/video/gspca/stv06xx/stv06xx.c
index bfae63f5584c..5d0241bb1611 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx.c
+++ b/drivers/media/video/gspca/stv06xx/stv06xx.c
@@ -312,8 +312,7 @@ out:
312 * The 0005 and 0100 chunks seem to appear only in compressed stream. 312 * The 0005 and 0100 chunks seem to appear only in compressed stream.
313 */ 313 */
314static void stv06xx_pkt_scan(struct gspca_dev *gspca_dev, 314static void stv06xx_pkt_scan(struct gspca_dev *gspca_dev,
315 struct gspca_frame *frame, /* target */ 315 u8 *data, /* isoc packet */
316 __u8 *data, /* isoc packet */
317 int len) /* iso packet length */ 316 int len) /* iso packet length */
318{ 317{
319 struct sd *sd = (struct sd *) gspca_dev; 318 struct sd *sd = (struct sd *) gspca_dev;
@@ -366,7 +365,7 @@ frame_data:
366 sd->to_skip -= skip; 365 sd->to_skip -= skip;
367 } 366 }
368 367
369 gspca_frame_add(gspca_dev, INTER_PACKET, frame, 368 gspca_frame_add(gspca_dev, INTER_PACKET,
370 data, chunk_len); 369 data, chunk_len);
371 break; 370 break;
372 371
@@ -378,7 +377,7 @@ frame_data:
378 377
379 /* Create a new frame, chunk length should be zero */ 378 /* Create a new frame, chunk length should be zero */
380 gspca_frame_add(gspca_dev, FIRST_PACKET, 379 gspca_frame_add(gspca_dev, FIRST_PACKET,
381 frame, data, 0); 380 NULL, 0);
382 381
383 if (sd->bridge == BRIDGE_ST6422) 382 if (sd->bridge == BRIDGE_ST6422)
384 sd->to_skip = gspca_dev->width * 4; 383 sd->to_skip = gspca_dev->width * 4;
@@ -394,8 +393,8 @@ frame_data:
394 PDEBUG(D_PACK, "End of frame detected"); 393 PDEBUG(D_PACK, "End of frame detected");
395 394
396 /* Complete the last frame (if any) */ 395 /* Complete the last frame (if any) */
397 frame = gspca_frame_add(gspca_dev, LAST_PACKET, 396 gspca_frame_add(gspca_dev, LAST_PACKET,
398 frame, data, 0); 397 NULL, 0);
399 398
400 if (chunk_len) 399 if (chunk_len)
401 PDEBUG(D_ERR, "Chunk length is " 400 PDEBUG(D_ERR, "Chunk length is "
diff --git a/drivers/media/video/gspca/sunplus.c b/drivers/media/video/gspca/sunplus.c
index 1a9af2ebdbef..72bf3b4f0a31 100644
--- a/drivers/media/video/gspca/sunplus.c
+++ b/drivers/media/video/gspca/sunplus.c
@@ -1116,7 +1116,6 @@ static void sd_stop0(struct gspca_dev *gspca_dev)
1116} 1116}
1117 1117
1118static void sd_pkt_scan(struct gspca_dev *gspca_dev, 1118static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1119 struct gspca_frame *frame, /* target */
1120 u8 *data, /* isoc packet */ 1119 u8 *data, /* isoc packet */
1121 int len) /* iso packet length */ 1120 int len) /* iso packet length */
1122{ 1121{
@@ -1186,11 +1185,11 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1186 break; 1185 break;
1187 } 1186 }
1188 if (sof) { /* start of frame */ 1187 if (sof) { /* start of frame */
1189 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, 1188 gspca_frame_add(gspca_dev, LAST_PACKET,
1190 ffd9, 2); 1189 ffd9, 2);
1191 1190
1192 /* put the JPEG header in the new frame */ 1191 /* put the JPEG header in the new frame */
1193 gspca_frame_add(gspca_dev, FIRST_PACKET, frame, 1192 gspca_frame_add(gspca_dev, FIRST_PACKET,
1194 sd->jpeg_hdr, JPEG_HDR_SZ); 1193 sd->jpeg_hdr, JPEG_HDR_SZ);
1195 } 1194 }
1196 1195
@@ -1198,7 +1197,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1198 i = 0; 1197 i = 0;
1199 do { 1198 do {
1200 if (data[i] == 0xff) { 1199 if (data[i] == 0xff) {
1201 gspca_frame_add(gspca_dev, INTER_PACKET, frame, 1200 gspca_frame_add(gspca_dev, INTER_PACKET,
1202 data, i + 1); 1201 data, i + 1);
1203 len -= i; 1202 len -= i;
1204 data += i; 1203 data += i;
@@ -1207,7 +1206,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1207 } 1206 }
1208 i++; 1207 i++;
1209 } while (i < len); 1208 } while (i < len);
1210 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); 1209 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
1211} 1210}
1212 1211
1213static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) 1212static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
diff --git a/drivers/media/video/gspca/t613.c b/drivers/media/video/gspca/t613.c
index 1d321c30d22f..55ef6a744427 100644
--- a/drivers/media/video/gspca/t613.c
+++ b/drivers/media/video/gspca/t613.c
@@ -938,7 +938,6 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
938} 938}
939 939
940static void sd_pkt_scan(struct gspca_dev *gspca_dev, 940static void sd_pkt_scan(struct gspca_dev *gspca_dev,
941 struct gspca_frame *frame, /* target */
942 u8 *data, /* isoc packet */ 941 u8 *data, /* isoc packet */
943 int len) /* iso packet length */ 942 int len) /* iso packet length */
944{ 943{
@@ -956,9 +955,9 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
956 /* extra bytes....., could be processed too but would be 955 /* extra bytes....., could be processed too but would be
957 * a waste of time, right now leave the application and 956 * a waste of time, right now leave the application and
958 * libjpeg do it for ourserlves.. */ 957 * libjpeg do it for ourserlves.. */
959 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, 958 gspca_frame_add(gspca_dev, LAST_PACKET,
960 ffd9, 2); 959 ffd9, 2);
961 gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, len); 960 gspca_frame_add(gspca_dev, FIRST_PACKET, data, len);
962 return; 961 return;
963 } 962 }
964 963
@@ -967,7 +966,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
967 * other's do not include it... */ 966 * other's do not include it... */
968 len -= 2; 967 len -= 2;
969 } 968 }
970 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); 969 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
971} 970}
972 971
973static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) 972static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
diff --git a/drivers/media/video/gspca/tv8532.c b/drivers/media/video/gspca/tv8532.c
index 4b44dde9f8b8..b74a3b6489c7 100644
--- a/drivers/media/video/gspca/tv8532.c
+++ b/drivers/media/video/gspca/tv8532.c
@@ -398,8 +398,7 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
398} 398}
399 399
400static void sd_pkt_scan(struct gspca_dev *gspca_dev, 400static void sd_pkt_scan(struct gspca_dev *gspca_dev,
401 struct gspca_frame *frame, /* target */ 401 u8 *data, /* isoc packet */
402 __u8 *data, /* isoc packet */
403 int len) /* iso packet length */ 402 int len) /* iso packet length */
404{ 403{
405 struct sd *sd = (struct sd *) gspca_dev; 404 struct sd *sd = (struct sd *) gspca_dev;
@@ -424,9 +423,9 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
424 * - 4 bytes 423 * - 4 bytes
425 */ 424 */
426 gspca_frame_add(gspca_dev, packet_type0, 425 gspca_frame_add(gspca_dev, packet_type0,
427 frame, data + 2, gspca_dev->width); 426 data + 2, gspca_dev->width);
428 gspca_frame_add(gspca_dev, packet_type1, 427 gspca_frame_add(gspca_dev, packet_type1,
429 frame, data + gspca_dev->width + 5, gspca_dev->width); 428 data + gspca_dev->width + 5, gspca_dev->width);
430} 429}
431 430
432static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) 431static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
diff --git a/drivers/media/video/gspca/vc032x.c b/drivers/media/video/gspca/vc032x.c
index 589042f6adbe..c090efcd8045 100644
--- a/drivers/media/video/gspca/vc032x.c
+++ b/drivers/media/video/gspca/vc032x.c
@@ -2987,7 +2987,6 @@ static void sd_stop0(struct gspca_dev *gspca_dev)
2987} 2987}
2988 2988
2989static void sd_pkt_scan(struct gspca_dev *gspca_dev, 2989static void sd_pkt_scan(struct gspca_dev *gspca_dev,
2990 struct gspca_frame *frame, /* target */
2991 u8 *data, /* isoc packet */ 2990 u8 *data, /* isoc packet */
2992 int len) /* iso pkt length */ 2991 int len) /* iso pkt length */
2993{ 2992{
@@ -2996,21 +2995,25 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
2996 if (data[0] == 0xff && data[1] == 0xd8) { 2995 if (data[0] == 0xff && data[1] == 0xd8) {
2997 PDEBUG(D_PACK, 2996 PDEBUG(D_PACK,
2998 "vc032x header packet found len %d", len); 2997 "vc032x header packet found len %d", len);
2999 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, 2998 gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
3000 data, 0);
3001 data += sd->image_offset; 2999 data += sd->image_offset;
3002 len -= sd->image_offset; 3000 len -= sd->image_offset;
3003 gspca_frame_add(gspca_dev, FIRST_PACKET, frame, 3001 gspca_frame_add(gspca_dev, FIRST_PACKET, data, len);
3004 data, len);
3005 return; 3002 return;
3006 } 3003 }
3007 3004
3008 /* The vc0321 sends some additional data after sending the complete 3005 /* The vc0321 sends some additional data after sending the complete
3009 * frame, we ignore this. */ 3006 * frame, we ignore this. */
3010 if (sd->bridge == BRIDGE_VC0321 3007 if (sd->bridge == BRIDGE_VC0321) {
3011 && len > frame->v4l2_buf.length - (frame->data_end - frame->data)) 3008 struct gspca_frame *frame;
3012 len = frame->v4l2_buf.length - (frame->data_end - frame->data); 3009 int l;
3013 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); 3010
3011 frame = gspca_get_i_frame(gspca_dev);
3012 l = frame->data_end - frame->data;
3013 if (len > frame->v4l2_buf.length - l)
3014 len = frame->v4l2_buf.length - l;
3015 }
3016 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
3014} 3017}
3015 3018
3016static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val) 3019static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val)
@@ -3092,6 +3095,8 @@ static int sd_querymenu(struct gspca_dev *gspca_dev,
3092 3095
3093 switch (menu->id) { 3096 switch (menu->id) {
3094 case V4L2_CID_POWER_LINE_FREQUENCY: 3097 case V4L2_CID_POWER_LINE_FREQUENCY:
3098 if (menu->index >= ARRAY_SIZE(freq_nm))
3099 break;
3095 strcpy((char *) menu->name, freq_nm[menu->index]); 3100 strcpy((char *) menu->name, freq_nm[menu->index]);
3096 return 0; 3101 return 0;
3097 } 3102 }
diff --git a/drivers/media/video/gspca/w996Xcf.c b/drivers/media/video/gspca/w996Xcf.c
new file mode 100644
index 000000000000..2fffe203bed8
--- /dev/null
+++ b/drivers/media/video/gspca/w996Xcf.c
@@ -0,0 +1,609 @@
1/**
2 *
3 * GSPCA sub driver for W996[78]CF JPEG USB Dual Mode Camera Chip.
4 *
5 * Copyright (C) 2009 Hans de Goede <hdegoede@redhat.com>
6 *
7 * This module is adapted from the in kernel v4l1 w9968cf driver:
8 *
9 * Copyright (C) 2002-2004 by Luca Risolia <luca.risolia@studio.unibo.it>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 *
25 */
26
27/* Note this is not a stand alone driver, it gets included in ov519.c, this
28 is a bit of a hack, but it needs the driver code for a lot of different
29 ov sensors which is already present in ov519.c (the old v4l1 driver used
30 the ovchipcam framework). When we have the time we really should move
31 the sensor drivers to v4l2 sub drivers, and properly split of this
32 driver from ov519.c */
33
34/* The CONEX_CAM define for jpeg.h needs renaming, now its used here too */
35#define CONEX_CAM
36#include "jpeg.h"
37
38#define W9968CF_I2C_BUS_DELAY 4 /* delay in us for I2C bit r/w operations */
39
40#define Y_QUANTABLE (sd->jpeg_hdr + JPEG_QT0_OFFSET)
41#define UV_QUANTABLE (sd->jpeg_hdr + JPEG_QT1_OFFSET)
42
43static const struct v4l2_pix_format w9968cf_vga_mode[] = {
44 {160, 120, V4L2_PIX_FMT_UYVY, V4L2_FIELD_NONE,
45 .bytesperline = 160 * 2,
46 .sizeimage = 160 * 120 * 2,
47 .colorspace = V4L2_COLORSPACE_JPEG},
48 {176, 144, V4L2_PIX_FMT_UYVY, V4L2_FIELD_NONE,
49 .bytesperline = 176 * 2,
50 .sizeimage = 176 * 144 * 2,
51 .colorspace = V4L2_COLORSPACE_JPEG},
52 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
53 .bytesperline = 320 * 2,
54 .sizeimage = 320 * 240 * 2,
55 .colorspace = V4L2_COLORSPACE_JPEG},
56 {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
57 .bytesperline = 352 * 2,
58 .sizeimage = 352 * 288 * 2,
59 .colorspace = V4L2_COLORSPACE_JPEG},
60 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
61 .bytesperline = 640 * 2,
62 .sizeimage = 640 * 480 * 2,
63 .colorspace = V4L2_COLORSPACE_JPEG},
64};
65
66static int reg_w(struct sd *sd, __u16 index, __u16 value);
67
68/*--------------------------------------------------------------------------
69 Write 64-bit data to the fast serial bus registers.
70 Return 0 on success, -1 otherwise.
71 --------------------------------------------------------------------------*/
72static int w9968cf_write_fsb(struct sd *sd, u16* data)
73{
74 struct usb_device* udev = sd->gspca_dev.dev;
75 u16 value;
76 int ret;
77
78 value = *data++;
79 memcpy(sd->gspca_dev.usb_buf, data, 6);
80
81 ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0,
82 USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE,
83 value, 0x06, sd->gspca_dev.usb_buf, 6, 500);
84 if (ret < 0) {
85 PDEBUG(D_ERR, "Write FSB registers failed (%d)", ret);
86 return ret;
87 }
88
89 return 0;
90}
91
92/*--------------------------------------------------------------------------
93 Write data to the serial bus control register.
94 Return 0 on success, a negative number otherwise.
95 --------------------------------------------------------------------------*/
96static int w9968cf_write_sb(struct sd *sd, u16 value)
97{
98 int ret;
99
100 /* We don't use reg_w here, as that would cause all writes when
101 bitbanging i2c to be logged, making the logs impossible to read */
102 ret = usb_control_msg(sd->gspca_dev.dev,
103 usb_sndctrlpipe(sd->gspca_dev.dev, 0),
104 0,
105 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
106 value, 0x01, NULL, 0, 500);
107
108 udelay(W9968CF_I2C_BUS_DELAY);
109
110 if (ret < 0) {
111 PDEBUG(D_ERR, "Write SB reg [01] %04x failed", value);
112 return ret;
113 }
114
115 return 0;
116}
117
118/*--------------------------------------------------------------------------
119 Read data from the serial bus control register.
120 Return 0 on success, a negative number otherwise.
121 --------------------------------------------------------------------------*/
122static int w9968cf_read_sb(struct sd *sd)
123{
124 int ret;
125
126 /* We don't use reg_r here, as the w9968cf is special and has 16
127 bit registers instead of 8 bit */
128 ret = usb_control_msg(sd->gspca_dev.dev,
129 usb_rcvctrlpipe(sd->gspca_dev.dev, 0),
130 1,
131 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
132 0, 0x01, sd->gspca_dev.usb_buf, 2, 500);
133 if (ret >= 0)
134 ret = sd->gspca_dev.usb_buf[0] |
135 (sd->gspca_dev.usb_buf[1] << 8);
136 else
137 PDEBUG(D_ERR, "Read SB reg [01] failed");
138
139 udelay(W9968CF_I2C_BUS_DELAY);
140
141 return ret;
142}
143
144/*--------------------------------------------------------------------------
145 Upload quantization tables for the JPEG compression.
146 This function is called by w9968cf_start_transfer().
147 Return 0 on success, a negative number otherwise.
148 --------------------------------------------------------------------------*/
149static int w9968cf_upload_quantizationtables(struct sd *sd)
150{
151 u16 a, b;
152 int ret = 0, i, j;
153
154 ret += reg_w(sd, 0x39, 0x0010); /* JPEG clock enable */
155
156 for (i = 0, j = 0; i < 32; i++, j += 2) {
157 a = Y_QUANTABLE[j] | ((unsigned)(Y_QUANTABLE[j+1]) << 8);
158 b = UV_QUANTABLE[j] | ((unsigned)(UV_QUANTABLE[j+1]) << 8);
159 ret += reg_w(sd, 0x40+i, a);
160 ret += reg_w(sd, 0x60+i, b);
161 }
162 ret += reg_w(sd, 0x39, 0x0012); /* JPEG encoder enable */
163
164 return ret;
165}
166
167/****************************************************************************
168 * Low-level I2C I/O functions. *
169 * The adapter supports the following I2C transfer functions: *
170 * i2c_adap_fastwrite_byte_data() (at 400 kHz bit frequency only) *
171 * i2c_adap_read_byte_data() *
172 * i2c_adap_read_byte() *
173 ****************************************************************************/
174
175static int w9968cf_smbus_start(struct sd *sd)
176{
177 int ret = 0;
178
179 ret += w9968cf_write_sb(sd, 0x0011); /* SDE=1, SDA=0, SCL=1 */
180 ret += w9968cf_write_sb(sd, 0x0010); /* SDE=1, SDA=0, SCL=0 */
181
182 return ret;
183}
184
185static int w9968cf_smbus_stop(struct sd *sd)
186{
187 int ret = 0;
188
189 ret += w9968cf_write_sb(sd, 0x0010); /* SDE=1, SDA=0, SCL=0 */
190 ret += w9968cf_write_sb(sd, 0x0011); /* SDE=1, SDA=0, SCL=1 */
191 ret += w9968cf_write_sb(sd, 0x0013); /* SDE=1, SDA=1, SCL=1 */
192
193 return ret;
194}
195
196static int w9968cf_smbus_write_byte(struct sd *sd, u8 v)
197{
198 u8 bit;
199 int ret = 0, sda;
200
201 for (bit = 0 ; bit < 8 ; bit++) {
202 sda = (v & 0x80) ? 2 : 0;
203 v <<= 1;
204 /* SDE=1, SDA=sda, SCL=0 */
205 ret += w9968cf_write_sb(sd, 0x10 | sda);
206 /* SDE=1, SDA=sda, SCL=1 */
207 ret += w9968cf_write_sb(sd, 0x11 | sda);
208 /* SDE=1, SDA=sda, SCL=0 */
209 ret += w9968cf_write_sb(sd, 0x10 | sda);
210 }
211
212 return ret;
213}
214
215static int w9968cf_smbus_read_byte(struct sd *sd, u8* v)
216{
217 u8 bit;
218 int ret = 0;
219
220 /* No need to ensure SDA is high as we are always called after
221 read_ack which ends with SDA high */
222 *v = 0;
223 for (bit = 0 ; bit < 8 ; bit++) {
224 *v <<= 1;
225 /* SDE=1, SDA=1, SCL=1 */
226 ret += w9968cf_write_sb(sd, 0x0013);
227 *v |= (w9968cf_read_sb(sd) & 0x0008) ? 1 : 0;
228 /* SDE=1, SDA=1, SCL=0 */
229 ret += w9968cf_write_sb(sd, 0x0012);
230 }
231
232 return ret;
233}
234
235static int w9968cf_smbus_write_nack(struct sd *sd)
236{
237 int ret = 0;
238
239 /* No need to ensure SDA is high as we are always called after
240 read_byte which ends with SDA high */
241 ret += w9968cf_write_sb(sd, 0x0013); /* SDE=1, SDA=1, SCL=1 */
242 ret += w9968cf_write_sb(sd, 0x0012); /* SDE=1, SDA=1, SCL=0 */
243
244 return ret;
245}
246
247static int w9968cf_smbus_read_ack(struct sd *sd)
248{
249 int ret = 0, sda;
250
251 /* Ensure SDA is high before raising clock to avoid a spurious stop */
252 ret += w9968cf_write_sb(sd, 0x0012); /* SDE=1, SDA=1, SCL=0 */
253 ret += w9968cf_write_sb(sd, 0x0013); /* SDE=1, SDA=1, SCL=1 */
254 sda = w9968cf_read_sb(sd);
255 ret += w9968cf_write_sb(sd, 0x0012); /* SDE=1, SDA=1, SCL=0 */
256 if (sda < 0)
257 ret += sda;
258 else if (sda & 0x08) {
259 PDEBUG(D_USBI, "Did not receive i2c ACK");
260 ret += -1;
261 }
262
263 return ret;
264}
265
266/* SMBus protocol: S Addr Wr [A] Subaddr [A] Value [A] P */
267static int w9968cf_i2c_w(struct sd *sd, u8 reg, u8 value)
268{
269 u16* data = (u16 *)sd->gspca_dev.usb_buf;
270 int ret = 0;
271
272 data[0] = 0x082f | ((sd->sensor_addr & 0x80) ? 0x1500 : 0x0);
273 data[0] |= (sd->sensor_addr & 0x40) ? 0x4000 : 0x0;
274 data[1] = 0x2082 | ((sd->sensor_addr & 0x40) ? 0x0005 : 0x0);
275 data[1] |= (sd->sensor_addr & 0x20) ? 0x0150 : 0x0;
276 data[1] |= (sd->sensor_addr & 0x10) ? 0x5400 : 0x0;
277 data[2] = 0x8208 | ((sd->sensor_addr & 0x08) ? 0x0015 : 0x0);
278 data[2] |= (sd->sensor_addr & 0x04) ? 0x0540 : 0x0;
279 data[2] |= (sd->sensor_addr & 0x02) ? 0x5000 : 0x0;
280 data[3] = 0x1d20 | ((sd->sensor_addr & 0x02) ? 0x0001 : 0x0);
281 data[3] |= (sd->sensor_addr & 0x01) ? 0x0054 : 0x0;
282
283 ret += w9968cf_write_fsb(sd, data);
284
285 data[0] = 0x8208 | ((reg & 0x80) ? 0x0015 : 0x0);
286 data[0] |= (reg & 0x40) ? 0x0540 : 0x0;
287 data[0] |= (reg & 0x20) ? 0x5000 : 0x0;
288 data[1] = 0x0820 | ((reg & 0x20) ? 0x0001 : 0x0);
289 data[1] |= (reg & 0x10) ? 0x0054 : 0x0;
290 data[1] |= (reg & 0x08) ? 0x1500 : 0x0;
291 data[1] |= (reg & 0x04) ? 0x4000 : 0x0;
292 data[2] = 0x2082 | ((reg & 0x04) ? 0x0005 : 0x0);
293 data[2] |= (reg & 0x02) ? 0x0150 : 0x0;
294 data[2] |= (reg & 0x01) ? 0x5400 : 0x0;
295 data[3] = 0x001d;
296
297 ret += w9968cf_write_fsb(sd, data);
298
299 data[0] = 0x8208 | ((value & 0x80) ? 0x0015 : 0x0);
300 data[0] |= (value & 0x40) ? 0x0540 : 0x0;
301 data[0] |= (value & 0x20) ? 0x5000 : 0x0;
302 data[1] = 0x0820 | ((value & 0x20) ? 0x0001 : 0x0);
303 data[1] |= (value & 0x10) ? 0x0054 : 0x0;
304 data[1] |= (value & 0x08) ? 0x1500 : 0x0;
305 data[1] |= (value & 0x04) ? 0x4000 : 0x0;
306 data[2] = 0x2082 | ((value & 0x04) ? 0x0005 : 0x0);
307 data[2] |= (value & 0x02) ? 0x0150 : 0x0;
308 data[2] |= (value & 0x01) ? 0x5400 : 0x0;
309 data[3] = 0xfe1d;
310
311 ret += w9968cf_write_fsb(sd, data);
312
313 if (!ret)
314 PDEBUG(D_USBO, "i2c 0x%02x -> [0x%02x]", value, reg);
315 else
316 PDEBUG(D_ERR, "i2c 0x%02x -> [0x%02x] failed", value, reg);
317
318 return ret;
319}
320
321/* SMBus protocol: S Addr Wr [A] Subaddr [A] P S Addr+1 Rd [A] [Value] NA P */
322static int w9968cf_i2c_r(struct sd *sd, u8 reg)
323{
324 int ret = 0;
325 u8 value;
326
327 /* Fast serial bus data control disable */
328 ret += w9968cf_write_sb(sd, 0x0013); /* don't change ! */
329
330 ret += w9968cf_smbus_start(sd);
331 ret += w9968cf_smbus_write_byte(sd, sd->sensor_addr);
332 ret += w9968cf_smbus_read_ack(sd);
333 ret += w9968cf_smbus_write_byte(sd, reg);
334 ret += w9968cf_smbus_read_ack(sd);
335 ret += w9968cf_smbus_stop(sd);
336 ret += w9968cf_smbus_start(sd);
337 ret += w9968cf_smbus_write_byte(sd, sd->sensor_addr + 1);
338 ret += w9968cf_smbus_read_ack(sd);
339 ret += w9968cf_smbus_read_byte(sd, &value);
340 /* signal we don't want to read anymore, the v4l1 driver used to
341 send an ack here which is very wrong! (and then fixed
342 the issues this gave by retrying reads) */
343 ret += w9968cf_smbus_write_nack(sd);
344 ret += w9968cf_smbus_stop(sd);
345
346 /* Fast serial bus data control re-enable */
347 ret += w9968cf_write_sb(sd, 0x0030);
348
349 if (!ret) {
350 ret = value;
351 PDEBUG(D_USBI, "i2c [0x%02X] -> 0x%02X", reg, value);
352 } else
353 PDEBUG(D_ERR, "i2c read [0x%02x] failed", reg);
354
355 return ret;
356}
357
358
359/*--------------------------------------------------------------------------
360 Turn on the LED on some webcams. A beep should be heard too.
361 Return 0 on success, a negative number otherwise.
362 --------------------------------------------------------------------------*/
363static int w9968cf_configure(struct sd *sd)
364{
365 int ret = 0;
366
367 ret += reg_w(sd, 0x00, 0xff00); /* power-down */
368 ret += reg_w(sd, 0x00, 0xbf17); /* reset everything */
369 ret += reg_w(sd, 0x00, 0xbf10); /* normal operation */
370 ret += reg_w(sd, 0x01, 0x0010); /* serial bus, SDS high */
371 ret += reg_w(sd, 0x01, 0x0000); /* serial bus, SDS low */
372 ret += reg_w(sd, 0x01, 0x0010); /* ..high 'beep-beep' */
373 ret += reg_w(sd, 0x01, 0x0030); /* Set sda scl to FSB mode */
374
375 if (ret)
376 PDEBUG(D_ERR, "Couldn't turn on the LED");
377
378 sd->stopped = 1;
379
380 return ret;
381}
382
383static int w9968cf_init(struct sd *sd)
384{
385 int ret = 0;
386 unsigned long hw_bufsize = sd->sif ? (352 * 288 * 2) : (640 * 480 * 2),
387 y0 = 0x0000,
388 u0 = y0 + hw_bufsize/2,
389 v0 = u0 + hw_bufsize/4,
390 y1 = v0 + hw_bufsize/4,
391 u1 = y1 + hw_bufsize/2,
392 v1 = u1 + hw_bufsize/4;
393
394 ret += reg_w(sd, 0x00, 0xff00); /* power off */
395 ret += reg_w(sd, 0x00, 0xbf10); /* power on */
396
397 ret += reg_w(sd, 0x03, 0x405d); /* DRAM timings */
398 ret += reg_w(sd, 0x04, 0x0030); /* SDRAM timings */
399
400 ret += reg_w(sd, 0x20, y0 & 0xffff); /* Y buf.0, low */
401 ret += reg_w(sd, 0x21, y0 >> 16); /* Y buf.0, high */
402 ret += reg_w(sd, 0x24, u0 & 0xffff); /* U buf.0, low */
403 ret += reg_w(sd, 0x25, u0 >> 16); /* U buf.0, high */
404 ret += reg_w(sd, 0x28, v0 & 0xffff); /* V buf.0, low */
405 ret += reg_w(sd, 0x29, v0 >> 16); /* V buf.0, high */
406
407 ret += reg_w(sd, 0x22, y1 & 0xffff); /* Y buf.1, low */
408 ret += reg_w(sd, 0x23, y1 >> 16); /* Y buf.1, high */
409 ret += reg_w(sd, 0x26, u1 & 0xffff); /* U buf.1, low */
410 ret += reg_w(sd, 0x27, u1 >> 16); /* U buf.1, high */
411 ret += reg_w(sd, 0x2a, v1 & 0xffff); /* V buf.1, low */
412 ret += reg_w(sd, 0x2b, v1 >> 16); /* V buf.1, high */
413
414 ret += reg_w(sd, 0x32, y1 & 0xffff); /* JPEG buf 0 low */
415 ret += reg_w(sd, 0x33, y1 >> 16); /* JPEG buf 0 high */
416
417 ret += reg_w(sd, 0x34, y1 & 0xffff); /* JPEG buf 1 low */
418 ret += reg_w(sd, 0x35, y1 >> 16); /* JPEG bug 1 high */
419
420 ret += reg_w(sd, 0x36, 0x0000);/* JPEG restart interval */
421 ret += reg_w(sd, 0x37, 0x0804);/*JPEG VLE FIFO threshold*/
422 ret += reg_w(sd, 0x38, 0x0000);/* disable hw up-scaling */
423 ret += reg_w(sd, 0x3f, 0x0000); /* JPEG/MCTL test data */
424
425 return ret;
426}
427
428static int w9968cf_set_crop_window(struct sd *sd)
429{
430 int ret = 0, start_cropx, start_cropy, x, y, fw, fh, cw, ch,
431 max_width, max_height;
432
433 if (sd->sif) {
434 max_width = 352;
435 max_height = 288;
436 } else {
437 max_width = 640;
438 max_height = 480;
439 }
440
441 if (sd->sensor == SEN_OV7620) {
442 /* Sigh, this is dependend on the clock / framerate changes
443 made by the frequency control, sick. */
444 if (sd->freq == 1) {
445 start_cropx = 277;
446 start_cropy = 37;
447 } else {
448 start_cropx = 105;
449 start_cropy = 37;
450 }
451 } else {
452 start_cropx = 320;
453 start_cropy = 35;
454 }
455
456 /* Work around to avoid FP arithmetics */
457 #define SC(x) ((x) << 10)
458
459 /* Scaling factors */
460 fw = SC(sd->gspca_dev.width) / max_width;
461 fh = SC(sd->gspca_dev.height) / max_height;
462
463 cw = (fw >= fh) ? max_width : SC(sd->gspca_dev.width)/fh;
464 ch = (fw >= fh) ? SC(sd->gspca_dev.height)/fw : max_height;
465
466 sd->sensor_width = max_width;
467 sd->sensor_height = max_height;
468
469 x = (max_width - cw) / 2;
470 y = (max_height - ch) / 2;
471
472 ret += reg_w(sd, 0x10, start_cropx + x);
473 ret += reg_w(sd, 0x11, start_cropy + y);
474 ret += reg_w(sd, 0x12, start_cropx + x + cw);
475 ret += reg_w(sd, 0x13, start_cropy + y + ch);
476
477 return ret;
478}
479
480static int w9968cf_mode_init_regs(struct sd *sd)
481{
482 int ret = 0, val, vs_polarity, hs_polarity;
483
484 ret += w9968cf_set_crop_window(sd);
485
486 ret += reg_w(sd, 0x14, sd->gspca_dev.width);
487 ret += reg_w(sd, 0x15, sd->gspca_dev.height);
488
489 /* JPEG width & height */
490 ret += reg_w(sd, 0x30, sd->gspca_dev.width);
491 ret += reg_w(sd, 0x31, sd->gspca_dev.height);
492
493 /* Y & UV frame buffer strides (in WORD) */
494 if (w9968cf_vga_mode[sd->gspca_dev.curr_mode].pixelformat ==
495 V4L2_PIX_FMT_JPEG) {
496 ret += reg_w(sd, 0x2c, sd->gspca_dev.width/2);
497 ret += reg_w(sd, 0x2d, sd->gspca_dev.width/4);
498 } else
499 ret += reg_w(sd, 0x2c, sd->gspca_dev.width);
500
501 ret += reg_w(sd, 0x00, 0xbf17); /* reset everything */
502 ret += reg_w(sd, 0x00, 0xbf10); /* normal operation */
503
504 /* Transfer size in WORDS (for UYVY format only) */
505 val = sd->gspca_dev.width * sd->gspca_dev.height;
506 ret += reg_w(sd, 0x3d, val & 0xffff); /* low bits */
507 ret += reg_w(sd, 0x3e, val >> 16); /* high bits */
508
509 if (w9968cf_vga_mode[sd->gspca_dev.curr_mode].pixelformat ==
510 V4L2_PIX_FMT_JPEG) {
511 /* We may get called multiple times (usb isoc bw negotiat.) */
512 if (!sd->jpeg_hdr)
513 sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL);
514 if (!sd->jpeg_hdr)
515 return -ENOMEM;
516
517 jpeg_define(sd->jpeg_hdr, sd->gspca_dev.height,
518 sd->gspca_dev.width, 0x22); /* JPEG 420 */
519 jpeg_set_qual(sd->jpeg_hdr, sd->quality);
520 ret += w9968cf_upload_quantizationtables(sd);
521 }
522
523 /* Video Capture Control Register */
524 if (sd->sensor == SEN_OV7620) {
525 /* Seems to work around a bug in the image sensor */
526 vs_polarity = 1;
527 hs_polarity = 1;
528 } else {
529 vs_polarity = 1;
530 hs_polarity = 0;
531 }
532
533 val = (vs_polarity << 12) | (hs_polarity << 11);
534
535 /* NOTE: We may not have enough memory to do double buffering while
536 doing compression (amount of memory differs per model cam).
537 So we use the second image buffer also as jpeg stream buffer
538 (see w9968cf_init), and disable double buffering. */
539 if (w9968cf_vga_mode[sd->gspca_dev.curr_mode].pixelformat ==
540 V4L2_PIX_FMT_JPEG) {
541 /* val |= 0x0002; YUV422P */
542 val |= 0x0003; /* YUV420P */
543 } else
544 val |= 0x0080; /* Enable HW double buffering */
545
546 /* val |= 0x0020; enable clamping */
547 /* val |= 0x0008; enable (1-2-1) filter */
548 /* val |= 0x000c; enable (2-3-6-3-2) filter */
549
550 val |= 0x8000; /* capt. enable */
551
552 ret += reg_w(sd, 0x16, val);
553
554 sd->gspca_dev.empty_packet = 0;
555
556 return ret;
557}
558
559static void w9968cf_stop0(struct sd *sd)
560{
561 if (sd->gspca_dev.present) {
562 reg_w(sd, 0x39, 0x0000); /* disable JPEG encoder */
563 reg_w(sd, 0x16, 0x0000); /* stop video capture */
564 }
565
566 kfree(sd->jpeg_hdr);
567 sd->jpeg_hdr = NULL;
568}
569
570/* The w9968cf docs say that a 0 sized packet means EOF (and also SOF
571 for the next frame). This seems to simply not be true when operating
572 in JPEG mode, in this case there may be empty packets within the
573 frame. So in JPEG mode use the JPEG SOI marker to detect SOF.
574
575 Note to make things even more interesting the w9968cf sends *PLANAR* jpeg,
576 to be precise it sends: SOI, SOF, DRI, SOS, Y-data, SOS, U-data, SOS,
577 V-data, EOI. */
578static void w9968cf_pkt_scan(struct gspca_dev *gspca_dev,
579 u8 *data, /* isoc packet */
580 int len) /* iso packet length */
581{
582 struct sd *sd = (struct sd *) gspca_dev;
583
584 if (w9968cf_vga_mode[gspca_dev->curr_mode].pixelformat ==
585 V4L2_PIX_FMT_JPEG) {
586 if (len >= 2 &&
587 data[0] == 0xff &&
588 data[1] == 0xd8) {
589 gspca_frame_add(gspca_dev, LAST_PACKET,
590 NULL, 0);
591 gspca_frame_add(gspca_dev, FIRST_PACKET,
592 sd->jpeg_hdr, JPEG_HDR_SZ);
593 /* Strip the ff d8, our own header (which adds
594 huffman and quantization tables) already has this */
595 len -= 2;
596 data += 2;
597 }
598 } else {
599 /* In UYVY mode an empty packet signals EOF */
600 if (gspca_dev->empty_packet) {
601 gspca_frame_add(gspca_dev, LAST_PACKET,
602 NULL, 0);
603 gspca_frame_add(gspca_dev, FIRST_PACKET,
604 NULL, 0);
605 gspca_dev->empty_packet = 0;
606 }
607 }
608 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
609}
diff --git a/drivers/media/video/gspca/zc3xx.c b/drivers/media/video/gspca/zc3xx.c
index 49c3c1226e0e..69e5dc4fc9de 100644
--- a/drivers/media/video/gspca/zc3xx.c
+++ b/drivers/media/video/gspca/zc3xx.c
@@ -61,17 +61,18 @@ struct sd {
61#define SENSOR_HV7131C 6 61#define SENSOR_HV7131C 6
62#define SENSOR_ICM105A 7 62#define SENSOR_ICM105A 7
63#define SENSOR_MC501CB 8 63#define SENSOR_MC501CB 8
64#define SENSOR_OV7620 9 64#define SENSOR_MI0360SOC 9
65/*#define SENSOR_OV7648 9 - same values */ 65#define SENSOR_OV7620 10
66#define SENSOR_OV7630C 10 66/*#define SENSOR_OV7648 10 - same values */
67#define SENSOR_PAS106 11 67#define SENSOR_OV7630C 11
68#define SENSOR_PAS202B 12 68#define SENSOR_PAS106 12
69#define SENSOR_PB0330 13 69#define SENSOR_PAS202B 13
70#define SENSOR_PO2030 14 70#define SENSOR_PB0330 14 /* (MI0360) */
71#define SENSOR_TAS5130CK 15 71#define SENSOR_PO2030 15
72#define SENSOR_TAS5130CXX 16 72#define SENSOR_TAS5130CK 16
73#define SENSOR_TAS5130C_VF0250 17 73#define SENSOR_TAS5130CXX 17
74#define SENSOR_MAX 18 74#define SENSOR_TAS5130C_VF0250 18
75#define SENSOR_MAX 19
75 unsigned short chip_revision; 76 unsigned short chip_revision;
76 77
77 u8 *jpeg_hdr; 78 u8 *jpeg_hdr;
@@ -420,9 +421,7 @@ static const struct usb_action adcm2700_NoFliker[] = {
420 {0xaa, 0xfe, 0x0010}, /* 00,fe,10,aa */ 421 {0xaa, 0xfe, 0x0010}, /* 00,fe,10,aa */
421 {} 422 {}
422}; 423};
423static const struct usb_action cs2102_Initial[] = { 424static const struct usb_action cs2102_Initial[] = { /* 320x240 */
424 {0xa1, 0x01, 0x0008},
425 {0xa1, 0x01, 0x0008},
426 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, 425 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
427 {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, 426 {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT},
428 {0xa0, 0x00, ZC3XX_R010_CMOSSENSORSELECT}, 427 {0xa0, 0x00, ZC3XX_R010_CMOSSENSORSELECT},
@@ -471,88 +470,10 @@ static const struct usb_action cs2102_Initial[] = {
471 {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, 470 {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
472 {0xa0, 0x68, ZC3XX_R18D_YTARGET}, 471 {0xa0, 0x68, ZC3XX_R18D_YTARGET},
473 {0xa0, 0x00, 0x01ad}, 472 {0xa0, 0x00, 0x01ad},
474 {0xa1, 0x01, 0x0002},
475 {0xa1, 0x01, 0x0008},
476 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* 00 */
477 {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */
478 {0xa1, 0x01, 0x01c8},
479 {0xa1, 0x01, 0x01c9},
480 {0xa1, 0x01, 0x01ca},
481 {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */
482 {0xa0, 0x24, ZC3XX_R120_GAMMA00}, /* gamma 5 */
483 {0xa0, 0x44, ZC3XX_R121_GAMMA01},
484 {0xa0, 0x64, ZC3XX_R122_GAMMA02},
485 {0xa0, 0x84, ZC3XX_R123_GAMMA03},
486 {0xa0, 0x9d, ZC3XX_R124_GAMMA04},
487 {0xa0, 0xb2, ZC3XX_R125_GAMMA05},
488 {0xa0, 0xc4, ZC3XX_R126_GAMMA06},
489 {0xa0, 0xd3, ZC3XX_R127_GAMMA07},
490 {0xa0, 0xe0, ZC3XX_R128_GAMMA08},
491 {0xa0, 0xeb, ZC3XX_R129_GAMMA09},
492 {0xa0, 0xf4, ZC3XX_R12A_GAMMA0A},
493 {0xa0, 0xfb, ZC3XX_R12B_GAMMA0B},
494 {0xa0, 0xff, ZC3XX_R12C_GAMMA0C},
495 {0xa0, 0xff, ZC3XX_R12D_GAMMA0D},
496 {0xa0, 0xff, ZC3XX_R12E_GAMMA0E},
497 {0xa0, 0xff, ZC3XX_R12F_GAMMA0F},
498 {0xa0, 0x18, ZC3XX_R130_GAMMA10},
499 {0xa0, 0x20, ZC3XX_R131_GAMMA11},
500 {0xa0, 0x20, ZC3XX_R132_GAMMA12},
501 {0xa0, 0x1c, ZC3XX_R133_GAMMA13},
502 {0xa0, 0x16, ZC3XX_R134_GAMMA14},
503 {0xa0, 0x13, ZC3XX_R135_GAMMA15},
504 {0xa0, 0x10, ZC3XX_R136_GAMMA16},
505 {0xa0, 0x0e, ZC3XX_R137_GAMMA17},
506 {0xa0, 0x0b, ZC3XX_R138_GAMMA18},
507 {0xa0, 0x09, ZC3XX_R139_GAMMA19},
508 {0xa0, 0x07, ZC3XX_R13A_GAMMA1A},
509 {0xa0, 0x06, ZC3XX_R13B_GAMMA1B},
510 {0xa0, 0x00, ZC3XX_R13C_GAMMA1C},
511 {0xa0, 0x00, ZC3XX_R13D_GAMMA1D},
512 {0xa0, 0x00, ZC3XX_R13E_GAMMA1E},
513 {0xa0, 0x01, ZC3XX_R13F_GAMMA1F},
514 {0xa0, 0x58, ZC3XX_R10A_RGB00}, /* matrix */
515 {0xa0, 0xf4, ZC3XX_R10B_RGB01},
516 {0xa0, 0xf4, ZC3XX_R10C_RGB02},
517 {0xa0, 0xf4, ZC3XX_R10D_RGB10},
518 {0xa0, 0x58, ZC3XX_R10E_RGB11},
519 {0xa0, 0xf4, ZC3XX_R10F_RGB12},
520 {0xa0, 0xf4, ZC3XX_R110_RGB20},
521 {0xa0, 0xf4, ZC3XX_R111_RGB21},
522 {0xa0, 0x58, ZC3XX_R112_RGB22},
523 {0xa1, 0x01, 0x0180},
524 {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
525 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
526 {0xaa, 0x23, 0x0001},
527 {0xaa, 0x24, 0x0055},
528 {0xaa, 0x25, 0x00cc},
529 {0xaa, 0x21, 0x003f},
530 {0xa0, 0x02, ZC3XX_R190_EXPOSURELIMITHIGH},
531 {0xa0, 0xab, ZC3XX_R191_EXPOSURELIMITMID},
532 {0xa0, 0x98, ZC3XX_R192_EXPOSURELIMITLOW},
533 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
534 {0xa0, 0x30, ZC3XX_R196_ANTIFLICKERMID},
535 {0xa0, 0xd4, ZC3XX_R197_ANTIFLICKERLOW},
536 {0xa0, 0x10, ZC3XX_R18C_AEFREEZE},
537 {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE},
538 {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF},
539 {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP},
540 {0xa0, 0x39, ZC3XX_R01D_HSYNC_0},
541 {0xa0, 0x70, ZC3XX_R01E_HSYNC_1},
542 {0xa0, 0xb0, ZC3XX_R01F_HSYNC_2},
543 {0xa0, 0xff, ZC3XX_R020_HSYNC_3},
544 {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE},
545 {0xa1, 0x01, 0x0180},
546 {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
547 {0xa0, 0x40, ZC3XX_R116_RGAIN},
548 {0xa0, 0x40, ZC3XX_R117_GGAIN},
549 {0xa0, 0x40, ZC3XX_R118_BGAIN},
550 {} 473 {}
551}; 474};
552 475
553static const struct usb_action cs2102_InitialScale[] = { 476static const struct usb_action cs2102_InitialScale[] = { /* 640x480 */
554 {0xa1, 0x01, 0x0008},
555 {0xa1, 0x01, 0x0008},
556 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, 477 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
557 {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, 478 {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT},
558 {0xa0, 0x00, ZC3XX_R010_CMOSSENSORSELECT}, 479 {0xa0, 0x00, ZC3XX_R010_CMOSSENSORSELECT},
@@ -601,57 +522,75 @@ static const struct usb_action cs2102_InitialScale[] = {
601 {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, 522 {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
602 {0xa0, 0x68, ZC3XX_R18D_YTARGET}, 523 {0xa0, 0x68, ZC3XX_R18D_YTARGET},
603 {0xa0, 0x00, 0x01ad}, 524 {0xa0, 0x00, 0x01ad},
604 {0xa1, 0x01, 0x0002}, 525 {}
605 {0xa1, 0x01, 0x0008}, 526};
606 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* 00 */ 527static const struct usb_action cs2102_50HZ[] = {
607 {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */ 528 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
608 {0xa1, 0x01, 0x01c8}, 529 {0xaa, 0x23, 0x0001},
609 {0xa1, 0x01, 0x01c9}, 530 {0xaa, 0x24, 0x005f},
610 {0xa1, 0x01, 0x01ca}, 531 {0xaa, 0x25, 0x0090},
611 {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */ 532 {0xaa, 0x21, 0x00dd},
612 {0xa0, 0x24, ZC3XX_R120_GAMMA00}, /* gamma 5 */ 533 {0xa0, 0x02, ZC3XX_R190_EXPOSURELIMITHIGH},
613 {0xa0, 0x44, ZC3XX_R121_GAMMA01}, 534 {0xa0, 0xbf, ZC3XX_R191_EXPOSURELIMITMID},
614 {0xa0, 0x64, ZC3XX_R122_GAMMA02}, 535 {0xa0, 0x20, ZC3XX_R192_EXPOSURELIMITLOW},
615 {0xa0, 0x84, ZC3XX_R123_GAMMA03}, 536 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
616 {0xa0, 0x9d, ZC3XX_R124_GAMMA04}, 537 {0xa0, 0x3a, ZC3XX_R196_ANTIFLICKERMID},
617 {0xa0, 0xb2, ZC3XX_R125_GAMMA05}, 538 {0xa0, 0x98, ZC3XX_R197_ANTIFLICKERLOW},
618 {0xa0, 0xc4, ZC3XX_R126_GAMMA06}, 539 {0xa0, 0x10, ZC3XX_R18C_AEFREEZE},
619 {0xa0, 0xd3, ZC3XX_R127_GAMMA07}, 540 {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE},
620 {0xa0, 0xe0, ZC3XX_R128_GAMMA08}, 541 {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF},
621 {0xa0, 0xeb, ZC3XX_R129_GAMMA09}, 542 {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP},
622 {0xa0, 0xf4, ZC3XX_R12A_GAMMA0A}, 543 {0xa0, 0xdd, ZC3XX_R01D_HSYNC_0},
623 {0xa0, 0xfb, ZC3XX_R12B_GAMMA0B}, 544 {0xa0, 0xe4, ZC3XX_R01E_HSYNC_1},
624 {0xa0, 0xff, ZC3XX_R12C_GAMMA0C}, 545 {0xa0, 0xf0, ZC3XX_R01F_HSYNC_2},
625 {0xa0, 0xff, ZC3XX_R12D_GAMMA0D}, 546 {0xa0, 0xff, ZC3XX_R020_HSYNC_3},
626 {0xa0, 0xff, ZC3XX_R12E_GAMMA0E}, 547 {}
627 {0xa0, 0xff, ZC3XX_R12F_GAMMA0F}, 548};
628 {0xa0, 0x18, ZC3XX_R130_GAMMA10}, 549static const struct usb_action cs2102_50HZScale[] = {
629 {0xa0, 0x20, ZC3XX_R131_GAMMA11}, 550 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
630 {0xa0, 0x20, ZC3XX_R132_GAMMA12}, 551 {0xaa, 0x23, 0x0000},
631 {0xa0, 0x1c, ZC3XX_R133_GAMMA13}, 552 {0xaa, 0x24, 0x00af},
632 {0xa0, 0x16, ZC3XX_R134_GAMMA14}, 553 {0xaa, 0x25, 0x00c8},
633 {0xa0, 0x13, ZC3XX_R135_GAMMA15}, 554 {0xaa, 0x21, 0x0068},
634 {0xa0, 0x10, ZC3XX_R136_GAMMA16}, 555 {0xa0, 0x01, ZC3XX_R190_EXPOSURELIMITHIGH},
635 {0xa0, 0x0e, ZC3XX_R137_GAMMA17}, 556 {0xa0, 0x5f, ZC3XX_R191_EXPOSURELIMITMID},
636 {0xa0, 0x0b, ZC3XX_R138_GAMMA18}, 557 {0xa0, 0x90, ZC3XX_R192_EXPOSURELIMITLOW},
637 {0xa0, 0x09, ZC3XX_R139_GAMMA19}, 558 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
638 {0xa0, 0x07, ZC3XX_R13A_GAMMA1A}, 559 {0xa0, 0x1d, ZC3XX_R196_ANTIFLICKERMID},
639 {0xa0, 0x06, ZC3XX_R13B_GAMMA1B}, 560 {0xa0, 0x4c, ZC3XX_R197_ANTIFLICKERLOW},
640 {0xa0, 0x00, ZC3XX_R13C_GAMMA1C}, 561 {0xa0, 0x10, ZC3XX_R18C_AEFREEZE},
641 {0xa0, 0x00, ZC3XX_R13D_GAMMA1D}, 562 {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE},
642 {0xa0, 0x00, ZC3XX_R13E_GAMMA1E}, 563 {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF},
643 {0xa0, 0x01, ZC3XX_R13F_GAMMA1F}, 564 {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP},
644 {0xa0, 0x58, ZC3XX_R10A_RGB00}, /* matrix */ 565 {0xa0, 0x68, ZC3XX_R01D_HSYNC_0},
645 {0xa0, 0xf4, ZC3XX_R10B_RGB01}, 566 {0xa0, 0xe3, ZC3XX_R01E_HSYNC_1},
646 {0xa0, 0xf4, ZC3XX_R10C_RGB02}, 567 {0xa0, 0xf0, ZC3XX_R01F_HSYNC_2},
647 {0xa0, 0xf4, ZC3XX_R10D_RGB10}, 568 {0xa0, 0xff, ZC3XX_R020_HSYNC_3},
648 {0xa0, 0x58, ZC3XX_R10E_RGB11}, 569 {}
649 {0xa0, 0xf4, ZC3XX_R10F_RGB12}, 570};
650 {0xa0, 0xf4, ZC3XX_R110_RGB20}, 571static const struct usb_action cs2102_60HZ[] = {
651 {0xa0, 0xf4, ZC3XX_R111_RGB21}, 572 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
652 {0xa0, 0x58, ZC3XX_R112_RGB22}, 573 {0xaa, 0x23, 0x0001},
653 {0xa1, 0x01, 0x0180}, 574 {0xaa, 0x24, 0x0055},
654 {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE}, 575 {0xaa, 0x25, 0x00cc},
576 {0xaa, 0x21, 0x003f},
577 {0xa0, 0x02, ZC3XX_R190_EXPOSURELIMITHIGH},
578 {0xa0, 0xab, ZC3XX_R191_EXPOSURELIMITMID},
579 {0xa0, 0x98, ZC3XX_R192_EXPOSURELIMITLOW},
580 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
581 {0xa0, 0x30, ZC3XX_R196_ANTIFLICKERMID},
582 {0xa0, 0xd4, ZC3XX_R197_ANTIFLICKERLOW},
583 {0xa0, 0x10, ZC3XX_R18C_AEFREEZE},
584 {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE},
585 {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF},
586 {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP},
587 {0xa0, 0x39, ZC3XX_R01D_HSYNC_0},
588 {0xa0, 0x70, ZC3XX_R01E_HSYNC_1},
589 {0xa0, 0xb0, ZC3XX_R01F_HSYNC_2},
590 {0xa0, 0xff, ZC3XX_R020_HSYNC_3},
591 {}
592};
593static const struct usb_action cs2102_60HZScale[] = {
655 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, 594 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
656 {0xaa, 0x23, 0x0000}, 595 {0xaa, 0x23, 0x0000},
657 {0xaa, 0x24, 0x00aa}, 596 {0xaa, 0x24, 0x00aa},
@@ -671,162 +610,50 @@ static const struct usb_action cs2102_InitialScale[] = {
671 {0xa0, 0xa5, ZC3XX_R01E_HSYNC_1}, 610 {0xa0, 0xa5, ZC3XX_R01E_HSYNC_1},
672 {0xa0, 0xf0, ZC3XX_R01F_HSYNC_2}, 611 {0xa0, 0xf0, ZC3XX_R01F_HSYNC_2},
673 {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, 612 {0xa0, 0xff, ZC3XX_R020_HSYNC_3},
674 {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE},
675 {0xa1, 0x01, 0x0180},
676 {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
677 {0xa0, 0x40, ZC3XX_R116_RGAIN},
678 {0xa0, 0x40, ZC3XX_R117_GGAIN},
679 {0xa0, 0x40, ZC3XX_R118_BGAIN},
680 {}
681};
682static const struct usb_action cs2102_50HZ[] = {
683 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
684 {0xaa, 0x0f, 0x008c}, /* 00,0f,8c,aa */
685 {0xaa, 0x03, 0x0005}, /* 00,03,05,aa */
686 {0xaa, 0x04, 0x00ac}, /* 00,04,ac,aa */
687 {0xaa, 0x10, 0x0005}, /* 00,10,05,aa */
688 {0xaa, 0x11, 0x00ac}, /* 00,11,ac,aa */
689 {0xaa, 0x1b, 0x0000}, /* 00,1b,00,aa */
690 {0xaa, 0x1c, 0x0005}, /* 00,1c,05,aa */
691 {0xaa, 0x1d, 0x00ac}, /* 00,1d,ac,aa */
692 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
693 {0xa0, 0x3f, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,3f,cc */
694 {0xa0, 0xf0, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,f0,cc */
695 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
696 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
697 {0xa0, 0x42, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,42,cc */
698 {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
699 {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
700 {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,10,cc */
701 {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc */
702 {0xa0, 0x8c, ZC3XX_R01D_HSYNC_0}, /* 00,1d,8c,cc */
703 {0xa0, 0xb0, ZC3XX_R01E_HSYNC_1}, /* 00,1e,b0,cc */
704 {0xa0, 0xd0, ZC3XX_R01F_HSYNC_2}, /* 00,1f,d0,cc */
705 {}
706};
707static const struct usb_action cs2102_50HZScale[] = {
708 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
709 {0xaa, 0x0f, 0x0093}, /* 00,0f,93,aa */
710 {0xaa, 0x03, 0x0005}, /* 00,03,05,aa */
711 {0xaa, 0x04, 0x00a1}, /* 00,04,a1,aa */
712 {0xaa, 0x10, 0x0005}, /* 00,10,05,aa */
713 {0xaa, 0x11, 0x00a1}, /* 00,11,a1,aa */
714 {0xaa, 0x1b, 0x0000}, /* 00,1b,00,aa */
715 {0xaa, 0x1c, 0x0005}, /* 00,1c,05,aa */
716 {0xaa, 0x1d, 0x00a1}, /* 00,1d,a1,aa */
717 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
718 {0xa0, 0x3f, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,3f,cc */
719 {0xa0, 0xf7, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,f7,cc */
720 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
721 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
722 {0xa0, 0x83, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,83,cc */
723 {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
724 {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
725 {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,10,cc */
726 {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc */
727 {0xa0, 0x93, ZC3XX_R01D_HSYNC_0}, /* 00,1d,93,cc */
728 {0xa0, 0xb0, ZC3XX_R01E_HSYNC_1}, /* 00,1e,b0,cc */
729 {0xa0, 0xd0, ZC3XX_R01F_HSYNC_2}, /* 00,1f,d0,cc */
730 {}
731};
732static const struct usb_action cs2102_60HZ[] = {
733 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
734 {0xaa, 0x0f, 0x005d}, /* 00,0f,5d,aa */
735 {0xaa, 0x03, 0x0005}, /* 00,03,05,aa */
736 {0xaa, 0x04, 0x00aa}, /* 00,04,aa,aa */
737 {0xaa, 0x10, 0x0005}, /* 00,10,05,aa */
738 {0xaa, 0x11, 0x00aa}, /* 00,11,aa,aa */
739 {0xaa, 0x1b, 0x0000}, /* 00,1b,00,aa */
740 {0xaa, 0x1c, 0x0005}, /* 00,1c,05,aa */
741 {0xaa, 0x1d, 0x00aa}, /* 00,1d,aa,aa */
742 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
743 {0xa0, 0x3f, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,3f,cc */
744 {0xa0, 0xe4, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,e4,cc */
745 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
746 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
747 {0xa0, 0x3a, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,3a,cc */
748 {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
749 {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
750 {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,10,cc */
751 {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc */
752 {0xa0, 0x5d, ZC3XX_R01D_HSYNC_0}, /* 00,1d,5d,cc */
753 {0xa0, 0x90, ZC3XX_R01E_HSYNC_1}, /* 00,1e,90,cc */
754 {0xa0, 0xd0, 0x00c8}, /* 00,c8,d0,cc */
755 {}
756};
757static const struct usb_action cs2102_60HZScale[] = {
758 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
759 {0xaa, 0x0f, 0x00b7}, /* 00,0f,b7,aa */
760 {0xaa, 0x03, 0x0005}, /* 00,03,05,aa */
761 {0xaa, 0x04, 0x00be}, /* 00,04,be,aa */
762 {0xaa, 0x10, 0x0005}, /* 00,10,05,aa */
763 {0xaa, 0x11, 0x00be}, /* 00,11,be,aa */
764 {0xaa, 0x1b, 0x0000}, /* 00,1b,00,aa */
765 {0xaa, 0x1c, 0x0005}, /* 00,1c,05,aa */
766 {0xaa, 0x1d, 0x00be}, /* 00,1d,be,aa */
767 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
768 {0xa0, 0x3f, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,3f,cc */
769 {0xa0, 0xfc, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,fc,cc */
770 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
771 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
772 {0xa0, 0x69, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,69,cc */
773 {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
774 {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
775 {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,10,cc */
776 {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc */
777 {0xa0, 0xb7, ZC3XX_R01D_HSYNC_0}, /* 00,1d,b7,cc */
778 {0xa0, 0xd0, ZC3XX_R01E_HSYNC_1}, /* 00,1e,d0,cc */
779 {0xa0, 0xe8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,e8,cc */
780 {} 613 {}
781}; 614};
782static const struct usb_action cs2102_NoFliker[] = { 615static const struct usb_action cs2102_NoFliker[] = {
783 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ 616 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
784 {0xaa, 0x0f, 0x0059}, /* 00,0f,59,aa */ 617 {0xaa, 0x23, 0x0001},
785 {0xaa, 0x03, 0x0005}, /* 00,03,05,aa */ 618 {0xaa, 0x24, 0x005f},
786 {0xaa, 0x04, 0x0080}, /* 00,04,80,aa */ 619 {0xaa, 0x25, 0x0000},
787 {0xaa, 0x10, 0x0005}, /* 00,10,05,aa */ 620 {0xaa, 0x21, 0x0001},
788 {0xaa, 0x11, 0x0080}, /* 00,11,80,aa */ 621 {0xa0, 0x02, ZC3XX_R190_EXPOSURELIMITHIGH},
789 {0xaa, 0x1b, 0x0000}, /* 00,1b,00,aa */ 622 {0xa0, 0xbf, ZC3XX_R191_EXPOSURELIMITMID},
790 {0xaa, 0x1c, 0x0005}, /* 00,1c,05,aa */ 623 {0xa0, 0x00, ZC3XX_R192_EXPOSURELIMITLOW},
791 {0xaa, 0x1d, 0x0080}, /* 00,1d,80,aa */ 624 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
792 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ 625 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
793 {0xa0, 0x3f, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,3f,cc */ 626 {0xa0, 0x80, ZC3XX_R197_ANTIFLICKERLOW},
794 {0xa0, 0xf0, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,f0,cc */ 627 {0xa0, 0x10, ZC3XX_R18C_AEFREEZE},
795 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ 628 {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE},
796 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ 629 {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF},
797 {0xa0, 0x10, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,10,cc */ 630 {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP},
798 {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ 631 {0xa0, 0x01, ZC3XX_R01D_HSYNC_0},
799 {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ 632 {0xa0, 0x40, ZC3XX_R01E_HSYNC_1},
800 {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,00,cc */ 633 {0xa0, 0xa0, ZC3XX_R01F_HSYNC_2},
801 {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,00,cc */ 634 {0xa0, 0xff, ZC3XX_R020_HSYNC_3},
802 {0xa0, 0x59, ZC3XX_R01D_HSYNC_0}, /* 00,1d,59,cc */
803 {0xa0, 0x90, ZC3XX_R01E_HSYNC_1}, /* 00,1e,90,cc */
804 {0xa0, 0xc8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,c8,cc */
805 {} 635 {}
806}; 636};
807static const struct usb_action cs2102_NoFlikerScale[] = { 637static const struct usb_action cs2102_NoFlikerScale[] = {
808 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ 638 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
809 {0xaa, 0x0f, 0x0059}, /* 00,0f,59,aa */ 639 {0xaa, 0x23, 0x0000},
810 {0xaa, 0x03, 0x0005}, /* 00,03,05,aa */ 640 {0xaa, 0x24, 0x00af},
811 {0xaa, 0x04, 0x0080}, /* 00,04,80,aa */ 641 {0xaa, 0x25, 0x0080},
812 {0xaa, 0x10, 0x0005}, /* 00,10,05,aa */ 642 {0xaa, 0x21, 0x0001},
813 {0xaa, 0x11, 0x0080}, /* 00,11,80,aa */ 643 {0xa0, 0x01, ZC3XX_R190_EXPOSURELIMITHIGH},
814 {0xaa, 0x1b, 0x0000}, /* 00,1b,00,aa */ 644 {0xa0, 0x5f, ZC3XX_R191_EXPOSURELIMITMID},
815 {0xaa, 0x1c, 0x0005}, /* 00,1c,05,aa */ 645 {0xa0, 0x80, ZC3XX_R192_EXPOSURELIMITLOW},
816 {0xaa, 0x1d, 0x0080}, /* 00,1d,80,aa */ 646 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
817 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ 647 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
818 {0xa0, 0x3f, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,3f,cc */ 648 {0xa0, 0x80, ZC3XX_R197_ANTIFLICKERLOW},
819 {0xa0, 0xf0, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,f0,cc */ 649 {0xa0, 0x10, ZC3XX_R18C_AEFREEZE},
820 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ 650 {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE},
821 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ 651 {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF},
822 {0xa0, 0x10, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,10,cc */ 652 {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP},
823 {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ 653 {0xa0, 0x01, ZC3XX_R01D_HSYNC_0},
824 {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ 654 {0xa0, 0x40, ZC3XX_R01E_HSYNC_1},
825 {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,00,cc */ 655 {0xa0, 0xa0, ZC3XX_R01F_HSYNC_2},
826 {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,00,cc */ 656 {0xa0, 0xff, ZC3XX_R020_HSYNC_3},
827 {0xa0, 0x59, ZC3XX_R01D_HSYNC_0}, /* 00,1d,59,cc */
828 {0xa0, 0x90, ZC3XX_R01E_HSYNC_1}, /* 00,1e,90,cc */
829 {0xa0, 0xc8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,c8,cc */
830 {} 657 {}
831}; 658};
832 659
@@ -4409,170 +4236,80 @@ static const struct usb_action pas202b_NoFlikerScale[] = {
4409 {} 4236 {}
4410}; 4237};
4411 4238
4412static const struct usb_action pb03303x_Initial[] = { 4239/* mi0360soc and pb0330 from vm30x.inf for 0ac8:301b and 0ac8:303b 07/02/13 */
4240static const struct usb_action mi0360soc_Initial[] = { /* 640x480 */
4413 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, 4241 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
4414 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, 4242 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
4415 {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, 4243 {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT},
4416 {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, 4244 {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT},
4417 {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, 4245 {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH},
4418 {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, 4246 {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW},
4419 {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, 4247 {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH},
4420 {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, 4248 {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW},
4421 {0xa0, 0xdc, ZC3XX_R08B_I2CDEVICEADDR}, /* 8b -> dc */ 4249 {0xa0, 0xdc, ZC3XX_R08B_I2CDEVICEADDR},
4422 {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, 4250 {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING},
4423 {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, 4251 {0xa0, 0x07, ZC3XX_R012_VIDEOCONTROLFUNC}, /*jfm: was 03*/
4424 {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, 4252/* {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, */
4425 {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, 4253 {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW},
4426 {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, 4254 {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW},
4427 {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, 4255 {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW},
4428 {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, 4256 {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW},
4429 {0xa0, 0xdc, ZC3XX_R08B_I2CDEVICEADDR}, 4257 {0xa0, 0xdc, ZC3XX_R08B_I2CDEVICEADDR},
4258 {0xdd, 0x00, 0x0200},
4430 {0xaa, 0x01, 0x0001}, 4259 {0xaa, 0x01, 0x0001},
4431 {0xaa, 0x06, 0x0000}, 4260 {0xaa, 0x06, 0x0000},
4432 {0xaa, 0x08, 0x0483}, 4261 {0xaa, 0x08, 0x0483},
4433 {0xaa, 0x01, 0x0004}, 4262 {0xaa, 0x01, 0x0004},
4434 {0xaa, 0x08, 0x0006}, 4263 {0xaa, 0x08, 0x0006},
4435 {0xaa, 0x02, 0x0011}, 4264 {0xaa, 0x02, 0x0011},
4436 {0xaa, 0x03, 0x01e7}, 4265 {0xaa, 0x03, 0x01e5}, /*jfm: was 01e7*/
4437 {0xaa, 0x04, 0x0287}, 4266 {0xaa, 0x04, 0x0285}, /*jfm: was 0287*/
4438 {0xaa, 0x07, 0x3002}, 4267 {0xaa, 0x07, 0x3002},
4439 {0xaa, 0x20, 0x1100}, 4268 {0xaa, 0x20, 0x5100}, /*jfm: was 1100*/
4440 {0xaa, 0x35, 0x0050}, 4269 {0xaa, 0x35, 0x507f}, /*jfm: was 0050*/
4441 {0xaa, 0x30, 0x0005}, 4270 {0xaa, 0x30, 0x0005},
4442 {0xaa, 0x31, 0x0000}, 4271 {0xaa, 0x31, 0x0000},
4443 {0xaa, 0x58, 0x0078}, 4272 {0xaa, 0x58, 0x0078},
4444 {0xaa, 0x62, 0x0411}, 4273 {0xaa, 0x62, 0x0411},
4445 {0xaa, 0x2b, 0x0028}, 4274 {0xaa, 0x2b, 0x0028},
4446 {0xaa, 0x2c, 0x0030}, 4275 {0xaa, 0x2c, 0x007f}, /*jfm: was 0030*/
4447 {0xaa, 0x2d, 0x0030}, 4276 {0xaa, 0x2d, 0x007f}, /*jfm: was 0030*/
4448 {0xaa, 0x2e, 0x0028}, 4277 {0xaa, 0x2e, 0x007f}, /*jfm: was 0030*/
4449 {0xa0, 0x10, ZC3XX_R087_EXPTIMEMID}, 4278 {0xa0, 0x10, ZC3XX_R087_EXPTIMEMID},
4450 {0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION}, 4279 {0xa0, 0xb7, ZC3XX_R101_SENSORCORRECTION}, /*jfm: was 37*/
4451 {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, 4280 {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC},
4452 {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, 4281 {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE},
4453 {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, 4282 {0xa0, 0x06, ZC3XX_R189_AWBSTATUS},
4454 {0xa0, 0x00, 0x01ad}, 4283 {0xa0, 0x09, 0x01ad}, /*jfm: was 00*/
4455 {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, 4284 {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE},
4456 {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, 4285 {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05},
4457 {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, 4286 {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},
4458 {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, 4287 {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
4459 {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN}, 4288 {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN},
4460 {0xa0, 0x78, ZC3XX_R18D_YTARGET}, 4289 {0xa0, 0x6c, ZC3XX_R18D_YTARGET}, /* jfm: was 78 */
4461 {0xa0, 0x61, ZC3XX_R116_RGAIN}, 4290 {0xa0, 0x61, ZC3XX_R116_RGAIN},
4462 {0xa0, 0x65, ZC3XX_R118_BGAIN}, 4291 {0xa0, 0x65, ZC3XX_R118_BGAIN},
4463
4464 {0xa1, 0x01, 0x0002},
4465 {0xa0, 0x09, 0x01ad},
4466 {0xa0, 0x15, 0x01ae},
4467 {0xa0, 0x0d, 0x003a},
4468 {0xa0, 0x02, 0x003b},
4469 {0xa0, 0x00, 0x0038},
4470 {0xa0, 0x50, ZC3XX_R10A_RGB00}, /* matrix */
4471 {0xa0, 0xf8, ZC3XX_R10B_RGB01},
4472 {0xa0, 0xf8, ZC3XX_R10C_RGB02},
4473 {0xa0, 0xf8, ZC3XX_R10D_RGB10},
4474 {0xa0, 0x50, ZC3XX_R10E_RGB11},
4475 {0xa0, 0xf8, ZC3XX_R10F_RGB12},
4476 {0xa0, 0xf8, ZC3XX_R110_RGB20},
4477 {0xa0, 0xf8, ZC3XX_R111_RGB21},
4478 {0xa0, 0x50, ZC3XX_R112_RGB22},
4479
4480 {0xa1, 0x01, 0x0008},
4481 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
4482 {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00},
4483 {0xa1, 0x01, 0x01c8},
4484 {0xa1, 0x01, 0x01c9},
4485 {0xa1, 0x01, 0x01ca},
4486 {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */
4487 {0xa0, 0x13, ZC3XX_R120_GAMMA00}, /* gamma 4 */
4488 {0xa0, 0x38, ZC3XX_R121_GAMMA01},
4489 {0xa0, 0x59, ZC3XX_R122_GAMMA02},
4490 {0xa0, 0x79, ZC3XX_R123_GAMMA03},
4491 {0xa0, 0x92, ZC3XX_R124_GAMMA04},
4492 {0xa0, 0xa7, ZC3XX_R125_GAMMA05},
4493 {0xa0, 0xb9, ZC3XX_R126_GAMMA06},
4494 {0xa0, 0xc8, ZC3XX_R127_GAMMA07},
4495 {0xa0, 0xd4, ZC3XX_R128_GAMMA08},
4496 {0xa0, 0xdf, ZC3XX_R129_GAMMA09},
4497 {0xa0, 0xe7, ZC3XX_R12A_GAMMA0A},
4498 {0xa0, 0xee, ZC3XX_R12B_GAMMA0B},
4499 {0xa0, 0xf4, ZC3XX_R12C_GAMMA0C},
4500 {0xa0, 0xf9, ZC3XX_R12D_GAMMA0D},
4501 {0xa0, 0xfc, ZC3XX_R12E_GAMMA0E},
4502 {0xa0, 0xff, ZC3XX_R12F_GAMMA0F},
4503 {0xa0, 0x26, ZC3XX_R130_GAMMA10},
4504 {0xa0, 0x22, ZC3XX_R131_GAMMA11},
4505 {0xa0, 0x20, ZC3XX_R132_GAMMA12},
4506 {0xa0, 0x1c, ZC3XX_R133_GAMMA13},
4507 {0xa0, 0x16, ZC3XX_R134_GAMMA14},
4508 {0xa0, 0x13, ZC3XX_R135_GAMMA15},
4509 {0xa0, 0x10, ZC3XX_R136_GAMMA16},
4510 {0xa0, 0x0d, ZC3XX_R137_GAMMA17},
4511 {0xa0, 0x0b, ZC3XX_R138_GAMMA18},
4512 {0xa0, 0x09, ZC3XX_R139_GAMMA19},
4513 {0xa0, 0x07, ZC3XX_R13A_GAMMA1A},
4514 {0xa0, 0x06, ZC3XX_R13B_GAMMA1B},
4515 {0xa0, 0x05, ZC3XX_R13C_GAMMA1C},
4516 {0xa0, 0x04, ZC3XX_R13D_GAMMA1D},
4517 {0xa0, 0x03, ZC3XX_R13E_GAMMA1E},
4518 {0xa0, 0x02, ZC3XX_R13F_GAMMA1F},
4519 {0xa0, 0x50, ZC3XX_R10A_RGB00}, /* matrix */
4520 {0xa0, 0xf8, ZC3XX_R10B_RGB01},
4521 {0xa0, 0xf8, ZC3XX_R10C_RGB02},
4522 {0xa0, 0xf8, ZC3XX_R10D_RGB10},
4523 {0xa0, 0x50, ZC3XX_R10E_RGB11},
4524 {0xa0, 0xf8, ZC3XX_R10F_RGB12},
4525 {0xa0, 0xf8, ZC3XX_R110_RGB20},
4526 {0xa0, 0xf8, ZC3XX_R111_RGB21},
4527 {0xa0, 0x50, ZC3XX_R112_RGB22},
4528
4529 {0xa1, 0x01, 0x0180},
4530 {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
4531 {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
4532 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
4533 {0xaa, 0x05, 0x0009},
4534 {0xaa, 0x09, 0x0134},
4535 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
4536 {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID},
4537 {0xa0, 0xec, ZC3XX_R192_EXPOSURELIMITLOW},
4538 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
4539 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
4540 {0xa0, 0x9c, ZC3XX_R197_ANTIFLICKERLOW},
4541 {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE},
4542 {0xa0, 0x1c, ZC3XX_R18F_AEUNFREEZE},
4543 {0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF},
4544 {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP},
4545 {0xa0, 0xd7, ZC3XX_R01D_HSYNC_0},
4546 {0xa0, 0xf4, ZC3XX_R01E_HSYNC_1},
4547 {0xa0, 0xf9, ZC3XX_R01F_HSYNC_2},
4548 {0xa0, 0xff, ZC3XX_R020_HSYNC_3},
4549 {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
4550 {0xa0, 0x09, 0x01ad},
4551 {0xa0, 0x15, 0x01ae},
4552 {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE},
4553 {0xa1, 0x01, 0x0180},
4554 {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
4555 {} 4292 {}
4556}; 4293};
4557 4294static const struct usb_action mi0360soc_InitialScale[] = { /* 320x240 */
4558static const struct usb_action pb03303x_InitialScale[] = {
4559 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, 4295 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
4560 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, 4296 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
4561 {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, 4297 {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT},
4562 {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, 4298 {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT},
4563 {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, 4299 {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH},
4564 {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, 4300 {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW},
4565 {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, 4301 {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH},
4566 {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, 4302 {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW},
4567 {0xa0, 0xdc, ZC3XX_R08B_I2CDEVICEADDR}, /* 8b -> dc */ 4303 {0xa0, 0xdc, ZC3XX_R08B_I2CDEVICEADDR},
4568 {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, 4304 {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING},
4569 {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, 4305 {0xa0, 0x07, ZC3XX_R012_VIDEOCONTROLFUNC}, /*jfm: was 03*/
4570 {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, 4306/* {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, */
4571 {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, 4307 {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW},
4572 {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, 4308 {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW},
4573 {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, 4309 {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW},
4574 {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, 4310 {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW},
4575 {0xa0, 0xdc, ZC3XX_R08B_I2CDEVICEADDR}, 4311 {0xa0, 0xdc, ZC3XX_R08B_I2CDEVICEADDR},
4312 {0xdd, 0x00, 0x0200},
4576 {0xaa, 0x01, 0x0001}, 4313 {0xaa, 0x01, 0x0001},
4577 {0xaa, 0x06, 0x0000}, 4314 {0xaa, 0x06, 0x0000},
4578 {0xaa, 0x08, 0x0483}, 4315 {0xaa, 0x08, 0x0483},
@@ -4582,111 +4319,111 @@ static const struct usb_action pb03303x_InitialScale[] = {
4582 {0xaa, 0x03, 0x01e7}, 4319 {0xaa, 0x03, 0x01e7},
4583 {0xaa, 0x04, 0x0287}, 4320 {0xaa, 0x04, 0x0287},
4584 {0xaa, 0x07, 0x3002}, 4321 {0xaa, 0x07, 0x3002},
4585 {0xaa, 0x20, 0x1100}, 4322 {0xaa, 0x20, 0x5100}, /*jfm: was 1100*/
4586 {0xaa, 0x35, 0x0050}, 4323 {0xaa, 0x35, 0x007f}, /*jfm: was 0050*/
4587 {0xaa, 0x30, 0x0005}, 4324 {0xaa, 0x30, 0x0005},
4588 {0xaa, 0x31, 0x0000}, 4325 {0xaa, 0x31, 0x0000},
4589 {0xaa, 0x58, 0x0078}, 4326 {0xaa, 0x58, 0x0078},
4590 {0xaa, 0x62, 0x0411}, 4327 {0xaa, 0x62, 0x0411},
4591 {0xaa, 0x2b, 0x0028}, 4328 {0xaa, 0x2b, 0x007f}, /*jfm: was 28*/
4592 {0xaa, 0x2c, 0x0030}, 4329 {0xaa, 0x2c, 0x007f}, /*jfm: was 30*/
4593 {0xaa, 0x2d, 0x0030}, 4330 {0xaa, 0x2d, 0x007f}, /*jfm: was 30*/
4594 {0xaa, 0x2e, 0x0028}, 4331 {0xaa, 0x2e, 0x007f}, /*jfm: was 28*/
4595 {0xa0, 0x10, ZC3XX_R087_EXPTIMEMID}, 4332 {0xa0, 0x10, ZC3XX_R087_EXPTIMEMID},
4596 {0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION}, 4333 {0xa0, 0xb7, ZC3XX_R101_SENSORCORRECTION}, /*jfm: was 37*/
4597 {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, 4334 {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC},
4598 {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, 4335 {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE},
4599 {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, 4336 {0xa0, 0x06, ZC3XX_R189_AWBSTATUS},
4600 {0xa0, 0x00, 0x01ad}, 4337 {0xa0, 0x09, 0x01ad}, /*jfm: was 00*/
4601 {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, 4338 {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE},
4602 {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, 4339 {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05},
4603 {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, 4340 {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},
4604 {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, 4341 {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
4605 {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN}, 4342 {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN},
4606 {0xa0, 0x78, ZC3XX_R18D_YTARGET}, 4343 {0xa0, 0x6c, ZC3XX_R18D_YTARGET}, /*jfm: was 78*/
4607 {0xa0, 0x61, ZC3XX_R116_RGAIN}, 4344 {0xa0, 0x61, ZC3XX_R116_RGAIN},
4608 {0xa0, 0x65, ZC3XX_R118_BGAIN}, 4345 {0xa0, 0x65, ZC3XX_R118_BGAIN},
4609 4346 {}
4610 {0xa1, 0x01, 0x0002}, 4347};
4611 4348static const struct usb_action mi360soc_AE50HZ[] = {
4612 {0xa0, 0x09, 0x01ad}, 4349 {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
4613 {0xa0, 0x15, 0x01ae}, 4350 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
4614 4351 {0xbb, 0x00, 0x0562},
4615 {0xa0, 0x0d, 0x003a}, 4352 {0xbb, 0x01, 0x09aa},
4616 {0xa0, 0x02, 0x003b}, 4353 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
4617 {0xa0, 0x00, 0x0038}, 4354 {0xa0, 0x03, ZC3XX_R191_EXPOSURELIMITMID},
4618 {0xa0, 0x50, ZC3XX_R10A_RGB00}, /* matrix */ 4355 {0xa0, 0x9b, ZC3XX_R192_EXPOSURELIMITLOW},
4619 {0xa0, 0xf8, ZC3XX_R10B_RGB01}, 4356 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
4620 {0xa0, 0xf8, ZC3XX_R10C_RGB02}, 4357 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
4621 {0xa0, 0xf8, ZC3XX_R10D_RGB10}, 4358 {0xa0, 0x47, ZC3XX_R197_ANTIFLICKERLOW},
4622 {0xa0, 0x50, ZC3XX_R10E_RGB11}, 4359 {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE},
4623 {0xa0, 0xf8, ZC3XX_R10F_RGB12}, 4360 {0xa0, 0x1c, ZC3XX_R18F_AEUNFREEZE},
4624 {0xa0, 0xf8, ZC3XX_R110_RGB20}, 4361 {0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF},
4625 {0xa0, 0xf8, ZC3XX_R111_RGB21}, 4362 {0xa0, 0x66, ZC3XX_R1AA_DIGITALGAINSTEP},
4626 {0xa0, 0x50, ZC3XX_R112_RGB22}, 4363 {0xa0, 0x62, ZC3XX_R01D_HSYNC_0},
4627 4364 {0xa0, 0x90, ZC3XX_R01E_HSYNC_1},
4628 {0xa1, 0x01, 0x0008}, 4365 {0xa0, 0xc8, ZC3XX_R01F_HSYNC_2},
4629 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */ 4366 {0xa0, 0xff, ZC3XX_R020_HSYNC_3},
4630 {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */ 4367 {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN},
4631 {0xa1, 0x01, 0x01c8}, 4368 {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
4632 {0xa1, 0x01, 0x01c9}, 4369 {}
4633 {0xa1, 0x01, 0x01ca}, 4370};
4634 {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */ 4371static const struct usb_action mi360soc_AE50HZScale[] = {
4635
4636 {0xa0, 0x13, ZC3XX_R120_GAMMA00}, /* gamma 4 */
4637 {0xa0, 0x38, ZC3XX_R121_GAMMA01},
4638 {0xa0, 0x59, ZC3XX_R122_GAMMA02},
4639 {0xa0, 0x79, ZC3XX_R123_GAMMA03},
4640 {0xa0, 0x92, ZC3XX_R124_GAMMA04},
4641 {0xa0, 0xa7, ZC3XX_R125_GAMMA05},
4642 {0xa0, 0xb9, ZC3XX_R126_GAMMA06},
4643 {0xa0, 0xc8, ZC3XX_R127_GAMMA07},
4644 {0xa0, 0xd4, ZC3XX_R128_GAMMA08},
4645 {0xa0, 0xdf, ZC3XX_R129_GAMMA09},
4646 {0xa0, 0xe7, ZC3XX_R12A_GAMMA0A},
4647 {0xa0, 0xee, ZC3XX_R12B_GAMMA0B},
4648 {0xa0, 0xf4, ZC3XX_R12C_GAMMA0C},
4649 {0xa0, 0xf9, ZC3XX_R12D_GAMMA0D},
4650 {0xa0, 0xfc, ZC3XX_R12E_GAMMA0E},
4651 {0xa0, 0xff, ZC3XX_R12F_GAMMA0F},
4652 {0xa0, 0x26, ZC3XX_R130_GAMMA10},
4653 {0xa0, 0x22, ZC3XX_R131_GAMMA11},
4654 {0xa0, 0x20, ZC3XX_R132_GAMMA12},
4655 {0xa0, 0x1c, ZC3XX_R133_GAMMA13},
4656 {0xa0, 0x16, ZC3XX_R134_GAMMA14},
4657 {0xa0, 0x13, ZC3XX_R135_GAMMA15},
4658 {0xa0, 0x10, ZC3XX_R136_GAMMA16},
4659 {0xa0, 0x0d, ZC3XX_R137_GAMMA17},
4660 {0xa0, 0x0b, ZC3XX_R138_GAMMA18},
4661 {0xa0, 0x09, ZC3XX_R139_GAMMA19},
4662 {0xa0, 0x07, ZC3XX_R13A_GAMMA1A},
4663 {0xa0, 0x06, ZC3XX_R13B_GAMMA1B},
4664 {0xa0, 0x05, ZC3XX_R13C_GAMMA1C},
4665 {0xa0, 0x04, ZC3XX_R13D_GAMMA1D},
4666 {0xa0, 0x03, ZC3XX_R13E_GAMMA1E},
4667 {0xa0, 0x02, ZC3XX_R13F_GAMMA1F},
4668 {0xa0, 0x50, ZC3XX_R10A_RGB00}, /* matrix */
4669 {0xa0, 0xf8, ZC3XX_R10B_RGB01},
4670 {0xa0, 0xf8, ZC3XX_R10C_RGB02},
4671 {0xa0, 0xf8, ZC3XX_R10D_RGB10},
4672 {0xa0, 0x50, ZC3XX_R10E_RGB11},
4673 {0xa0, 0xf8, ZC3XX_R10F_RGB12},
4674 {0xa0, 0xf8, ZC3XX_R110_RGB20},
4675 {0xa0, 0xf8, ZC3XX_R111_RGB21},
4676 {0xa0, 0x50, ZC3XX_R112_RGB22},
4677
4678 {0xa1, 0x01, 0x0180},
4679 {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE}, 4372 {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
4373 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
4374 {0xbb, 0x00, 0x0509},
4375 {0xbb, 0x01, 0x0934},
4376 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
4377 {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID},
4378 {0xa0, 0xd2, ZC3XX_R192_EXPOSURELIMITLOW},
4379 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
4380 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
4381 {0xa0, 0x9a, ZC3XX_R197_ANTIFLICKERLOW},
4382 {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE},
4383 {0xa0, 0x1c, ZC3XX_R18F_AEUNFREEZE},
4384 {0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF},
4385 {0xa0, 0x66, ZC3XX_R1AA_DIGITALGAINSTEP},
4386 {0xa0, 0xd7, ZC3XX_R01D_HSYNC_0},
4387 {0xa0, 0xf4, ZC3XX_R01E_HSYNC_1},
4388 {0xa0, 0xf9, ZC3XX_R01F_HSYNC_2},
4389 {0xa0, 0xff, ZC3XX_R020_HSYNC_3},
4390 {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
4391 {}
4392};
4393static const struct usb_action mi360soc_AE60HZ[] = {
4394 {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
4395 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
4396 {0xbb, 0x00, 0x053d},
4397 {0xbb, 0x01, 0x096e},
4398 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
4399 {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID},
4400 {0xa0, 0xdd, ZC3XX_R192_EXPOSURELIMITLOW},
4401 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
4402 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
4403 {0xa0, 0x3d, ZC3XX_R197_ANTIFLICKERLOW},
4404 {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE},
4405 {0xa0, 0x1c, ZC3XX_R18F_AEUNFREEZE},
4406 {0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF},
4407 {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP},
4408 {0xa0, 0x62, ZC3XX_R01D_HSYNC_0},
4409 {0xa0, 0x90, ZC3XX_R01E_HSYNC_1},
4410 {0xa0, 0xc8, ZC3XX_R01F_HSYNC_2},
4411 {0xa0, 0xff, ZC3XX_R020_HSYNC_3},
4412 {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN},
4413 {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
4414 {}
4415};
4416static const struct usb_action mi360soc_AE60HZScale[] = {
4680 {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE}, 4417 {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
4681 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, 4418 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
4682 {0xaa, 0x05, 0x0009}, 4419 {0xbb, 0x00, 0x0509},
4683 {0xaa, 0x09, 0x0134}, 4420 {0xbb, 0x01, 0x0983},
4684 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, 4421 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
4685 {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, 4422 {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID},
4686 {0xa0, 0xec, ZC3XX_R192_EXPOSURELIMITLOW}, 4423 {0xa0, 0x8f, ZC3XX_R192_EXPOSURELIMITLOW},
4687 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, 4424 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
4688 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, 4425 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
4689 {0xa0, 0x9c, ZC3XX_R197_ANTIFLICKERLOW}, 4426 {0xa0, 0x81, ZC3XX_R197_ANTIFLICKERLOW},
4690 {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE}, 4427 {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE},
4691 {0xa0, 0x1c, ZC3XX_R18F_AEUNFREEZE}, 4428 {0xa0, 0x1c, ZC3XX_R18F_AEUNFREEZE},
4692 {0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF}, 4429 {0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF},
@@ -4696,20 +4433,60 @@ static const struct usb_action pb03303x_InitialScale[] = {
4696 {0xa0, 0xf9, ZC3XX_R01F_HSYNC_2}, 4433 {0xa0, 0xf9, ZC3XX_R01F_HSYNC_2},
4697 {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, 4434 {0xa0, 0xff, ZC3XX_R020_HSYNC_3},
4698 {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, 4435 {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
4699 {0xa0, 0x09, 0x01ad}, 4436 {}
4700 {0xa0, 0x15, 0x01ae}, 4437};
4701 {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE}, 4438static const struct usb_action mi360soc_AENoFliker[] = {
4702 {0xa1, 0x01, 0x0180}, 4439 {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
4440 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
4441 {0xbb, 0x00, 0x0509},
4442 {0xbb, 0x01, 0x0960},
4443 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
4444 {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID},
4445 {0xa0, 0xf0, ZC3XX_R192_EXPOSURELIMITLOW},
4446 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
4447 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
4448 {0xa0, 0x04, ZC3XX_R197_ANTIFLICKERLOW},
4449 {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE},
4450 {0xa0, 0x1c, ZC3XX_R18F_AEUNFREEZE},
4451 {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF},
4452 {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP},
4453 {0xa0, 0x09, ZC3XX_R01D_HSYNC_0},
4454 {0xa0, 0x40, ZC3XX_R01E_HSYNC_1},
4455 {0xa0, 0x90, ZC3XX_R01F_HSYNC_2},
4456 {0xa0, 0xe0, ZC3XX_R020_HSYNC_3},
4457 {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN},
4703 {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, 4458 {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
4704 {} 4459 {}
4705}; 4460};
4706static const struct usb_action pb0330xx_Initial[] = { 4461static const struct usb_action mi360soc_AENoFlikerScale[] = {
4707 {0xa1, 0x01, 0x0008}, 4462 {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
4708 {0xa1, 0x01, 0x0008}, 4463 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
4464 {0xbb, 0x00, 0x0534},
4465 {0xbb, 0x02, 0x0960},
4466 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
4467 {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID},
4468 {0xa0, 0xf0, ZC3XX_R192_EXPOSURELIMITLOW},
4469 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
4470 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
4471 {0xa0, 0x04, ZC3XX_R197_ANTIFLICKERLOW},
4472 {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE},
4473 {0xa0, 0x1c, ZC3XX_R18F_AEUNFREEZE},
4474 {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF},
4475 {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP},
4476 {0xa0, 0x34, ZC3XX_R01D_HSYNC_0},
4477 {0xa0, 0x60, ZC3XX_R01E_HSYNC_1},
4478 {0xa0, 0x90, ZC3XX_R01F_HSYNC_2},
4479 {0xa0, 0xe0, ZC3XX_R020_HSYNC_3},
4480 {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN},
4481 {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
4482 {}
4483};
4484
4485static const struct usb_action pb0330_Initial[] = { /* 640x480 */
4709 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, 4486 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
4710 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* 00 */ 4487 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* 00 */
4711 {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, 4488 {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT},
4712 {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, 4489 {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT},
4713 {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, 4490 {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH},
4714 {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, 4491 {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW},
4715 {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, 4492 {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH},
@@ -4721,11 +4498,12 @@ static const struct usb_action pb0330xx_Initial[] = {
4721 {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, 4498 {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW},
4722 {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, 4499 {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW},
4723 {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, 4500 {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW},
4501 {0xdd, 0x00, 0x0200},
4724 {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, 4502 {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC},
4725 {0xaa, 0x01, 0x0006}, 4503 {0xaa, 0x01, 0x0006},
4726 {0xaa, 0x02, 0x0011}, 4504 {0xaa, 0x02, 0x0011},
4727 {0xaa, 0x03, 0x01e7}, 4505 {0xaa, 0x03, 0x01e5}, /*jfm: was 1e7*/
4728 {0xaa, 0x04, 0x0287}, 4506 {0xaa, 0x04, 0x0285}, /*jfm: was 0287*/
4729 {0xaa, 0x06, 0x0003}, 4507 {0xaa, 0x06, 0x0003},
4730 {0xaa, 0x07, 0x3002}, 4508 {0xaa, 0x07, 0x3002},
4731 {0xaa, 0x20, 0x1100}, 4509 {0xaa, 0x20, 0x1100},
@@ -4743,88 +4521,21 @@ static const struct usb_action pb0330xx_Initial[] = {
4743 {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, 4521 {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC},
4744 {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, 4522 {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE},
4745 {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, 4523 {0xa0, 0x06, ZC3XX_R189_AWBSTATUS},
4746 {0xa0, 0x00, 0x01ad}, 4524 {0xa0, 0x09, 0x01ad}, /*jfm: was 00 */
4525 {0xa0, 0x15, 0x01ae},
4747 {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, 4526 {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE},
4748 {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, 4527 {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05},
4749 {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, 4528 {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},
4750 {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, 4529 {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
4751 {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN}, 4530 {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN},
4752 {0xa0, 0x6c, ZC3XX_R18D_YTARGET}, 4531 {0xa0, 0x78, ZC3XX_R18D_YTARGET}, /*jfm: was 6c*/
4753 {0xa1, 0x01, 0x0002},
4754 {0xa0, 0x09, 0x01ad},
4755 {0xa0, 0x15, 0x01ae},
4756 {0xa0, 0x00, ZC3XX_R092_I2CADDRESSSELECT},
4757 {0xa0, 0x02, ZC3XX_R090_I2CCOMMAND},
4758 {0xa1, 0x01, 0x0091},
4759 {0xa1, 0x01, 0x0095},
4760 {0xa1, 0x01, 0x0096},
4761 {0xa0, 0x50, ZC3XX_R10A_RGB00}, /* matrix */
4762 {0xa0, 0xf8, ZC3XX_R10B_RGB01},
4763 {0xa0, 0xf8, ZC3XX_R10C_RGB02},
4764 {0xa0, 0xf8, ZC3XX_R10D_RGB10},
4765 {0xa0, 0x50, ZC3XX_R10E_RGB11},
4766 {0xa0, 0xf8, ZC3XX_R10F_RGB12},
4767 {0xa0, 0xf8, ZC3XX_R110_RGB20},
4768 {0xa0, 0xf8, ZC3XX_R111_RGB21},
4769 {0xa0, 0x50, ZC3XX_R112_RGB22},
4770 {0xa1, 0x01, 0x0008},
4771 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */
4772 {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */
4773 {0xa1, 0x01, 0x01c8},
4774 {0xa1, 0x01, 0x01c9},
4775 {0xa1, 0x01, 0x01ca},
4776 {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */
4777
4778 {0xa0, 0x50, ZC3XX_R10A_RGB00}, /* matrix */
4779 {0xa0, 0xf8, ZC3XX_R10B_RGB01},
4780 {0xa0, 0xf8, ZC3XX_R10C_RGB02},
4781 {0xa0, 0xf8, ZC3XX_R10D_RGB10},
4782 {0xa0, 0x50, ZC3XX_R10E_RGB11},
4783 {0xa0, 0xf8, ZC3XX_R10F_RGB12},
4784 {0xa0, 0xf8, ZC3XX_R110_RGB20},
4785 {0xa0, 0xf8, ZC3XX_R111_RGB21},
4786 {0xa0, 0x50, ZC3XX_R112_RGB22},
4787 {0xa1, 0x01, 0x0180},
4788 {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
4789 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
4790 {0xaa, 0x05, 0x0066},
4791 {0xaa, 0x09, 0x02b2},
4792 {0xaa, 0x10, 0x0002},
4793
4794 {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN},
4795 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
4796 {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID},
4797 {0xa0, 0x8c, ZC3XX_R192_EXPOSURELIMITLOW},
4798 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
4799 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
4800 {0xa0, 0x8a, ZC3XX_R197_ANTIFLICKERLOW},
4801 {0xa0, 0x10, ZC3XX_R18C_AEFREEZE},
4802 {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE},
4803 {0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF},
4804 {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP},
4805 {0xa0, 0xd7, ZC3XX_R01D_HSYNC_0},
4806 {0xa0, 0xf0, ZC3XX_R01E_HSYNC_1},
4807 {0xa0, 0xf8, ZC3XX_R01F_HSYNC_2},
4808 {0xa0, 0xff, ZC3XX_R020_HSYNC_3},
4809 {0xa0, 0x09, 0x01ad},
4810 {0xa0, 0x15, 0x01ae},
4811 {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE},
4812 {0xa1, 0x01, 0x0180},
4813 {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
4814 {0xa1, 0x01, 0x0008},
4815 {0xa1, 0x01, 0x0007},
4816/* {0xa0, 0x30, 0x0007}, */
4817/* {0xa0, 0x00, 0x0007}, */
4818 {} 4532 {}
4819}; 4533};
4820 4534static const struct usb_action pb0330_InitialScale[] = { /* 320x240 */
4821static const struct usb_action pb0330xx_InitialScale[] = {
4822 {0xa1, 0x01, 0x0008},
4823 {0xa1, 0x01, 0x0008},
4824 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, 4535 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
4825 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* 00 */ 4536 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* 00 */
4826 {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, 4537 {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT},
4827 {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, /* 10 */ 4538 {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT},
4828 {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, 4539 {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH},
4829 {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, 4540 {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW},
4830 {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, 4541 {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH},
@@ -4836,6 +4547,7 @@ static const struct usb_action pb0330xx_InitialScale[] = {
4836 {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, 4547 {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW},
4837 {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, 4548 {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW},
4838 {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, 4549 {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW},
4550 {0xdd, 0x00, 0x0200},
4839 {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, 4551 {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC},
4840 {0xaa, 0x01, 0x0006}, 4552 {0xaa, 0x01, 0x0006},
4841 {0xaa, 0x02, 0x0011}, 4553 {0xaa, 0x02, 0x0011},
@@ -4858,53 +4570,43 @@ static const struct usb_action pb0330xx_InitialScale[] = {
4858 {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, 4570 {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC},
4859 {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, 4571 {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE},
4860 {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, 4572 {0xa0, 0x06, ZC3XX_R189_AWBSTATUS},
4861 {0xa0, 0x00, 0x01ad}, 4573 {0xa0, 0x09, 0x01ad},
4574 {0xa0, 0x15, 0x01ae},
4862 {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, 4575 {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE},
4863 {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, 4576 {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05},
4864 {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, 4577 {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},
4865 {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, 4578 {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
4866 {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN}, 4579 {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN},
4867 {0xa0, 0x6c, ZC3XX_R18D_YTARGET}, 4580 {0xa0, 0x78, ZC3XX_R18D_YTARGET}, /*jfm: was 6c*/
4868 {0xa1, 0x01, 0x0002}, 4581 {}
4869 {0xa0, 0x09, 0x01ad}, 4582};
4870 {0xa0, 0x15, 0x01ae}, 4583static const struct usb_action pb0330_50HZ[] = {
4871 {0xa0, 0x00, ZC3XX_R092_I2CADDRESSSELECT},
4872 {0xa0, 0x02, ZC3XX_R090_I2CCOMMAND},
4873 {0xa1, 0x01, 0x0091},
4874 {0xa1, 0x01, 0x0095},
4875 {0xa1, 0x01, 0x0096},
4876 {0xa0, 0x50, ZC3XX_R10A_RGB00}, /* matrix */
4877 {0xa0, 0xf8, ZC3XX_R10B_RGB01},
4878 {0xa0, 0xf8, ZC3XX_R10C_RGB02},
4879 {0xa0, 0xf8, ZC3XX_R10D_RGB10},
4880 {0xa0, 0x50, ZC3XX_R10E_RGB11},
4881 {0xa0, 0xf8, ZC3XX_R10F_RGB12},
4882 {0xa0, 0xf8, ZC3XX_R110_RGB20},
4883 {0xa0, 0xf8, ZC3XX_R111_RGB21},
4884 {0xa0, 0x50, ZC3XX_R112_RGB22},
4885 {0xa1, 0x01, 0x0008},
4886 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */
4887 {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */
4888 {0xa1, 0x01, 0x01c8},
4889 {0xa1, 0x01, 0x01c9},
4890 {0xa1, 0x01, 0x01ca},
4891 {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */
4892
4893 {0xa0, 0x50, ZC3XX_R10A_RGB00}, /* matrix */
4894 {0xa0, 0xf8, ZC3XX_R10B_RGB01},
4895 {0xa0, 0xf8, ZC3XX_R10C_RGB02},
4896 {0xa0, 0xf8, ZC3XX_R10D_RGB10},
4897 {0xa0, 0x50, ZC3XX_R10E_RGB11},
4898 {0xa0, 0xf8, ZC3XX_R10F_RGB12},
4899 {0xa0, 0xf8, ZC3XX_R110_RGB20},
4900 {0xa0, 0xf8, ZC3XX_R111_RGB21},
4901 {0xa0, 0x50, ZC3XX_R112_RGB22},
4902 {0xa1, 0x01, 0x0180},
4903 {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
4904 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, 4584 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
4905 {0xaa, 0x05, 0x0066}, 4585 {0xbb, 0x00, 0x055c},
4906 {0xaa, 0x09, 0x02b2}, 4586 {0xbb, 0x01, 0x09aa},
4907 {0xaa, 0x10, 0x0002}, 4587 {0xbb, 0x00, 0x1001},
4588 {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN},
4589 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
4590 {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID},
4591 {0xa0, 0xc4, ZC3XX_R192_EXPOSURELIMITLOW},
4592 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
4593 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
4594 {0xa0, 0x47, ZC3XX_R197_ANTIFLICKERLOW},
4595 {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE},
4596 {0xa0, 0x1a, ZC3XX_R18F_AEUNFREEZE},
4597 {0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF},
4598 {0xa0, 0x66, ZC3XX_R1AA_DIGITALGAINSTEP},
4599 {0xa0, 0x5c, ZC3XX_R01D_HSYNC_0},
4600 {0xa0, 0x90, ZC3XX_R01E_HSYNC_1},
4601 {0xa0, 0xc8, ZC3XX_R01F_HSYNC_2},
4602 {0xa0, 0xff, ZC3XX_R020_HSYNC_3},
4603 {}
4604};
4605static const struct usb_action pb0330_50HZScale[] = {
4606 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
4607 {0xbb, 0x00, 0x0566},
4608 {0xbb, 0x02, 0x09b2},
4609 {0xbb, 0x00, 0x1002},
4908 {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN}, 4610 {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN},
4909 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, 4611 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
4910 {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, 4612 {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID},
@@ -4912,124 +4614,102 @@ static const struct usb_action pb0330xx_InitialScale[] = {
4912 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, 4614 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
4913 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, 4615 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
4914 {0xa0, 0x8a, ZC3XX_R197_ANTIFLICKERLOW}, 4616 {0xa0, 0x8a, ZC3XX_R197_ANTIFLICKERLOW},
4915 {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, 4617 {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE},
4916 {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, 4618 {0xa0, 0x1a, ZC3XX_R18F_AEUNFREEZE},
4917 {0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF}, 4619 {0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF},
4918 {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, 4620 {0xa0, 0x66, ZC3XX_R1AA_DIGITALGAINSTEP},
4919 {0xa0, 0xd7, ZC3XX_R01D_HSYNC_0}, 4621 {0xa0, 0xd7, ZC3XX_R01D_HSYNC_0},
4920 {0xa0, 0xf0, ZC3XX_R01E_HSYNC_1}, 4622 {0xa0, 0xf0, ZC3XX_R01E_HSYNC_1},
4921 {0xa0, 0xf8, ZC3XX_R01F_HSYNC_2}, 4623 {0xa0, 0xf8, ZC3XX_R01F_HSYNC_2},
4922 {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, 4624 {0xa0, 0xff, ZC3XX_R020_HSYNC_3},
4923 {0xa0, 0x09, 0x01ad},
4924 {0xa0, 0x15, 0x01ae},
4925 {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE},
4926 {0xa1, 0x01, 0x0180},
4927 {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
4928 {0xa1, 0x01, 0x0008},
4929 {0xa1, 0x01, 0x0007},
4930/* {0xa0, 0x30, 0x0007}, */
4931/* {0xa0, 0x00, 0x0007}, */
4932 {}
4933};
4934static const struct usb_action pb0330_50HZ[] = {
4935 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
4936 {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,07,cc */
4937 {0xa0, 0xee, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,ee,cc */
4938 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
4939 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
4940 {0xa0, 0x46, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,46,cc */
4941 {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
4942 {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
4943 {0xa0, 0x0c, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,0c,cc */
4944 {0xa0, 0x26, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,26,cc */
4945 {0xa0, 0x68, ZC3XX_R01D_HSYNC_0}, /* 00,1d,68,cc */
4946 {0xa0, 0x90, ZC3XX_R01E_HSYNC_1}, /* 00,1e,90,cc */
4947 {0xa0, 0xc8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,c8,cc */
4948 {}
4949};
4950static const struct usb_action pb0330_50HZScale[] = {
4951 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
4952 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
4953 {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,07,cc */
4954 {0xa0, 0xa0, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,a0,cc */
4955 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
4956 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
4957 {0xa0, 0x7a, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,7a,cc */
4958 {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
4959 {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
4960 {0xa0, 0x0c, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,0c,cc */
4961 {0xa0, 0x26, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,26,cc */
4962 {0xa0, 0xe5, ZC3XX_R01D_HSYNC_0}, /* 00,1d,e5,cc */
4963 {0xa0, 0xf0, ZC3XX_R01E_HSYNC_1}, /* 00,1e,f0,cc */
4964 {0xa0, 0xf8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,f8,cc */
4965 {} 4625 {}
4966}; 4626};
4967static const struct usb_action pb0330_60HZ[] = { 4627static const struct usb_action pb0330_60HZ[] = {
4968 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ 4628 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
4969 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ 4629 {0xbb, 0x00, 0x0535},
4970 {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,07,cc */ 4630 {0xbb, 0x01, 0x0974},
4971 {0xa0, 0xdd, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,dd,cc */ 4631 {0xbb, 0x00, 0x1001},
4972 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ 4632 {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN},
4973 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ 4633 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
4974 {0xa0, 0x3d, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,3d,cc */ 4634 {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID},
4975 {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ 4635 {0xa0, 0xfe, ZC3XX_R192_EXPOSURELIMITLOW},
4976 {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ 4636 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
4977 {0xa0, 0x0c, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,0c,cc */ 4637 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
4978 {0xa0, 0x26, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,26,cc */ 4638 {0xa0, 0x3e, ZC3XX_R197_ANTIFLICKERLOW},
4979 {0xa0, 0x43, ZC3XX_R01D_HSYNC_0}, /* 00,1d,43,cc */ 4639 {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE},
4980 {0xa0, 0x50, ZC3XX_R01E_HSYNC_1}, /* 00,1e,50,cc */ 4640 {0xa0, 0x1a, ZC3XX_R18F_AEUNFREEZE},
4981 {0xa0, 0x90, ZC3XX_R01F_HSYNC_2}, /* 00,1f,90,cc */ 4641 {0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF},
4642 {0xa0, 0x66, ZC3XX_R1AA_DIGITALGAINSTEP},
4643 {0xa0, 0x35, ZC3XX_R01D_HSYNC_0},
4644 {0xa0, 0x50, ZC3XX_R01E_HSYNC_1},
4645 {0xa0, 0x90, ZC3XX_R01F_HSYNC_2},
4646 {0xa0, 0xd0, ZC3XX_R020_HSYNC_3},
4982 {} 4647 {}
4983}; 4648};
4984static const struct usb_action pb0330_60HZScale[] = { 4649static const struct usb_action pb0330_60HZScale[] = {
4985 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ 4650 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
4986 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ 4651 {0xbb, 0x00, 0x0535},
4987 {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,07,cc */ 4652 {0xbb, 0x02, 0x096c},
4988 {0xa0, 0xa0, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,a0,cc */ 4653 {0xbb, 0x00, 0x1002},
4989 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ 4654 {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN},
4990 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ 4655 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
4991 {0xa0, 0x7a, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,7a,cc */ 4656 {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID},
4992 {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ 4657 {0xa0, 0xc0, ZC3XX_R192_EXPOSURELIMITLOW},
4993 {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ 4658 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
4994 {0xa0, 0x0c, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,0c,cc */ 4659 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
4995 {0xa0, 0x26, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,26,cc */ 4660 {0xa0, 0x7c, ZC3XX_R197_ANTIFLICKERLOW},
4996 {0xa0, 0x41, ZC3XX_R01D_HSYNC_0}, /* 00,1d,41,cc */ 4661 {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE},
4997 {0xa0, 0x50, ZC3XX_R01E_HSYNC_1}, /* 00,1e,50,cc */ 4662 {0xa0, 0x1a, ZC3XX_R18F_AEUNFREEZE},
4998 {0xa0, 0x90, ZC3XX_R01F_HSYNC_2}, /* 00,1f,90,cc */ 4663 {0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF},
4664 {0xa0, 0x66, ZC3XX_R1AA_DIGITALGAINSTEP},
4665 {0xa0, 0x35, ZC3XX_R01D_HSYNC_0},
4666 {0xa0, 0x50, ZC3XX_R01E_HSYNC_1},
4667 {0xa0, 0x90, ZC3XX_R01F_HSYNC_2},
4668 {0xa0, 0xd0, ZC3XX_R020_HSYNC_3},
4999 {} 4669 {}
5000}; 4670};
5001static const struct usb_action pb0330_NoFliker[] = { 4671static const struct usb_action pb0330_NoFliker[] = {
5002 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ 4672 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
5003 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ 4673 {0xbb, 0x00, 0x0509},
5004 {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,07,cc */ 4674 {0xbb, 0x02, 0x0940},
5005 {0xa0, 0xf0, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,f0,cc */ 4675 {0xbb, 0x00, 0x1002},
5006 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ 4676 {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN},
5007 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ 4677 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
5008 {0xa0, 0x10, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,10,cc */ 4678 {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID},
5009 {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ 4679 {0xa0, 0xf0, ZC3XX_R192_EXPOSURELIMITLOW},
5010 {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ 4680 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
5011 {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,00,cc */ 4681 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
5012 {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,00,cc */ 4682 {0xa0, 0x01, ZC3XX_R197_ANTIFLICKERLOW},
5013 {0xa0, 0x09, ZC3XX_R01D_HSYNC_0}, /* 00,1d,09,cc */ 4683 {0xa0, 0x10, ZC3XX_R18C_AEFREEZE},
5014 {0xa0, 0x40, ZC3XX_R01E_HSYNC_1}, /* 00,1e,40,cc */ 4684 {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE},
5015 {0xa0, 0x90, ZC3XX_R01F_HSYNC_2}, /* 00,1f,90,cc */ 4685 {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF},
4686 {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP},
4687 {0xa0, 0x09, ZC3XX_R01D_HSYNC_0},
4688 {0xa0, 0x40, ZC3XX_R01E_HSYNC_1},
4689 {0xa0, 0x90, ZC3XX_R01F_HSYNC_2},
4690 {0xa0, 0xe0, ZC3XX_R020_HSYNC_3},
5016 {} 4691 {}
5017}; 4692};
5018static const struct usb_action pb0330_NoFlikerScale[] = { 4693static const struct usb_action pb0330_NoFlikerScale[] = {
5019 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ 4694 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
5020 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ 4695 {0xbb, 0x00, 0x0535},
5021 {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,07,cc */ 4696 {0xbb, 0x01, 0x0980},
5022 {0xa0, 0xf0, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,f0,cc */ 4697 {0xbb, 0x00, 0x1001},
5023 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ 4698 {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN},
5024 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ 4699 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
5025 {0xa0, 0x10, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,10,cc */ 4700 {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID},
5026 {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ 4701 {0xa0, 0xf0, ZC3XX_R192_EXPOSURELIMITLOW},
5027 {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ 4702 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
5028 {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,00,cc */ 4703 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
5029 {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,00,cc */ 4704 {0xa0, 0x01, ZC3XX_R197_ANTIFLICKERLOW},
5030 {0xa0, 0x09, ZC3XX_R01D_HSYNC_0}, /* 00,1d,09,cc */ 4705 {0xa0, 0x10, ZC3XX_R18C_AEFREEZE},
5031 {0xa0, 0x40, ZC3XX_R01E_HSYNC_1}, /* 00,1e,40,cc */ 4706 {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE},
5032 {0xa0, 0x90, ZC3XX_R01F_HSYNC_2}, /* 00,1f,90,cc */ 4707 {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF},
4708 {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP},
4709 {0xa0, 0x35, ZC3XX_R01D_HSYNC_0},
4710 {0xa0, 0x60, ZC3XX_R01E_HSYNC_1},
4711 {0xa0, 0x90, ZC3XX_R01F_HSYNC_2},
4712 {0xa0, 0xe0, ZC3XX_R020_HSYNC_3},
5033 {} 4713 {}
5034}; 4714};
5035 4715
@@ -5655,7 +5335,7 @@ static const struct usb_action tas5130CK_InitialScale[] = {
5655 {} 5335 {}
5656}; 5336};
5657 5337
5658static const struct usb_action tas5130cxx_Initial[] = { 5338static const struct usb_action tas5130cxx_InitialScale[] = { /* 320x240 */
5659 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, 5339 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
5660 {0xa0, 0x50, ZC3XX_R002_CLOCKSELECT}, 5340 {0xa0, 0x50, ZC3XX_R002_CLOCKSELECT},
5661 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, 5341 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
@@ -5684,74 +5364,19 @@ static const struct usb_action tas5130cxx_Initial[] = {
5684 {0xa0, 0xf7, ZC3XX_R101_SENSORCORRECTION}, 5364 {0xa0, 0xf7, ZC3XX_R101_SENSORCORRECTION},
5685 {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, 5365 {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE},
5686 {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, 5366 {0xa0, 0x06, ZC3XX_R189_AWBSTATUS},
5687 {0xa0, 0x68, ZC3XX_R18D_YTARGET}, 5367 {0xa0, 0x95, ZC3XX_R18D_YTARGET},
5688 {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN}, 5368 {0xa0, 0x50, ZC3XX_R1A8_DIGITALGAIN},
5689 {0xa0, 0x00, 0x01ad}, 5369 {0xa0, 0x00, 0x01ad},
5690 {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, 5370 {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE},
5691 {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, 5371 {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05},
5692 {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, 5372 {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},
5693 {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, 5373 {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
5694 {0xa1, 0x01, 0x0002},
5695 {0xa1, 0x01, 0x0008},
5696 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */
5697 {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */
5698 {0xa1, 0x01, 0x01c8},
5699 {0xa1, 0x01, 0x01c9},
5700 {0xa1, 0x01, 0x01ca},
5701 {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */
5702
5703 {0xa0, 0x68, ZC3XX_R10A_RGB00}, /* matrix */
5704 {0xa0, 0xec, ZC3XX_R10B_RGB01},
5705 {0xa0, 0xec, ZC3XX_R10C_RGB02},
5706 {0xa0, 0xec, ZC3XX_R10D_RGB10},
5707 {0xa0, 0x68, ZC3XX_R10E_RGB11},
5708 {0xa0, 0xec, ZC3XX_R10F_RGB12},
5709 {0xa0, 0xec, ZC3XX_R110_RGB20},
5710 {0xa0, 0xec, ZC3XX_R111_RGB21},
5711 {0xa0, 0x68, ZC3XX_R112_RGB22},
5712
5713 {0xa1, 0x01, 0x018d},
5714 {0xa0, 0x90, ZC3XX_R18D_YTARGET}, /* 90 */
5715 {0xa1, 0x01, 0x0180},
5716 {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
5717 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
5718
5719 {0xaa, 0xa3, 0x0001},
5720 {0xaa, 0xa4, 0x0077},
5721 {0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH},
5722 {0xa0, 0x77, ZC3XX_R0A4_EXPOSURETIMELOW},
5723
5724 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 00 */
5725 {0xa0, 0x03, ZC3XX_R191_EXPOSURELIMITMID}, /* 03 */
5726 {0xa0, 0xe8, ZC3XX_R192_EXPOSURELIMITLOW}, /* e8 */
5727 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 0 */
5728 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 0 */
5729 {0xa0, 0x7d, ZC3XX_R197_ANTIFLICKERLOW}, /* 7d */
5730
5731 {0xa0, 0x0c, ZC3XX_R18C_AEFREEZE},
5732 {0xa0, 0x18, ZC3XX_R18F_AEUNFREEZE},
5733 {0xa0, 0x08, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 08 */
5734 {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 24 */
5735 {0xa0, 0xf0, ZC3XX_R01D_HSYNC_0},
5736 {0xa0, 0xf4, ZC3XX_R01E_HSYNC_1},
5737 {0xa0, 0xf8, ZC3XX_R01F_HSYNC_2},
5738 {0xa0, 0xff, ZC3XX_R020_HSYNC_3},
5739 {0xa0, 0x03, ZC3XX_R09F_MAXXHIGH},
5740 {0xa0, 0xc0, ZC3XX_R0A0_MAXXLOW},
5741 {0xa0, 0x50, ZC3XX_R11D_GLOBALGAIN}, /* 50 */
5742 {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE},
5743 {0xa1, 0x01, 0x0180},
5744 {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
5745 {} 5374 {}
5746}; 5375};
5747static const struct usb_action tas5130cxx_InitialScale[] = { 5376static const struct usb_action tas5130cxx_Initial[] = { /* 640x480 */
5748/*?? {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, */
5749 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, 5377 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
5750 {0xa0, 0x40, ZC3XX_R002_CLOCKSELECT}, 5378 {0xa0, 0x40, ZC3XX_R002_CLOCKSELECT},
5751
5752 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, 5379 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
5753 {0xa1, 0x01, 0x0008},
5754
5755 {0xa0, 0x02, ZC3XX_R010_CMOSSENSORSELECT}, 5380 {0xa0, 0x02, ZC3XX_R010_CMOSSENSORSELECT},
5756 {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, 5381 {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING},
5757 {0xa0, 0x00, ZC3XX_R001_SYSTEMOPERATING}, 5382 {0xa0, 0x00, ZC3XX_R001_SYSTEMOPERATING},
@@ -5775,63 +5400,13 @@ static const struct usb_action tas5130cxx_InitialScale[] = {
5775 {0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION}, 5400 {0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION},
5776 {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, 5401 {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE},
5777 {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, 5402 {0xa0, 0x06, ZC3XX_R189_AWBSTATUS},
5778 {0xa0, 0x68, ZC3XX_R18D_YTARGET}, 5403 {0xa0, 0x95, ZC3XX_R18D_YTARGET},
5779 {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN}, 5404 {0xa0, 0x50, ZC3XX_R1A8_DIGITALGAIN},
5780 {0xa0, 0x00, 0x01ad}, 5405 {0xa0, 0x00, 0x01ad},
5781 {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, 5406 {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE},
5782 {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, 5407 {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05},
5783 {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, 5408 {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},
5784 {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, 5409 {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
5785 {0xa1, 0x01, 0x0002},
5786 {0xa1, 0x01, 0x0008},
5787
5788 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
5789 {0xa1, 0x01, 0x0008}, /* clock ? */
5790 {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */
5791 {0xa1, 0x01, 0x01c8},
5792 {0xa1, 0x01, 0x01c9},
5793 {0xa1, 0x01, 0x01ca},
5794 {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */
5795
5796 {0xa0, 0x68, ZC3XX_R10A_RGB00}, /* matrix */
5797 {0xa0, 0xec, ZC3XX_R10B_RGB01},
5798 {0xa0, 0xec, ZC3XX_R10C_RGB02},
5799 {0xa0, 0xec, ZC3XX_R10D_RGB10},
5800 {0xa0, 0x68, ZC3XX_R10E_RGB11},
5801 {0xa0, 0xec, ZC3XX_R10F_RGB12},
5802 {0xa0, 0xec, ZC3XX_R110_RGB20},
5803 {0xa0, 0xec, ZC3XX_R111_RGB21},
5804 {0xa0, 0x68, ZC3XX_R112_RGB22},
5805
5806 {0xa1, 0x01, 0x018d},
5807 {0xa0, 0x90, ZC3XX_R18D_YTARGET},
5808 {0xa1, 0x01, 0x0180},
5809 {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
5810 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
5811 {0xaa, 0xa3, 0x0001},
5812 {0xaa, 0xa4, 0x0063},
5813 {0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH},
5814 {0xa0, 0x63, ZC3XX_R0A4_EXPOSURETIMELOW},
5815 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
5816 {0xa0, 0x02, ZC3XX_R191_EXPOSURELIMITMID},
5817 {0xa0, 0x38, ZC3XX_R192_EXPOSURELIMITLOW},
5818 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
5819 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
5820 {0xa0, 0x47, ZC3XX_R197_ANTIFLICKERLOW},
5821 {0xa0, 0x0c, ZC3XX_R18C_AEFREEZE},
5822 {0xa0, 0x18, ZC3XX_R18F_AEUNFREEZE},
5823 {0xa0, 0x08, ZC3XX_R1A9_DIGITALLIMITDIFF},
5824 {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP},
5825 {0xa0, 0xd3, ZC3XX_R01D_HSYNC_0},
5826 {0xa0, 0xda, ZC3XX_R01E_HSYNC_1},
5827 {0xa0, 0xea, ZC3XX_R01F_HSYNC_2},
5828 {0xa0, 0xff, ZC3XX_R020_HSYNC_3},
5829 {0xa0, 0x03, ZC3XX_R09F_MAXXHIGH},
5830 {0xa0, 0x4c, ZC3XX_R0A0_MAXXLOW},
5831 {0xa0, 0x50, ZC3XX_R11D_GLOBALGAIN},
5832 {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE},
5833 {0xa1, 0x01, 0x0180},
5834 {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
5835 {} 5410 {}
5836}; 5411};
5837static const struct usb_action tas5130cxx_50HZ[] = { 5412static const struct usb_action tas5130cxx_50HZ[] = {
@@ -5841,20 +5416,22 @@ static const struct usb_action tas5130cxx_50HZ[] = {
5841 {0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH}, /* 00,a3,01,cc */ 5416 {0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH}, /* 00,a3,01,cc */
5842 {0xa0, 0x63, ZC3XX_R0A4_EXPOSURETIMELOW}, /* 00,a4,63,cc */ 5417 {0xa0, 0x63, ZC3XX_R0A4_EXPOSURETIMELOW}, /* 00,a4,63,cc */
5843 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ 5418 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
5844 {0xa0, 0x02, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,02,cc */ 5419 {0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID},
5845 {0xa0, 0x38, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,38,cc */ 5420 {0xa0, 0xfe, ZC3XX_R192_EXPOSURELIMITLOW},
5846 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ 5421 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
5847 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ 5422 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
5848 {0xa0, 0x47, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,47,cc */ 5423 {0xa0, 0x47, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,47,cc */
5849 {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ 5424 {0xa0, 0x0c, ZC3XX_R18C_AEFREEZE},
5850 {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ 5425 {0xa0, 0x18, ZC3XX_R18F_AEUNFREEZE},
5851 {0xa0, 0x0c, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,0c,cc */ 5426 {0xa0, 0x08, ZC3XX_R1A9_DIGITALLIMITDIFF},
5852 {0xa0, 0x26, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,26,cc */ 5427 {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP},
5853 {0xa0, 0xd3, ZC3XX_R01D_HSYNC_0}, /* 00,1d,d3,cc */ 5428 {0xa0, 0xd3, ZC3XX_R01D_HSYNC_0}, /* 00,1d,d3,cc */
5854 {0xa0, 0xda, ZC3XX_R01E_HSYNC_1}, /* 00,1e,da,cc */ 5429 {0xa0, 0xda, ZC3XX_R01E_HSYNC_1}, /* 00,1e,da,cc */
5855 {0xa0, 0xea, ZC3XX_R01F_HSYNC_2}, /* 00,1f,ea,cc */ 5430 {0xa0, 0xea, ZC3XX_R01F_HSYNC_2}, /* 00,1f,ea,cc */
5856 {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */ 5431 {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */
5857 {0xa0, 0x03, ZC3XX_R09F_MAXXHIGH}, /* 00,9f,03,cc */ 5432 {0xa0, 0x03, ZC3XX_R09F_MAXXHIGH}, /* 00,9f,03,cc */
5433 {0xa0, 0x4c, ZC3XX_R0A0_MAXXLOW},
5434 {0xa0, 0x50, ZC3XX_R11D_GLOBALGAIN},
5858 {} 5435 {}
5859}; 5436};
5860static const struct usb_action tas5130cxx_50HZScale[] = { 5437static const struct usb_action tas5130cxx_50HZScale[] = {
@@ -5864,20 +5441,22 @@ static const struct usb_action tas5130cxx_50HZScale[] = {
5864 {0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH}, /* 00,a3,01,cc */ 5441 {0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH}, /* 00,a3,01,cc */
5865 {0xa0, 0x77, ZC3XX_R0A4_EXPOSURETIMELOW}, /* 00,a4,77,cc */ 5442 {0xa0, 0x77, ZC3XX_R0A4_EXPOSURETIMELOW}, /* 00,a4,77,cc */
5866 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ 5443 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
5867 {0xa0, 0x03, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,03,cc */ 5444 {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID},
5868 {0xa0, 0xe8, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,e8,cc */ 5445 {0xa0, 0xd0, ZC3XX_R192_EXPOSURELIMITLOW},
5869 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ 5446 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
5870 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ 5447 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
5871 {0xa0, 0x7d, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,7d,cc */ 5448 {0xa0, 0x7d, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,7d,cc */
5872 {0xa0, 0x14, ZC3XX_R18C_AEFREEZE}, /* 01,8c,14,cc */ 5449 {0xa0, 0x0c, ZC3XX_R18C_AEFREEZE},
5873 {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ 5450 {0xa0, 0x18, ZC3XX_R18F_AEUNFREEZE},
5874 {0xa0, 0x0c, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,0c,cc */ 5451 {0xa0, 0x08, ZC3XX_R1A9_DIGITALLIMITDIFF},
5875 {0xa0, 0x26, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,26,cc */ 5452 {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP},
5876 {0xa0, 0xf0, ZC3XX_R01D_HSYNC_0}, /* 00,1d,f0,cc */ 5453 {0xa0, 0xf0, ZC3XX_R01D_HSYNC_0}, /* 00,1d,f0,cc */
5877 {0xa0, 0xf4, ZC3XX_R01E_HSYNC_1}, /* 00,1e,f4,cc */ 5454 {0xa0, 0xf4, ZC3XX_R01E_HSYNC_1}, /* 00,1e,f4,cc */
5878 {0xa0, 0xf8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,f8,cc */ 5455 {0xa0, 0xf8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,f8,cc */
5879 {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */ 5456 {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */
5880 {0xa0, 0x03, ZC3XX_R09F_MAXXHIGH}, /* 00,9f,03,cc */ 5457 {0xa0, 0x03, ZC3XX_R09F_MAXXHIGH}, /* 00,9f,03,cc */
5458 {0xa0, 0xc0, ZC3XX_R0A0_MAXXLOW},
5459 {0xa0, 0x50, ZC3XX_R11D_GLOBALGAIN},
5881 {} 5460 {}
5882}; 5461};
5883static const struct usb_action tas5130cxx_60HZ[] = { 5462static const struct usb_action tas5130cxx_60HZ[] = {
@@ -5887,20 +5466,22 @@ static const struct usb_action tas5130cxx_60HZ[] = {
5887 {0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH}, /* 00,a3,01,cc */ 5466 {0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH}, /* 00,a3,01,cc */
5888 {0xa0, 0x36, ZC3XX_R0A4_EXPOSURETIMELOW}, /* 00,a4,36,cc */ 5467 {0xa0, 0x36, ZC3XX_R0A4_EXPOSURETIMELOW}, /* 00,a4,36,cc */
5889 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ 5468 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
5890 {0xa0, 0x01, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,01,cc */ 5469 {0xa0, 0x05, ZC3XX_R191_EXPOSURELIMITMID},
5891 {0xa0, 0xf0, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,f0,cc */ 5470 {0xa0, 0x54, ZC3XX_R192_EXPOSURELIMITLOW},
5892 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ 5471 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
5893 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ 5472 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
5894 {0xa0, 0x3e, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,3e,cc */ 5473 {0xa0, 0x3e, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,3e,cc */
5895 {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ 5474 {0xa0, 0x0c, ZC3XX_R18C_AEFREEZE},
5896 {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ 5475 {0xa0, 0x18, ZC3XX_R18F_AEUNFREEZE},
5897 {0xa0, 0x0c, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,0c,cc */ 5476 {0xa0, 0x08, ZC3XX_R1A9_DIGITALLIMITDIFF},
5898 {0xa0, 0x26, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,26,cc */ 5477 {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP},
5899 {0xa0, 0xca, ZC3XX_R01D_HSYNC_0}, /* 00,1d,ca,cc */ 5478 {0xa0, 0xca, ZC3XX_R01D_HSYNC_0}, /* 00,1d,ca,cc */
5900 {0xa0, 0xd0, ZC3XX_R01E_HSYNC_1}, /* 00,1e,d0,cc */ 5479 {0xa0, 0xd0, ZC3XX_R01E_HSYNC_1}, /* 00,1e,d0,cc */
5901 {0xa0, 0xe0, ZC3XX_R01F_HSYNC_2}, /* 00,1f,e0,cc */ 5480 {0xa0, 0xe0, ZC3XX_R01F_HSYNC_2}, /* 00,1f,e0,cc */
5902 {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */ 5481 {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */
5903 {0xa0, 0x03, ZC3XX_R09F_MAXXHIGH}, /* 00,9f,03,cc */ 5482 {0xa0, 0x03, ZC3XX_R09F_MAXXHIGH}, /* 00,9f,03,cc */
5483 {0xa0, 0x28, ZC3XX_R0A0_MAXXLOW},
5484 {0xa0, 0x50, ZC3XX_R11D_GLOBALGAIN},
5904 {} 5485 {}
5905}; 5486};
5906static const struct usb_action tas5130cxx_60HZScale[] = { 5487static const struct usb_action tas5130cxx_60HZScale[] = {
@@ -5910,20 +5491,22 @@ static const struct usb_action tas5130cxx_60HZScale[] = {
5910 {0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH}, /* 00,a3,01,cc */ 5491 {0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH}, /* 00,a3,01,cc */
5911 {0xa0, 0x77, ZC3XX_R0A4_EXPOSURETIMELOW}, /* 00,a4,77,cc */ 5492 {0xa0, 0x77, ZC3XX_R0A4_EXPOSURETIMELOW}, /* 00,a4,77,cc */
5912 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ 5493 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
5913 {0xa0, 0x03, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,03,cc */ 5494 {0xa0, 0x09, ZC3XX_R191_EXPOSURELIMITMID},
5914 {0xa0, 0xe8, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,e8,cc */ 5495 {0xa0, 0x47, ZC3XX_R192_EXPOSURELIMITLOW},
5915 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ 5496 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
5916 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ 5497 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
5917 {0xa0, 0x7d, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,7d,cc */ 5498 {0xa0, 0x7d, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,7d,cc */
5918 {0xa0, 0x14, ZC3XX_R18C_AEFREEZE}, /* 01,8c,14,cc */ 5499 {0xa0, 0x0c, ZC3XX_R18C_AEFREEZE},
5919 {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ 5500 {0xa0, 0x18, ZC3XX_R18F_AEUNFREEZE},
5920 {0xa0, 0x0c, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,0c,cc */ 5501 {0xa0, 0x08, ZC3XX_R1A9_DIGITALLIMITDIFF},
5921 {0xa0, 0x26, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,26,cc */ 5502 {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP},
5922 {0xa0, 0xc8, ZC3XX_R01D_HSYNC_0}, /* 00,1d,c8,cc */ 5503 {0xa0, 0xc8, ZC3XX_R01D_HSYNC_0}, /* 00,1d,c8,cc */
5923 {0xa0, 0xd0, ZC3XX_R01E_HSYNC_1}, /* 00,1e,d0,cc */ 5504 {0xa0, 0xd0, ZC3XX_R01E_HSYNC_1}, /* 00,1e,d0,cc */
5924 {0xa0, 0xe0, ZC3XX_R01F_HSYNC_2}, /* 00,1f,e0,cc */ 5505 {0xa0, 0xe0, ZC3XX_R01F_HSYNC_2}, /* 00,1f,e0,cc */
5925 {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */ 5506 {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */
5926 {0xa0, 0x03, ZC3XX_R09F_MAXXHIGH}, /* 00,9f,03,cc */ 5507 {0xa0, 0x03, ZC3XX_R09F_MAXXHIGH}, /* 00,9f,03,cc */
5508 {0xa0, 0x20, ZC3XX_R0A0_MAXXLOW},
5509 {0xa0, 0x50, ZC3XX_R11D_GLOBALGAIN},
5927 {} 5510 {}
5928}; 5511};
5929static const struct usb_action tas5130cxx_NoFliker[] = { 5512static const struct usb_action tas5130cxx_NoFliker[] = {
@@ -5933,13 +5516,13 @@ static const struct usb_action tas5130cxx_NoFliker[] = {
5933 {0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH}, /* 00,a3,01,cc */ 5516 {0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH}, /* 00,a3,01,cc */
5934 {0xa0, 0x40, ZC3XX_R0A4_EXPOSURETIMELOW}, /* 00,a4,40,cc */ 5517 {0xa0, 0x40, ZC3XX_R0A4_EXPOSURETIMELOW}, /* 00,a4,40,cc */
5935 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ 5518 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
5936 {0xa0, 0x01, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,01,cc */ 5519 {0xa0, 0x05, ZC3XX_R191_EXPOSURELIMITMID},
5937 {0xa0, 0xf0, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,f0,cc */ 5520 {0xa0, 0xa0, ZC3XX_R192_EXPOSURELIMITLOW},
5938 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ 5521 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
5939 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ 5522 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
5940 {0xa0, 0x10, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,10,cc */ 5523 {0xa0, 0x04, ZC3XX_R197_ANTIFLICKERLOW},
5941 {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ 5524 {0xa0, 0x0c, ZC3XX_R18C_AEFREEZE},
5942 {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ 5525 {0xa0, 0x18, ZC3XX_R18F_AEUNFREEZE},
5943 {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,00,cc */ 5526 {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,00,cc */
5944 {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,00,cc */ 5527 {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,00,cc */
5945 {0xa0, 0xbc, ZC3XX_R01D_HSYNC_0}, /* 00,1d,bc,cc */ 5528 {0xa0, 0xbc, ZC3XX_R01D_HSYNC_0}, /* 00,1d,bc,cc */
@@ -5947,6 +5530,8 @@ static const struct usb_action tas5130cxx_NoFliker[] = {
5947 {0xa0, 0xe0, ZC3XX_R01F_HSYNC_2}, /* 00,1f,e0,cc */ 5530 {0xa0, 0xe0, ZC3XX_R01F_HSYNC_2}, /* 00,1f,e0,cc */
5948 {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */ 5531 {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */
5949 {0xa0, 0x02, ZC3XX_R09F_MAXXHIGH}, /* 00,9f,02,cc */ 5532 {0xa0, 0x02, ZC3XX_R09F_MAXXHIGH}, /* 00,9f,02,cc */
5533 {0xa0, 0xf0, ZC3XX_R0A0_MAXXLOW},
5534 {0xa0, 0x50, ZC3XX_R11D_GLOBALGAIN},
5950 {} 5535 {}
5951}; 5536};
5952 5537
@@ -5957,13 +5542,13 @@ static const struct usb_action tas5130cxx_NoFlikerScale[] = {
5957 {0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH}, /* 00,a3,01,cc */ 5542 {0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH}, /* 00,a3,01,cc */
5958 {0xa0, 0x90, ZC3XX_R0A4_EXPOSURETIMELOW}, /* 00,a4,90,cc */ 5543 {0xa0, 0x90, ZC3XX_R0A4_EXPOSURETIMELOW}, /* 00,a4,90,cc */
5959 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ 5544 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
5960 {0xa0, 0x03, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,03,cc */ 5545 {0xa0, 0x0a, ZC3XX_R191_EXPOSURELIMITMID},
5961 {0xa0, 0xf0, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,f0,cc */ 5546 {0xa0, 0x00, ZC3XX_R192_EXPOSURELIMITLOW},
5962 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ 5547 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
5963 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ 5548 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
5964 {0xa0, 0x10, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,10,cc */ 5549 {0xa0, 0x04, ZC3XX_R197_ANTIFLICKERLOW},
5965 {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ 5550 {0xa0, 0x0c, ZC3XX_R18C_AEFREEZE},
5966 {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ 5551 {0xa0, 0x18, ZC3XX_R18F_AEUNFREEZE},
5967 {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,00,cc */ 5552 {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,00,cc */
5968 {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,00,cc */ 5553 {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,00,cc */
5969 {0xa0, 0xbc, ZC3XX_R01D_HSYNC_0}, /* 00,1d,bc,cc */ 5554 {0xa0, 0xbc, ZC3XX_R01D_HSYNC_0}, /* 00,1d,bc,cc */
@@ -5971,6 +5556,8 @@ static const struct usb_action tas5130cxx_NoFlikerScale[] = {
5971 {0xa0, 0xe0, ZC3XX_R01F_HSYNC_2}, /* 00,1f,e0,cc */ 5556 {0xa0, 0xe0, ZC3XX_R01F_HSYNC_2}, /* 00,1f,e0,cc */
5972 {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */ 5557 {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */
5973 {0xa0, 0x02, ZC3XX_R09F_MAXXHIGH}, /* 00,9f,02,cc */ 5558 {0xa0, 0x02, ZC3XX_R09F_MAXXHIGH}, /* 00,9f,02,cc */
5559 {0xa0, 0xf0, ZC3XX_R0A0_MAXXLOW},
5560 {0xa0, 0x50, ZC3XX_R11D_GLOBALGAIN},
5974 {} 5561 {}
5975}; 5562};
5976 5563
@@ -6303,8 +5890,10 @@ static __u16 i2c_read(struct gspca_dev *gspca_dev,
6303 5890
6304 reg_w_i(gspca_dev->dev, reg, 0x0092); 5891 reg_w_i(gspca_dev->dev, reg, 0x0092);
6305 reg_w_i(gspca_dev->dev, 0x02, 0x0090); /* <- read command */ 5892 reg_w_i(gspca_dev->dev, 0x02, 0x0090); /* <- read command */
6306 msleep(25); 5893 msleep(20);
6307 retbyte = reg_r_i(gspca_dev, 0x0091); /* read status */ 5894 retbyte = reg_r_i(gspca_dev, 0x0091); /* read status */
5895 if (retbyte != 0x00)
5896 err("i2c_r status error %02x", retbyte);
6308 retval = reg_r_i(gspca_dev, 0x0095); /* read Lowbyte */ 5897 retval = reg_r_i(gspca_dev, 0x0095); /* read Lowbyte */
6309 retval |= reg_r_i(gspca_dev, 0x0096) << 8; /* read Hightbyte */ 5898 retval |= reg_r_i(gspca_dev, 0x0096) << 8; /* read Hightbyte */
6310 PDEBUG(D_USBI, "i2c r [%02x] -> %04x (%02x)", 5899 PDEBUG(D_USBI, "i2c r [%02x] -> %04x (%02x)",
@@ -6323,8 +5912,10 @@ static __u8 i2c_write(struct gspca_dev *gspca_dev,
6323 reg_w_i(gspca_dev->dev, valL, 0x93); 5912 reg_w_i(gspca_dev->dev, valL, 0x93);
6324 reg_w_i(gspca_dev->dev, valH, 0x94); 5913 reg_w_i(gspca_dev->dev, valH, 0x94);
6325 reg_w_i(gspca_dev->dev, 0x01, 0x90); /* <- write command */ 5914 reg_w_i(gspca_dev->dev, 0x01, 0x90); /* <- write command */
6326 msleep(15); 5915 msleep(1);
6327 retbyte = reg_r_i(gspca_dev, 0x0091); /* read status */ 5916 retbyte = reg_r_i(gspca_dev, 0x0091); /* read status */
5917 if (retbyte != 0x00)
5918 err("i2c_w status error %02x", retbyte);
6328 PDEBUG(D_USBO, "i2c w [%02x] = %02x%02x (%02x)", 5919 PDEBUG(D_USBO, "i2c w [%02x] = %02x%02x (%02x)",
6329 reg, valH, valL, retbyte); 5920 reg, valH, valL, retbyte);
6330 return retbyte; 5921 return retbyte;
@@ -6359,7 +5950,7 @@ static void usb_exchange(struct gspca_dev *gspca_dev,
6359 break; 5950 break;
6360 } 5951 }
6361 action++; 5952 action++;
6362/* msleep(1); */ 5953 msleep(1);
6363 } 5954 }
6364} 5955}
6365 5956
@@ -6380,11 +5971,13 @@ static void setmatrix(struct gspca_dev *gspca_dev)
6380 {0x4c, 0xf5, 0xff, 0xf9, 0x51, 0xf5, 0xfb, 0xed, 0x5f}; 5971 {0x4c, 0xf5, 0xff, 0xf9, 0x51, 0xf5, 0xfb, 0xed, 0x5f};
6381 static const __u8 po2030_matrix[9] = 5972 static const __u8 po2030_matrix[9] =
6382 {0x60, 0xf0, 0xf0, 0xf0, 0x60, 0xf0, 0xf0, 0xf0, 0x60}; 5973 {0x60, 0xf0, 0xf0, 0xf0, 0x60, 0xf0, 0xf0, 0xf0, 0x60};
5974 static const u8 tas5130c_matrix[9] =
5975 {0x68, 0xec, 0xec, 0xec, 0x68, 0xec, 0xec, 0xec, 0x68};
6383 static const __u8 vf0250_matrix[9] = 5976 static const __u8 vf0250_matrix[9] =
6384 {0x7b, 0xea, 0xea, 0xea, 0x7b, 0xea, 0xea, 0xea, 0x7b}; 5977 {0x7b, 0xea, 0xea, 0xea, 0x7b, 0xea, 0xea, 0xea, 0x7b};
6385 static const __u8 *matrix_tb[SENSOR_MAX] = { 5978 static const __u8 *matrix_tb[SENSOR_MAX] = {
6386 adcm2700_matrix, /* SENSOR_ADCM2700 0 */ 5979 adcm2700_matrix, /* SENSOR_ADCM2700 0 */
6387 NULL, /* SENSOR_CS2102 1 */ 5980 ov7620_matrix, /* SENSOR_CS2102 1 */
6388 NULL, /* SENSOR_CS2102K 2 */ 5981 NULL, /* SENSOR_CS2102K 2 */
6389 gc0305_matrix, /* SENSOR_GC0305 3 */ 5982 gc0305_matrix, /* SENSOR_GC0305 3 */
6390 NULL, /* SENSOR_HDCS2020b 4 */ 5983 NULL, /* SENSOR_HDCS2020b 4 */
@@ -6392,15 +5985,16 @@ static void setmatrix(struct gspca_dev *gspca_dev)
6392 NULL, /* SENSOR_HV7131C 6 */ 5985 NULL, /* SENSOR_HV7131C 6 */
6393 NULL, /* SENSOR_ICM105A 7 */ 5986 NULL, /* SENSOR_ICM105A 7 */
6394 NULL, /* SENSOR_MC501CB 8 */ 5987 NULL, /* SENSOR_MC501CB 8 */
6395 ov7620_matrix, /* SENSOR_OV7620 9 */ 5988 gc0305_matrix, /* SENSOR_MI0360SOC 9 */
6396 NULL, /* SENSOR_OV7630C 10 */ 5989 ov7620_matrix, /* SENSOR_OV7620 10 */
6397 NULL, /* SENSOR_PAS106 11 */ 5990 NULL, /* SENSOR_OV7630C 11 */
6398 pas202b_matrix, /* SENSOR_PAS202B 12 */ 5991 NULL, /* SENSOR_PAS106 12 */
6399 NULL, /* SENSOR_PB0330 13 */ 5992 pas202b_matrix, /* SENSOR_PAS202B 13 */
6400 po2030_matrix, /* SENSOR_PO2030 14 */ 5993 gc0305_matrix, /* SENSOR_PB0330 14 */
6401 NULL, /* SENSOR_TAS5130CK 15 */ 5994 po2030_matrix, /* SENSOR_PO2030 15 */
6402 NULL, /* SENSOR_TAS5130CXX 16 */ 5995 NULL, /* SENSOR_TAS5130CK 16 */
6403 vf0250_matrix, /* SENSOR_TAS5130C_VF0250 17 */ 5996 tas5130c_matrix, /* SENSOR_TAS5130CXX 17 */
5997 vf0250_matrix, /* SENSOR_TAS5130C_VF0250 18 */
6404 }; 5998 };
6405 5999
6406 matrix = matrix_tb[sd->sensor]; 6000 matrix = matrix_tb[sd->sensor];
@@ -6640,39 +6234,43 @@ static int setlightfreq(struct gspca_dev *gspca_dev)
6640 {MC501CB_NoFliker, MC501CB_NoFlikerScale, 6234 {MC501CB_NoFliker, MC501CB_NoFlikerScale,
6641 MC501CB_50HZ, MC501CB_50HZScale, 6235 MC501CB_50HZ, MC501CB_50HZScale,
6642 MC501CB_60HZ, MC501CB_60HZScale}, 6236 MC501CB_60HZ, MC501CB_60HZScale},
6643/* SENSOR_OV7620 9 */ 6237/* SENSOR_MI0360SOC 9 */
6238 {mi360soc_AENoFlikerScale, mi360soc_AENoFliker,
6239 mi360soc_AE50HZScale, mi360soc_AE50HZ,
6240 mi360soc_AE60HZScale, mi360soc_AE60HZ},
6241/* SENSOR_OV7620 10 */
6644 {OV7620_NoFliker, OV7620_NoFliker, 6242 {OV7620_NoFliker, OV7620_NoFliker,
6645 OV7620_50HZ, OV7620_50HZ, 6243 OV7620_50HZ, OV7620_50HZ,
6646 OV7620_60HZ, OV7620_60HZ}, 6244 OV7620_60HZ, OV7620_60HZ},
6647/* SENSOR_OV7630C 10 */ 6245/* SENSOR_OV7630C 11 */
6648 {NULL, NULL, 6246 {NULL, NULL,
6649 NULL, NULL, 6247 NULL, NULL,
6650 NULL, NULL}, 6248 NULL, NULL},
6651/* SENSOR_PAS106 11 */ 6249/* SENSOR_PAS106 12 */
6652 {pas106b_NoFliker, pas106b_NoFliker, 6250 {pas106b_NoFliker, pas106b_NoFliker,
6653 pas106b_50HZ, pas106b_50HZ, 6251 pas106b_50HZ, pas106b_50HZ,
6654 pas106b_60HZ, pas106b_60HZ}, 6252 pas106b_60HZ, pas106b_60HZ},
6655/* SENSOR_PAS202B 12 */ 6253/* SENSOR_PAS202B 13 */
6656 {pas202b_NoFlikerScale, pas202b_NoFliker, 6254 {pas202b_NoFlikerScale, pas202b_NoFliker,
6657 pas202b_50HZScale, pas202b_50HZ, 6255 pas202b_50HZScale, pas202b_50HZ,
6658 pas202b_60HZScale, pas202b_60HZ}, 6256 pas202b_60HZScale, pas202b_60HZ},
6659/* SENSOR_PB0330 13 */ 6257/* SENSOR_PB0330 14 */
6660 {pb0330_NoFliker, pb0330_NoFlikerScale, 6258 {pb0330_NoFlikerScale, pb0330_NoFliker,
6661 pb0330_50HZ, pb0330_50HZScale, 6259 pb0330_50HZScale, pb0330_50HZ,
6662 pb0330_60HZ, pb0330_60HZScale}, 6260 pb0330_60HZScale, pb0330_60HZ},
6663/* SENSOR_PO2030 14 */ 6261/* SENSOR_PO2030 15 */
6664 {PO2030_NoFliker, PO2030_NoFliker, 6262 {PO2030_NoFliker, PO2030_NoFliker,
6665 PO2030_50HZ, PO2030_50HZ, 6263 PO2030_50HZ, PO2030_50HZ,
6666 PO2030_60HZ, PO2030_60HZ}, 6264 PO2030_60HZ, PO2030_60HZ},
6667/* SENSOR_TAS5130CK 15 */ 6265/* SENSOR_TAS5130CK 16 */
6668 {tas5130cxx_NoFliker, tas5130cxx_NoFlikerScale, 6266 {tas5130cxx_NoFlikerScale, tas5130cxx_NoFliker,
6669 tas5130cxx_50HZ, tas5130cxx_50HZScale, 6267 tas5130cxx_50HZScale, tas5130cxx_50HZ,
6670 tas5130cxx_60HZ, tas5130cxx_60HZScale}, 6268 tas5130cxx_60HZScale, tas5130cxx_60HZ},
6671/* SENSOR_TAS5130CXX 16 */ 6269/* SENSOR_TAS5130CXX 17 */
6672 {tas5130cxx_NoFliker, tas5130cxx_NoFlikerScale, 6270 {tas5130cxx_NoFlikerScale, tas5130cxx_NoFliker,
6673 tas5130cxx_50HZ, tas5130cxx_50HZScale, 6271 tas5130cxx_50HZScale, tas5130cxx_50HZ,
6674 tas5130cxx_60HZ, tas5130cxx_60HZScale}, 6272 tas5130cxx_60HZScale, tas5130cxx_60HZ},
6675/* SENSOR_TAS5130C_VF0250 17 */ 6273/* SENSOR_TAS5130C_VF0250 18 */
6676 {tas5130c_vf0250_NoFliker, tas5130c_vf0250_NoFlikerScale, 6274 {tas5130c_vf0250_NoFliker, tas5130c_vf0250_NoFlikerScale,
6677 tas5130c_vf0250_50HZ, tas5130c_vf0250_50HZScale, 6275 tas5130c_vf0250_50HZ, tas5130c_vf0250_50HZScale,
6678 tas5130c_vf0250_60HZ, tas5130c_vf0250_60HZScale}, 6276 tas5130c_vf0250_60HZ, tas5130c_vf0250_60HZScale},
@@ -6729,6 +6327,7 @@ static void send_unknown(struct usb_device *dev, int sensor)
6729 case SENSOR_ADCM2700: 6327 case SENSOR_ADCM2700:
6730 case SENSOR_GC0305: 6328 case SENSOR_GC0305:
6731 case SENSOR_OV7620: 6329 case SENSOR_OV7620:
6330 case SENSOR_MI0360SOC:
6732 case SENSOR_PB0330: 6331 case SENSOR_PB0330:
6733 case SENSOR_PO2030: 6332 case SENSOR_PO2030:
6734 reg_w(dev, 0x0d, 0x003a); 6333 reg_w(dev, 0x0d, 0x003a);
@@ -6820,7 +6419,7 @@ static int vga_2wr_probe(struct gspca_dev *gspca_dev)
6820 start_2wr_probe(dev, 0x0e); /* PAS202BCB */ 6419 start_2wr_probe(dev, 0x0e); /* PAS202BCB */
6821 reg_w(dev, 0x08, 0x008d); 6420 reg_w(dev, 0x08, 0x008d);
6822 i2c_write(gspca_dev, 0x03, 0xaa, 0x00); 6421 i2c_write(gspca_dev, 0x03, 0xaa, 0x00);
6823 msleep(500); 6422 msleep(50);
6824 retword = i2c_read(gspca_dev, 0x03); 6423 retword = i2c_read(gspca_dev, 0x03);
6825 if (retword != 0) 6424 if (retword != 0)
6826 return 0x0e; /* PAS202BCB */ 6425 return 0x0e; /* PAS202BCB */
@@ -6863,7 +6462,8 @@ struct sensor_by_chipset_revision {
6863 __u8 internal_sensor_id; 6462 __u8 internal_sensor_id;
6864}; 6463};
6865static const struct sensor_by_chipset_revision chipset_revision_sensor[] = { 6464static const struct sensor_by_chipset_revision chipset_revision_sensor[] = {
6866 {0xc001, 0x13}, /* MI0360 */ 6465 {0xc000, 0x12}, /* TAS5130C */
6466 {0xc001, 0x13}, /* MI0360SOC */
6867 {0xe001, 0x13}, 6467 {0xe001, 0x13},
6868 {0x8001, 0x13}, 6468 {0x8001, 0x13},
6869 {0x8000, 0x14}, /* CS2102K */ 6469 {0x8000, 0x14}, /* CS2102K */
@@ -6963,7 +6563,6 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev)
6963 reg_w(dev, 0x01, 0x0001); 6563 reg_w(dev, 0x01, 0x0001);
6964 reg_w(dev, 0xee, 0x008b); 6564 reg_w(dev, 0xee, 0x008b);
6965 reg_w(dev, 0x03, 0x0012); 6565 reg_w(dev, 0x03, 0x0012);
6966/* msleep(150); */
6967 reg_w(dev, 0x01, 0x0012); 6566 reg_w(dev, 0x01, 0x0012);
6968 reg_w(dev, 0x05, 0x0012); 6567 reg_w(dev, 0x05, 0x0012);
6969 retword = i2c_read(gspca_dev, 0x00) << 8; /* ID 0 */ 6568 retword = i2c_read(gspca_dev, 0x00) << 8; /* ID 0 */
@@ -7025,7 +6624,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
7025 int vga = 1; /* 1: vga, 0: sif */ 6624 int vga = 1; /* 1: vga, 0: sif */
7026 static const __u8 gamma[SENSOR_MAX] = { 6625 static const __u8 gamma[SENSOR_MAX] = {
7027 4, /* SENSOR_ADCM2700 0 */ 6626 4, /* SENSOR_ADCM2700 0 */
7028 5, /* SENSOR_CS2102 1 */ 6627 4, /* SENSOR_CS2102 1 */
7029 5, /* SENSOR_CS2102K 2 */ 6628 5, /* SENSOR_CS2102K 2 */
7030 4, /* SENSOR_GC0305 3 */ 6629 4, /* SENSOR_GC0305 3 */
7031 4, /* SENSOR_HDCS2020b 4 */ 6630 4, /* SENSOR_HDCS2020b 4 */
@@ -7033,15 +6632,16 @@ static int sd_config(struct gspca_dev *gspca_dev,
7033 4, /* SENSOR_HV7131C 6 */ 6632 4, /* SENSOR_HV7131C 6 */
7034 4, /* SENSOR_ICM105A 7 */ 6633 4, /* SENSOR_ICM105A 7 */
7035 4, /* SENSOR_MC501CB 8 */ 6634 4, /* SENSOR_MC501CB 8 */
7036 3, /* SENSOR_OV7620 9 */ 6635 4, /* SENSOR_MI0360SOC 9 */
7037 4, /* SENSOR_OV7630C 10 */ 6636 3, /* SENSOR_OV7620 10 */
7038 4, /* SENSOR_PAS106 11 */ 6637 4, /* SENSOR_OV7630C 11 */
7039 4, /* SENSOR_PAS202B 12 */ 6638 4, /* SENSOR_PAS106 12 */
7040 4, /* SENSOR_PB0330 13 */ 6639 4, /* SENSOR_PAS202B 13 */
7041 4, /* SENSOR_PO2030 14 */ 6640 4, /* SENSOR_PB0330 14 */
7042 4, /* SENSOR_TAS5130CK 15 */ 6641 4, /* SENSOR_PO2030 15 */
7043 4, /* SENSOR_TAS5130CXX 16 */ 6642 4, /* SENSOR_TAS5130CK 16 */
7044 3, /* SENSOR_TAS5130C_VF0250 17 */ 6643 3, /* SENSOR_TAS5130CXX 17 */
6644 3, /* SENSOR_TAS5130C_VF0250 18 */
7045 }; 6645 };
7046 6646
7047 /* define some sensors from the vendor/product */ 6647 /* define some sensors from the vendor/product */
@@ -7103,7 +6703,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
7103 break; 6703 break;
7104 case 0x10: 6704 case 0x10:
7105 case 0x12: 6705 case 0x12:
7106 PDEBUG(D_PROBE, "Find Sensor TAS5130"); 6706 PDEBUG(D_PROBE, "Find Sensor TAS5130C");
7107 sd->sensor = SENSOR_TAS5130CXX; 6707 sd->sensor = SENSOR_TAS5130CXX;
7108 break; 6708 break;
7109 case 0x11: 6709 case 0x11:
@@ -7112,9 +6712,9 @@ static int sd_config(struct gspca_dev *gspca_dev,
7112 break; 6712 break;
7113 case 0x13: 6713 case 0x13:
7114 PDEBUG(D_PROBE, 6714 PDEBUG(D_PROBE,
7115 "Find Sensor MI0360. Chip revision %x", 6715 "Find Sensor MI0360SOC. Chip revision %x",
7116 sd->chip_revision); 6716 sd->chip_revision);
7117 sd->sensor = SENSOR_PB0330; 6717 sd->sensor = SENSOR_MI0360SOC;
7118 break; 6718 break;
7119 case 0x14: 6719 case 0x14:
7120 PDEBUG(D_PROBE, 6720 PDEBUG(D_PROBE,
@@ -7228,17 +6828,17 @@ static int sd_start(struct gspca_dev *gspca_dev)
7228 {hv7131cxx_InitialScale, hv7131cxx_Initial}, /* 6 */ 6828 {hv7131cxx_InitialScale, hv7131cxx_Initial}, /* 6 */
7229 {icm105axx_InitialScale, icm105axx_Initial}, /* 7 */ 6829 {icm105axx_InitialScale, icm105axx_Initial}, /* 7 */
7230 {MC501CB_InitialScale, MC501CB_Initial}, /* 8 */ 6830 {MC501CB_InitialScale, MC501CB_Initial}, /* 8 */
7231 {OV7620_mode0, OV7620_mode1}, /* 9 */ 6831 {mi0360soc_Initial, mi0360soc_InitialScale}, /* 9 */
7232 {ov7630c_InitialScale, ov7630c_Initial}, /* 10 */ 6832 {OV7620_mode0, OV7620_mode1}, /* 10 */
7233 {pas106b_InitialScale, pas106b_Initial}, /* 11 */ 6833 {ov7630c_InitialScale, ov7630c_Initial}, /* 11 */
7234 {pas202b_Initial, pas202b_InitialScale}, /* 12 */ 6834 {pas106b_InitialScale, pas106b_Initial}, /* 12 */
7235 {pb0330xx_InitialScale, pb0330xx_Initial}, /* 13 */ 6835 {pas202b_Initial, pas202b_InitialScale}, /* 13 */
7236/* or {pb03303x_InitialScale, pb03303x_Initial}, */ 6836 {pb0330_Initial, pb0330_InitialScale}, /* 14 */
7237 {PO2030_mode0, PO2030_mode1}, /* 14 */ 6837 {PO2030_mode0, PO2030_mode1}, /* 15 */
7238 {tas5130CK_InitialScale, tas5130CK_Initial}, /* 15 */ 6838 {tas5130CK_InitialScale, tas5130CK_Initial}, /* 16 */
7239 {tas5130cxx_InitialScale, tas5130cxx_Initial}, /* 16 */ 6839 {tas5130cxx_Initial, tas5130cxx_InitialScale}, /* 17 */
7240 {tas5130c_vf0250_InitialScale, tas5130c_vf0250_Initial}, 6840 {tas5130c_vf0250_InitialScale, tas5130c_vf0250_Initial},
7241 /* 17 */ 6841 /* 18 */
7242 }; 6842 };
7243 6843
7244 /* create the JPEG header */ 6844 /* create the JPEG header */
@@ -7258,19 +6858,6 @@ static int sd_start(struct gspca_dev *gspca_dev)
7258 case SENSOR_PAS106: 6858 case SENSOR_PAS106:
7259 usb_exchange(gspca_dev, pas106b_Initial_com); 6859 usb_exchange(gspca_dev, pas106b_Initial_com);
7260 break; 6860 break;
7261 case SENSOR_PB0330:
7262 if (mode) {
7263 if (sd->chip_revision == 0xc001
7264 || sd->chip_revision == 0xe001
7265 || sd->chip_revision == 0x8001)
7266 zc3_init = pb03303x_Initial;
7267 } else {
7268 if (sd->chip_revision == 0xc001
7269 || sd->chip_revision == 0xe001
7270 || sd->chip_revision == 0x8001)
7271 zc3_init = pb03303x_InitialScale;
7272 }
7273 break;
7274 } 6861 }
7275 usb_exchange(gspca_dev, zc3_init); 6862 usb_exchange(gspca_dev, zc3_init);
7276 6863
@@ -7310,10 +6897,8 @@ static int sd_start(struct gspca_dev *gspca_dev)
7310 6897
7311 /* set the gamma tables when not set */ 6898 /* set the gamma tables when not set */
7312 switch (sd->sensor) { 6899 switch (sd->sensor) {
7313 case SENSOR_CS2102: /* gamma set in xxx_Initial */ 6900 case SENSOR_CS2102K: /* gamma set in xxx_Initial */
7314 case SENSOR_CS2102K:
7315 case SENSOR_HDCS2020b: 6901 case SENSOR_HDCS2020b:
7316 case SENSOR_PB0330: /* pb with chip_revision - see above */
7317 case SENSOR_OV7630C: 6902 case SENSOR_OV7630C:
7318 case SENSOR_TAS5130CK: 6903 case SENSOR_TAS5130CK:
7319 break; 6904 break;
@@ -7365,7 +6950,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
7365 setautogain(gspca_dev); 6950 setautogain(gspca_dev);
7366 switch (sd->sensor) { 6951 switch (sd->sensor) {
7367 case SENSOR_PO2030: 6952 case SENSOR_PO2030:
7368 msleep(500); 6953 msleep(50);
7369 reg_r(gspca_dev, 0x0008); 6954 reg_r(gspca_dev, 0x0008);
7370 reg_r(gspca_dev, 0x0007); 6955 reg_r(gspca_dev, 0x0007);
7371 /*fall thru*/ 6956 /*fall thru*/
@@ -7389,17 +6974,16 @@ static void sd_stop0(struct gspca_dev *gspca_dev)
7389} 6974}
7390 6975
7391static void sd_pkt_scan(struct gspca_dev *gspca_dev, 6976static void sd_pkt_scan(struct gspca_dev *gspca_dev,
7392 struct gspca_frame *frame, 6977 u8 *data,
7393 __u8 *data,
7394 int len) 6978 int len)
7395{ 6979{
7396 struct sd *sd = (struct sd *) gspca_dev; 6980 struct sd *sd = (struct sd *) gspca_dev;
7397 6981
7398 if (data[0] == 0xff && data[1] == 0xd8) { /* start of frame */ 6982 if (data[0] == 0xff && data[1] == 0xd8) { /* start of frame */
7399 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, 6983 gspca_frame_add(gspca_dev, LAST_PACKET,
7400 data, 0); 6984 NULL, 0);
7401 /* put the JPEG header in the new frame */ 6985 /* put the JPEG header in the new frame */
7402 gspca_frame_add(gspca_dev, FIRST_PACKET, frame, 6986 gspca_frame_add(gspca_dev, FIRST_PACKET,
7403 sd->jpeg_hdr, JPEG_HDR_SZ); 6987 sd->jpeg_hdr, JPEG_HDR_SZ);
7404 6988
7405 /* remove the webcam's header: 6989 /* remove the webcam's header:
@@ -7411,7 +6995,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
7411 data += 18; 6995 data += 18;
7412 len -= 18; 6996 len -= 18;
7413 } 6997 }
7414 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); 6998 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
7415} 6999}
7416 7000
7417static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) 7001static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
diff --git a/drivers/media/video/hdpvr/hdpvr-video.c b/drivers/media/video/hdpvr/hdpvr-video.c
index 2eb9dc2ebe59..b5439cabb381 100644
--- a/drivers/media/video/hdpvr/hdpvr-video.c
+++ b/drivers/media/video/hdpvr/hdpvr-video.c
@@ -139,7 +139,7 @@ int hdpvr_alloc_buffers(struct hdpvr_device *dev, uint count)
139 urb = usb_alloc_urb(0, GFP_KERNEL); 139 urb = usb_alloc_urb(0, GFP_KERNEL);
140 if (!urb) { 140 if (!urb) {
141 v4l2_err(&dev->v4l2_dev, "cannot allocate urb\n"); 141 v4l2_err(&dev->v4l2_dev, "cannot allocate urb\n");
142 goto exit; 142 goto exit_urb;
143 } 143 }
144 buf->urb = urb; 144 buf->urb = urb;
145 145
@@ -148,7 +148,7 @@ int hdpvr_alloc_buffers(struct hdpvr_device *dev, uint count)
148 if (!mem) { 148 if (!mem) {
149 v4l2_err(&dev->v4l2_dev, 149 v4l2_err(&dev->v4l2_dev,
150 "cannot allocate usb transfer buffer\n"); 150 "cannot allocate usb transfer buffer\n");
151 goto exit; 151 goto exit_urb_buffer;
152 } 152 }
153 153
154 usb_fill_bulk_urb(buf->urb, dev->udev, 154 usb_fill_bulk_urb(buf->urb, dev->udev,
@@ -161,6 +161,10 @@ int hdpvr_alloc_buffers(struct hdpvr_device *dev, uint count)
161 list_add_tail(&buf->buff_list, &dev->free_buff_list); 161 list_add_tail(&buf->buff_list, &dev->free_buff_list);
162 } 162 }
163 return 0; 163 return 0;
164exit_urb_buffer:
165 usb_free_urb(urb);
166exit_urb:
167 kfree(buf);
164exit: 168exit:
165 hdpvr_free_buffers(dev); 169 hdpvr_free_buffers(dev);
166 return retval; 170 return retval;
diff --git a/drivers/media/video/hexium_gemini.c b/drivers/media/video/hexium_gemini.c
index 71c211402eb5..60d992ee2589 100644
--- a/drivers/media/video/hexium_gemini.c
+++ b/drivers/media/video/hexium_gemini.c
@@ -251,7 +251,7 @@ static int vidioc_s_input(struct file *file, void *fh, unsigned int input)
251 251
252 DEB_EE(("VIDIOC_S_INPUT %d.\n", input)); 252 DEB_EE(("VIDIOC_S_INPUT %d.\n", input));
253 253
254 if (input < 0 || input >= HEXIUM_INPUTS) 254 if (input >= HEXIUM_INPUTS)
255 return -EINVAL; 255 return -EINVAL;
256 256
257 hexium->cur_input = input; 257 hexium->cur_input = input;
diff --git a/drivers/media/video/hexium_orion.c b/drivers/media/video/hexium_orion.c
index 39d65ca41c62..938a1f8f880a 100644
--- a/drivers/media/video/hexium_orion.c
+++ b/drivers/media/video/hexium_orion.c
@@ -350,7 +350,7 @@ static int vidioc_s_input(struct file *file, void *fh, unsigned int input)
350 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; 350 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
351 struct hexium *hexium = (struct hexium *) dev->ext_priv; 351 struct hexium *hexium = (struct hexium *) dev->ext_priv;
352 352
353 if (input < 0 || input >= HEXIUM_INPUTS) 353 if (input >= HEXIUM_INPUTS)
354 return -EINVAL; 354 return -EINVAL;
355 355
356 hexium->cur_input = input; 356 hexium->cur_input = input;
diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c
index 247d3115a9b7..64360d26b32d 100644
--- a/drivers/media/video/ir-kbd-i2c.c
+++ b/drivers/media/video/ir-kbd-i2c.c
@@ -275,7 +275,7 @@ static void ir_key_poll(struct IR_i2c *ir)
275 if (0 == rc) { 275 if (0 == rc) {
276 ir_input_nokey(ir->input, &ir->ir); 276 ir_input_nokey(ir->input, &ir->ir);
277 } else { 277 } else {
278 ir_input_keydown(ir->input, &ir->ir, ir_key, ir_raw); 278 ir_input_keydown(ir->input, &ir->ir, ir_key);
279 } 279 }
280} 280}
281 281
@@ -299,7 +299,7 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
299{ 299{
300 struct ir_scancode_table *ir_codes = NULL; 300 struct ir_scancode_table *ir_codes = NULL;
301 const char *name = NULL; 301 const char *name = NULL;
302 int ir_type; 302 int ir_type = 0;
303 struct IR_i2c *ir; 303 struct IR_i2c *ir;
304 struct input_dev *input_dev; 304 struct input_dev *input_dev;
305 struct i2c_adapter *adap = client->adapter; 305 struct i2c_adapter *adap = client->adapter;
@@ -353,10 +353,8 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
353 ir_type = IR_TYPE_RC5; 353 ir_type = IR_TYPE_RC5;
354 ir_codes = &ir_codes_fusionhdtv_mce_table; 354 ir_codes = &ir_codes_fusionhdtv_mce_table;
355 break; 355 break;
356 case 0x7a:
357 case 0x47: 356 case 0x47:
358 case 0x71: 357 case 0x71:
359 case 0x2d:
360 if (adap->id == I2C_HW_B_CX2388x || 358 if (adap->id == I2C_HW_B_CX2388x ||
361 adap->id == I2C_HW_B_CX2341X) { 359 adap->id == I2C_HW_B_CX2341X) {
362 /* Handled by cx88-input */ 360 /* Handled by cx88-input */
@@ -381,10 +379,6 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
381 ir_type = IR_TYPE_OTHER; 379 ir_type = IR_TYPE_OTHER;
382 ir_codes = &ir_codes_avermedia_cardbus_table; 380 ir_codes = &ir_codes_avermedia_cardbus_table;
383 break; 381 break;
384 default:
385 dprintk(1, DEVNAME ": Unsupported i2c address 0x%02x\n", addr);
386 err = -ENODEV;
387 goto err_out_free;
388 } 382 }
389 383
390 /* Let the caller override settings */ 384 /* Let the caller override settings */
@@ -427,7 +421,7 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
427 } 421 }
428 422
429 /* Make sure we are all setup before going on */ 423 /* Make sure we are all setup before going on */
430 if (!name || !ir->get_key || !ir_codes) { 424 if (!name || !ir->get_key || !ir_type || !ir_codes) {
431 dprintk(1, DEVNAME ": Unsupported device at address 0x%02x\n", 425 dprintk(1, DEVNAME ": Unsupported device at address 0x%02x\n",
432 addr); 426 addr);
433 err = -ENODEV; 427 err = -ENODEV;
@@ -443,7 +437,10 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
443 dev_name(&client->dev)); 437 dev_name(&client->dev));
444 438
445 /* init + register input device */ 439 /* init + register input device */
446 ir_input_init(input_dev, &ir->ir, ir_type, ir->ir_codes); 440 err = ir_input_init(input_dev, &ir->ir, ir_type, ir->ir_codes);
441 if (err < 0)
442 goto err_out_free;
443
447 input_dev->id.bustype = BUS_I2C; 444 input_dev->id.bustype = BUS_I2C;
448 input_dev->name = ir->name; 445 input_dev->name = ir->name;
449 input_dev->phys = ir->phys; 446 input_dev->phys = ir->phys;
@@ -462,6 +459,7 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
462 return 0; 459 return 0;
463 460
464 err_out_free: 461 err_out_free:
462 ir_input_free(input_dev);
465 input_free_device(input_dev); 463 input_free_device(input_dev);
466 kfree(ir); 464 kfree(ir);
467 return err; 465 return err;
@@ -475,6 +473,7 @@ static int ir_remove(struct i2c_client *client)
475 cancel_delayed_work_sync(&ir->work); 473 cancel_delayed_work_sync(&ir->work);
476 474
477 /* unregister device */ 475 /* unregister device */
476 ir_input_free(ir->input);
478 input_unregister_device(ir->input); 477 input_unregister_device(ir->input);
479 478
480 /* free memory */ 479 /* free memory */
diff --git a/drivers/media/video/ivtv/ivtv-cards.c b/drivers/media/video/ivtv/ivtv-cards.c
index 4873b6ca5801..79d0fe4990d6 100644
--- a/drivers/media/video/ivtv/ivtv-cards.c
+++ b/drivers/media/video/ivtv/ivtv-cards.c
@@ -136,7 +136,8 @@ static const struct ivtv_card ivtv_card_pvr350 = {
136 .hw_audio = IVTV_HW_MSP34XX, 136 .hw_audio = IVTV_HW_MSP34XX,
137 .hw_audio_ctrl = IVTV_HW_MSP34XX, 137 .hw_audio_ctrl = IVTV_HW_MSP34XX,
138 .hw_all = IVTV_HW_MSP34XX | IVTV_HW_SAA7115 | 138 .hw_all = IVTV_HW_MSP34XX | IVTV_HW_SAA7115 |
139 IVTV_HW_SAA7127 | IVTV_HW_TVEEPROM | IVTV_HW_TUNER, 139 IVTV_HW_SAA7127 | IVTV_HW_TVEEPROM | IVTV_HW_TUNER |
140 IVTV_HW_I2C_IR_RX_HAUP_EXT | IVTV_HW_I2C_IR_RX_HAUP_INT,
140 .video_inputs = { 141 .video_inputs = {
141 { IVTV_CARD_INPUT_VID_TUNER, 0, IVTV_SAA71XX_COMPOSITE4 }, 142 { IVTV_CARD_INPUT_VID_TUNER, 0, IVTV_SAA71XX_COMPOSITE4 },
142 { IVTV_CARD_INPUT_SVIDEO1, 1, IVTV_SAA71XX_SVIDEO0 }, 143 { IVTV_CARD_INPUT_SVIDEO1, 1, IVTV_SAA71XX_SVIDEO0 },
@@ -199,7 +200,9 @@ static const struct ivtv_card ivtv_card_pvr150 = {
199 .hw_audio_ctrl = IVTV_HW_CX25840, 200 .hw_audio_ctrl = IVTV_HW_CX25840,
200 .hw_muxer = IVTV_HW_WM8775, 201 .hw_muxer = IVTV_HW_WM8775,
201 .hw_all = IVTV_HW_WM8775 | IVTV_HW_CX25840 | 202 .hw_all = IVTV_HW_WM8775 | IVTV_HW_CX25840 |
202 IVTV_HW_TVEEPROM | IVTV_HW_TUNER, 203 IVTV_HW_TVEEPROM | IVTV_HW_TUNER |
204 IVTV_HW_I2C_IR_RX_HAUP_EXT | IVTV_HW_I2C_IR_RX_HAUP_INT |
205 IVTV_HW_Z8F0811_IR_HAUP,
203 .video_inputs = { 206 .video_inputs = {
204 { IVTV_CARD_INPUT_VID_TUNER, 0, CX25840_COMPOSITE7 }, 207 { IVTV_CARD_INPUT_VID_TUNER, 0, CX25840_COMPOSITE7 },
205 { IVTV_CARD_INPUT_SVIDEO1, 1, CX25840_SVIDEO1 }, 208 { IVTV_CARD_INPUT_SVIDEO1, 1, CX25840_SVIDEO1 },
@@ -955,7 +958,8 @@ static const struct ivtv_card ivtv_card_avertv_mce116 = {
955 .hw_video = IVTV_HW_CX25840, 958 .hw_video = IVTV_HW_CX25840,
956 .hw_audio = IVTV_HW_CX25840, 959 .hw_audio = IVTV_HW_CX25840,
957 .hw_audio_ctrl = IVTV_HW_CX25840, 960 .hw_audio_ctrl = IVTV_HW_CX25840,
958 .hw_all = IVTV_HW_CX25840 | IVTV_HW_TUNER | IVTV_HW_WM8739, 961 .hw_all = IVTV_HW_CX25840 | IVTV_HW_TUNER | IVTV_HW_WM8739 |
962 IVTV_HW_I2C_IR_RX_AVER,
959 .video_inputs = { 963 .video_inputs = {
960 { IVTV_CARD_INPUT_VID_TUNER, 0, CX25840_COMPOSITE2 }, 964 { IVTV_CARD_INPUT_VID_TUNER, 0, CX25840_COMPOSITE2 },
961 { IVTV_CARD_INPUT_SVIDEO1, 1, CX25840_SVIDEO3 }, 965 { IVTV_CARD_INPUT_SVIDEO1, 1, CX25840_SVIDEO3 },
@@ -965,6 +969,7 @@ static const struct ivtv_card ivtv_card_avertv_mce116 = {
965 { IVTV_CARD_INPUT_AUD_TUNER, CX25840_AUDIO5 }, 969 { IVTV_CARD_INPUT_AUD_TUNER, CX25840_AUDIO5 },
966 { IVTV_CARD_INPUT_LINE_IN1, CX25840_AUDIO_SERIAL, 1 }, 970 { IVTV_CARD_INPUT_LINE_IN1, CX25840_AUDIO_SERIAL, 1 },
967 }, 971 },
972 .radio_input = { IVTV_CARD_INPUT_AUD_TUNER, CX25840_AUDIO5 },
968 /* enable line-in */ 973 /* enable line-in */
969 .gpio_init = { .direction = 0xe000, .initial_value = 0x4000 }, 974 .gpio_init = { .direction = 0xe000, .initial_value = 0x4000 },
970 .xceive_pin = 10, 975 .xceive_pin = 10,
@@ -1025,13 +1030,15 @@ static const struct ivtv_card ivtv_card_aver_pvr150 = {
1025/* AVerMedia UltraTV 1500 MCE (newer non-cx88 version, M113 variant) card */ 1030/* AVerMedia UltraTV 1500 MCE (newer non-cx88 version, M113 variant) card */
1026 1031
1027static const struct ivtv_card_pci_info ivtv_pci_aver_ultra1500mce[] = { 1032static const struct ivtv_card_pci_info ivtv_pci_aver_ultra1500mce[] = {
1028 { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_AVERMEDIA, 0xc019 }, 1033 { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_AVERMEDIA, 0xc019 }, /* NTSC */
1034 { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_AVERMEDIA, 0xc01b }, /* PAL/SECAM */
1029 { 0, 0, 0 } 1035 { 0, 0, 0 }
1030}; 1036};
1031 1037
1032static const struct ivtv_card ivtv_card_aver_ultra1500mce = { 1038static const struct ivtv_card ivtv_card_aver_ultra1500mce = {
1033 .type = IVTV_CARD_AVER_ULTRA1500MCE, 1039 .type = IVTV_CARD_AVER_ULTRA1500MCE,
1034 .name = "AVerMedia UltraTV 1500 MCE / AVerTV M113 Philips Tuner", 1040 .name = "AVerMedia UltraTV 1500 MCE / AVerTV M113 Philips Tuner",
1041 .comment = "For non-NTSC tuners, use the pal= or secam= module options",
1035 .v4l2_capabilities = IVTV_CAP_ENCODER, 1042 .v4l2_capabilities = IVTV_CAP_ENCODER,
1036 .hw_video = IVTV_HW_CX25840, 1043 .hw_video = IVTV_HW_CX25840,
1037 .hw_audio = IVTV_HW_CX25840, 1044 .hw_audio = IVTV_HW_CX25840,
@@ -1058,6 +1065,7 @@ static const struct ivtv_card ivtv_card_aver_ultra1500mce = {
1058 .tuners = { 1065 .tuners = {
1059 /* The UltraTV 1500 MCE has a Philips FM1236 MK5 TV/FM tuner */ 1066 /* The UltraTV 1500 MCE has a Philips FM1236 MK5 TV/FM tuner */
1060 { .std = V4L2_STD_MN, .tuner = TUNER_PHILIPS_FM1236_MK3 }, 1067 { .std = V4L2_STD_MN, .tuner = TUNER_PHILIPS_FM1236_MK3 },
1068 { .std = V4L2_STD_PAL_SECAM, .tuner = TUNER_PHILIPS_FM1216MK5 },
1061 }, 1069 },
1062 .pci_list = ivtv_pci_aver_ultra1500mce, 1070 .pci_list = ivtv_pci_aver_ultra1500mce,
1063 .i2c = &ivtv_i2c_std, 1071 .i2c = &ivtv_i2c_std,
diff --git a/drivers/media/video/ivtv/ivtv-cards.h b/drivers/media/video/ivtv/ivtv-cards.h
index e99a0a255578..6148827ec885 100644
--- a/drivers/media/video/ivtv/ivtv-cards.h
+++ b/drivers/media/video/ivtv/ivtv-cards.h
@@ -87,26 +87,43 @@
87#define IVTV_PCI_ID_GOTVIEW1 0xffac 87#define IVTV_PCI_ID_GOTVIEW1 0xffac
88#define IVTV_PCI_ID_GOTVIEW2 0xffad 88#define IVTV_PCI_ID_GOTVIEW2 0xffad
89 89
90/* hardware flags, no gaps allowed, IVTV_HW_GPIO must always be last */ 90/* hardware flags, no gaps allowed */
91#define IVTV_HW_CX25840 (1 << 0) 91#define IVTV_HW_CX25840 (1 << 0)
92#define IVTV_HW_SAA7115 (1 << 1) 92#define IVTV_HW_SAA7115 (1 << 1)
93#define IVTV_HW_SAA7127 (1 << 2) 93#define IVTV_HW_SAA7127 (1 << 2)
94#define IVTV_HW_MSP34XX (1 << 3) 94#define IVTV_HW_MSP34XX (1 << 3)
95#define IVTV_HW_TUNER (1 << 4) 95#define IVTV_HW_TUNER (1 << 4)
96#define IVTV_HW_WM8775 (1 << 5) 96#define IVTV_HW_WM8775 (1 << 5)
97#define IVTV_HW_CS53L32A (1 << 6) 97#define IVTV_HW_CS53L32A (1 << 6)
98#define IVTV_HW_TVEEPROM (1 << 7) 98#define IVTV_HW_TVEEPROM (1 << 7)
99#define IVTV_HW_SAA7114 (1 << 8) 99#define IVTV_HW_SAA7114 (1 << 8)
100#define IVTV_HW_UPD64031A (1 << 9) 100#define IVTV_HW_UPD64031A (1 << 9)
101#define IVTV_HW_UPD6408X (1 << 10) 101#define IVTV_HW_UPD6408X (1 << 10)
102#define IVTV_HW_SAA717X (1 << 11) 102#define IVTV_HW_SAA717X (1 << 11)
103#define IVTV_HW_WM8739 (1 << 12) 103#define IVTV_HW_WM8739 (1 << 12)
104#define IVTV_HW_VP27SMPX (1 << 13) 104#define IVTV_HW_VP27SMPX (1 << 13)
105#define IVTV_HW_M52790 (1 << 14) 105#define IVTV_HW_M52790 (1 << 14)
106#define IVTV_HW_GPIO (1 << 15) 106#define IVTV_HW_GPIO (1 << 15)
107#define IVTV_HW_I2C_IR_RX_AVER (1 << 16)
108#define IVTV_HW_I2C_IR_RX_HAUP_EXT (1 << 17) /* External before internal */
109#define IVTV_HW_I2C_IR_RX_HAUP_INT (1 << 18)
110#define IVTV_HW_Z8F0811_IR_TX_HAUP (1 << 19)
111#define IVTV_HW_Z8F0811_IR_RX_HAUP (1 << 20)
112
113#define IVTV_HW_Z8F0811_IR_HAUP (IVTV_HW_Z8F0811_IR_RX_HAUP | \
114 IVTV_HW_Z8F0811_IR_TX_HAUP)
107 115
108#define IVTV_HW_SAA711X (IVTV_HW_SAA7115 | IVTV_HW_SAA7114) 116#define IVTV_HW_SAA711X (IVTV_HW_SAA7115 | IVTV_HW_SAA7114)
109 117
118#define IVTV_HW_IR_RX_ANY (IVTV_HW_I2C_IR_RX_AVER | \
119 IVTV_HW_I2C_IR_RX_HAUP_EXT | \
120 IVTV_HW_I2C_IR_RX_HAUP_INT | \
121 IVTV_HW_Z8F0811_IR_RX_HAUP)
122
123#define IVTV_HW_IR_TX_ANY (IVTV_HW_Z8F0811_IR_TX_HAUP)
124
125#define IVTV_HW_IR_ANY (IVTV_HW_IR_RX_ANY | IVTV_HW_IR_TX_ANY)
126
110/* video inputs */ 127/* video inputs */
111#define IVTV_CARD_INPUT_VID_TUNER 1 128#define IVTV_CARD_INPUT_VID_TUNER 1
112#define IVTV_CARD_INPUT_SVIDEO1 2 129#define IVTV_CARD_INPUT_SVIDEO1 2
diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c
index 7cdbc1a8f218..347c3344f56d 100644
--- a/drivers/media/video/ivtv/ivtv-driver.c
+++ b/drivers/media/video/ivtv/ivtv-driver.c
@@ -91,10 +91,15 @@ static int radio[IVTV_MAX_CARDS] = { -1, -1, -1, -1, -1, -1, -1, -1,
91 -1, -1, -1, -1, -1, -1, -1, -1, 91 -1, -1, -1, -1, -1, -1, -1, -1,
92 -1, -1, -1, -1, -1, -1, -1, -1, 92 -1, -1, -1, -1, -1, -1, -1, -1,
93 -1, -1, -1, -1, -1, -1, -1, -1 }; 93 -1, -1, -1, -1, -1, -1, -1, -1 };
94static int i2c_clock_period[IVTV_MAX_CARDS] = { -1, -1, -1, -1, -1, -1, -1, -1,
95 -1, -1, -1, -1, -1, -1, -1, -1,
96 -1, -1, -1, -1, -1, -1, -1, -1,
97 -1, -1, -1, -1, -1, -1, -1, -1 };
94 98
95static unsigned int cardtype_c = 1; 99static unsigned int cardtype_c = 1;
96static unsigned int tuner_c = 1; 100static unsigned int tuner_c = 1;
97static unsigned int radio_c = 1; 101static unsigned int radio_c = 1;
102static unsigned int i2c_clock_period_c = 1;
98static char pal[] = "---"; 103static char pal[] = "---";
99static char secam[] = "--"; 104static char secam[] = "--";
100static char ntsc[] = "-"; 105static char ntsc[] = "-";
@@ -151,6 +156,7 @@ module_param(dec_vbi_buffers, int, 0644);
151 156
152module_param(tunertype, int, 0644); 157module_param(tunertype, int, 0644);
153module_param(newi2c, int, 0644); 158module_param(newi2c, int, 0644);
159module_param_array(i2c_clock_period, int, &i2c_clock_period_c, 0644);
154 160
155MODULE_PARM_DESC(tuner, "Tuner type selection,\n" 161MODULE_PARM_DESC(tuner, "Tuner type selection,\n"
156 "\t\t\tsee tuner.h for values"); 162 "\t\t\tsee tuner.h for values");
@@ -245,6 +251,10 @@ MODULE_PARM_DESC(newi2c,
245 "Use new I2C implementation\n" 251 "Use new I2C implementation\n"
246 "\t\t\t-1 is autodetect, 0 is off, 1 is on\n" 252 "\t\t\t-1 is autodetect, 0 is off, 1 is on\n"
247 "\t\t\tDefault is autodetect"); 253 "\t\t\tDefault is autodetect");
254MODULE_PARM_DESC(i2c_clock_period,
255 "Period of SCL for the I2C bus controlled by the CX23415/6\n"
256 "\t\t\tMin: 10 usec (100 kHz), Max: 4500 usec (222 Hz)\n"
257 "\t\t\tDefault: " __stringify(IVTV_DEFAULT_I2C_CLOCK_PERIOD));
248 258
249MODULE_PARM_DESC(ivtv_first_minor, "Set device node number assigned to first card"); 259MODULE_PARM_DESC(ivtv_first_minor, "Set device node number assigned to first card");
250 260
@@ -600,6 +610,15 @@ static void ivtv_process_options(struct ivtv *itv)
600 itv->options.cardtype = cardtype[itv->instance]; 610 itv->options.cardtype = cardtype[itv->instance];
601 itv->options.tuner = tuner[itv->instance]; 611 itv->options.tuner = tuner[itv->instance];
602 itv->options.radio = radio[itv->instance]; 612 itv->options.radio = radio[itv->instance];
613
614 itv->options.i2c_clock_period = i2c_clock_period[itv->instance];
615 if (itv->options.i2c_clock_period == -1)
616 itv->options.i2c_clock_period = IVTV_DEFAULT_I2C_CLOCK_PERIOD;
617 else if (itv->options.i2c_clock_period < 10)
618 itv->options.i2c_clock_period = 10;
619 else if (itv->options.i2c_clock_period > 4500)
620 itv->options.i2c_clock_period = 4500;
621
603 itv->options.newi2c = newi2c; 622 itv->options.newi2c = newi2c;
604 if (tunertype < -1 || tunertype > 1) { 623 if (tunertype < -1 || tunertype > 1) {
605 IVTV_WARN("Invalid tunertype argument, will autodetect instead\n"); 624 IVTV_WARN("Invalid tunertype argument, will autodetect instead\n");
@@ -865,6 +884,10 @@ static void ivtv_load_and_init_modules(struct ivtv *itv)
865 itv->hw_flags |= device; 884 itv->hw_flags |= device;
866 } 885 }
867 886
887 /* probe for legacy IR controllers that aren't in card definitions */
888 if ((itv->hw_flags & IVTV_HW_IR_ANY) == 0)
889 ivtv_i2c_new_ir_legacy(itv);
890
868 if (itv->card->hw_all & IVTV_HW_CX25840) 891 if (itv->card->hw_all & IVTV_HW_CX25840)
869 itv->sd_video = ivtv_find_hw(itv, IVTV_HW_CX25840); 892 itv->sd_video = ivtv_find_hw(itv, IVTV_HW_CX25840);
870 else if (itv->card->hw_all & IVTV_HW_SAA717X) 893 else if (itv->card->hw_all & IVTV_HW_SAA717X)
diff --git a/drivers/media/video/ivtv/ivtv-driver.h b/drivers/media/video/ivtv/ivtv-driver.h
index 440f7328a7ed..e4816da6482b 100644
--- a/drivers/media/video/ivtv/ivtv-driver.h
+++ b/drivers/media/video/ivtv/ivtv-driver.h
@@ -64,6 +64,7 @@
64#include <media/v4l2-device.h> 64#include <media/v4l2-device.h>
65#include <media/tuner.h> 65#include <media/tuner.h>
66#include <media/cx2341x.h> 66#include <media/cx2341x.h>
67#include <media/ir-kbd-i2c.h>
67 68
68#include <linux/ivtv.h> 69#include <linux/ivtv.h>
69 70
@@ -176,12 +177,16 @@ extern int ivtv_debug;
176 177
177#define IVTV_MAX_PGM_INDEX (400) 178#define IVTV_MAX_PGM_INDEX (400)
178 179
180/* Default I2C SCL period in microseconds */
181#define IVTV_DEFAULT_I2C_CLOCK_PERIOD 20
182
179struct ivtv_options { 183struct ivtv_options {
180 int kilobytes[IVTV_MAX_STREAMS]; /* size in kilobytes of each stream */ 184 int kilobytes[IVTV_MAX_STREAMS]; /* size in kilobytes of each stream */
181 int cardtype; /* force card type on load */ 185 int cardtype; /* force card type on load */
182 int tuner; /* set tuner on load */ 186 int tuner; /* set tuner on load */
183 int radio; /* enable/disable radio */ 187 int radio; /* enable/disable radio */
184 int newi2c; /* new I2C algorithm */ 188 int newi2c; /* new I2C algorithm */
189 int i2c_clock_period; /* period of SCL for I2C bus */
185}; 190};
186 191
187/* ivtv-specific mailbox template */ 192/* ivtv-specific mailbox template */
@@ -677,6 +682,7 @@ struct ivtv {
677 int i2c_state; /* i2c bit state */ 682 int i2c_state; /* i2c bit state */
678 struct mutex i2c_bus_lock; /* lock i2c bus */ 683 struct mutex i2c_bus_lock; /* lock i2c bus */
679 684
685 struct IR_i2c_init_data ir_i2c_init_data;
680 686
681 /* Program Index information */ 687 /* Program Index information */
682 u32 pgm_info_offset; /* start of pgm info in encoder memory */ 688 u32 pgm_info_offset; /* start of pgm info in encoder memory */
diff --git a/drivers/media/video/ivtv/ivtv-i2c.c b/drivers/media/video/ivtv/ivtv-i2c.c
index b9c71e61f7d6..2ee03c2a1b58 100644
--- a/drivers/media/video/ivtv/ivtv-i2c.c
+++ b/drivers/media/video/ivtv/ivtv-i2c.c
@@ -88,6 +88,11 @@
88#define IVTV_UPD64083_I2C_ADDR 0x5c 88#define IVTV_UPD64083_I2C_ADDR 0x5c
89#define IVTV_VP27SMPX_I2C_ADDR 0x5b 89#define IVTV_VP27SMPX_I2C_ADDR 0x5b
90#define IVTV_M52790_I2C_ADDR 0x48 90#define IVTV_M52790_I2C_ADDR 0x48
91#define IVTV_AVERMEDIA_IR_RX_I2C_ADDR 0x40
92#define IVTV_HAUP_EXT_IR_RX_I2C_ADDR 0x1a
93#define IVTV_HAUP_INT_IR_RX_I2C_ADDR 0x18
94#define IVTV_Z8F0811_IR_TX_I2C_ADDR 0x70
95#define IVTV_Z8F0811_IR_RX_I2C_ADDR 0x71
91 96
92/* This array should match the IVTV_HW_ defines */ 97/* This array should match the IVTV_HW_ defines */
93static const u8 hw_addrs[] = { 98static const u8 hw_addrs[] = {
@@ -106,7 +111,12 @@ static const u8 hw_addrs[] = {
106 IVTV_WM8739_I2C_ADDR, 111 IVTV_WM8739_I2C_ADDR,
107 IVTV_VP27SMPX_I2C_ADDR, 112 IVTV_VP27SMPX_I2C_ADDR,
108 IVTV_M52790_I2C_ADDR, 113 IVTV_M52790_I2C_ADDR,
109 0 /* IVTV_HW_GPIO dummy driver ID */ 114 0, /* IVTV_HW_GPIO dummy driver ID */
115 IVTV_AVERMEDIA_IR_RX_I2C_ADDR, /* IVTV_HW_I2C_IR_RX_AVER */
116 IVTV_HAUP_EXT_IR_RX_I2C_ADDR, /* IVTV_HW_I2C_IR_RX_HAUP_EXT */
117 IVTV_HAUP_INT_IR_RX_I2C_ADDR, /* IVTV_HW_I2C_IR_RX_HAUP_INT */
118 IVTV_Z8F0811_IR_TX_I2C_ADDR, /* IVTV_HW_Z8F0811_IR_TX_HAUP */
119 IVTV_Z8F0811_IR_RX_I2C_ADDR, /* IVTV_HW_Z8F0811_IR_RX_HAUP */
110}; 120};
111 121
112/* This array should match the IVTV_HW_ defines */ 122/* This array should match the IVTV_HW_ defines */
@@ -126,7 +136,12 @@ static const char *hw_modules[] = {
126 "wm8739", 136 "wm8739",
127 "vp27smpx", 137 "vp27smpx",
128 "m52790", 138 "m52790",
129 NULL 139 NULL,
140 NULL, /* IVTV_HW_I2C_IR_RX_AVER */
141 NULL, /* IVTV_HW_I2C_IR_RX_HAUP_EXT */
142 NULL, /* IVTV_HW_I2C_IR_RX_HAUP_INT */
143 NULL, /* IVTV_HW_Z8F0811_IR_TX_HAUP */
144 NULL, /* IVTV_HW_Z8F0811_IR_RX_HAUP */
130}; 145};
131 146
132/* This array should match the IVTV_HW_ defines */ 147/* This array should match the IVTV_HW_ defines */
@@ -147,8 +162,95 @@ static const char * const hw_devicenames[] = {
147 "vp27smpx", 162 "vp27smpx",
148 "m52790", 163 "m52790",
149 "gpio", 164 "gpio",
165 "ir_video", /* IVTV_HW_I2C_IR_RX_AVER */
166 "ir_video", /* IVTV_HW_I2C_IR_RX_HAUP_EXT */
167 "ir_video", /* IVTV_HW_I2C_IR_RX_HAUP_INT */
168 "ir_tx_z8f0811_haup", /* IVTV_HW_Z8F0811_IR_TX_HAUP */
169 "ir_rx_z8f0811_haup", /* IVTV_HW_Z8F0811_IR_RX_HAUP */
150}; 170};
151 171
172static int ivtv_i2c_new_ir(struct ivtv *itv, u32 hw, const char *type, u8 addr)
173{
174 struct i2c_board_info info;
175 struct i2c_adapter *adap = &itv->i2c_adap;
176 struct IR_i2c_init_data *init_data = &itv->ir_i2c_init_data;
177 unsigned short addr_list[2] = { addr, I2C_CLIENT_END };
178
179 /* Only allow one IR transmitter to be registered per board */
180 if (hw & IVTV_HW_IR_TX_ANY) {
181 if (itv->hw_flags & IVTV_HW_IR_TX_ANY)
182 return -1;
183 memset(&info, 0, sizeof(struct i2c_board_info));
184 strlcpy(info.type, type, I2C_NAME_SIZE);
185 return i2c_new_probed_device(adap, &info, addr_list) == NULL
186 ? -1 : 0;
187 }
188
189 /* Only allow one IR receiver to be registered per board */
190 if (itv->hw_flags & IVTV_HW_IR_RX_ANY)
191 return -1;
192
193 /* Our default information for ir-kbd-i2c.c to use */
194 switch (hw) {
195 case IVTV_HW_I2C_IR_RX_AVER:
196 init_data->ir_codes = &ir_codes_avermedia_cardbus_table;
197 init_data->internal_get_key_func =
198 IR_KBD_GET_KEY_AVERMEDIA_CARDBUS;
199 init_data->type = IR_TYPE_OTHER;
200 init_data->name = "AVerMedia AVerTV card";
201 break;
202 case IVTV_HW_I2C_IR_RX_HAUP_EXT:
203 case IVTV_HW_I2C_IR_RX_HAUP_INT:
204 /* Default to old black remote */
205 init_data->ir_codes = &ir_codes_rc5_tv_table;
206 init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP;
207 init_data->type = IR_TYPE_RC5;
208 init_data->name = itv->card_name;
209 break;
210 case IVTV_HW_Z8F0811_IR_RX_HAUP:
211 /* Default to grey remote */
212 init_data->ir_codes = &ir_codes_hauppauge_new_table;
213 init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR;
214 init_data->type = IR_TYPE_RC5;
215 init_data->name = itv->card_name;
216 break;
217 }
218
219 memset(&info, 0, sizeof(struct i2c_board_info));
220 info.platform_data = init_data;
221 strlcpy(info.type, type, I2C_NAME_SIZE);
222
223 return i2c_new_probed_device(adap, &info, addr_list) == NULL ? -1 : 0;
224}
225
226/* Instantiate the IR receiver device using probing -- undesirable */
227struct i2c_client *ivtv_i2c_new_ir_legacy(struct ivtv *itv)
228{
229 struct i2c_board_info info;
230 /*
231 * The external IR receiver is at i2c address 0x34.
232 * The internal IR receiver is at i2c address 0x30.
233 *
234 * In theory, both can be fitted, and Hauppauge suggests an external
235 * overrides an internal. That's why we probe 0x1a (~0x34) first. CB
236 *
237 * Some of these addresses we probe may collide with other i2c address
238 * allocations, so this function must be called after all other i2c
239 * devices we care about are registered.
240 */
241 const unsigned short addr_list[] = {
242 0x1a, /* Hauppauge IR external - collides with WM8739 */
243 0x18, /* Hauppauge IR internal */
244 0x71, /* Hauppauge IR (PVR150) */
245 0x6b, /* Adaptec IR */
246 I2C_CLIENT_END
247 };
248
249 memset(&info, 0, sizeof(struct i2c_board_info));
250 strlcpy(info.type, "ir_video", I2C_NAME_SIZE);
251 return i2c_new_probed_device(&itv->i2c_adap, &info, addr_list);
252}
253
152int ivtv_i2c_register(struct ivtv *itv, unsigned idx) 254int ivtv_i2c_register(struct ivtv *itv, unsigned idx)
153{ 255{
154 struct v4l2_subdev *sd; 256 struct v4l2_subdev *sd;
@@ -178,8 +280,15 @@ int ivtv_i2c_register(struct ivtv *itv, unsigned idx)
178 sd->grp_id = 1 << idx; 280 sd->grp_id = 1 << idx;
179 return sd ? 0 : -1; 281 return sd ? 0 : -1;
180 } 282 }
283
284 if (hw & IVTV_HW_IR_ANY)
285 return ivtv_i2c_new_ir(itv, hw, type, hw_addrs[idx]);
286
287 /* Is it not an I2C device or one we do not wish to register? */
181 if (!hw_addrs[idx]) 288 if (!hw_addrs[idx])
182 return -1; 289 return -1;
290
291 /* It's an I2C device other than an analog tuner or IR chip */
183 if (hw == IVTV_HW_UPD64031A || hw == IVTV_HW_UPD6408X) { 292 if (hw == IVTV_HW_UPD64031A || hw == IVTV_HW_UPD6408X) {
184 sd = v4l2_i2c_new_subdev(&itv->v4l2_dev, 293 sd = v4l2_i2c_new_subdev(&itv->v4l2_dev,
185 adap, mod, type, 0, I2C_ADDRS(hw_addrs[idx])); 294 adap, mod, type, 0, I2C_ADDRS(hw_addrs[idx]));
@@ -564,20 +673,22 @@ static struct i2c_adapter ivtv_i2c_adap_template = {
564 .owner = THIS_MODULE, 673 .owner = THIS_MODULE,
565}; 674};
566 675
676#define IVTV_ALGO_BIT_TIMEOUT (2) /* seconds */
677
567static const struct i2c_algo_bit_data ivtv_i2c_algo_template = { 678static const struct i2c_algo_bit_data ivtv_i2c_algo_template = {
568 .setsda = ivtv_setsda_old, 679 .setsda = ivtv_setsda_old,
569 .setscl = ivtv_setscl_old, 680 .setscl = ivtv_setscl_old,
570 .getsda = ivtv_getsda_old, 681 .getsda = ivtv_getsda_old,
571 .getscl = ivtv_getscl_old, 682 .getscl = ivtv_getscl_old,
572 .udelay = 10, 683 .udelay = IVTV_DEFAULT_I2C_CLOCK_PERIOD / 2, /* microseconds */
573 .timeout = 200, 684 .timeout = IVTV_ALGO_BIT_TIMEOUT * HZ, /* jiffies */
574}; 685};
575 686
576static struct i2c_client ivtv_i2c_client_template = { 687static struct i2c_client ivtv_i2c_client_template = {
577 .name = "ivtv internal", 688 .name = "ivtv internal",
578}; 689};
579 690
580/* init + register i2c adapter + instantiate IR receiver */ 691/* init + register i2c adapter */
581int init_ivtv_i2c(struct ivtv *itv) 692int init_ivtv_i2c(struct ivtv *itv)
582{ 693{
583 int retval; 694 int retval;
@@ -585,11 +696,10 @@ int init_ivtv_i2c(struct ivtv *itv)
585 IVTV_DEBUG_I2C("i2c init\n"); 696 IVTV_DEBUG_I2C("i2c init\n");
586 697
587 /* Sanity checks for the I2C hardware arrays. They must be the 698 /* Sanity checks for the I2C hardware arrays. They must be the
588 * same size and GPIO must be the last entry. 699 * same size.
589 */ 700 */
590 if (ARRAY_SIZE(hw_devicenames) != ARRAY_SIZE(hw_addrs) || 701 if (ARRAY_SIZE(hw_devicenames) != ARRAY_SIZE(hw_addrs) ||
591 ARRAY_SIZE(hw_devicenames) != ARRAY_SIZE(hw_modules) || 702 ARRAY_SIZE(hw_devicenames) != ARRAY_SIZE(hw_modules)) {
592 IVTV_HW_GPIO != (1 << (ARRAY_SIZE(hw_addrs) - 1))) {
593 IVTV_ERR("Mismatched I2C hardware arrays\n"); 703 IVTV_ERR("Mismatched I2C hardware arrays\n");
594 return -ENODEV; 704 return -ENODEV;
595 } 705 }
@@ -602,6 +712,7 @@ int init_ivtv_i2c(struct ivtv *itv)
602 memcpy(&itv->i2c_algo, &ivtv_i2c_algo_template, 712 memcpy(&itv->i2c_algo, &ivtv_i2c_algo_template,
603 sizeof(struct i2c_algo_bit_data)); 713 sizeof(struct i2c_algo_bit_data));
604 } 714 }
715 itv->i2c_algo.udelay = itv->options.i2c_clock_period / 2;
605 itv->i2c_algo.data = itv; 716 itv->i2c_algo.data = itv;
606 itv->i2c_adap.algo_data = &itv->i2c_algo; 717 itv->i2c_adap.algo_data = &itv->i2c_algo;
607 718
@@ -623,32 +734,6 @@ int init_ivtv_i2c(struct ivtv *itv)
623 else 734 else
624 retval = i2c_bit_add_bus(&itv->i2c_adap); 735 retval = i2c_bit_add_bus(&itv->i2c_adap);
625 736
626 /* Instantiate the IR receiver device, if present */
627 if (retval == 0) {
628 struct i2c_board_info info;
629 /* The external IR receiver is at i2c address 0x34 (0x35 for
630 reads). Future Hauppauge cards will have an internal
631 receiver at 0x30 (0x31 for reads). In theory, both can be
632 fitted, and Hauppauge suggest an external overrides an
633 internal.
634
635 That's why we probe 0x1a (~0x34) first. CB
636 */
637 const unsigned short addr_list[] = {
638 0x1a, /* Hauppauge IR external */
639 0x18, /* Hauppauge IR internal */
640 0x71, /* Hauppauge IR (PVR150) */
641 0x64, /* Pixelview IR */
642 0x30, /* KNC ONE IR */
643 0x6b, /* Adaptec IR */
644 I2C_CLIENT_END
645 };
646
647 memset(&info, 0, sizeof(struct i2c_board_info));
648 strlcpy(info.type, "ir_video", I2C_NAME_SIZE);
649 i2c_new_probed_device(&itv->i2c_adap, &info, addr_list);
650 }
651
652 return retval; 737 return retval;
653} 738}
654 739
diff --git a/drivers/media/video/ivtv/ivtv-i2c.h b/drivers/media/video/ivtv/ivtv-i2c.h
index 396928a06a54..9332920ca4ff 100644
--- a/drivers/media/video/ivtv/ivtv-i2c.h
+++ b/drivers/media/video/ivtv/ivtv-i2c.h
@@ -21,6 +21,7 @@
21#ifndef IVTV_I2C_H 21#ifndef IVTV_I2C_H
22#define IVTV_I2C_H 22#define IVTV_I2C_H
23 23
24struct i2c_client *ivtv_i2c_new_ir_legacy(struct ivtv *itv);
24int ivtv_i2c_register(struct ivtv *itv, unsigned idx); 25int ivtv_i2c_register(struct ivtv *itv, unsigned idx);
25struct v4l2_subdev *ivtv_find_hw(struct ivtv *itv, u32 hw); 26struct v4l2_subdev *ivtv_find_hw(struct ivtv *itv, u32 hw);
26 27
diff --git a/drivers/media/video/mxb.c b/drivers/media/video/mxb.c
index 3454070e63f0..c1fc6dc776f5 100644
--- a/drivers/media/video/mxb.c
+++ b/drivers/media/video/mxb.c
@@ -478,7 +478,7 @@ static int vidioc_s_input(struct file *file, void *fh, unsigned int input)
478 478
479 DEB_EE(("VIDIOC_S_INPUT %d.\n", input)); 479 DEB_EE(("VIDIOC_S_INPUT %d.\n", input));
480 480
481 if (input < 0 || input >= MXB_INPUTS) 481 if (input >= MXB_INPUTS)
482 return -EINVAL; 482 return -EINVAL;
483 483
484 mxb->cur_input = input; 484 mxb->cur_input = input;
diff --git a/drivers/media/video/ov9640.c b/drivers/media/video/ov9640.c
new file mode 100644
index 000000000000..c81ae2192887
--- /dev/null
+++ b/drivers/media/video/ov9640.c
@@ -0,0 +1,801 @@
1/*
2 * OmniVision OV96xx Camera Driver
3 *
4 * Copyright (C) 2009 Marek Vasut <marek.vasut@gmail.com>
5 *
6 * Based on ov772x camera driver:
7 *
8 * Copyright (C) 2008 Renesas Solutions Corp.
9 * Kuninori Morimoto <morimoto.kuninori@renesas.com>
10 *
11 * Based on ov7670 and soc_camera_platform driver,
12 *
13 * Copyright 2006-7 Jonathan Corbet <corbet@lwn.net>
14 * Copyright (C) 2008 Magnus Damm
15 * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de>
16 *
17 * This program is free software; you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License version 2 as
19 * published by the Free Software Foundation.
20 */
21
22#include <linux/init.h>
23#include <linux/module.h>
24#include <linux/i2c.h>
25#include <linux/slab.h>
26#include <linux/delay.h>
27#include <linux/videodev2.h>
28#include <media/v4l2-chip-ident.h>
29#include <media/v4l2-common.h>
30#include <media/soc_camera.h>
31
32#include "ov9640.h"
33
34/* default register setup */
35static const struct ov9640_reg ov9640_regs_dflt[] = {
36 { OV9640_COM5, OV9640_COM5_SYSCLK | OV9640_COM5_LONGEXP },
37 { OV9640_COM6, OV9640_COM6_OPT_BLC | OV9640_COM6_ADBLC_BIAS |
38 OV9640_COM6_FMT_RST | OV9640_COM6_ADBLC_OPTEN },
39 { OV9640_PSHFT, OV9640_PSHFT_VAL(0x01) },
40 { OV9640_ACOM, OV9640_ACOM_2X_ANALOG | OV9640_ACOM_RSVD },
41 { OV9640_TSLB, OV9640_TSLB_YUYV_UYVY },
42 { OV9640_COM16, OV9640_COM16_RB_AVG },
43
44 /* Gamma curve P */
45 { 0x6c, 0x40 }, { 0x6d, 0x30 }, { 0x6e, 0x4b }, { 0x6f, 0x60 },
46 { 0x70, 0x70 }, { 0x71, 0x70 }, { 0x72, 0x70 }, { 0x73, 0x70 },
47 { 0x74, 0x60 }, { 0x75, 0x60 }, { 0x76, 0x50 }, { 0x77, 0x48 },
48 { 0x78, 0x3a }, { 0x79, 0x2e }, { 0x7a, 0x28 }, { 0x7b, 0x22 },
49
50 /* Gamma curve T */
51 { 0x7c, 0x04 }, { 0x7d, 0x07 }, { 0x7e, 0x10 }, { 0x7f, 0x28 },
52 { 0x80, 0x36 }, { 0x81, 0x44 }, { 0x82, 0x52 }, { 0x83, 0x60 },
53 { 0x84, 0x6c }, { 0x85, 0x78 }, { 0x86, 0x8c }, { 0x87, 0x9e },
54 { 0x88, 0xbb }, { 0x89, 0xd2 }, { 0x8a, 0xe6 },
55};
56
57/* Configurations
58 * NOTE: for YUV, alter the following registers:
59 * COM12 |= OV9640_COM12_YUV_AVG
60 *
61 * for RGB, alter the following registers:
62 * COM7 |= OV9640_COM7_RGB
63 * COM13 |= OV9640_COM13_RGB_AVG
64 * COM15 |= proper RGB color encoding mode
65 */
66static const struct ov9640_reg ov9640_regs_qqcif[] = {
67 { OV9640_CLKRC, OV9640_CLKRC_DPLL_EN | OV9640_CLKRC_DIV(0x0f) },
68 { OV9640_COM1, OV9640_COM1_QQFMT | OV9640_COM1_HREF_2SKIP },
69 { OV9640_COM4, OV9640_COM4_QQ_VP | OV9640_COM4_RSVD },
70 { OV9640_COM7, OV9640_COM7_QCIF },
71 { OV9640_COM12, OV9640_COM12_RSVD },
72 { OV9640_COM13, OV9640_COM13_GAMMA_RAW | OV9640_COM13_MATRIX_EN },
73 { OV9640_COM15, OV9640_COM15_OR_10F0 },
74};
75
76static const struct ov9640_reg ov9640_regs_qqvga[] = {
77 { OV9640_CLKRC, OV9640_CLKRC_DPLL_EN | OV9640_CLKRC_DIV(0x07) },
78 { OV9640_COM1, OV9640_COM1_QQFMT | OV9640_COM1_HREF_2SKIP },
79 { OV9640_COM4, OV9640_COM4_QQ_VP | OV9640_COM4_RSVD },
80 { OV9640_COM7, OV9640_COM7_QVGA },
81 { OV9640_COM12, OV9640_COM12_RSVD },
82 { OV9640_COM13, OV9640_COM13_GAMMA_RAW | OV9640_COM13_MATRIX_EN },
83 { OV9640_COM15, OV9640_COM15_OR_10F0 },
84};
85
86static const struct ov9640_reg ov9640_regs_qcif[] = {
87 { OV9640_CLKRC, OV9640_CLKRC_DPLL_EN | OV9640_CLKRC_DIV(0x07) },
88 { OV9640_COM4, OV9640_COM4_QQ_VP | OV9640_COM4_RSVD },
89 { OV9640_COM7, OV9640_COM7_QCIF },
90 { OV9640_COM12, OV9640_COM12_RSVD },
91 { OV9640_COM13, OV9640_COM13_GAMMA_RAW | OV9640_COM13_MATRIX_EN },
92 { OV9640_COM15, OV9640_COM15_OR_10F0 },
93};
94
95static const struct ov9640_reg ov9640_regs_qvga[] = {
96 { OV9640_CLKRC, OV9640_CLKRC_DPLL_EN | OV9640_CLKRC_DIV(0x03) },
97 { OV9640_COM4, OV9640_COM4_QQ_VP | OV9640_COM4_RSVD },
98 { OV9640_COM7, OV9640_COM7_QVGA },
99 { OV9640_COM12, OV9640_COM12_RSVD },
100 { OV9640_COM13, OV9640_COM13_GAMMA_RAW | OV9640_COM13_MATRIX_EN },
101 { OV9640_COM15, OV9640_COM15_OR_10F0 },
102};
103
104static const struct ov9640_reg ov9640_regs_cif[] = {
105 { OV9640_CLKRC, OV9640_CLKRC_DPLL_EN | OV9640_CLKRC_DIV(0x03) },
106 { OV9640_COM3, OV9640_COM3_VP },
107 { OV9640_COM7, OV9640_COM7_CIF },
108 { OV9640_COM12, OV9640_COM12_RSVD },
109 { OV9640_COM13, OV9640_COM13_GAMMA_RAW | OV9640_COM13_MATRIX_EN },
110 { OV9640_COM15, OV9640_COM15_OR_10F0 },
111};
112
113static const struct ov9640_reg ov9640_regs_vga[] = {
114 { OV9640_CLKRC, OV9640_CLKRC_DPLL_EN | OV9640_CLKRC_DIV(0x01) },
115 { OV9640_COM3, OV9640_COM3_VP },
116 { OV9640_COM7, OV9640_COM7_VGA },
117 { OV9640_COM12, OV9640_COM12_RSVD },
118 { OV9640_COM13, OV9640_COM13_GAMMA_RAW | OV9640_COM13_MATRIX_EN },
119 { OV9640_COM15, OV9640_COM15_OR_10F0 },
120};
121
122static const struct ov9640_reg ov9640_regs_sxga[] = {
123 { OV9640_CLKRC, OV9640_CLKRC_DPLL_EN | OV9640_CLKRC_DIV(0x01) },
124 { OV9640_COM3, OV9640_COM3_VP },
125 { OV9640_COM7, 0 },
126 { OV9640_COM12, OV9640_COM12_RSVD },
127 { OV9640_COM13, OV9640_COM13_GAMMA_RAW | OV9640_COM13_MATRIX_EN },
128 { OV9640_COM15, OV9640_COM15_OR_10F0 },
129};
130
131static const struct ov9640_reg ov9640_regs_yuv[] = {
132 { OV9640_MTX1, 0x58 },
133 { OV9640_MTX2, 0x48 },
134 { OV9640_MTX3, 0x10 },
135 { OV9640_MTX4, 0x28 },
136 { OV9640_MTX5, 0x48 },
137 { OV9640_MTX6, 0x70 },
138 { OV9640_MTX7, 0x40 },
139 { OV9640_MTX8, 0x40 },
140 { OV9640_MTX9, 0x40 },
141 { OV9640_MTXS, 0x0f },
142};
143
144static const struct ov9640_reg ov9640_regs_rgb[] = {
145 { OV9640_MTX1, 0x71 },
146 { OV9640_MTX2, 0x3e },
147 { OV9640_MTX3, 0x0c },
148 { OV9640_MTX4, 0x33 },
149 { OV9640_MTX5, 0x72 },
150 { OV9640_MTX6, 0x00 },
151 { OV9640_MTX7, 0x2b },
152 { OV9640_MTX8, 0x66 },
153 { OV9640_MTX9, 0xd2 },
154 { OV9640_MTXS, 0x65 },
155};
156
157/*
158 * TODO: this sensor also supports RGB555 and RGB565 formats, but support for
159 * them has not yet been sufficiently tested and so it is not included with
160 * this version of the driver. To test and debug these formats add two entries
161 * to the below array, see ov722x.c for an example.
162 */
163static const struct soc_camera_data_format ov9640_fmt_lists[] = {
164 {
165 .name = "UYVY",
166 .fourcc = V4L2_PIX_FMT_UYVY,
167 .depth = 16,
168 .colorspace = V4L2_COLORSPACE_JPEG,
169 },
170};
171
172static const struct v4l2_queryctrl ov9640_controls[] = {
173 {
174 .id = V4L2_CID_VFLIP,
175 .type = V4L2_CTRL_TYPE_BOOLEAN,
176 .name = "Flip Vertically",
177 .minimum = 0,
178 .maximum = 1,
179 .step = 1,
180 .default_value = 0,
181 },
182 {
183 .id = V4L2_CID_HFLIP,
184 .type = V4L2_CTRL_TYPE_BOOLEAN,
185 .name = "Flip Horizontally",
186 .minimum = 0,
187 .maximum = 1,
188 .step = 1,
189 .default_value = 0,
190 },
191};
192
193/* read a register */
194static int ov9640_reg_read(struct i2c_client *client, u8 reg, u8 *val)
195{
196 int ret;
197 u8 data = reg;
198 struct i2c_msg msg = {
199 .addr = client->addr,
200 .flags = 0,
201 .len = 1,
202 .buf = &data,
203 };
204
205 ret = i2c_transfer(client->adapter, &msg, 1);
206 if (ret < 0)
207 goto err;
208
209 msg.flags = I2C_M_RD;
210 ret = i2c_transfer(client->adapter, &msg, 1);
211 if (ret < 0)
212 goto err;
213
214 *val = data;
215 return 0;
216
217err:
218 dev_err(&client->dev, "Failed reading register 0x%02x!\n", reg);
219 return ret;
220}
221
222/* write a register */
223static int ov9640_reg_write(struct i2c_client *client, u8 reg, u8 val)
224{
225 int ret;
226 u8 _val;
227 unsigned char data[2] = { reg, val };
228 struct i2c_msg msg = {
229 .addr = client->addr,
230 .flags = 0,
231 .len = 2,
232 .buf = data,
233 };
234
235 ret = i2c_transfer(client->adapter, &msg, 1);
236 if (ret < 0) {
237 dev_err(&client->dev, "Failed writing register 0x%02x!\n", reg);
238 return ret;
239 }
240
241 /* we have to read the register back ... no idea why, maybe HW bug */
242 ret = ov9640_reg_read(client, reg, &_val);
243 if (ret)
244 dev_err(&client->dev,
245 "Failed reading back register 0x%02x!\n", reg);
246
247 return 0;
248}
249
250
251/* Read a register, alter its bits, write it back */
252static int ov9640_reg_rmw(struct i2c_client *client, u8 reg, u8 set, u8 unset)
253{
254 u8 val;
255 int ret;
256
257 ret = ov9640_reg_read(client, reg, &val);
258 if (ret) {
259 dev_err(&client->dev,
260 "[Read]-Modify-Write of register %02x failed!\n", reg);
261 return val;
262 }
263
264 val |= set;
265 val &= ~unset;
266
267 ret = ov9640_reg_write(client, reg, val);
268 if (ret)
269 dev_err(&client->dev,
270 "Read-Modify-[Write] of register %02x failed!\n", reg);
271
272 return ret;
273}
274
275/* Soft reset the camera. This has nothing to do with the RESET pin! */
276static int ov9640_reset(struct i2c_client *client)
277{
278 int ret;
279
280 ret = ov9640_reg_write(client, OV9640_COM7, OV9640_COM7_SCCB_RESET);
281 if (ret)
282 dev_err(&client->dev,
283 "An error occured while entering soft reset!\n");
284
285 return ret;
286}
287
288/* Start/Stop streaming from the device */
289static int ov9640_s_stream(struct v4l2_subdev *sd, int enable)
290{
291 return 0;
292}
293
294/* Alter bus settings on camera side */
295static int ov9640_set_bus_param(struct soc_camera_device *icd,
296 unsigned long flags)
297{
298 return 0;
299}
300
301/* Request bus settings on camera side */
302static unsigned long ov9640_query_bus_param(struct soc_camera_device *icd)
303{
304 struct soc_camera_link *icl = to_soc_camera_link(icd);
305
306 /*
307 * REVISIT: the camera probably can do 10 bit transfers, but I don't
308 * have those pins connected on my hardware.
309 */
310 unsigned long flags = SOCAM_PCLK_SAMPLE_RISING | SOCAM_MASTER |
311 SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_HSYNC_ACTIVE_HIGH |
312 SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8;
313
314 return soc_camera_apply_sensor_flags(icl, flags);
315}
316
317/* Get status of additional camera capabilities */
318static int ov9640_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
319{
320 struct i2c_client *client = sd->priv;
321 struct ov9640_priv *priv = container_of(i2c_get_clientdata(client),
322 struct ov9640_priv, subdev);
323
324 switch (ctrl->id) {
325 case V4L2_CID_VFLIP:
326 ctrl->value = priv->flag_vflip;
327 break;
328 case V4L2_CID_HFLIP:
329 ctrl->value = priv->flag_hflip;
330 break;
331 }
332 return 0;
333}
334
335/* Set status of additional camera capabilities */
336static int ov9640_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
337{
338 struct i2c_client *client = sd->priv;
339 struct ov9640_priv *priv = container_of(i2c_get_clientdata(client),
340 struct ov9640_priv, subdev);
341
342 int ret = 0;
343
344 switch (ctrl->id) {
345 case V4L2_CID_VFLIP:
346 priv->flag_vflip = ctrl->value;
347 if (ctrl->value)
348 ret = ov9640_reg_rmw(client, OV9640_MVFP,
349 OV9640_MVFP_V, 0);
350 else
351 ret = ov9640_reg_rmw(client, OV9640_MVFP,
352 0, OV9640_MVFP_V);
353 break;
354 case V4L2_CID_HFLIP:
355 priv->flag_hflip = ctrl->value;
356 if (ctrl->value)
357 ret = ov9640_reg_rmw(client, OV9640_MVFP,
358 OV9640_MVFP_H, 0);
359 else
360 ret = ov9640_reg_rmw(client, OV9640_MVFP,
361 0, OV9640_MVFP_H);
362 break;
363 }
364
365 return ret;
366}
367
368/* Get chip identification */
369static int ov9640_g_chip_ident(struct v4l2_subdev *sd,
370 struct v4l2_dbg_chip_ident *id)
371{
372 struct i2c_client *client = sd->priv;
373 struct ov9640_priv *priv = container_of(i2c_get_clientdata(client),
374 struct ov9640_priv, subdev);
375
376 id->ident = priv->model;
377 id->revision = priv->revision;
378
379 return 0;
380}
381
382#ifdef CONFIG_VIDEO_ADV_DEBUG
383static int ov9640_get_register(struct v4l2_subdev *sd,
384 struct v4l2_dbg_register *reg)
385{
386 struct i2c_client *client = sd->priv;
387 int ret;
388 u8 val;
389
390 if (reg->reg & ~0xff)
391 return -EINVAL;
392
393 reg->size = 1;
394
395 ret = ov9640_reg_read(client, reg->reg, &val);
396 if (ret)
397 return ret;
398
399 reg->val = (__u64)val;
400
401 return 0;
402}
403
404static int ov9640_set_register(struct v4l2_subdev *sd,
405 struct v4l2_dbg_register *reg)
406{
407 struct i2c_client *client = sd->priv;
408
409 if (reg->reg & ~0xff || reg->val & ~0xff)
410 return -EINVAL;
411
412 return ov9640_reg_write(client, reg->reg, reg->val);
413}
414#endif
415
416/* select nearest higher resolution for capture */
417static void ov9640_res_roundup(u32 *width, u32 *height)
418{
419 int i;
420 enum { QQCIF, QQVGA, QCIF, QVGA, CIF, VGA, SXGA };
421 int res_x[] = { 88, 160, 176, 320, 352, 640, 1280 };
422 int res_y[] = { 72, 120, 144, 240, 288, 480, 960 };
423
424 for (i = 0; i < ARRAY_SIZE(res_x); i++) {
425 if (res_x[i] >= *width && res_y[i] >= *height) {
426 *width = res_x[i];
427 *height = res_y[i];
428 return;
429 }
430 }
431
432 *width = res_x[SXGA];
433 *height = res_y[SXGA];
434}
435
436/* Prepare necessary register changes depending on color encoding */
437static void ov9640_alter_regs(u32 pixfmt, struct ov9640_reg_alt *alt)
438{
439 switch (pixfmt) {
440 case V4L2_PIX_FMT_UYVY:
441 alt->com12 = OV9640_COM12_YUV_AVG;
442 alt->com13 = OV9640_COM13_Y_DELAY_EN |
443 OV9640_COM13_YUV_DLY(0x01);
444 break;
445 case V4L2_PIX_FMT_RGB555:
446 alt->com7 = OV9640_COM7_RGB;
447 alt->com13 = OV9640_COM13_RGB_AVG;
448 alt->com15 = OV9640_COM15_RGB_555;
449 break;
450 case V4L2_PIX_FMT_RGB565:
451 alt->com7 = OV9640_COM7_RGB;
452 alt->com13 = OV9640_COM13_RGB_AVG;
453 alt->com15 = OV9640_COM15_RGB_565;
454 break;
455 };
456}
457
458/* Setup registers according to resolution and color encoding */
459static int ov9640_write_regs(struct i2c_client *client,
460 u32 width, u32 pixfmt, struct ov9640_reg_alt *alts)
461{
462 const struct ov9640_reg *ov9640_regs, *matrix_regs;
463 int ov9640_regs_len, matrix_regs_len;
464 int i, ret;
465 u8 val;
466
467 /* select register configuration for given resolution */
468 switch (width) {
469 case W_QQCIF:
470 ov9640_regs = ov9640_regs_qqcif;
471 ov9640_regs_len = ARRAY_SIZE(ov9640_regs_qqcif);
472 break;
473 case W_QQVGA:
474 ov9640_regs = ov9640_regs_qqvga;
475 ov9640_regs_len = ARRAY_SIZE(ov9640_regs_qqvga);
476 break;
477 case W_QCIF:
478 ov9640_regs = ov9640_regs_qcif;
479 ov9640_regs_len = ARRAY_SIZE(ov9640_regs_qcif);
480 break;
481 case W_QVGA:
482 ov9640_regs = ov9640_regs_qvga;
483 ov9640_regs_len = ARRAY_SIZE(ov9640_regs_qvga);
484 break;
485 case W_CIF:
486 ov9640_regs = ov9640_regs_cif;
487 ov9640_regs_len = ARRAY_SIZE(ov9640_regs_cif);
488 break;
489 case W_VGA:
490 ov9640_regs = ov9640_regs_vga;
491 ov9640_regs_len = ARRAY_SIZE(ov9640_regs_vga);
492 break;
493 case W_SXGA:
494 ov9640_regs = ov9640_regs_sxga;
495 ov9640_regs_len = ARRAY_SIZE(ov9640_regs_sxga);
496 break;
497 default:
498 dev_err(&client->dev, "Failed to select resolution!\n");
499 return -EINVAL;
500 }
501
502 /* select color matrix configuration for given color encoding */
503 if (pixfmt == V4L2_PIX_FMT_UYVY) {
504 matrix_regs = ov9640_regs_yuv;
505 matrix_regs_len = ARRAY_SIZE(ov9640_regs_yuv);
506 } else {
507 matrix_regs = ov9640_regs_rgb;
508 matrix_regs_len = ARRAY_SIZE(ov9640_regs_rgb);
509 }
510
511 /* write register settings into the module */
512 for (i = 0; i < ov9640_regs_len; i++) {
513 val = ov9640_regs[i].val;
514
515 switch (ov9640_regs[i].reg) {
516 case OV9640_COM7:
517 val |= alts->com7;
518 break;
519 case OV9640_COM12:
520 val |= alts->com12;
521 break;
522 case OV9640_COM13:
523 val |= alts->com13;
524 break;
525 case OV9640_COM15:
526 val |= alts->com15;
527 break;
528 }
529
530 ret = ov9640_reg_write(client, ov9640_regs[i].reg, val);
531 if (ret)
532 return ret;
533 }
534
535 /* write color matrix configuration into the module */
536 for (i = 0; i < matrix_regs_len; i++) {
537 ret = ov9640_reg_write(client, matrix_regs[i].reg,
538 matrix_regs[i].val);
539 if (ret)
540 return ret;
541 }
542
543 return 0;
544}
545
546/* program default register values */
547static int ov9640_prog_dflt(struct i2c_client *client)
548{
549 int i, ret;
550
551 for (i = 0; i < ARRAY_SIZE(ov9640_regs_dflt); i++) {
552 ret = ov9640_reg_write(client, ov9640_regs_dflt[i].reg,
553 ov9640_regs_dflt[i].val);
554 if (ret)
555 return ret;
556 }
557
558 /* wait for the changes to actually happen, 140ms are not enough yet */
559 mdelay(150);
560
561 return 0;
562}
563
564/* set the format we will capture in */
565static int ov9640_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
566{
567 struct i2c_client *client = sd->priv;
568 struct v4l2_pix_format *pix = &f->fmt.pix;
569 struct ov9640_reg_alt alts = {0};
570 int ret;
571
572 ov9640_res_roundup(&pix->width, &pix->height);
573 ov9640_alter_regs(pix->pixelformat, &alts);
574
575 ov9640_reset(client);
576
577 ret = ov9640_prog_dflt(client);
578 if (ret)
579 return ret;
580
581 return ov9640_write_regs(client, pix->width, pix->pixelformat, &alts);
582}
583
584static int ov9640_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
585{
586 struct v4l2_pix_format *pix = &f->fmt.pix;
587
588 ov9640_res_roundup(&pix->width, &pix->height);
589 pix->field = V4L2_FIELD_NONE;
590
591 return 0;
592}
593
594static int ov9640_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
595{
596 a->c.left = 0;
597 a->c.top = 0;
598 a->c.width = W_SXGA;
599 a->c.height = H_SXGA;
600 a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
601
602 return 0;
603}
604
605static int ov9640_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
606{
607 a->bounds.left = 0;
608 a->bounds.top = 0;
609 a->bounds.width = W_SXGA;
610 a->bounds.height = H_SXGA;
611 a->defrect = a->bounds;
612 a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
613 a->pixelaspect.numerator = 1;
614 a->pixelaspect.denominator = 1;
615
616 return 0;
617}
618
619
620
621static int ov9640_video_probe(struct soc_camera_device *icd,
622 struct i2c_client *client)
623{
624 struct ov9640_priv *priv = i2c_get_clientdata(client);
625 u8 pid, ver, midh, midl;
626 const char *devname;
627 int ret = 0;
628
629 /*
630 * We must have a parent by now. And it cannot be a wrong one.
631 * So this entire test is completely redundant.
632 */
633 if (!icd->dev.parent ||
634 to_soc_camera_host(icd->dev.parent)->nr != icd->iface) {
635 dev_err(&client->dev, "Parent missing or invalid!\n");
636 ret = -ENODEV;
637 goto err;
638 }
639
640 icd->formats = ov9640_fmt_lists;
641 icd->num_formats = ARRAY_SIZE(ov9640_fmt_lists);
642
643 /*
644 * check and show product ID and manufacturer ID
645 */
646
647 ret = ov9640_reg_read(client, OV9640_PID, &pid);
648 if (ret)
649 goto err;
650
651 ret = ov9640_reg_read(client, OV9640_VER, &ver);
652 if (ret)
653 goto err;
654
655 ret = ov9640_reg_read(client, OV9640_MIDH, &midh);
656 if (ret)
657 goto err;
658
659 ret = ov9640_reg_read(client, OV9640_MIDL, &midl);
660 if (ret)
661 goto err;
662
663 switch (VERSION(pid, ver)) {
664 case OV9640_V2:
665 devname = "ov9640";
666 priv->model = V4L2_IDENT_OV9640;
667 priv->revision = 2;
668 case OV9640_V3:
669 devname = "ov9640";
670 priv->model = V4L2_IDENT_OV9640;
671 priv->revision = 3;
672 break;
673 default:
674 dev_err(&client->dev, "Product ID error %x:%x\n", pid, ver);
675 ret = -ENODEV;
676 goto err;
677 }
678
679 dev_info(&client->dev, "%s Product ID %0x:%0x Manufacturer ID %x:%x\n",
680 devname, pid, ver, midh, midl);
681
682err:
683 return ret;
684}
685
686static struct soc_camera_ops ov9640_ops = {
687 .set_bus_param = ov9640_set_bus_param,
688 .query_bus_param = ov9640_query_bus_param,
689 .controls = ov9640_controls,
690 .num_controls = ARRAY_SIZE(ov9640_controls),
691};
692
693static struct v4l2_subdev_core_ops ov9640_core_ops = {
694 .g_ctrl = ov9640_g_ctrl,
695 .s_ctrl = ov9640_s_ctrl,
696 .g_chip_ident = ov9640_g_chip_ident,
697#ifdef CONFIG_VIDEO_ADV_DEBUG
698 .g_register = ov9640_get_register,
699 .s_register = ov9640_set_register,
700#endif
701
702};
703
704static struct v4l2_subdev_video_ops ov9640_video_ops = {
705 .s_stream = ov9640_s_stream,
706 .s_fmt = ov9640_s_fmt,
707 .try_fmt = ov9640_try_fmt,
708 .cropcap = ov9640_cropcap,
709 .g_crop = ov9640_g_crop,
710
711};
712
713static struct v4l2_subdev_ops ov9640_subdev_ops = {
714 .core = &ov9640_core_ops,
715 .video = &ov9640_video_ops,
716};
717
718/*
719 * i2c_driver function
720 */
721static int ov9640_probe(struct i2c_client *client,
722 const struct i2c_device_id *did)
723{
724 struct ov9640_priv *priv;
725 struct soc_camera_device *icd = client->dev.platform_data;
726 struct soc_camera_link *icl;
727 int ret;
728
729 if (!icd) {
730 dev_err(&client->dev, "Missing soc-camera data!\n");
731 return -EINVAL;
732 }
733
734 icl = to_soc_camera_link(icd);
735 if (!icl) {
736 dev_err(&client->dev, "Missing platform_data for driver\n");
737 return -EINVAL;
738 }
739
740 priv = kzalloc(sizeof(struct ov9640_priv), GFP_KERNEL);
741 if (!priv) {
742 dev_err(&client->dev,
743 "Failed to allocate memory for private data!\n");
744 return -ENOMEM;
745 }
746
747 v4l2_i2c_subdev_init(&priv->subdev, client, &ov9640_subdev_ops);
748
749 icd->ops = &ov9640_ops;
750
751 ret = ov9640_video_probe(icd, client);
752
753 if (ret) {
754 icd->ops = NULL;
755 i2c_set_clientdata(client, NULL);
756 kfree(priv);
757 }
758
759 return ret;
760}
761
762static int ov9640_remove(struct i2c_client *client)
763{
764 struct ov9640_priv *priv = i2c_get_clientdata(client);
765
766 i2c_set_clientdata(client, NULL);
767 kfree(priv);
768 return 0;
769}
770
771static const struct i2c_device_id ov9640_id[] = {
772 { "ov9640", 0 },
773 { }
774};
775MODULE_DEVICE_TABLE(i2c, ov9640_id);
776
777static struct i2c_driver ov9640_i2c_driver = {
778 .driver = {
779 .name = "ov9640",
780 },
781 .probe = ov9640_probe,
782 .remove = ov9640_remove,
783 .id_table = ov9640_id,
784};
785
786static int __init ov9640_module_init(void)
787{
788 return i2c_add_driver(&ov9640_i2c_driver);
789}
790
791static void __exit ov9640_module_exit(void)
792{
793 i2c_del_driver(&ov9640_i2c_driver);
794}
795
796module_init(ov9640_module_init);
797module_exit(ov9640_module_exit);
798
799MODULE_DESCRIPTION("SoC Camera driver for OmniVision OV96xx");
800MODULE_AUTHOR("Marek Vasut <marek.vasut@gmail.com>");
801MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/ov9640.h b/drivers/media/video/ov9640.h
new file mode 100644
index 000000000000..f8a51b70792e
--- /dev/null
+++ b/drivers/media/video/ov9640.h
@@ -0,0 +1,209 @@
1/*
2 * OmniVision OV96xx Camera Header File
3 *
4 * Copyright (C) 2009 Marek Vasut <marek.vasut@gmail.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#ifndef __DRIVERS_MEDIA_VIDEO_OV9640_H__
12#define __DRIVERS_MEDIA_VIDEO_OV9640_H__
13
14/* Register definitions */
15#define OV9640_GAIN 0x00
16#define OV9640_BLUE 0x01
17#define OV9640_RED 0x02
18#define OV9640_VFER 0x03
19#define OV9640_COM1 0x04
20#define OV9640_BAVE 0x05
21#define OV9640_GEAVE 0x06
22#define OV9640_RSID 0x07
23#define OV9640_RAVE 0x08
24#define OV9640_COM2 0x09
25#define OV9640_PID 0x0a
26#define OV9640_VER 0x0b
27#define OV9640_COM3 0x0c
28#define OV9640_COM4 0x0d
29#define OV9640_COM5 0x0e
30#define OV9640_COM6 0x0f
31#define OV9640_AECH 0x10
32#define OV9640_CLKRC 0x11
33#define OV9640_COM7 0x12
34#define OV9640_COM8 0x13
35#define OV9640_COM9 0x14
36#define OV9640_COM10 0x15
37/* 0x16 - RESERVED */
38#define OV9640_HSTART 0x17
39#define OV9640_HSTOP 0x18
40#define OV9640_VSTART 0x19
41#define OV9640_VSTOP 0x1a
42#define OV9640_PSHFT 0x1b
43#define OV9640_MIDH 0x1c
44#define OV9640_MIDL 0x1d
45#define OV9640_MVFP 0x1e
46#define OV9640_LAEC 0x1f
47#define OV9640_BOS 0x20
48#define OV9640_GBOS 0x21
49#define OV9640_GROS 0x22
50#define OV9640_ROS 0x23
51#define OV9640_AEW 0x24
52#define OV9640_AEB 0x25
53#define OV9640_VPT 0x26
54#define OV9640_BBIAS 0x27
55#define OV9640_GBBIAS 0x28
56/* 0x29 - RESERVED */
57#define OV9640_EXHCH 0x2a
58#define OV9640_EXHCL 0x2b
59#define OV9640_RBIAS 0x2c
60#define OV9640_ADVFL 0x2d
61#define OV9640_ADVFH 0x2e
62#define OV9640_YAVE 0x2f
63#define OV9640_HSYST 0x30
64#define OV9640_HSYEN 0x31
65#define OV9640_HREF 0x32
66#define OV9640_CHLF 0x33
67#define OV9640_ARBLM 0x34
68/* 0x35..0x36 - RESERVED */
69#define OV9640_ADC 0x37
70#define OV9640_ACOM 0x38
71#define OV9640_OFON 0x39
72#define OV9640_TSLB 0x3a
73#define OV9640_COM11 0x3b
74#define OV9640_COM12 0x3c
75#define OV9640_COM13 0x3d
76#define OV9640_COM14 0x3e
77#define OV9640_EDGE 0x3f
78#define OV9640_COM15 0x40
79#define OV9640_COM16 0x41
80#define OV9640_COM17 0x42
81/* 0x43..0x4e - RESERVED */
82#define OV9640_MTX1 0x4f
83#define OV9640_MTX2 0x50
84#define OV9640_MTX3 0x51
85#define OV9640_MTX4 0x52
86#define OV9640_MTX5 0x53
87#define OV9640_MTX6 0x54
88#define OV9640_MTX7 0x55
89#define OV9640_MTX8 0x56
90#define OV9640_MTX9 0x57
91#define OV9640_MTXS 0x58
92/* 0x59..0x61 - RESERVED */
93#define OV9640_LCC1 0x62
94#define OV9640_LCC2 0x63
95#define OV9640_LCC3 0x64
96#define OV9640_LCC4 0x65
97#define OV9640_LCC5 0x66
98#define OV9640_MANU 0x67
99#define OV9640_MANV 0x68
100#define OV9640_HV 0x69
101#define OV9640_MBD 0x6a
102#define OV9640_DBLV 0x6b
103#define OV9640_GSP 0x6c /* ... till 0x7b */
104#define OV9640_GST 0x7c /* ... till 0x8a */
105
106#define OV9640_CLKRC_DPLL_EN 0x80
107#define OV9640_CLKRC_DIRECT 0x40
108#define OV9640_CLKRC_DIV(x) ((x) & 0x3f)
109
110#define OV9640_PSHFT_VAL(x) ((x) & 0xff)
111
112#define OV9640_ACOM_2X_ANALOG 0x80
113#define OV9640_ACOM_RSVD 0x12
114
115#define OV9640_MVFP_V 0x10
116#define OV9640_MVFP_H 0x20
117
118#define OV9640_COM1_HREF_NOSKIP 0x00
119#define OV9640_COM1_HREF_2SKIP 0x04
120#define OV9640_COM1_HREF_3SKIP 0x08
121#define OV9640_COM1_QQFMT 0x20
122
123#define OV9640_COM2_SSM 0x10
124
125#define OV9640_COM3_VP 0x04
126
127#define OV9640_COM4_QQ_VP 0x80
128#define OV9640_COM4_RSVD 0x40
129
130#define OV9640_COM5_SYSCLK 0x80
131#define OV9640_COM5_LONGEXP 0x01
132
133#define OV9640_COM6_OPT_BLC 0x40
134#define OV9640_COM6_ADBLC_BIAS 0x08
135#define OV9640_COM6_FMT_RST 0x82
136#define OV9640_COM6_ADBLC_OPTEN 0x01
137
138#define OV9640_COM7_RAW_RGB 0x01
139#define OV9640_COM7_RGB 0x04
140#define OV9640_COM7_QCIF 0x08
141#define OV9640_COM7_QVGA 0x10
142#define OV9640_COM7_CIF 0x20
143#define OV9640_COM7_VGA 0x40
144#define OV9640_COM7_SCCB_RESET 0x80
145
146#define OV9640_TSLB_YVYU_YUYV 0x04
147#define OV9640_TSLB_YUYV_UYVY 0x08
148
149#define OV9640_COM12_YUV_AVG 0x04
150#define OV9640_COM12_RSVD 0x40
151
152#define OV9640_COM13_GAMMA_NONE 0x00
153#define OV9640_COM13_GAMMA_Y 0x40
154#define OV9640_COM13_GAMMA_RAW 0x80
155#define OV9640_COM13_RGB_AVG 0x20
156#define OV9640_COM13_MATRIX_EN 0x10
157#define OV9640_COM13_Y_DELAY_EN 0x08
158#define OV9640_COM13_YUV_DLY(x) ((x) & 0x07)
159
160#define OV9640_COM15_OR_00FF 0x00
161#define OV9640_COM15_OR_01FE 0x40
162#define OV9640_COM15_OR_10F0 0xc0
163#define OV9640_COM15_RGB_NORM 0x00
164#define OV9640_COM15_RGB_565 0x10
165#define OV9640_COM15_RGB_555 0x30
166
167#define OV9640_COM16_RB_AVG 0x01
168
169/* IDs */
170#define OV9640_V2 0x9648
171#define OV9640_V3 0x9649
172#define VERSION(pid, ver) (((pid) << 8) | ((ver) & 0xFF))
173
174/* supported resolutions */
175enum {
176 W_QQCIF = 88,
177 W_QQVGA = 160,
178 W_QCIF = 176,
179 W_QVGA = 320,
180 W_CIF = 352,
181 W_VGA = 640,
182 W_SXGA = 1280
183};
184#define H_SXGA 960
185
186/* Misc. structures */
187struct ov9640_reg_alt {
188 u8 com7;
189 u8 com12;
190 u8 com13;
191 u8 com15;
192};
193
194struct ov9640_reg {
195 u8 reg;
196 u8 val;
197};
198
199struct ov9640_priv {
200 struct v4l2_subdev subdev;
201
202 int model;
203 int revision;
204
205 bool flag_vflip;
206 bool flag_hflip;
207};
208
209#endif /* __DRIVERS_MEDIA_VIDEO_OV9640_H__ */
diff --git a/drivers/media/video/pms.c b/drivers/media/video/pms.c
index a1ad38fc49c1..73ec970ca5ca 100644
--- a/drivers/media/video/pms.c
+++ b/drivers/media/video/pms.c
@@ -14,8 +14,10 @@
14 * unless the userspace driver also doesn't work for you... 14 * unless the userspace driver also doesn't work for you...
15 * 15 *
16 * Changes: 16 * Changes:
17 * 08/07/2003 Daniele Bellucci <bellucda@tiscali.it> 17 * 25-11-2009 Hans Verkuil <hverkuil@xs4all.nl>
18 * - pms_capture: report back -EFAULT 18 * - converted to version 2 of the V4L API.
19 * 08/07/2003 Daniele Bellucci <bellucda@tiscali.it>
20 * - pms_capture: report back -EFAULT
19 */ 21 */
20 22
21#include <linux/module.h> 23#include <linux/module.h>
@@ -27,175 +29,183 @@
27#include <linux/mm.h> 29#include <linux/mm.h>
28#include <linux/ioport.h> 30#include <linux/ioport.h>
29#include <linux/init.h> 31#include <linux/init.h>
32#include <linux/version.h>
33#include <linux/mutex.h>
34#include <asm/uaccess.h>
30#include <asm/io.h> 35#include <asm/io.h>
31#include <linux/videodev.h> 36
37#include <linux/videodev2.h>
32#include <media/v4l2-common.h> 38#include <media/v4l2-common.h>
33#include <media/v4l2-ioctl.h> 39#include <media/v4l2-ioctl.h>
34#include <linux/mutex.h> 40#include <media/v4l2-device.h>
35 41
36#include <asm/uaccess.h> 42MODULE_LICENSE("GPL");
37 43
38 44
39#define MOTOROLA 1 45#define MOTOROLA 1
40#define PHILIPS2 2 46#define PHILIPS2 2 /* SAA7191 */
41#define PHILIPS1 3 47#define PHILIPS1 3
42#define MVVMEMORYWIDTH 0x40 /* 512 bytes */ 48#define MVVMEMORYWIDTH 0x40 /* 512 bytes */
43 49
44struct pms_device 50struct i2c_info {
45{
46 struct video_device v;
47 struct video_picture picture;
48 int height;
49 int width;
50 unsigned long in_use;
51 struct mutex lock;
52};
53
54struct i2c_info
55{
56 u8 slave; 51 u8 slave;
57 u8 sub; 52 u8 sub;
58 u8 data; 53 u8 data;
59 u8 hits; 54 u8 hits;
60}; 55};
61 56
62static int i2c_count; 57struct pms {
63static struct i2c_info i2cinfo[64]; 58 struct v4l2_device v4l2_dev;
59 struct video_device vdev;
60 int height;
61 int width;
62 int depth;
63 int input;
64 s32 brightness, saturation, hue, contrast;
65 unsigned long in_use;
66 struct mutex lock;
67 int i2c_count;
68 struct i2c_info i2cinfo[64];
69
70 int decoder;
71 int standard; /* 0 - auto 1 - ntsc 2 - pal 3 - secam */
72 v4l2_std_id std;
73 int io;
74 int data;
75 void __iomem *mem;
76};
64 77
65static int decoder = PHILIPS2; 78static struct pms pms_card;
66static int standard; /* 0 - auto 1 - ntsc 2 - pal 3 - secam */
67 79
68/* 80/*
69 * I/O ports and Shared Memory 81 * I/O ports and Shared Memory
70 */ 82 */
71 83
72static int io_port = 0x250; 84static int io_port = 0x250;
73static int data_port = 0x251; 85module_param(io_port, int, 0);
74static int mem_base = 0xC8000;
75static void __iomem *mem;
76static int video_nr = -1;
77 86
87static int mem_base = 0xc8000;
88module_param(mem_base, int, 0);
78 89
90static int video_nr = -1;
91module_param(video_nr, int, 0);
79 92
80static inline void mvv_write(u8 index, u8 value) 93
94static inline void mvv_write(struct pms *dev, u8 index, u8 value)
81{ 95{
82 outw(index|(value<<8), io_port); 96 outw(index | (value << 8), dev->io);
83} 97}
84 98
85static inline u8 mvv_read(u8 index) 99static inline u8 mvv_read(struct pms *dev, u8 index)
86{ 100{
87 outb(index, io_port); 101 outb(index, dev->io);
88 return inb(data_port); 102 return inb(dev->data);
89} 103}
90 104
91static int pms_i2c_stat(u8 slave) 105static int pms_i2c_stat(struct pms *dev, u8 slave)
92{ 106{
93 int counter; 107 int counter = 0;
94 int i; 108 int i;
95 109
96 outb(0x28, io_port); 110 outb(0x28, dev->io);
97 111
98 counter=0; 112 while ((inb(dev->data) & 0x01) == 0)
99 while((inb(data_port)&0x01)==0) 113 if (counter++ == 256)
100 if(counter++==256)
101 break; 114 break;
102 115
103 while((inb(data_port)&0x01)!=0) 116 while ((inb(dev->data) & 0x01) != 0)
104 if(counter++==256) 117 if (counter++ == 256)
105 break; 118 break;
106 119
107 outb(slave, io_port); 120 outb(slave, dev->io);
108 121
109 counter=0; 122 counter = 0;
110 while((inb(data_port)&0x01)==0) 123 while ((inb(dev->data) & 0x01) == 0)
111 if(counter++==256) 124 if (counter++ == 256)
112 break; 125 break;
113 126
114 while((inb(data_port)&0x01)!=0) 127 while ((inb(dev->data) & 0x01) != 0)
115 if(counter++==256) 128 if (counter++ == 256)
116 break; 129 break;
117 130
118 for(i=0;i<12;i++) 131 for (i = 0; i < 12; i++) {
119 { 132 char st = inb(dev->data);
120 char st=inb(data_port); 133
121 if((st&2)!=0) 134 if ((st & 2) != 0)
122 return -1; 135 return -1;
123 if((st&1)==0) 136 if ((st & 1) == 0)
124 break; 137 break;
125 } 138 }
126 outb(0x29, io_port); 139 outb(0x29, dev->io);
127 return inb(data_port); 140 return inb(dev->data);
128} 141}
129 142
130static int pms_i2c_write(u16 slave, u16 sub, u16 data) 143static int pms_i2c_write(struct pms *dev, u16 slave, u16 sub, u16 data)
131{ 144{
132 int skip=0; 145 int skip = 0;
133 int count; 146 int count;
134 int i; 147 int i;
135 148
136 for(i=0;i<i2c_count;i++) 149 for (i = 0; i < dev->i2c_count; i++) {
137 { 150 if ((dev->i2cinfo[i].slave == slave) &&
138 if((i2cinfo[i].slave==slave) && 151 (dev->i2cinfo[i].sub == sub)) {
139 (i2cinfo[i].sub == sub)) 152 if (dev->i2cinfo[i].data == data)
140 { 153 skip = 1;
141 if(i2cinfo[i].data==data) 154 dev->i2cinfo[i].data = data;
142 skip=1; 155 i = dev->i2c_count + 1;
143 i2cinfo[i].data=data;
144 i=i2c_count+1;
145 } 156 }
146 } 157 }
147 158
148 if(i==i2c_count && i2c_count<64) 159 if (i == dev->i2c_count && dev->i2c_count < 64) {
149 { 160 dev->i2cinfo[dev->i2c_count].slave = slave;
150 i2cinfo[i2c_count].slave=slave; 161 dev->i2cinfo[dev->i2c_count].sub = sub;
151 i2cinfo[i2c_count].sub=sub; 162 dev->i2cinfo[dev->i2c_count].data = data;
152 i2cinfo[i2c_count].data=data; 163 dev->i2c_count++;
153 i2c_count++;
154 } 164 }
155 165
156 if(skip) 166 if (skip)
157 return 0; 167 return 0;
158 168
159 mvv_write(0x29, sub); 169 mvv_write(dev, 0x29, sub);
160 mvv_write(0x2A, data); 170 mvv_write(dev, 0x2A, data);
161 mvv_write(0x28, slave); 171 mvv_write(dev, 0x28, slave);
162 172
163 outb(0x28, io_port); 173 outb(0x28, dev->io);
164 174
165 count=0; 175 count = 0;
166 while((inb(data_port)&1)==0) 176 while ((inb(dev->data) & 1) == 0)
167 if(count>255) 177 if (count > 255)
168 break; 178 break;
169 while((inb(data_port)&1)!=0) 179 while ((inb(dev->data) & 1) != 0)
170 if(count>255) 180 if (count > 255)
171 break; 181 break;
172 182
173 count=inb(data_port); 183 count = inb(dev->data);
174 184
175 if(count&2) 185 if (count & 2)
176 return -1; 186 return -1;
177 return count; 187 return count;
178} 188}
179 189
180static int pms_i2c_read(int slave, int sub) 190static int pms_i2c_read(struct pms *dev, int slave, int sub)
181{ 191{
182 int i=0; 192 int i;
183 for(i=0;i<i2c_count;i++) 193
184 { 194 for (i = 0; i < dev->i2c_count; i++) {
185 if(i2cinfo[i].slave==slave && i2cinfo[i].sub==sub) 195 if (dev->i2cinfo[i].slave == slave && dev->i2cinfo[i].sub == sub)
186 return i2cinfo[i].data; 196 return dev->i2cinfo[i].data;
187 } 197 }
188 return 0; 198 return 0;
189} 199}
190 200
191 201
192static void pms_i2c_andor(int slave, int sub, int and, int or) 202static void pms_i2c_andor(struct pms *dev, int slave, int sub, int and, int or)
193{ 203{
194 u8 tmp; 204 u8 tmp;
195 205
196 tmp=pms_i2c_read(slave, sub); 206 tmp = pms_i2c_read(dev, slave, sub);
197 tmp = (tmp&and)|or; 207 tmp = (tmp & and) | or;
198 pms_i2c_write(slave, sub, tmp); 208 pms_i2c_write(dev, slave, sub, tmp);
199} 209}
200 210
201/* 211/*
@@ -203,100 +213,108 @@ static void pms_i2c_andor(int slave, int sub, int and, int or)
203 */ 213 */
204 214
205 215
206static void pms_videosource(short source) 216static void pms_videosource(struct pms *dev, short source)
207{ 217{
208 mvv_write(0x2E, source?0x31:0x30); 218 switch (dev->decoder) {
219 case MOTOROLA:
220 break;
221 case PHILIPS2:
222 pms_i2c_andor(dev, 0x8a, 0x06, 0x7f, source ? 0x80 : 0);
223 break;
224 case PHILIPS1:
225 break;
226 }
227 mvv_write(dev, 0x2E, 0x31);
228 /* Was: mvv_write(dev, 0x2E, source ? 0x31 : 0x30);
229 But could not make this work correctly. Only Composite input
230 worked for me. */
209} 231}
210 232
211static void pms_hue(short hue) 233static void pms_hue(struct pms *dev, short hue)
212{ 234{
213 switch(decoder) 235 switch (dev->decoder) {
214 { 236 case MOTOROLA:
215 case MOTOROLA: 237 pms_i2c_write(dev, 0x8a, 0x00, hue);
216 pms_i2c_write(0x8A, 0x00, hue); 238 break;
217 break; 239 case PHILIPS2:
218 case PHILIPS2: 240 pms_i2c_write(dev, 0x8a, 0x07, hue);
219 pms_i2c_write(0x8A, 0x07, hue); 241 break;
220 break; 242 case PHILIPS1:
221 case PHILIPS1: 243 pms_i2c_write(dev, 0x42, 0x07, hue);
222 pms_i2c_write(0x42, 0x07, hue); 244 break;
223 break;
224 } 245 }
225} 246}
226 247
227static void pms_colour(short colour) 248static void pms_saturation(struct pms *dev, short sat)
228{ 249{
229 switch(decoder) 250 switch (dev->decoder) {
230 { 251 case MOTOROLA:
231 case MOTOROLA: 252 pms_i2c_write(dev, 0x8a, 0x00, sat);
232 pms_i2c_write(0x8A, 0x00, colour); 253 break;
233 break; 254 case PHILIPS1:
234 case PHILIPS1: 255 pms_i2c_write(dev, 0x42, 0x12, sat);
235 pms_i2c_write(0x42, 0x12, colour); 256 break;
236 break;
237 } 257 }
238} 258}
239 259
240 260
241static void pms_contrast(short contrast) 261static void pms_contrast(struct pms *dev, short contrast)
242{ 262{
243 switch(decoder) 263 switch (dev->decoder) {
244 { 264 case MOTOROLA:
245 case MOTOROLA: 265 pms_i2c_write(dev, 0x8a, 0x00, contrast);
246 pms_i2c_write(0x8A, 0x00, contrast); 266 break;
247 break; 267 case PHILIPS1:
248 case PHILIPS1: 268 pms_i2c_write(dev, 0x42, 0x13, contrast);
249 pms_i2c_write(0x42, 0x13, contrast); 269 break;
250 break;
251 } 270 }
252} 271}
253 272
254static void pms_brightness(short brightness) 273static void pms_brightness(struct pms *dev, short brightness)
255{ 274{
256 switch(decoder) 275 switch (dev->decoder) {
257 { 276 case MOTOROLA:
258 case MOTOROLA: 277 pms_i2c_write(dev, 0x8a, 0x00, brightness);
259 pms_i2c_write(0x8A, 0x00, brightness); 278 pms_i2c_write(dev, 0x8a, 0x00, brightness);
260 pms_i2c_write(0x8A, 0x00, brightness); 279 pms_i2c_write(dev, 0x8a, 0x00, brightness);
261 pms_i2c_write(0x8A, 0x00, brightness); 280 break;
262 break; 281 case PHILIPS1:
263 case PHILIPS1: 282 pms_i2c_write(dev, 0x42, 0x19, brightness);
264 pms_i2c_write(0x42, 0x19, brightness); 283 break;
265 break;
266 } 284 }
267} 285}
268 286
269 287
270static void pms_format(short format) 288static void pms_format(struct pms *dev, short format)
271{ 289{
272 int target; 290 int target;
273 standard = format;
274 291
275 if(decoder==PHILIPS1) 292 dev->standard = format;
276 target=0x42; 293
277 else if(decoder==PHILIPS2) 294 if (dev->decoder == PHILIPS1)
278 target=0x8A; 295 target = 0x42;
296 else if (dev->decoder == PHILIPS2)
297 target = 0x8a;
279 else 298 else
280 return; 299 return;
281 300
282 switch(format) 301 switch (format) {
283 { 302 case 0: /* Auto */
284 case 0: /* Auto */ 303 pms_i2c_andor(dev, target, 0x0d, 0xfe, 0x00);
285 pms_i2c_andor(target, 0x0D, 0xFE,0x00); 304 pms_i2c_andor(dev, target, 0x0f, 0x3f, 0x80);
286 pms_i2c_andor(target, 0x0F, 0x3F,0x80); 305 break;
287 break; 306 case 1: /* NTSC */
288 case 1: /* NTSC */ 307 pms_i2c_andor(dev, target, 0x0d, 0xfe, 0x00);
289 pms_i2c_andor(target, 0x0D, 0xFE, 0x00); 308 pms_i2c_andor(dev, target, 0x0f, 0x3f, 0x40);
290 pms_i2c_andor(target, 0x0F, 0x3F, 0x40); 309 break;
291 break; 310 case 2: /* PAL */
292 case 2: /* PAL */ 311 pms_i2c_andor(dev, target, 0x0d, 0xfe, 0x00);
293 pms_i2c_andor(target, 0x0D, 0xFE, 0x00); 312 pms_i2c_andor(dev, target, 0x0f, 0x3f, 0x00);
294 pms_i2c_andor(target, 0x0F, 0x3F, 0x00); 313 break;
295 break; 314 case 3: /* SECAM */
296 case 3: /* SECAM */ 315 pms_i2c_andor(dev, target, 0x0d, 0xfe, 0x01);
297 pms_i2c_andor(target, 0x0D, 0xFE, 0x01); 316 pms_i2c_andor(dev, target, 0x0f, 0x3f, 0x00);
298 pms_i2c_andor(target, 0x0F, 0x3F, 0x00); 317 break;
299 break;
300 } 318 }
301} 319}
302 320
@@ -308,18 +326,17 @@ static void pms_format(short format)
308 * people need it. We also don't yet use the PMS interrupt. 326 * people need it. We also don't yet use the PMS interrupt.
309 */ 327 */
310 328
311static void pms_hstart(short start) 329static void pms_hstart(struct pms *dev, short start)
312{ 330{
313 switch(decoder) 331 switch (dev->decoder) {
314 { 332 case PHILIPS1:
315 case PHILIPS1: 333 pms_i2c_write(dev, 0x8a, 0x05, start);
316 pms_i2c_write(0x8A, 0x05, start); 334 pms_i2c_write(dev, 0x8a, 0x18, start);
317 pms_i2c_write(0x8A, 0x18, start); 335 break;
318 break; 336 case PHILIPS2:
319 case PHILIPS2: 337 pms_i2c_write(dev, 0x42, 0x05, start);
320 pms_i2c_write(0x42, 0x05, start); 338 pms_i2c_write(dev, 0x42, 0x18, start);
321 pms_i2c_write(0x42, 0x18, start); 339 break;
322 break;
323 } 340 }
324} 341}
325 342
@@ -327,293 +344,271 @@ static void pms_hstart(short start)
327 * Bandpass filters 344 * Bandpass filters
328 */ 345 */
329 346
330static void pms_bandpass(short pass) 347static void pms_bandpass(struct pms *dev, short pass)
331{ 348{
332 if(decoder==PHILIPS2) 349 if (dev->decoder == PHILIPS2)
333 pms_i2c_andor(0x8A, 0x06, 0xCF, (pass&0x03)<<4); 350 pms_i2c_andor(dev, 0x8a, 0x06, 0xcf, (pass & 0x03) << 4);
334 else if(decoder==PHILIPS1) 351 else if (dev->decoder == PHILIPS1)
335 pms_i2c_andor(0x42, 0x06, 0xCF, (pass&0x03)<<4); 352 pms_i2c_andor(dev, 0x42, 0x06, 0xcf, (pass & 0x03) << 4);
336} 353}
337 354
338static void pms_antisnow(short snow) 355static void pms_antisnow(struct pms *dev, short snow)
339{ 356{
340 if(decoder==PHILIPS2) 357 if (dev->decoder == PHILIPS2)
341 pms_i2c_andor(0x8A, 0x06, 0xF3, (snow&0x03)<<2); 358 pms_i2c_andor(dev, 0x8a, 0x06, 0xf3, (snow & 0x03) << 2);
342 else if(decoder==PHILIPS1) 359 else if (dev->decoder == PHILIPS1)
343 pms_i2c_andor(0x42, 0x06, 0xF3, (snow&0x03)<<2); 360 pms_i2c_andor(dev, 0x42, 0x06, 0xf3, (snow & 0x03) << 2);
344} 361}
345 362
346static void pms_sharpness(short sharp) 363static void pms_sharpness(struct pms *dev, short sharp)
347{ 364{
348 if(decoder==PHILIPS2) 365 if (dev->decoder == PHILIPS2)
349 pms_i2c_andor(0x8A, 0x06, 0xFC, sharp&0x03); 366 pms_i2c_andor(dev, 0x8a, 0x06, 0xfc, sharp & 0x03);
350 else if(decoder==PHILIPS1) 367 else if (dev->decoder == PHILIPS1)
351 pms_i2c_andor(0x42, 0x06, 0xFC, sharp&0x03); 368 pms_i2c_andor(dev, 0x42, 0x06, 0xfc, sharp & 0x03);
352} 369}
353 370
354static void pms_chromaagc(short agc) 371static void pms_chromaagc(struct pms *dev, short agc)
355{ 372{
356 if(decoder==PHILIPS2) 373 if (dev->decoder == PHILIPS2)
357 pms_i2c_andor(0x8A, 0x0C, 0x9F, (agc&0x03)<<5); 374 pms_i2c_andor(dev, 0x8a, 0x0c, 0x9f, (agc & 0x03) << 5);
358 else if(decoder==PHILIPS1) 375 else if (dev->decoder == PHILIPS1)
359 pms_i2c_andor(0x42, 0x0C, 0x9F, (agc&0x03)<<5); 376 pms_i2c_andor(dev, 0x42, 0x0c, 0x9f, (agc & 0x03) << 5);
360} 377}
361 378
362static void pms_vertnoise(short noise) 379static void pms_vertnoise(struct pms *dev, short noise)
363{ 380{
364 if(decoder==PHILIPS2) 381 if (dev->decoder == PHILIPS2)
365 pms_i2c_andor(0x8A, 0x10, 0xFC, noise&3); 382 pms_i2c_andor(dev, 0x8a, 0x10, 0xfc, noise & 3);
366 else if(decoder==PHILIPS1) 383 else if (dev->decoder == PHILIPS1)
367 pms_i2c_andor(0x42, 0x10, 0xFC, noise&3); 384 pms_i2c_andor(dev, 0x42, 0x10, 0xfc, noise & 3);
368} 385}
369 386
370static void pms_forcecolour(short colour) 387static void pms_forcecolour(struct pms *dev, short colour)
371{ 388{
372 if(decoder==PHILIPS2) 389 if (dev->decoder == PHILIPS2)
373 pms_i2c_andor(0x8A, 0x0C, 0x7F, (colour&1)<<7); 390 pms_i2c_andor(dev, 0x8a, 0x0c, 0x7f, (colour & 1) << 7);
374 else if(decoder==PHILIPS1) 391 else if (dev->decoder == PHILIPS1)
375 pms_i2c_andor(0x42, 0x0C, 0x7, (colour&1)<<7); 392 pms_i2c_andor(dev, 0x42, 0x0c, 0x7, (colour & 1) << 7);
376} 393}
377 394
378static void pms_antigamma(short gamma) 395static void pms_antigamma(struct pms *dev, short gamma)
379{ 396{
380 if(decoder==PHILIPS2) 397 if (dev->decoder == PHILIPS2)
381 pms_i2c_andor(0xB8, 0x00, 0x7F, (gamma&1)<<7); 398 pms_i2c_andor(dev, 0xb8, 0x00, 0x7f, (gamma & 1) << 7);
382 else if(decoder==PHILIPS1) 399 else if (dev->decoder == PHILIPS1)
383 pms_i2c_andor(0x42, 0x20, 0x7, (gamma&1)<<7); 400 pms_i2c_andor(dev, 0x42, 0x20, 0x7, (gamma & 1) << 7);
384} 401}
385 402
386static void pms_prefilter(short filter) 403static void pms_prefilter(struct pms *dev, short filter)
387{ 404{
388 if(decoder==PHILIPS2) 405 if (dev->decoder == PHILIPS2)
389 pms_i2c_andor(0x8A, 0x06, 0xBF, (filter&1)<<6); 406 pms_i2c_andor(dev, 0x8a, 0x06, 0xbf, (filter & 1) << 6);
390 else if(decoder==PHILIPS1) 407 else if (dev->decoder == PHILIPS1)
391 pms_i2c_andor(0x42, 0x06, 0xBF, (filter&1)<<6); 408 pms_i2c_andor(dev, 0x42, 0x06, 0xbf, (filter & 1) << 6);
392} 409}
393 410
394static void pms_hfilter(short filter) 411static void pms_hfilter(struct pms *dev, short filter)
395{ 412{
396 if(decoder==PHILIPS2) 413 if (dev->decoder == PHILIPS2)
397 pms_i2c_andor(0xB8, 0x04, 0x1F, (filter&7)<<5); 414 pms_i2c_andor(dev, 0xb8, 0x04, 0x1f, (filter & 7) << 5);
398 else if(decoder==PHILIPS1) 415 else if (dev->decoder == PHILIPS1)
399 pms_i2c_andor(0x42, 0x24, 0x1F, (filter&7)<<5); 416 pms_i2c_andor(dev, 0x42, 0x24, 0x1f, (filter & 7) << 5);
400} 417}
401 418
402static void pms_vfilter(short filter) 419static void pms_vfilter(struct pms *dev, short filter)
403{ 420{
404 if(decoder==PHILIPS2) 421 if (dev->decoder == PHILIPS2)
405 pms_i2c_andor(0xB8, 0x08, 0x9F, (filter&3)<<5); 422 pms_i2c_andor(dev, 0xb8, 0x08, 0x9f, (filter & 3) << 5);
406 else if(decoder==PHILIPS1) 423 else if (dev->decoder == PHILIPS1)
407 pms_i2c_andor(0x42, 0x28, 0x9F, (filter&3)<<5); 424 pms_i2c_andor(dev, 0x42, 0x28, 0x9f, (filter & 3) << 5);
408} 425}
409 426
410static void pms_killcolour(short colour) 427static void pms_killcolour(struct pms *dev, short colour)
411{ 428{
412 if(decoder==PHILIPS2) 429 if (dev->decoder == PHILIPS2) {
413 { 430 pms_i2c_andor(dev, 0x8a, 0x08, 0x07, (colour & 0x1f) << 3);
414 pms_i2c_andor(0x8A, 0x08, 0x07, (colour&0x1F)<<3); 431 pms_i2c_andor(dev, 0x8a, 0x09, 0x07, (colour & 0x1f) << 3);
415 pms_i2c_andor(0x8A, 0x09, 0x07, (colour&0x1F)<<3); 432 } else if (dev->decoder == PHILIPS1) {
416 } 433 pms_i2c_andor(dev, 0x42, 0x08, 0x07, (colour & 0x1f) << 3);
417 else if(decoder==PHILIPS1) 434 pms_i2c_andor(dev, 0x42, 0x09, 0x07, (colour & 0x1f) << 3);
418 {
419 pms_i2c_andor(0x42, 0x08, 0x07, (colour&0x1F)<<3);
420 pms_i2c_andor(0x42, 0x09, 0x07, (colour&0x1F)<<3);
421 } 435 }
422} 436}
423 437
424static void pms_chromagain(short chroma) 438static void pms_chromagain(struct pms *dev, short chroma)
425{ 439{
426 if(decoder==PHILIPS2) 440 if (dev->decoder == PHILIPS2)
427 { 441 pms_i2c_write(dev, 0x8a, 0x11, chroma);
428 pms_i2c_write(0x8A, 0x11, chroma); 442 else if (dev->decoder == PHILIPS1)
429 } 443 pms_i2c_write(dev, 0x42, 0x11, chroma);
430 else if(decoder==PHILIPS1)
431 {
432 pms_i2c_write(0x42, 0x11, chroma);
433 }
434} 444}
435 445
436 446
437static void pms_spacialcompl(short data) 447static void pms_spacialcompl(struct pms *dev, short data)
438{ 448{
439 mvv_write(0x3B, data); 449 mvv_write(dev, 0x3b, data);
440} 450}
441 451
442static void pms_spacialcomph(short data) 452static void pms_spacialcomph(struct pms *dev, short data)
443{ 453{
444 mvv_write(0x3A, data); 454 mvv_write(dev, 0x3a, data);
445} 455}
446 456
447static void pms_vstart(short start) 457static void pms_vstart(struct pms *dev, short start)
448{ 458{
449 mvv_write(0x16, start); 459 mvv_write(dev, 0x16, start);
450 mvv_write(0x17, (start>>8)&0x01); 460 mvv_write(dev, 0x17, (start >> 8) & 0x01);
451} 461}
452 462
453#endif 463#endif
454 464
455static void pms_secamcross(short cross) 465static void pms_secamcross(struct pms *dev, short cross)
456{ 466{
457 if(decoder==PHILIPS2) 467 if (dev->decoder == PHILIPS2)
458 pms_i2c_andor(0x8A, 0x0F, 0xDF, (cross&1)<<5); 468 pms_i2c_andor(dev, 0x8a, 0x0f, 0xdf, (cross & 1) << 5);
459 else if(decoder==PHILIPS1) 469 else if (dev->decoder == PHILIPS1)
460 pms_i2c_andor(0x42, 0x0F, 0xDF, (cross&1)<<5); 470 pms_i2c_andor(dev, 0x42, 0x0f, 0xdf, (cross & 1) << 5);
461} 471}
462 472
463 473
464static void pms_swsense(short sense) 474static void pms_swsense(struct pms *dev, short sense)
465{ 475{
466 if(decoder==PHILIPS2) 476 if (dev->decoder == PHILIPS2) {
467 { 477 pms_i2c_write(dev, 0x8a, 0x0a, sense);
468 pms_i2c_write(0x8A, 0x0A, sense); 478 pms_i2c_write(dev, 0x8a, 0x0b, sense);
469 pms_i2c_write(0x8A, 0x0B, sense); 479 } else if (dev->decoder == PHILIPS1) {
470 } 480 pms_i2c_write(dev, 0x42, 0x0a, sense);
471 else if(decoder==PHILIPS1) 481 pms_i2c_write(dev, 0x42, 0x0b, sense);
472 {
473 pms_i2c_write(0x42, 0x0A, sense);
474 pms_i2c_write(0x42, 0x0B, sense);
475 } 482 }
476} 483}
477 484
478 485
479static void pms_framerate(short frr) 486static void pms_framerate(struct pms *dev, short frr)
480{ 487{
481 int fps=(standard==1)?30:25; 488 int fps = (dev->std & V4L2_STD_525_60) ? 30 : 25;
482 if(frr==0) 489
490 if (frr == 0)
483 return; 491 return;
484 fps=fps/frr; 492 fps = fps/frr;
485 mvv_write(0x14,0x80|fps); 493 mvv_write(dev, 0x14, 0x80 | fps);
486 mvv_write(0x15,1); 494 mvv_write(dev, 0x15, 1);
487} 495}
488 496
489static void pms_vert(u8 deciden, u8 decinum) 497static void pms_vert(struct pms *dev, u8 deciden, u8 decinum)
490{ 498{
491 mvv_write(0x1C, deciden); /* Denominator */ 499 mvv_write(dev, 0x1c, deciden); /* Denominator */
492 mvv_write(0x1D, decinum); /* Numerator */ 500 mvv_write(dev, 0x1d, decinum); /* Numerator */
493} 501}
494 502
495/* 503/*
496 * Turn 16bit ratios into best small ratio the chipset can grok 504 * Turn 16bit ratios into best small ratio the chipset can grok
497 */ 505 */
498 506
499static void pms_vertdeci(unsigned short decinum, unsigned short deciden) 507static void pms_vertdeci(struct pms *dev, unsigned short decinum, unsigned short deciden)
500{ 508{
501 /* Knock it down by /5 once */ 509 /* Knock it down by / 5 once */
502 if(decinum%5==0) 510 if (decinum % 5 == 0) {
503 { 511 deciden /= 5;
504 deciden/=5; 512 decinum /= 5;
505 decinum/=5;
506 } 513 }
507 /* 514 /*
508 * 3's 515 * 3's
509 */ 516 */
510 while(decinum%3==0 && deciden%3==0) 517 while (decinum % 3 == 0 && deciden % 3 == 0) {
511 { 518 deciden /= 3;
512 deciden/=3; 519 decinum /= 3;
513 decinum/=3;
514 } 520 }
515 /* 521 /*
516 * 2's 522 * 2's
517 */ 523 */
518 while(decinum%2==0 && deciden%2==0) 524 while (decinum % 2 == 0 && deciden % 2 == 0) {
519 { 525 decinum /= 2;
520 decinum/=2; 526 deciden /= 2;
521 deciden/=2;
522 } 527 }
523 /* 528 /*
524 * Fudgyify 529 * Fudgyify
525 */ 530 */
526 while(deciden>32) 531 while (deciden > 32) {
527 { 532 deciden /= 2;
528 deciden/=2; 533 decinum = (decinum + 1) / 2;
529 decinum=(decinum+1)/2;
530 } 534 }
531 if(deciden==32) 535 if (deciden == 32)
532 deciden--; 536 deciden--;
533 pms_vert(deciden,decinum); 537 pms_vert(dev, deciden, decinum);
534} 538}
535 539
536static void pms_horzdeci(short decinum, short deciden) 540static void pms_horzdeci(struct pms *dev, short decinum, short deciden)
537{ 541{
538 if(decinum<=512) 542 if (decinum <= 512) {
539 { 543 if (decinum % 5 == 0) {
540 if(decinum%5==0) 544 decinum /= 5;
541 { 545 deciden /= 5;
542 decinum/=5;
543 deciden/=5;
544 } 546 }
545 } 547 } else {
546 else 548 decinum = 512;
547 { 549 deciden = 640; /* 768 would be ideal */
548 decinum=512;
549 deciden=640; /* 768 would be ideal */
550 } 550 }
551 551
552 while(((decinum|deciden)&1)==0) 552 while (((decinum | deciden) & 1) == 0) {
553 { 553 decinum >>= 1;
554 decinum>>=1; 554 deciden >>= 1;
555 deciden>>=1;
556 } 555 }
557 while(deciden>32) 556 while (deciden > 32) {
558 { 557 deciden >>= 1;
559 deciden>>=1; 558 decinum = (decinum + 1) >> 1;
560 decinum=(decinum+1)>>1;
561 } 559 }
562 if(deciden==32) 560 if (deciden == 32)
563 deciden--; 561 deciden--;
564 562
565 mvv_write(0x24, 0x80|deciden); 563 mvv_write(dev, 0x24, 0x80 | deciden);
566 mvv_write(0x25, decinum); 564 mvv_write(dev, 0x25, decinum);
567} 565}
568 566
569static void pms_resolution(short width, short height) 567static void pms_resolution(struct pms *dev, short width, short height)
570{ 568{
571 int fg_height; 569 int fg_height;
572 570
573 fg_height=height; 571 fg_height = height;
574 if(fg_height>280) 572 if (fg_height > 280)
575 fg_height=280; 573 fg_height = 280;
576 574
577 mvv_write(0x18, fg_height); 575 mvv_write(dev, 0x18, fg_height);
578 mvv_write(0x19, fg_height>>8); 576 mvv_write(dev, 0x19, fg_height >> 8);
579 577
580 if(standard==1) 578 if (dev->std & V4L2_STD_525_60) {
581 { 579 mvv_write(dev, 0x1a, 0xfc);
582 mvv_write(0x1A, 0xFC); 580 mvv_write(dev, 0x1b, 0x00);
583 mvv_write(0x1B, 0x00); 581 if (height > fg_height)
584 if(height>fg_height) 582 pms_vertdeci(dev, 240, 240);
585 pms_vertdeci(240,240);
586 else 583 else
587 pms_vertdeci(fg_height,240); 584 pms_vertdeci(dev, fg_height, 240);
588 } 585 } else {
589 else 586 mvv_write(dev, 0x1a, 0x1a);
590 { 587 mvv_write(dev, 0x1b, 0x01);
591 mvv_write(0x1A, 0x1A); 588 if (fg_height > 256)
592 mvv_write(0x1B, 0x01); 589 pms_vertdeci(dev, 270, 270);
593 if(fg_height>256)
594 pms_vertdeci(270,270);
595 else 590 else
596 pms_vertdeci(fg_height, 270); 591 pms_vertdeci(dev, fg_height, 270);
597 } 592 }
598 mvv_write(0x12,0); 593 mvv_write(dev, 0x12, 0);
599 mvv_write(0x13, MVVMEMORYWIDTH); 594 mvv_write(dev, 0x13, MVVMEMORYWIDTH);
600 mvv_write(0x42, 0x00); 595 mvv_write(dev, 0x42, 0x00);
601 mvv_write(0x43, 0x00); 596 mvv_write(dev, 0x43, 0x00);
602 mvv_write(0x44, MVVMEMORYWIDTH); 597 mvv_write(dev, 0x44, MVVMEMORYWIDTH);
603 598
604 mvv_write(0x22, width+8); 599 mvv_write(dev, 0x22, width + 8);
605 mvv_write(0x23, (width+8)>> 8); 600 mvv_write(dev, 0x23, (width + 8) >> 8);
606 601
607 if(standard==1) 602 if (dev->std & V4L2_STD_525_60)
608 pms_horzdeci(width,640); 603 pms_horzdeci(dev, width, 640);
609 else 604 else
610 pms_horzdeci(width+8, 768); 605 pms_horzdeci(dev, width + 8, 768);
611 606
612 mvv_write(0x30, mvv_read(0x30)&0xFE); 607 mvv_write(dev, 0x30, mvv_read(dev, 0x30) & 0xfe);
613 mvv_write(0x08, mvv_read(0x08)|0x01); 608 mvv_write(dev, 0x08, mvv_read(dev, 0x08) | 0x01);
614 mvv_write(0x01, mvv_read(0x01)&0xFD); 609 mvv_write(dev, 0x01, mvv_read(dev, 0x01) & 0xfd);
615 mvv_write(0x32, 0x00); 610 mvv_write(dev, 0x32, 0x00);
616 mvv_write(0x33, MVVMEMORYWIDTH); 611 mvv_write(dev, 0x33, MVVMEMORYWIDTH);
617} 612}
618 613
619 614
@@ -621,52 +616,49 @@ static void pms_resolution(short width, short height)
621 * Set Input 616 * Set Input
622 */ 617 */
623 618
624static void pms_vcrinput(short input) 619static void pms_vcrinput(struct pms *dev, short input)
625{ 620{
626 if(decoder==PHILIPS2) 621 if (dev->decoder == PHILIPS2)
627 pms_i2c_andor(0x8A,0x0D,0x7F,(input&1)<<7); 622 pms_i2c_andor(dev, 0x8a, 0x0d, 0x7f, (input & 1) << 7);
628 else if(decoder==PHILIPS1) 623 else if (dev->decoder == PHILIPS1)
629 pms_i2c_andor(0x42,0x0D,0x7F,(input&1)<<7); 624 pms_i2c_andor(dev, 0x42, 0x0d, 0x7f, (input & 1) << 7);
630} 625}
631 626
632 627
633static int pms_capture(struct pms_device *dev, char __user *buf, int rgb555, int count) 628static int pms_capture(struct pms *dev, char __user *buf, int rgb555, int count)
634{ 629{
635 int y; 630 int y;
636 int dw = 2*dev->width; 631 int dw = 2 * dev->width;
637 632 char tmp[dw + 32]; /* using a temp buffer is faster than direct */
638 char tmp[dw+32]; /* using a temp buffer is faster than direct */
639 int cnt = 0; 633 int cnt = 0;
640 int len=0; 634 int len = 0;
641 unsigned char r8 = 0x5; /* value for reg8 */ 635 unsigned char r8 = 0x5; /* value for reg8 */
642 636
643 if (rgb555) 637 if (rgb555)
644 r8 |= 0x20; /* else use untranslated rgb = 565 */ 638 r8 |= 0x20; /* else use untranslated rgb = 565 */
645 mvv_write(0x08,r8); /* capture rgb555/565, init DRAM, PC enable */ 639 mvv_write(dev, 0x08, r8); /* capture rgb555/565, init DRAM, PC enable */
646 640
647/* printf("%d %d %d %d %d %x %x\n",width,height,voff,nom,den,mvv_buf); */ 641/* printf("%d %d %d %d %d %x %x\n",width,height,voff,nom,den,mvv_buf); */
648 642
649 for (y = 0; y < dev->height; y++ ) 643 for (y = 0; y < dev->height; y++) {
650 { 644 writeb(0, dev->mem); /* synchronisiert neue Zeile */
651 writeb(0, mem); /* synchronisiert neue Zeile */
652 645
653 /* 646 /*
654 * This is in truth a fifo, be very careful as if you 647 * This is in truth a fifo, be very careful as if you
655 * forgot this odd things will occur 8) 648 * forgot this odd things will occur 8)
656 */ 649 */
657 650
658 memcpy_fromio(tmp, mem, dw+32); /* discard 16 word */ 651 memcpy_fromio(tmp, dev->mem, dw + 32); /* discard 16 word */
659 cnt -= dev->height; 652 cnt -= dev->height;
660 while (cnt <= 0) 653 while (cnt <= 0) {
661 {
662 /* 654 /*
663 * Don't copy too far 655 * Don't copy too far
664 */ 656 */
665 int dt=dw; 657 int dt = dw;
666 if(dt+len>count) 658 if (dt + len > count)
667 dt=count-len; 659 dt = count - len;
668 cnt += dev->height; 660 cnt += dev->height;
669 if (copy_to_user(buf, tmp+32, dt)) 661 if (copy_to_user(buf, tmp + 32, dt))
670 return len ? len : -EFAULT; 662 return len ? len : -EFAULT;
671 buf += dt; 663 buf += dt;
672 len += dt; 664 len += dt;
@@ -680,221 +672,278 @@ static int pms_capture(struct pms_device *dev, char __user *buf, int rgb555, int
680 * Video4linux interfacing 672 * Video4linux interfacing
681 */ 673 */
682 674
683static long pms_do_ioctl(struct file *file, unsigned int cmd, void *arg) 675static int pms_querycap(struct file *file, void *priv,
676 struct v4l2_capability *vcap)
684{ 677{
685 struct video_device *dev = video_devdata(file); 678 struct pms *dev = video_drvdata(file);
686 struct pms_device *pd=(struct pms_device *)dev;
687
688 switch(cmd)
689 {
690 case VIDIOCGCAP:
691 {
692 struct video_capability *b = arg;
693 strcpy(b->name, "Mediavision PMS");
694 b->type = VID_TYPE_CAPTURE|VID_TYPE_SCALES;
695 b->channels = 4;
696 b->audios = 0;
697 b->maxwidth = 640;
698 b->maxheight = 480;
699 b->minwidth = 16;
700 b->minheight = 16;
701 return 0;
702 }
703 case VIDIOCGCHAN:
704 {
705 struct video_channel *v = arg;
706 if(v->channel<0 || v->channel>3)
707 return -EINVAL;
708 v->flags=0;
709 v->tuners=1;
710 /* Good question.. its composite or SVHS so.. */
711 v->type = VIDEO_TYPE_CAMERA;
712 switch(v->channel)
713 {
714 case 0:
715 strcpy(v->name, "Composite");break;
716 case 1:
717 strcpy(v->name, "SVideo");break;
718 case 2:
719 strcpy(v->name, "Composite(VCR)");break;
720 case 3:
721 strcpy(v->name, "SVideo(VCR)");break;
722 }
723 return 0;
724 }
725 case VIDIOCSCHAN:
726 {
727 struct video_channel *v = arg;
728 if(v->channel<0 || v->channel>3)
729 return -EINVAL;
730 mutex_lock(&pd->lock);
731 pms_videosource(v->channel&1);
732 pms_vcrinput(v->channel>>1);
733 mutex_unlock(&pd->lock);
734 return 0;
735 }
736 case VIDIOCGTUNER:
737 {
738 struct video_tuner *v = arg;
739 if(v->tuner)
740 return -EINVAL;
741 strcpy(v->name, "Format");
742 v->rangelow=0;
743 v->rangehigh=0;
744 v->flags= VIDEO_TUNER_PAL|VIDEO_TUNER_NTSC|VIDEO_TUNER_SECAM;
745 switch(standard)
746 {
747 case 0:
748 v->mode = VIDEO_MODE_AUTO;
749 break;
750 case 1:
751 v->mode = VIDEO_MODE_NTSC;
752 break;
753 case 2:
754 v->mode = VIDEO_MODE_PAL;
755 break;
756 case 3:
757 v->mode = VIDEO_MODE_SECAM;
758 break;
759 }
760 return 0;
761 }
762 case VIDIOCSTUNER:
763 {
764 struct video_tuner *v = arg;
765 if(v->tuner)
766 return -EINVAL;
767 mutex_lock(&pd->lock);
768 switch(v->mode)
769 {
770 case VIDEO_MODE_AUTO:
771 pms_framerate(25);
772 pms_secamcross(0);
773 pms_format(0);
774 break;
775 case VIDEO_MODE_NTSC:
776 pms_framerate(30);
777 pms_secamcross(0);
778 pms_format(1);
779 break;
780 case VIDEO_MODE_PAL:
781 pms_framerate(25);
782 pms_secamcross(0);
783 pms_format(2);
784 break;
785 case VIDEO_MODE_SECAM:
786 pms_framerate(25);
787 pms_secamcross(1);
788 pms_format(2);
789 break;
790 default:
791 mutex_unlock(&pd->lock);
792 return -EINVAL;
793 }
794 mutex_unlock(&pd->lock);
795 return 0;
796 }
797 case VIDIOCGPICT:
798 {
799 struct video_picture *p = arg;
800 *p = pd->picture;
801 return 0;
802 }
803 case VIDIOCSPICT:
804 {
805 struct video_picture *p = arg;
806 if(!((p->palette==VIDEO_PALETTE_RGB565 && p->depth==16)
807 ||(p->palette==VIDEO_PALETTE_RGB555 && p->depth==15)))
808 return -EINVAL;
809 pd->picture= *p;
810 679
811 /* 680 strlcpy(vcap->driver, dev->v4l2_dev.name, sizeof(vcap->driver));
812 * Now load the card. 681 strlcpy(vcap->card, "Mediavision PMS", sizeof(vcap->card));
813 */ 682 strlcpy(vcap->bus_info, "ISA", sizeof(vcap->bus_info));
683 vcap->version = KERNEL_VERSION(0, 0, 3);
684 vcap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE;
685 return 0;
686}
814 687
815 mutex_lock(&pd->lock); 688static int pms_enum_input(struct file *file, void *fh, struct v4l2_input *vin)
816 pms_brightness(p->brightness>>8); 689{
817 pms_hue(p->hue>>8); 690 static const char *inputs[4] = {
818 pms_colour(p->colour>>8); 691 "Composite",
819 pms_contrast(p->contrast>>8); 692 "S-Video",
820 mutex_unlock(&pd->lock); 693 "Composite (VCR)",
821 return 0; 694 "S-Video (VCR)"
822 } 695 };
823 case VIDIOCSWIN: 696
824 { 697 if (vin->index > 3)
825 struct video_window *vw = arg; 698 return -EINVAL;
826 if(vw->flags) 699 strlcpy(vin->name, inputs[vin->index], sizeof(vin->name));
827 return -EINVAL; 700 vin->type = V4L2_INPUT_TYPE_CAMERA;
828 if(vw->clipcount) 701 vin->audioset = 0;
829 return -EINVAL; 702 vin->tuner = 0;
830 if(vw->height<16||vw->height>480) 703 vin->std = V4L2_STD_ALL;
831 return -EINVAL; 704 vin->status = 0;
832 if(vw->width<16||vw->width>640) 705 return 0;
833 return -EINVAL; 706}
834 pd->width=vw->width; 707
835 pd->height=vw->height; 708static int pms_g_input(struct file *file, void *fh, unsigned int *inp)
836 mutex_lock(&pd->lock); 709{
837 pms_resolution(pd->width, pd->height); 710 struct pms *dev = video_drvdata(file);
838 mutex_unlock(&pd->lock); /* Ok we figured out what to use from our wide choice */ 711
839 return 0; 712 *inp = dev->input;
840 } 713 return 0;
841 case VIDIOCGWIN: 714}
842 { 715
843 struct video_window *vw = arg; 716static int pms_s_input(struct file *file, void *fh, unsigned int inp)
844 memset(vw,0,sizeof(*vw)); 717{
845 vw->width=pd->width; 718 struct pms *dev = video_drvdata(file);
846 vw->height=pd->height; 719
847 return 0; 720 if (inp > 3)
848 } 721 return -EINVAL;
849 case VIDIOCKEY: 722
850 return 0; 723 mutex_lock(&dev->lock);
851 case VIDIOCCAPTURE: 724 dev->input = inp;
852 case VIDIOCGFBUF: 725 pms_videosource(dev, inp & 1);
853 case VIDIOCSFBUF: 726 pms_vcrinput(dev, inp >> 1);
854 case VIDIOCGFREQ: 727 mutex_unlock(&dev->lock);
855 case VIDIOCSFREQ: 728 return 0;
856 case VIDIOCGAUDIO: 729}
857 case VIDIOCSAUDIO: 730
858 return -EINVAL; 731static int pms_g_std(struct file *file, void *fh, v4l2_std_id *std)
859 default: 732{
860 return -ENOIOCTLCMD; 733 struct pms *dev = video_drvdata(file);
734
735 *std = dev->std;
736 return 0;
737}
738
739static int pms_s_std(struct file *file, void *fh, v4l2_std_id *std)
740{
741 struct pms *dev = video_drvdata(file);
742 int ret = 0;
743
744 dev->std = *std;
745 mutex_lock(&dev->lock);
746 if (dev->std & V4L2_STD_NTSC) {
747 pms_framerate(dev, 30);
748 pms_secamcross(dev, 0);
749 pms_format(dev, 1);
750 } else if (dev->std & V4L2_STD_PAL) {
751 pms_framerate(dev, 25);
752 pms_secamcross(dev, 0);
753 pms_format(dev, 2);
754 } else if (dev->std & V4L2_STD_SECAM) {
755 pms_framerate(dev, 25);
756 pms_secamcross(dev, 1);
757 pms_format(dev, 2);
758 } else {
759 ret = -EINVAL;
760 }
761 /*
762 switch (v->mode) {
763 case VIDEO_MODE_AUTO:
764 pms_framerate(dev, 25);
765 pms_secamcross(dev, 0);
766 pms_format(dev, 0);
767 break;
768 }*/
769 mutex_unlock(&dev->lock);
770 return 0;
771}
772
773static int pms_queryctrl(struct file *file, void *priv,
774 struct v4l2_queryctrl *qc)
775{
776 switch (qc->id) {
777 case V4L2_CID_BRIGHTNESS:
778 return v4l2_ctrl_query_fill(qc, 0, 255, 1, 139);
779 case V4L2_CID_CONTRAST:
780 return v4l2_ctrl_query_fill(qc, 0, 255, 1, 70);
781 case V4L2_CID_SATURATION:
782 return v4l2_ctrl_query_fill(qc, 0, 255, 1, 64);
783 case V4L2_CID_HUE:
784 return v4l2_ctrl_query_fill(qc, 0, 255, 1, 0);
785 }
786 return -EINVAL;
787}
788
789static int pms_g_ctrl(struct file *file, void *priv,
790 struct v4l2_control *ctrl)
791{
792 struct pms *dev = video_drvdata(file);
793 int ret = 0;
794
795 switch (ctrl->id) {
796 case V4L2_CID_BRIGHTNESS:
797 ctrl->value = dev->brightness;
798 break;
799 case V4L2_CID_CONTRAST:
800 ctrl->value = dev->contrast;
801 break;
802 case V4L2_CID_SATURATION:
803 ctrl->value = dev->saturation;
804 break;
805 case V4L2_CID_HUE:
806 ctrl->value = dev->hue;
807 break;
808 default:
809 ret = -EINVAL;
810 break;
811 }
812 return ret;
813}
814
815static int pms_s_ctrl(struct file *file, void *priv,
816 struct v4l2_control *ctrl)
817{
818 struct pms *dev = video_drvdata(file);
819 int ret = 0;
820
821 mutex_lock(&dev->lock);
822 switch (ctrl->id) {
823 case V4L2_CID_BRIGHTNESS:
824 dev->brightness = ctrl->value;
825 pms_brightness(dev, dev->brightness);
826 break;
827 case V4L2_CID_CONTRAST:
828 dev->contrast = ctrl->value;
829 pms_contrast(dev, dev->contrast);
830 break;
831 case V4L2_CID_SATURATION:
832 dev->saturation = ctrl->value;
833 pms_saturation(dev, dev->saturation);
834 break;
835 case V4L2_CID_HUE:
836 dev->hue = ctrl->value;
837 pms_hue(dev, dev->hue);
838 break;
839 default:
840 ret = -EINVAL;
841 break;
861 } 842 }
843 mutex_unlock(&dev->lock);
844 return ret;
845}
846
847static int pms_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
848{
849 struct pms *dev = video_drvdata(file);
850 struct v4l2_pix_format *pix = &fmt->fmt.pix;
851
852 pix->width = dev->width;
853 pix->height = dev->height;
854 pix->pixelformat = dev->width == 15 ?
855 V4L2_PIX_FMT_RGB555 : V4L2_PIX_FMT_RGB565;
856 pix->field = V4L2_FIELD_NONE;
857 pix->bytesperline = 2 * dev->width;
858 pix->sizeimage = 2 * dev->width * dev->height;
859 /* Just a guess */
860 pix->colorspace = V4L2_COLORSPACE_SRGB;
862 return 0; 861 return 0;
863} 862}
864 863
865static long pms_ioctl(struct file *file, 864static int pms_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
866 unsigned int cmd, unsigned long arg)
867{ 865{
868 return video_usercopy(file, cmd, arg, pms_do_ioctl); 866 struct v4l2_pix_format *pix = &fmt->fmt.pix;
867
868 if (pix->height < 16 || pix->height > 480)
869 return -EINVAL;
870 if (pix->width < 16 || pix->width > 640)
871 return -EINVAL;
872 if (pix->pixelformat != V4L2_PIX_FMT_RGB555 &&
873 pix->pixelformat != V4L2_PIX_FMT_RGB565)
874 return -EINVAL;
875 pix->field = V4L2_FIELD_NONE;
876 pix->bytesperline = 2 * pix->width;
877 pix->sizeimage = 2 * pix->width * pix->height;
878 /* Just a guess */
879 pix->colorspace = V4L2_COLORSPACE_SRGB;
880 return 0;
881}
882
883static int pms_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
884{
885 struct pms *dev = video_drvdata(file);
886 struct v4l2_pix_format *pix = &fmt->fmt.pix;
887 int ret = pms_try_fmt_vid_cap(file, fh, fmt);
888
889 if (ret)
890 return ret;
891 mutex_lock(&dev->lock);
892 dev->width = pix->width;
893 dev->height = pix->height;
894 dev->depth = (pix->pixelformat == V4L2_PIX_FMT_RGB555) ? 15 : 16;
895 pms_resolution(dev, dev->width, dev->height);
896 /* Ok we figured out what to use from our wide choice */
897 mutex_unlock(&dev->lock);
898 return 0;
899}
900
901static int pms_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdesc *fmt)
902{
903 static struct v4l2_fmtdesc formats[] = {
904 { 0, 0, 0,
905 "RGB 5:5:5", V4L2_PIX_FMT_RGB555,
906 { 0, 0, 0, 0 }
907 },
908 { 0, 0, 0,
909 "RGB 5:6:5", V4L2_PIX_FMT_RGB565,
910 { 0, 0, 0, 0 }
911 },
912 };
913 enum v4l2_buf_type type = fmt->type;
914
915 if (fmt->index > 1)
916 return -EINVAL;
917
918 *fmt = formats[fmt->index];
919 fmt->type = type;
920 return 0;
869} 921}
870 922
871static ssize_t pms_read(struct file *file, char __user *buf, 923static ssize_t pms_read(struct file *file, char __user *buf,
872 size_t count, loff_t *ppos) 924 size_t count, loff_t *ppos)
873{ 925{
874 struct video_device *v = video_devdata(file); 926 struct pms *dev = video_drvdata(file);
875 struct pms_device *pd=(struct pms_device *)v;
876 int len; 927 int len;
877 928
878 mutex_lock(&pd->lock); 929 mutex_lock(&dev->lock);
879 len=pms_capture(pd, buf, (pd->picture.depth==16)?0:1,count); 930 len = pms_capture(dev, buf, (dev->depth == 15), count);
880 mutex_unlock(&pd->lock); 931 mutex_unlock(&dev->lock);
881 return len; 932 return len;
882} 933}
883 934
884static int pms_exclusive_open(struct file *file) 935static int pms_exclusive_open(struct file *file)
885{ 936{
886 struct video_device *v = video_devdata(file); 937 struct pms *dev = video_drvdata(file);
887 struct pms_device *pd = (struct pms_device *)v;
888 938
889 return test_and_set_bit(0, &pd->in_use) ? -EBUSY : 0; 939 return test_and_set_bit(0, &dev->in_use) ? -EBUSY : 0;
890} 940}
891 941
892static int pms_exclusive_release(struct file *file) 942static int pms_exclusive_release(struct file *file)
893{ 943{
894 struct video_device *v = video_devdata(file); 944 struct pms *dev = video_drvdata(file);
895 struct pms_device *pd = (struct pms_device *)v;
896 945
897 clear_bit(0, &pd->in_use); 946 clear_bit(0, &dev->in_use);
898 return 0; 947 return 0;
899} 948}
900 949
@@ -902,78 +951,81 @@ static const struct v4l2_file_operations pms_fops = {
902 .owner = THIS_MODULE, 951 .owner = THIS_MODULE,
903 .open = pms_exclusive_open, 952 .open = pms_exclusive_open,
904 .release = pms_exclusive_release, 953 .release = pms_exclusive_release,
905 .ioctl = pms_ioctl, 954 .ioctl = video_ioctl2,
906 .read = pms_read, 955 .read = pms_read,
907}; 956};
908 957
909static struct video_device pms_template= 958static const struct v4l2_ioctl_ops pms_ioctl_ops = {
910{ 959 .vidioc_querycap = pms_querycap,
911 .name = "Mediavision PMS", 960 .vidioc_g_input = pms_g_input,
912 .fops = &pms_fops, 961 .vidioc_s_input = pms_s_input,
913 .release = video_device_release_empty, 962 .vidioc_enum_input = pms_enum_input,
963 .vidioc_g_std = pms_g_std,
964 .vidioc_s_std = pms_s_std,
965 .vidioc_queryctrl = pms_queryctrl,
966 .vidioc_g_ctrl = pms_g_ctrl,
967 .vidioc_s_ctrl = pms_s_ctrl,
968 .vidioc_enum_fmt_vid_cap = pms_enum_fmt_vid_cap,
969 .vidioc_g_fmt_vid_cap = pms_g_fmt_vid_cap,
970 .vidioc_s_fmt_vid_cap = pms_s_fmt_vid_cap,
971 .vidioc_try_fmt_vid_cap = pms_try_fmt_vid_cap,
914}; 972};
915 973
916static struct pms_device pms_device;
917
918
919/* 974/*
920 * Probe for and initialise the Mediavision PMS 975 * Probe for and initialise the Mediavision PMS
921 */ 976 */
922 977
923static int init_mediavision(void) 978static int init_mediavision(struct pms *dev)
924{ 979{
925 int id; 980 int id;
926 int idec, decst; 981 int idec, decst;
927 int i; 982 int i;
928 983 static const unsigned char i2c_defs[] = {
929 unsigned char i2c_defs[]={ 984 0x4c, 0x30, 0x00, 0xe8,
930 0x4C,0x30,0x00,0xE8, 985 0xb6, 0xe2, 0x00, 0x00,
931 0xB6,0xE2,0x00,0x00, 986 0xff, 0xff, 0x00, 0x00,
932 0xFF,0xFF,0x00,0x00, 987 0x00, 0x00, 0x78, 0x98,
933 0x00,0x00,0x78,0x98, 988 0x00, 0x00, 0x00, 0x00,
934 0x00,0x00,0x00,0x00, 989 0x34, 0x0a, 0xf4, 0xce,
935 0x34,0x0A,0xF4,0xCE, 990 0xe4
936 0xE4
937 }; 991 };
938 992
939 mem = ioremap(mem_base, 0x800); 993 dev->mem = ioremap(mem_base, 0x800);
940 if (!mem) 994 if (!dev->mem)
941 return -ENOMEM; 995 return -ENOMEM;
942 996
943 if (!request_region(0x9A01, 1, "Mediavision PMS config")) 997 if (!request_region(0x9a01, 1, "Mediavision PMS config")) {
944 { 998 printk(KERN_WARNING "mediavision: unable to detect: 0x9a01 in use.\n");
945 printk(KERN_WARNING "mediavision: unable to detect: 0x9A01 in use.\n"); 999 iounmap(dev->mem);
946 iounmap(mem);
947 return -EBUSY; 1000 return -EBUSY;
948 } 1001 }
949 if (!request_region(io_port, 3, "Mediavision PMS")) 1002 if (!request_region(dev->io, 3, "Mediavision PMS")) {
950 { 1003 printk(KERN_WARNING "mediavision: I/O port %d in use.\n", dev->io);
951 printk(KERN_WARNING "mediavision: I/O port %d in use.\n", io_port); 1004 release_region(0x9a01, 1);
952 release_region(0x9A01, 1); 1005 iounmap(dev->mem);
953 iounmap(mem);
954 return -EBUSY; 1006 return -EBUSY;
955 } 1007 }
956 outb(0xB8, 0x9A01); /* Unlock */ 1008 outb(0xb8, 0x9a01); /* Unlock */
957 outb(io_port>>4, 0x9A01); /* Set IO port */ 1009 outb(dev->io >> 4, 0x9a01); /* Set IO port */
958 1010
959 1011
960 id=mvv_read(3); 1012 id = mvv_read(dev, 3);
961 decst=pms_i2c_stat(0x43); 1013 decst = pms_i2c_stat(dev, 0x43);
962 1014
963 if(decst!=-1) 1015 if (decst != -1)
964 idec=2; 1016 idec = 2;
965 else if(pms_i2c_stat(0xb9)!=-1) 1017 else if (pms_i2c_stat(dev, 0xb9) != -1)
966 idec=3; 1018 idec = 3;
967 else if(pms_i2c_stat(0x8b)!=-1) 1019 else if (pms_i2c_stat(dev, 0x8b) != -1)
968 idec=1; 1020 idec = 1;
969 else 1021 else
970 idec=0; 1022 idec = 0;
971 1023
972 printk(KERN_INFO "PMS type is %d\n", idec); 1024 printk(KERN_INFO "PMS type is %d\n", idec);
973 if(idec == 0) { 1025 if (idec == 0) {
974 release_region(io_port, 3); 1026 release_region(dev->io, 3);
975 release_region(0x9A01, 1); 1027 release_region(0x9a01, 1);
976 iounmap(mem); 1028 iounmap(dev->mem);
977 return -ENODEV; 1029 return -ENODEV;
978 } 1030 }
979 1031
@@ -981,51 +1033,50 @@ static int init_mediavision(void)
981 * Ok we have a PMS of some sort 1033 * Ok we have a PMS of some sort
982 */ 1034 */
983 1035
984 mvv_write(0x04, mem_base>>12); /* Set the memory area */ 1036 mvv_write(dev, 0x04, mem_base >> 12); /* Set the memory area */
985 1037
986 /* Ok now load the defaults */ 1038 /* Ok now load the defaults */
987 1039
988 for(i=0;i<0x19;i++) 1040 for (i = 0; i < 0x19; i++) {
989 { 1041 if (i2c_defs[i] == 0xff)
990 if(i2c_defs[i]==0xFF) 1042 pms_i2c_andor(dev, 0x8a, i, 0x07, 0x00);
991 pms_i2c_andor(0x8A, i, 0x07,0x00);
992 else 1043 else
993 pms_i2c_write(0x8A, i, i2c_defs[i]); 1044 pms_i2c_write(dev, 0x8a, i, i2c_defs[i]);
994 } 1045 }
995 1046
996 pms_i2c_write(0xB8,0x00,0x12); 1047 pms_i2c_write(dev, 0xb8, 0x00, 0x12);
997 pms_i2c_write(0xB8,0x04,0x00); 1048 pms_i2c_write(dev, 0xb8, 0x04, 0x00);
998 pms_i2c_write(0xB8,0x07,0x00); 1049 pms_i2c_write(dev, 0xb8, 0x07, 0x00);
999 pms_i2c_write(0xB8,0x08,0x00); 1050 pms_i2c_write(dev, 0xb8, 0x08, 0x00);
1000 pms_i2c_write(0xB8,0x09,0xFF); 1051 pms_i2c_write(dev, 0xb8, 0x09, 0xff);
1001 pms_i2c_write(0xB8,0x0A,0x00); 1052 pms_i2c_write(dev, 0xb8, 0x0a, 0x00);
1002 pms_i2c_write(0xB8,0x0B,0x10); 1053 pms_i2c_write(dev, 0xb8, 0x0b, 0x10);
1003 pms_i2c_write(0xB8,0x10,0x03); 1054 pms_i2c_write(dev, 0xb8, 0x10, 0x03);
1004 1055
1005 mvv_write(0x01, 0x00); 1056 mvv_write(dev, 0x01, 0x00);
1006 mvv_write(0x05, 0xA0); 1057 mvv_write(dev, 0x05, 0xa0);
1007 mvv_write(0x08, 0x25); 1058 mvv_write(dev, 0x08, 0x25);
1008 mvv_write(0x09, 0x00); 1059 mvv_write(dev, 0x09, 0x00);
1009 mvv_write(0x0A, 0x20|MVVMEMORYWIDTH); 1060 mvv_write(dev, 0x0a, 0x20 | MVVMEMORYWIDTH);
1010 1061
1011 mvv_write(0x10, 0x02); 1062 mvv_write(dev, 0x10, 0x02);
1012 mvv_write(0x1E, 0x0C); 1063 mvv_write(dev, 0x1e, 0x0c);
1013 mvv_write(0x1F, 0x03); 1064 mvv_write(dev, 0x1f, 0x03);
1014 mvv_write(0x26, 0x06); 1065 mvv_write(dev, 0x26, 0x06);
1015 1066
1016 mvv_write(0x2B, 0x00); 1067 mvv_write(dev, 0x2b, 0x00);
1017 mvv_write(0x2C, 0x20); 1068 mvv_write(dev, 0x2c, 0x20);
1018 mvv_write(0x2D, 0x00); 1069 mvv_write(dev, 0x2d, 0x00);
1019 mvv_write(0x2F, 0x70); 1070 mvv_write(dev, 0x2f, 0x70);
1020 mvv_write(0x32, 0x00); 1071 mvv_write(dev, 0x32, 0x00);
1021 mvv_write(0x33, MVVMEMORYWIDTH); 1072 mvv_write(dev, 0x33, MVVMEMORYWIDTH);
1022 mvv_write(0x34, 0x00); 1073 mvv_write(dev, 0x34, 0x00);
1023 mvv_write(0x35, 0x00); 1074 mvv_write(dev, 0x35, 0x00);
1024 mvv_write(0x3A, 0x80); 1075 mvv_write(dev, 0x3a, 0x80);
1025 mvv_write(0x3B, 0x10); 1076 mvv_write(dev, 0x3b, 0x10);
1026 mvv_write(0x20, 0x00); 1077 mvv_write(dev, 0x20, 0x00);
1027 mvv_write(0x21, 0x00); 1078 mvv_write(dev, 0x21, 0x00);
1028 mvv_write(0x30, 0x22); 1079 mvv_write(dev, 0x30, 0x22);
1029 return 0; 1080 return 0;
1030} 1081}
1031 1082
@@ -1038,53 +1089,77 @@ static int enable;
1038module_param(enable, int, 0); 1089module_param(enable, int, 0);
1039#endif 1090#endif
1040 1091
1041static int __init init_pms_cards(void) 1092static int __init pms_init(void)
1042{ 1093{
1043 printk(KERN_INFO "Mediavision Pro Movie Studio driver 0.02\n"); 1094 struct pms *dev = &pms_card;
1095 struct v4l2_device *v4l2_dev = &dev->v4l2_dev;
1096 int res;
1097
1098 strlcpy(v4l2_dev->name, "pms", sizeof(v4l2_dev->name));
1099
1100 v4l2_info(v4l2_dev, "Mediavision Pro Movie Studio driver 0.03\n");
1044 1101
1045#ifndef MODULE 1102#ifndef MODULE
1046 if (!enable) { 1103 if (!enable) {
1047 printk(KERN_INFO "PMS: not enabled, use pms.enable=1 to " 1104 v4l2_err(v4l2_dev,
1048 "probe\n"); 1105 "PMS: not enabled, use pms.enable=1 to probe\n");
1049 return -ENODEV; 1106 return -ENODEV;
1050 } 1107 }
1051#endif 1108#endif
1052 1109
1053 data_port = io_port +1; 1110 dev->decoder = PHILIPS2;
1111 dev->io = io_port;
1112 dev->data = io_port + 1;
1054 1113
1055 if(init_mediavision()) 1114 if (init_mediavision(dev)) {
1056 { 1115 v4l2_err(v4l2_dev, "Board not found.\n");
1057 printk(KERN_INFO "Board not found.\n");
1058 return -ENODEV; 1116 return -ENODEV;
1059 } 1117 }
1060 memcpy(&pms_device, &pms_template, sizeof(pms_template));
1061 mutex_init(&pms_device.lock);
1062 pms_device.height=240;
1063 pms_device.width=320;
1064 pms_swsense(75);
1065 pms_resolution(320,240);
1066 return video_register_device((struct video_device *)&pms_device, VFL_TYPE_GRABBER, video_nr);
1067}
1068
1069module_param(io_port, int, 0);
1070module_param(mem_base, int, 0);
1071module_param(video_nr, int, 0);
1072MODULE_LICENSE("GPL");
1073 1118
1119 res = v4l2_device_register(NULL, v4l2_dev);
1120 if (res < 0) {
1121 v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
1122 return res;
1123 }
1074 1124
1075static void __exit shutdown_mediavision(void) 1125 strlcpy(dev->vdev.name, v4l2_dev->name, sizeof(dev->vdev.name));
1076{ 1126 dev->vdev.v4l2_dev = v4l2_dev;
1077 release_region(io_port,3); 1127 dev->vdev.fops = &pms_fops;
1078 release_region(0x9A01, 1); 1128 dev->vdev.ioctl_ops = &pms_ioctl_ops;
1129 dev->vdev.release = video_device_release_empty;
1130 video_set_drvdata(&dev->vdev, dev);
1131 mutex_init(&dev->lock);
1132 dev->std = V4L2_STD_NTSC_M;
1133 dev->height = 240;
1134 dev->width = 320;
1135 dev->depth = 15;
1136 dev->brightness = 139;
1137 dev->contrast = 70;
1138 dev->hue = 0;
1139 dev->saturation = 64;
1140 pms_swsense(dev, 75);
1141 pms_resolution(dev, 320, 240);
1142 pms_videosource(dev, 0);
1143 pms_vcrinput(dev, 0);
1144 if (video_register_device(&dev->vdev, VFL_TYPE_GRABBER, video_nr) < 0) {
1145 v4l2_device_unregister(&dev->v4l2_dev);
1146 release_region(dev->io, 3);
1147 release_region(0x9a01, 1);
1148 iounmap(dev->mem);
1149 return -EINVAL;
1150 }
1151 return 0;
1079} 1152}
1080 1153
1081static void __exit cleanup_pms_module(void) 1154static void __exit pms_exit(void)
1082{ 1155{
1083 shutdown_mediavision(); 1156 struct pms *dev = &pms_card;
1084 video_unregister_device((struct video_device *)&pms_device);
1085 iounmap(mem);
1086}
1087 1157
1088module_init(init_pms_cards); 1158 video_unregister_device(&dev->vdev);
1089module_exit(cleanup_pms_module); 1159 release_region(dev->io, 3);
1160 release_region(0x9a01, 1);
1161 iounmap(dev->mem);
1162}
1090 1163
1164module_init(pms_init);
1165module_exit(pms_exit);
diff --git a/drivers/media/video/pvrusb2/pvrusb2-debugifc.c b/drivers/media/video/pvrusb2/pvrusb2-debugifc.c
index fbe3856bdca6..ae977668c496 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-debugifc.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-debugifc.c
@@ -142,6 +142,9 @@ int pvr2_debugifc_print_info(struct pvr2_hdw *hdw,char *buf,unsigned int acnt)
142{ 142{
143 int bcnt = 0; 143 int bcnt = 0;
144 int ccnt; 144 int ccnt;
145 ccnt = scnprintf(buf, acnt, "Driver hardware description: %s\n",
146 pvr2_hdw_get_desc(hdw));
147 bcnt += ccnt; acnt -= ccnt; buf += ccnt;
145 ccnt = scnprintf(buf,acnt,"Driver state info:\n"); 148 ccnt = scnprintf(buf,acnt,"Driver state info:\n");
146 bcnt += ccnt; acnt -= ccnt; buf += ccnt; 149 bcnt += ccnt; acnt -= ccnt; buf += ccnt;
147 ccnt = pvr2_hdw_state_report(hdw,buf,acnt); 150 ccnt = pvr2_hdw_state_report(hdw,buf,acnt);
@@ -249,11 +252,15 @@ static int pvr2_debugifc_do1cmd(struct pvr2_hdw *hdw,const char *buf,
249 scnt = debugifc_isolate_word(buf,count,&wptr,&wlen); 252 scnt = debugifc_isolate_word(buf,count,&wptr,&wlen);
250 if (scnt && wptr) { 253 if (scnt && wptr) {
251 count -= scnt; buf += scnt; 254 count -= scnt; buf += scnt;
252 if (debugifc_match_keyword(wptr,wlen,"prom")) { 255 if (debugifc_match_keyword(wptr, wlen,
253 pvr2_hdw_cpufw_set_enabled(hdw,!0,!0); 256 "prom")) {
254 } else if (debugifc_match_keyword(wptr,wlen, 257 pvr2_hdw_cpufw_set_enabled(hdw, 2, !0);
255 "ram")) { 258 } else if (debugifc_match_keyword(wptr, wlen,
256 pvr2_hdw_cpufw_set_enabled(hdw,0,!0); 259 "ram8k")) {
260 pvr2_hdw_cpufw_set_enabled(hdw, 0, !0);
261 } else if (debugifc_match_keyword(wptr, wlen,
262 "ram16k")) {
263 pvr2_hdw_cpufw_set_enabled(hdw, 1, !0);
257 } else { 264 } else {
258 return -EINVAL; 265 return -EINVAL;
259 } 266 }
diff --git a/drivers/media/video/pvrusb2/pvrusb2-devattr.c b/drivers/media/video/pvrusb2/pvrusb2-devattr.c
index e4d7c13cab87..6bc16c13ccef 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-devattr.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-devattr.c
@@ -58,7 +58,7 @@ static const char *pvr2_fw1_names_29xxx[] = {
58}; 58};
59 59
60static const struct pvr2_device_desc pvr2_device_29xxx = { 60static const struct pvr2_device_desc pvr2_device_29xxx = {
61 .description = "WinTV PVR USB2 Model Category 29xxx", 61 .description = "WinTV PVR USB2 Model 29xxx",
62 .shortname = "29xxx", 62 .shortname = "29xxx",
63 .client_table.lst = pvr2_cli_29xxx, 63 .client_table.lst = pvr2_cli_29xxx,
64 .client_table.cnt = ARRAY_SIZE(pvr2_cli_29xxx), 64 .client_table.cnt = ARRAY_SIZE(pvr2_cli_29xxx),
@@ -91,7 +91,7 @@ static const char *pvr2_fw1_names_24xxx[] = {
91}; 91};
92 92
93static const struct pvr2_device_desc pvr2_device_24xxx = { 93static const struct pvr2_device_desc pvr2_device_24xxx = {
94 .description = "WinTV PVR USB2 Model Category 24xxx", 94 .description = "WinTV PVR USB2 Model 24xxx",
95 .shortname = "24xxx", 95 .shortname = "24xxx",
96 .client_table.lst = pvr2_cli_24xxx, 96 .client_table.lst = pvr2_cli_24xxx,
97 .client_table.cnt = ARRAY_SIZE(pvr2_cli_24xxx), 97 .client_table.cnt = ARRAY_SIZE(pvr2_cli_24xxx),
@@ -340,7 +340,7 @@ static const char *pvr2_fw1_names_73xxx[] = {
340}; 340};
341 341
342static const struct pvr2_device_desc pvr2_device_73xxx = { 342static const struct pvr2_device_desc pvr2_device_73xxx = {
343 .description = "WinTV HVR-1900 Model Category 73xxx", 343 .description = "WinTV HVR-1900 Model 73xxx",
344 .shortname = "73xxx", 344 .shortname = "73xxx",
345 .client_table.lst = pvr2_cli_73xxx, 345 .client_table.lst = pvr2_cli_73xxx,
346 .client_table.cnt = ARRAY_SIZE(pvr2_cli_73xxx), 346 .client_table.cnt = ARRAY_SIZE(pvr2_cli_73xxx),
@@ -351,6 +351,7 @@ static const struct pvr2_device_desc pvr2_device_73xxx = {
351 .flag_has_analogtuner = !0, 351 .flag_has_analogtuner = !0,
352 .flag_has_composite = !0, 352 .flag_has_composite = !0,
353 .flag_has_svideo = !0, 353 .flag_has_svideo = !0,
354 .flag_fx2_16kb = !0,
354 .signal_routing_scheme = PVR2_ROUTING_SCHEME_HAUPPAUGE, 355 .signal_routing_scheme = PVR2_ROUTING_SCHEME_HAUPPAUGE,
355 .digital_control_scheme = PVR2_DIGITAL_SCHEME_HAUPPAUGE, 356 .digital_control_scheme = PVR2_DIGITAL_SCHEME_HAUPPAUGE,
356 .led_scheme = PVR2_LED_SCHEME_HAUPPAUGE, 357 .led_scheme = PVR2_LED_SCHEME_HAUPPAUGE,
@@ -445,7 +446,7 @@ static const char *pvr2_fw1_names_75xxx[] = {
445}; 446};
446 447
447static const struct pvr2_device_desc pvr2_device_750xx = { 448static const struct pvr2_device_desc pvr2_device_750xx = {
448 .description = "WinTV HVR-1950 Model Category 750xx", 449 .description = "WinTV HVR-1950 Model 750xx",
449 .shortname = "750xx", 450 .shortname = "750xx",
450 .client_table.lst = pvr2_cli_73xxx, 451 .client_table.lst = pvr2_cli_73xxx,
451 .client_table.cnt = ARRAY_SIZE(pvr2_cli_73xxx), 452 .client_table.cnt = ARRAY_SIZE(pvr2_cli_73xxx),
@@ -456,6 +457,7 @@ static const struct pvr2_device_desc pvr2_device_750xx = {
456 .flag_has_analogtuner = !0, 457 .flag_has_analogtuner = !0,
457 .flag_has_composite = !0, 458 .flag_has_composite = !0,
458 .flag_has_svideo = !0, 459 .flag_has_svideo = !0,
460 .flag_fx2_16kb = !0,
459 .signal_routing_scheme = PVR2_ROUTING_SCHEME_HAUPPAUGE, 461 .signal_routing_scheme = PVR2_ROUTING_SCHEME_HAUPPAUGE,
460 .digital_control_scheme = PVR2_DIGITAL_SCHEME_HAUPPAUGE, 462 .digital_control_scheme = PVR2_DIGITAL_SCHEME_HAUPPAUGE,
461 .default_std_mask = V4L2_STD_NTSC_M, 463 .default_std_mask = V4L2_STD_NTSC_M,
@@ -467,7 +469,7 @@ static const struct pvr2_device_desc pvr2_device_750xx = {
467}; 469};
468 470
469static const struct pvr2_device_desc pvr2_device_751xx = { 471static const struct pvr2_device_desc pvr2_device_751xx = {
470 .description = "WinTV HVR-1950 Model Category 751xx", 472 .description = "WinTV HVR-1950 Model 751xx",
471 .shortname = "751xx", 473 .shortname = "751xx",
472 .client_table.lst = pvr2_cli_73xxx, 474 .client_table.lst = pvr2_cli_73xxx,
473 .client_table.cnt = ARRAY_SIZE(pvr2_cli_73xxx), 475 .client_table.cnt = ARRAY_SIZE(pvr2_cli_73xxx),
@@ -478,6 +480,7 @@ static const struct pvr2_device_desc pvr2_device_751xx = {
478 .flag_has_analogtuner = !0, 480 .flag_has_analogtuner = !0,
479 .flag_has_composite = !0, 481 .flag_has_composite = !0,
480 .flag_has_svideo = !0, 482 .flag_has_svideo = !0,
483 .flag_fx2_16kb = !0,
481 .signal_routing_scheme = PVR2_ROUTING_SCHEME_HAUPPAUGE, 484 .signal_routing_scheme = PVR2_ROUTING_SCHEME_HAUPPAUGE,
482 .digital_control_scheme = PVR2_DIGITAL_SCHEME_HAUPPAUGE, 485 .digital_control_scheme = PVR2_DIGITAL_SCHEME_HAUPPAUGE,
483 .default_std_mask = V4L2_STD_NTSC_M, 486 .default_std_mask = V4L2_STD_NTSC_M,
diff --git a/drivers/media/video/pvrusb2/pvrusb2-devattr.h b/drivers/media/video/pvrusb2/pvrusb2-devattr.h
index ea04ecf8aa39..e5b9594eb5f6 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-devattr.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-devattr.h
@@ -176,6 +176,7 @@ struct pvr2_device_desc {
176 unsigned int flag_has_analogtuner:1; /* Has analog tuner */ 176 unsigned int flag_has_analogtuner:1; /* Has analog tuner */
177 unsigned int flag_has_composite:1; /* Has composite input */ 177 unsigned int flag_has_composite:1; /* Has composite input */
178 unsigned int flag_has_svideo:1; /* Has s-video input */ 178 unsigned int flag_has_svideo:1; /* Has s-video input */
179 unsigned int flag_fx2_16kb:1; /* 16KB FX2 firmware OK here */
179}; 180};
180 181
181extern struct usb_device_id pvr2_device_table[]; 182extern struct usb_device_id pvr2_device_table[];
diff --git a/drivers/media/video/pvrusb2/pvrusb2-encoder.c b/drivers/media/video/pvrusb2/pvrusb2-encoder.c
index 54ac5349dee2..e046fdaec5ae 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-encoder.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-encoder.c
@@ -294,7 +294,10 @@ static int pvr2_encoder_cmd(void *ctxt,
294 pvr2_trace( 294 pvr2_trace(
295 PVR2_TRACE_ERROR_LEGS, 295 PVR2_TRACE_ERROR_LEGS,
296 "Giving up on command." 296 "Giving up on command."
297 " This is normally recovered by the driver."); 297 " This is normally recovered via a firmware"
298 " reload and re-initialization; concern"
299 " is only warranted if this happens repeatedly"
300 " and rapidly.");
298 break; 301 break;
299 } 302 }
300 wrData[0] = 0x7; 303 wrData[0] = 0x7;
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h b/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
index 5fcad28211d2..de5485f506b1 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
@@ -270,6 +270,7 @@ struct pvr2_hdw {
270 270
271 int force_dirty; /* consider all controls dirty if true */ 271 int force_dirty; /* consider all controls dirty if true */
272 int flag_ok; /* device in known good state */ 272 int flag_ok; /* device in known good state */
273 int flag_modulefail; /* true if at least one module failed to load */
273 int flag_disconnected; /* flag_ok == 0 due to disconnect */ 274 int flag_disconnected; /* flag_ok == 0 due to disconnect */
274 int flag_init_ok; /* true if structure is fully initialized */ 275 int flag_init_ok; /* true if structure is fully initialized */
275 int fw1_state; /* current situation with fw1 */ 276 int fw1_state; /* current situation with fw1 */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
index 13639b302700..1bbdab08fe0e 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
@@ -1447,6 +1447,7 @@ static int pvr2_upload_firmware1(struct pvr2_hdw *hdw)
1447 const struct firmware *fw_entry = NULL; 1447 const struct firmware *fw_entry = NULL;
1448 void *fw_ptr; 1448 void *fw_ptr;
1449 unsigned int pipe; 1449 unsigned int pipe;
1450 unsigned int fwsize;
1450 int ret; 1451 int ret;
1451 u16 address; 1452 u16 address;
1452 1453
@@ -1473,9 +1474,21 @@ static int pvr2_upload_firmware1(struct pvr2_hdw *hdw)
1473 usb_clear_halt(hdw->usb_dev, usb_sndbulkpipe(hdw->usb_dev, 0 & 0x7f)); 1474 usb_clear_halt(hdw->usb_dev, usb_sndbulkpipe(hdw->usb_dev, 0 & 0x7f));
1474 1475
1475 pipe = usb_sndctrlpipe(hdw->usb_dev, 0); 1476 pipe = usb_sndctrlpipe(hdw->usb_dev, 0);
1477 fwsize = fw_entry->size;
1476 1478
1477 if (fw_entry->size != 0x2000){ 1479 if ((fwsize != 0x2000) &&
1478 pvr2_trace(PVR2_TRACE_ERROR_LEGS,"wrong fx2 firmware size"); 1480 (!(hdw->hdw_desc->flag_fx2_16kb && (fwsize == 0x4000)))) {
1481 if (hdw->hdw_desc->flag_fx2_16kb) {
1482 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1483 "Wrong fx2 firmware size"
1484 " (expected 8192 or 16384, got %u)",
1485 fwsize);
1486 } else {
1487 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1488 "Wrong fx2 firmware size"
1489 " (expected 8192, got %u)",
1490 fwsize);
1491 }
1479 release_firmware(fw_entry); 1492 release_firmware(fw_entry);
1480 return -ENOMEM; 1493 return -ENOMEM;
1481 } 1494 }
@@ -1493,7 +1506,7 @@ static int pvr2_upload_firmware1(struct pvr2_hdw *hdw)
1493 chunk. */ 1506 chunk. */
1494 1507
1495 ret = 0; 1508 ret = 0;
1496 for(address = 0; address < fw_entry->size; address += 0x800) { 1509 for (address = 0; address < fwsize; address += 0x800) {
1497 memcpy(fw_ptr, fw_entry->data + address, 0x800); 1510 memcpy(fw_ptr, fw_entry->data + address, 0x800);
1498 ret += usb_control_msg(hdw->usb_dev, pipe, 0xa0, 0x40, address, 1511 ret += usb_control_msg(hdw->usb_dev, pipe, 0xa0, 0x40, address,
1499 0, fw_ptr, 0x800, HZ); 1512 0, fw_ptr, 0x800, HZ);
@@ -1509,8 +1522,8 @@ static int pvr2_upload_firmware1(struct pvr2_hdw *hdw)
1509 1522
1510 trace_firmware("Upload done (%d bytes sent)",ret); 1523 trace_firmware("Upload done (%d bytes sent)",ret);
1511 1524
1512 /* We should have written 8192 bytes */ 1525 /* We should have written fwsize bytes */
1513 if (ret == 8192) { 1526 if (ret == fwsize) {
1514 hdw->fw1_state = FW1_STATE_RELOAD; 1527 hdw->fw1_state = FW1_STATE_RELOAD;
1515 return 0; 1528 return 0;
1516 } 1529 }
@@ -2030,7 +2043,8 @@ static int pvr2_hdw_load_subdev(struct pvr2_hdw *hdw,
2030 fname = (mid < ARRAY_SIZE(module_names)) ? module_names[mid] : NULL; 2043 fname = (mid < ARRAY_SIZE(module_names)) ? module_names[mid] : NULL;
2031 if (!fname) { 2044 if (!fname) {
2032 pvr2_trace(PVR2_TRACE_ERROR_LEGS, 2045 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2033 "Module ID %u for device %s has no name", 2046 "Module ID %u for device %s has no name?"
2047 " The driver might have a configuration problem.",
2034 mid, 2048 mid,
2035 hdw->hdw_desc->description); 2049 hdw->hdw_desc->description);
2036 return -EINVAL; 2050 return -EINVAL;
@@ -2058,7 +2072,8 @@ static int pvr2_hdw_load_subdev(struct pvr2_hdw *hdw,
2058 if (!i2ccnt) { 2072 if (!i2ccnt) {
2059 pvr2_trace(PVR2_TRACE_ERROR_LEGS, 2073 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2060 "Module ID %u (%s) for device %s:" 2074 "Module ID %u (%s) for device %s:"
2061 " No i2c addresses", 2075 " No i2c addresses."
2076 " The driver might have a configuration problem.",
2062 mid, fname, hdw->hdw_desc->description); 2077 mid, fname, hdw->hdw_desc->description);
2063 return -EINVAL; 2078 return -EINVAL;
2064 } 2079 }
@@ -2090,7 +2105,9 @@ static int pvr2_hdw_load_subdev(struct pvr2_hdw *hdw,
2090 2105
2091 if (!sd) { 2106 if (!sd) {
2092 pvr2_trace(PVR2_TRACE_ERROR_LEGS, 2107 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2093 "Module ID %u (%s) for device %s failed to load", 2108 "Module ID %u (%s) for device %s failed to load."
2109 " Possible missing sub-device kernel module or"
2110 " initialization failure within module.",
2094 mid, fname, hdw->hdw_desc->description); 2111 mid, fname, hdw->hdw_desc->description);
2095 return -EIO; 2112 return -EIO;
2096 } 2113 }
@@ -2132,7 +2149,10 @@ static void pvr2_hdw_load_modules(struct pvr2_hdw *hdw)
2132 for (idx = 0; idx < ct->cnt; idx++) { 2149 for (idx = 0; idx < ct->cnt; idx++) {
2133 if (pvr2_hdw_load_subdev(hdw, &ct->lst[idx]) < 0) okFl = 0; 2150 if (pvr2_hdw_load_subdev(hdw, &ct->lst[idx]) < 0) okFl = 0;
2134 } 2151 }
2135 if (!okFl) pvr2_hdw_render_useless(hdw); 2152 if (!okFl) {
2153 hdw->flag_modulefail = !0;
2154 pvr2_hdw_render_useless(hdw);
2155 }
2136} 2156}
2137 2157
2138 2158
@@ -2334,6 +2354,20 @@ static void pvr2_hdw_setup(struct pvr2_hdw *hdw)
2334 break; 2354 break;
2335 } 2355 }
2336 } 2356 }
2357 if (hdw->flag_modulefail) {
2358 pvr2_trace(
2359 PVR2_TRACE_ERROR_LEGS,
2360 "***WARNING*** pvrusb2 driver initialization"
2361 " failed due to the failure of one or more"
2362 " sub-device kernel modules.");
2363 pvr2_trace(
2364 PVR2_TRACE_ERROR_LEGS,
2365 "You need to resolve the failing condition"
2366 " before this driver can function. There"
2367 " should be some earlier messages giving more"
2368 " information about the problem.");
2369 break;
2370 }
2337 if (procreload) { 2371 if (procreload) {
2338 pvr2_trace( 2372 pvr2_trace(
2339 PVR2_TRACE_ERROR_LEGS, 2373 PVR2_TRACE_ERROR_LEGS,
@@ -2419,6 +2453,8 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf,
2419 hdw = kzalloc(sizeof(*hdw),GFP_KERNEL); 2453 hdw = kzalloc(sizeof(*hdw),GFP_KERNEL);
2420 pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_create: hdw=%p, type \"%s\"", 2454 pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_create: hdw=%p, type \"%s\"",
2421 hdw,hdw_desc->description); 2455 hdw,hdw_desc->description);
2456 pvr2_trace(PVR2_TRACE_INFO, "Hardware description: %s",
2457 hdw_desc->description);
2422 if (!hdw) goto fail; 2458 if (!hdw) goto fail;
2423 2459
2424 init_timer(&hdw->quiescent_timer); 2460 init_timer(&hdw->quiescent_timer);
@@ -3480,7 +3516,7 @@ static u8 *pvr2_full_eeprom_fetch(struct pvr2_hdw *hdw)
3480 3516
3481 3517
3482void pvr2_hdw_cpufw_set_enabled(struct pvr2_hdw *hdw, 3518void pvr2_hdw_cpufw_set_enabled(struct pvr2_hdw *hdw,
3483 int prom_flag, 3519 int mode,
3484 int enable_flag) 3520 int enable_flag)
3485{ 3521{
3486 int ret; 3522 int ret;
@@ -3503,11 +3539,12 @@ void pvr2_hdw_cpufw_set_enabled(struct pvr2_hdw *hdw,
3503 break; 3539 break;
3504 } 3540 }
3505 3541
3506 hdw->fw_cpu_flag = (prom_flag == 0); 3542 hdw->fw_cpu_flag = (mode != 2);
3507 if (hdw->fw_cpu_flag) { 3543 if (hdw->fw_cpu_flag) {
3544 hdw->fw_size = (mode == 1) ? 0x4000 : 0x2000;
3508 pvr2_trace(PVR2_TRACE_FIRMWARE, 3545 pvr2_trace(PVR2_TRACE_FIRMWARE,
3509 "Preparing to suck out CPU firmware"); 3546 "Preparing to suck out CPU firmware"
3510 hdw->fw_size = 0x2000; 3547 " (size=%u)", hdw->fw_size);
3511 hdw->fw_buffer = kzalloc(hdw->fw_size,GFP_KERNEL); 3548 hdw->fw_buffer = kzalloc(hdw->fw_size,GFP_KERNEL);
3512 if (!hdw->fw_buffer) { 3549 if (!hdw->fw_buffer) {
3513 hdw->fw_size = 0; 3550 hdw->fw_size = 0;
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.h b/drivers/media/video/pvrusb2/pvrusb2-hdw.h
index 7b6940554e9a..56e70eae20c1 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.h
@@ -219,7 +219,7 @@ int pvr2_hdw_get_stdenum_value(struct pvr2_hdw *hdw,struct v4l2_standard *std,
219 this may prevent the device from running (and leaving this mode may 219 this may prevent the device from running (and leaving this mode may
220 imply a device reset). */ 220 imply a device reset). */
221void pvr2_hdw_cpufw_set_enabled(struct pvr2_hdw *, 221void pvr2_hdw_cpufw_set_enabled(struct pvr2_hdw *,
222 int prom_flag, 222 int mode, /* 0=8KB FX2, 1=16KB FX2, 2=PROM */
223 int enable_flag); 223 int enable_flag);
224 224
225/* Return true if we're in a mode for retrieval CPU firmware */ 225/* Return true if we're in a mode for retrieval CPU firmware */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
index a334b1a966a2..7cbe18c4ca95 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
@@ -50,6 +50,7 @@ MODULE_PARM_DESC(disable_autoload_ir_video,
50 50
51/* Mapping of IR schemes to known I2C addresses - if any */ 51/* Mapping of IR schemes to known I2C addresses - if any */
52static const unsigned char ir_video_addresses[] = { 52static const unsigned char ir_video_addresses[] = {
53 [PVR2_IR_SCHEME_ZILOG] = 0x71,
53 [PVR2_IR_SCHEME_29XXX] = 0x18, 54 [PVR2_IR_SCHEME_29XXX] = 0x18,
54 [PVR2_IR_SCHEME_24XXX] = 0x18, 55 [PVR2_IR_SCHEME_24XXX] = 0x18,
55}; 56};
diff --git a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
index 2d8825e5b1be..6aa48e0ae731 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
@@ -913,6 +913,15 @@ static void pvr2_v4l2_dev_destroy(struct pvr2_v4l2_dev *dip)
913} 913}
914 914
915 915
916static void pvr2_v4l2_dev_disassociate_parent(struct pvr2_v4l2_dev *dip)
917{
918 if (!dip) return;
919 if (!dip->devbase.parent) return;
920 dip->devbase.parent = NULL;
921 device_move(&dip->devbase.dev, NULL, DPM_ORDER_NONE);
922}
923
924
916static void pvr2_v4l2_destroy_no_lock(struct pvr2_v4l2 *vp) 925static void pvr2_v4l2_destroy_no_lock(struct pvr2_v4l2 *vp)
917{ 926{
918 if (vp->dev_video) { 927 if (vp->dev_video) {
@@ -943,6 +952,8 @@ static void pvr2_v4l2_internal_check(struct pvr2_channel *chp)
943 struct pvr2_v4l2 *vp; 952 struct pvr2_v4l2 *vp;
944 vp = container_of(chp,struct pvr2_v4l2,channel); 953 vp = container_of(chp,struct pvr2_v4l2,channel);
945 if (!vp->channel.mc_head->disconnect_flag) return; 954 if (!vp->channel.mc_head->disconnect_flag) return;
955 pvr2_v4l2_dev_disassociate_parent(vp->dev_video);
956 pvr2_v4l2_dev_disassociate_parent(vp->dev_radio);
946 if (vp->vfirst) return; 957 if (vp->vfirst) return;
947 pvr2_v4l2_destroy_no_lock(vp); 958 pvr2_v4l2_destroy_no_lock(vp);
948} 959}
@@ -1250,12 +1261,13 @@ static void pvr2_v4l2_dev_init(struct pvr2_v4l2_dev *dip,
1250 struct pvr2_v4l2 *vp, 1261 struct pvr2_v4l2 *vp,
1251 int v4l_type) 1262 int v4l_type)
1252{ 1263{
1264 struct usb_device *usbdev;
1253 int mindevnum; 1265 int mindevnum;
1254 int unit_number; 1266 int unit_number;
1255 int *nr_ptr = NULL; 1267 int *nr_ptr = NULL;
1256 dip->v4lp = vp; 1268 dip->v4lp = vp;
1257 1269
1258 1270 usbdev = pvr2_hdw_get_dev(vp->channel.mc_head->hdw);
1259 dip->v4l_type = v4l_type; 1271 dip->v4l_type = v4l_type;
1260 switch (v4l_type) { 1272 switch (v4l_type) {
1261 case VFL_TYPE_GRABBER: 1273 case VFL_TYPE_GRABBER:
@@ -1296,6 +1308,7 @@ static void pvr2_v4l2_dev_init(struct pvr2_v4l2_dev *dip,
1296 if (nr_ptr && (unit_number >= 0) && (unit_number < PVR_NUM)) { 1308 if (nr_ptr && (unit_number >= 0) && (unit_number < PVR_NUM)) {
1297 mindevnum = nr_ptr[unit_number]; 1309 mindevnum = nr_ptr[unit_number];
1298 } 1310 }
1311 dip->devbase.parent = &usbdev->dev;
1299 if ((video_register_device(&dip->devbase, 1312 if ((video_register_device(&dip->devbase,
1300 dip->v4l_type, mindevnum) < 0) && 1313 dip->v4l_type, mindevnum) < 0) &&
1301 (video_register_device(&dip->devbase, 1314 (video_register_device(&dip->devbase,
diff --git a/drivers/media/video/pwc/pwc-if.c b/drivers/media/video/pwc/pwc-if.c
index f976df452a34..89b620f6db7b 100644
--- a/drivers/media/video/pwc/pwc-if.c
+++ b/drivers/media/video/pwc/pwc-if.c
@@ -68,6 +68,7 @@
68#endif 68#endif
69#include <linux/vmalloc.h> 69#include <linux/vmalloc.h>
70#include <asm/io.h> 70#include <asm/io.h>
71#include <linux/kernel.h> /* simple_strtol() */
71 72
72#include "pwc.h" 73#include "pwc.h"
73#include "pwc-kiara.h" 74#include "pwc-kiara.h"
@@ -1916,19 +1917,6 @@ disconnect_out:
1916 unlock_kernel(); 1917 unlock_kernel();
1917} 1918}
1918 1919
1919/* *grunt* We have to do atoi ourselves :-( */
1920static int pwc_atoi(const char *s)
1921{
1922 int k = 0;
1923
1924 k = 0;
1925 while (*s != '\0' && *s >= '0' && *s <= '9') {
1926 k = 10 * k + (*s - '0');
1927 s++;
1928 }
1929 return k;
1930}
1931
1932 1920
1933/* 1921/*
1934 * Initialization code & module stuff 1922 * Initialization code & module stuff
@@ -2078,13 +2066,16 @@ static int __init usb_pwc_init(void)
2078 } 2066 }
2079 else { 2067 else {
2080 /* No type or serial number specified, just a number. */ 2068 /* No type or serial number specified, just a number. */
2081 device_hint[i].device_node = pwc_atoi(s); 2069 device_hint[i].device_node =
2070 simple_strtol(s, NULL, 10);
2082 } 2071 }
2083 } 2072 }
2084 else { 2073 else {
2085 /* There's a colon, so we have at least a type and a device node */ 2074 /* There's a colon, so we have at least a type and a device node */
2086 device_hint[i].type = pwc_atoi(s); 2075 device_hint[i].type =
2087 device_hint[i].device_node = pwc_atoi(colon + 1); 2076 simple_strtol(s, NULL, 10);
2077 device_hint[i].device_node =
2078 simple_strtol(colon + 1, NULL, 10);
2088 if (*dot != '\0') { 2079 if (*dot != '\0') {
2089 /* There's a serial number as well */ 2080 /* There's a serial number as well */
2090 int k; 2081 int k;
diff --git a/drivers/media/video/rj54n1cb0c.c b/drivers/media/video/rj54n1cb0c.c
new file mode 100644
index 000000000000..373f2a30a677
--- /dev/null
+++ b/drivers/media/video/rj54n1cb0c.c
@@ -0,0 +1,1219 @@
1/*
2 * Driver for RJ54N1CB0C CMOS Image Sensor from Micron
3 *
4 * Copyright (C) 2009, Guennadi Liakhovetski <g.liakhovetski@gmx.de>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#include <linux/delay.h>
12#include <linux/i2c.h>
13#include <linux/slab.h>
14#include <linux/videodev2.h>
15
16#include <media/v4l2-subdev.h>
17#include <media/v4l2-chip-ident.h>
18#include <media/soc_camera.h>
19
20#define RJ54N1_DEV_CODE 0x0400
21#define RJ54N1_DEV_CODE2 0x0401
22#define RJ54N1_OUT_SEL 0x0403
23#define RJ54N1_XY_OUTPUT_SIZE_S_H 0x0404
24#define RJ54N1_X_OUTPUT_SIZE_S_L 0x0405
25#define RJ54N1_Y_OUTPUT_SIZE_S_L 0x0406
26#define RJ54N1_XY_OUTPUT_SIZE_P_H 0x0407
27#define RJ54N1_X_OUTPUT_SIZE_P_L 0x0408
28#define RJ54N1_Y_OUTPUT_SIZE_P_L 0x0409
29#define RJ54N1_LINE_LENGTH_PCK_S_H 0x040a
30#define RJ54N1_LINE_LENGTH_PCK_S_L 0x040b
31#define RJ54N1_LINE_LENGTH_PCK_P_H 0x040c
32#define RJ54N1_LINE_LENGTH_PCK_P_L 0x040d
33#define RJ54N1_RESIZE_N 0x040e
34#define RJ54N1_RESIZE_N_STEP 0x040f
35#define RJ54N1_RESIZE_STEP 0x0410
36#define RJ54N1_RESIZE_HOLD_H 0x0411
37#define RJ54N1_RESIZE_HOLD_L 0x0412
38#define RJ54N1_H_OBEN_OFS 0x0413
39#define RJ54N1_V_OBEN_OFS 0x0414
40#define RJ54N1_RESIZE_CONTROL 0x0415
41#define RJ54N1_INC_USE_SEL_H 0x0425
42#define RJ54N1_INC_USE_SEL_L 0x0426
43#define RJ54N1_MIRROR_STILL_MODE 0x0427
44#define RJ54N1_INIT_START 0x0428
45#define RJ54N1_SCALE_1_2_LEV 0x0429
46#define RJ54N1_SCALE_4_LEV 0x042a
47#define RJ54N1_Y_GAIN 0x04d8
48#define RJ54N1_APT_GAIN_UP 0x04fa
49#define RJ54N1_RA_SEL_UL 0x0530
50#define RJ54N1_BYTE_SWAP 0x0531
51#define RJ54N1_OUT_SIGPO 0x053b
52#define RJ54N1_FRAME_LENGTH_S_H 0x0595
53#define RJ54N1_FRAME_LENGTH_S_L 0x0596
54#define RJ54N1_FRAME_LENGTH_P_H 0x0597
55#define RJ54N1_FRAME_LENGTH_P_L 0x0598
56#define RJ54N1_IOC 0x05ef
57#define RJ54N1_TG_BYPASS 0x0700
58#define RJ54N1_PLL_L 0x0701
59#define RJ54N1_PLL_N 0x0702
60#define RJ54N1_PLL_EN 0x0704
61#define RJ54N1_RATIO_TG 0x0706
62#define RJ54N1_RATIO_T 0x0707
63#define RJ54N1_RATIO_R 0x0708
64#define RJ54N1_RAMP_TGCLK_EN 0x0709
65#define RJ54N1_OCLK_DSP 0x0710
66#define RJ54N1_RATIO_OP 0x0711
67#define RJ54N1_RATIO_O 0x0712
68#define RJ54N1_OCLK_SEL_EN 0x0713
69#define RJ54N1_CLK_RST 0x0717
70#define RJ54N1_RESET_STANDBY 0x0718
71
72#define E_EXCLK (1 << 7)
73#define SOFT_STDBY (1 << 4)
74#define SEN_RSTX (1 << 2)
75#define TG_RSTX (1 << 1)
76#define DSP_RSTX (1 << 0)
77
78#define RESIZE_HOLD_SEL (1 << 2)
79#define RESIZE_GO (1 << 1)
80
81#define RJ54N1_COLUMN_SKIP 0
82#define RJ54N1_ROW_SKIP 0
83#define RJ54N1_MAX_WIDTH 1600
84#define RJ54N1_MAX_HEIGHT 1200
85
86/* I2C addresses: 0x50, 0x51, 0x60, 0x61 */
87
88static const struct soc_camera_data_format rj54n1_colour_formats[] = {
89 {
90 .name = "YUYV",
91 .depth = 16,
92 .fourcc = V4L2_PIX_FMT_YUYV,
93 .colorspace = V4L2_COLORSPACE_JPEG,
94 }, {
95 .name = "RGB565",
96 .depth = 16,
97 .fourcc = V4L2_PIX_FMT_RGB565,
98 .colorspace = V4L2_COLORSPACE_SRGB,
99 }
100};
101
102struct rj54n1_clock_div {
103 u8 ratio_tg;
104 u8 ratio_t;
105 u8 ratio_r;
106 u8 ratio_op;
107 u8 ratio_o;
108};
109
110struct rj54n1 {
111 struct v4l2_subdev subdev;
112 struct v4l2_rect rect; /* Sensor window */
113 unsigned short width; /* Output window */
114 unsigned short height;
115 unsigned short resize; /* Sensor * 1024 / resize = Output */
116 struct rj54n1_clock_div clk_div;
117 u32 fourcc;
118 unsigned short scale;
119 u8 bank;
120};
121
122struct rj54n1_reg_val {
123 u16 reg;
124 u8 val;
125};
126
127const static struct rj54n1_reg_val bank_4[] = {
128 {0x417, 0},
129 {0x42c, 0},
130 {0x42d, 0xf0},
131 {0x42e, 0},
132 {0x42f, 0x50},
133 {0x430, 0xf5},
134 {0x431, 0x16},
135 {0x432, 0x20},
136 {0x433, 0},
137 {0x434, 0xc8},
138 {0x43c, 8},
139 {0x43e, 0x90},
140 {0x445, 0x83},
141 {0x4ba, 0x58},
142 {0x4bb, 4},
143 {0x4bc, 0x20},
144 {0x4db, 4},
145 {0x4fe, 2},
146};
147
148const static struct rj54n1_reg_val bank_5[] = {
149 {0x514, 0},
150 {0x516, 0},
151 {0x518, 0},
152 {0x51a, 0},
153 {0x51d, 0xff},
154 {0x56f, 0x28},
155 {0x575, 0x40},
156 {0x5bc, 0x48},
157 {0x5c1, 6},
158 {0x5e5, 0x11},
159 {0x5e6, 0x43},
160 {0x5e7, 0x33},
161 {0x5e8, 0x21},
162 {0x5e9, 0x30},
163 {0x5ea, 0x0},
164 {0x5eb, 0xa5},
165 {0x5ec, 0xff},
166 {0x5fe, 2},
167};
168
169const static struct rj54n1_reg_val bank_7[] = {
170 {0x70a, 0},
171 {0x714, 0xff},
172 {0x715, 0xff},
173 {0x716, 0x1f},
174 {0x7FE, 0x02},
175};
176
177const static struct rj54n1_reg_val bank_8[] = {
178 {0x800, 0x00},
179 {0x801, 0x01},
180 {0x802, 0x61},
181 {0x805, 0x00},
182 {0x806, 0x00},
183 {0x807, 0x00},
184 {0x808, 0x00},
185 {0x809, 0x01},
186 {0x80A, 0x61},
187 {0x80B, 0x00},
188 {0x80C, 0x01},
189 {0x80D, 0x00},
190 {0x80E, 0x00},
191 {0x80F, 0x00},
192 {0x810, 0x00},
193 {0x811, 0x01},
194 {0x812, 0x61},
195 {0x813, 0x00},
196 {0x814, 0x11},
197 {0x815, 0x00},
198 {0x816, 0x41},
199 {0x817, 0x00},
200 {0x818, 0x51},
201 {0x819, 0x01},
202 {0x81A, 0x1F},
203 {0x81B, 0x00},
204 {0x81C, 0x01},
205 {0x81D, 0x00},
206 {0x81E, 0x11},
207 {0x81F, 0x00},
208 {0x820, 0x41},
209 {0x821, 0x00},
210 {0x822, 0x51},
211 {0x823, 0x00},
212 {0x824, 0x00},
213 {0x825, 0x00},
214 {0x826, 0x47},
215 {0x827, 0x01},
216 {0x828, 0x4F},
217 {0x829, 0x00},
218 {0x82A, 0x00},
219 {0x82B, 0x00},
220 {0x82C, 0x30},
221 {0x82D, 0x00},
222 {0x82E, 0x40},
223 {0x82F, 0x00},
224 {0x830, 0xB3},
225 {0x831, 0x00},
226 {0x832, 0xE3},
227 {0x833, 0x00},
228 {0x834, 0x00},
229 {0x835, 0x00},
230 {0x836, 0x00},
231 {0x837, 0x00},
232 {0x838, 0x00},
233 {0x839, 0x01},
234 {0x83A, 0x61},
235 {0x83B, 0x00},
236 {0x83C, 0x01},
237 {0x83D, 0x00},
238 {0x83E, 0x00},
239 {0x83F, 0x00},
240 {0x840, 0x00},
241 {0x841, 0x01},
242 {0x842, 0x61},
243 {0x843, 0x00},
244 {0x844, 0x1D},
245 {0x845, 0x00},
246 {0x846, 0x00},
247 {0x847, 0x00},
248 {0x848, 0x00},
249 {0x849, 0x01},
250 {0x84A, 0x1F},
251 {0x84B, 0x00},
252 {0x84C, 0x05},
253 {0x84D, 0x00},
254 {0x84E, 0x19},
255 {0x84F, 0x01},
256 {0x850, 0x21},
257 {0x851, 0x01},
258 {0x852, 0x5D},
259 {0x853, 0x00},
260 {0x854, 0x00},
261 {0x855, 0x00},
262 {0x856, 0x19},
263 {0x857, 0x01},
264 {0x858, 0x21},
265 {0x859, 0x00},
266 {0x85A, 0x00},
267 {0x85B, 0x00},
268 {0x85C, 0x00},
269 {0x85D, 0x00},
270 {0x85E, 0x00},
271 {0x85F, 0x00},
272 {0x860, 0xB3},
273 {0x861, 0x00},
274 {0x862, 0xE3},
275 {0x863, 0x00},
276 {0x864, 0x00},
277 {0x865, 0x00},
278 {0x866, 0x00},
279 {0x867, 0x00},
280 {0x868, 0x00},
281 {0x869, 0xE2},
282 {0x86A, 0x00},
283 {0x86B, 0x01},
284 {0x86C, 0x06},
285 {0x86D, 0x00},
286 {0x86E, 0x00},
287 {0x86F, 0x00},
288 {0x870, 0x60},
289 {0x871, 0x8C},
290 {0x872, 0x10},
291 {0x873, 0x00},
292 {0x874, 0xE0},
293 {0x875, 0x00},
294 {0x876, 0x27},
295 {0x877, 0x01},
296 {0x878, 0x00},
297 {0x879, 0x00},
298 {0x87A, 0x00},
299 {0x87B, 0x03},
300 {0x87C, 0x00},
301 {0x87D, 0x00},
302 {0x87E, 0x00},
303 {0x87F, 0x00},
304 {0x880, 0x00},
305 {0x881, 0x00},
306 {0x882, 0x00},
307 {0x883, 0x00},
308 {0x884, 0x00},
309 {0x885, 0x00},
310 {0x886, 0xF8},
311 {0x887, 0x00},
312 {0x888, 0x03},
313 {0x889, 0x00},
314 {0x88A, 0x64},
315 {0x88B, 0x00},
316 {0x88C, 0x03},
317 {0x88D, 0x00},
318 {0x88E, 0xB1},
319 {0x88F, 0x00},
320 {0x890, 0x03},
321 {0x891, 0x01},
322 {0x892, 0x1D},
323 {0x893, 0x00},
324 {0x894, 0x03},
325 {0x895, 0x01},
326 {0x896, 0x4B},
327 {0x897, 0x00},
328 {0x898, 0xE5},
329 {0x899, 0x00},
330 {0x89A, 0x01},
331 {0x89B, 0x00},
332 {0x89C, 0x01},
333 {0x89D, 0x04},
334 {0x89E, 0xC8},
335 {0x89F, 0x00},
336 {0x8A0, 0x01},
337 {0x8A1, 0x01},
338 {0x8A2, 0x61},
339 {0x8A3, 0x00},
340 {0x8A4, 0x01},
341 {0x8A5, 0x00},
342 {0x8A6, 0x00},
343 {0x8A7, 0x00},
344 {0x8A8, 0x00},
345 {0x8A9, 0x00},
346 {0x8AA, 0x7F},
347 {0x8AB, 0x03},
348 {0x8AC, 0x00},
349 {0x8AD, 0x00},
350 {0x8AE, 0x00},
351 {0x8AF, 0x00},
352 {0x8B0, 0x00},
353 {0x8B1, 0x00},
354 {0x8B6, 0x00},
355 {0x8B7, 0x01},
356 {0x8B8, 0x00},
357 {0x8B9, 0x00},
358 {0x8BA, 0x02},
359 {0x8BB, 0x00},
360 {0x8BC, 0xFF},
361 {0x8BD, 0x00},
362 {0x8FE, 0x02},
363};
364
365const static struct rj54n1_reg_val bank_10[] = {
366 {0x10bf, 0x69}
367};
368
369/* Clock dividers - these are default register values, divider = register + 1 */
370const static struct rj54n1_clock_div clk_div = {
371 .ratio_tg = 3 /* default: 5 */,
372 .ratio_t = 4 /* default: 1 */,
373 .ratio_r = 4 /* default: 0 */,
374 .ratio_op = 1 /* default: 5 */,
375 .ratio_o = 9 /* default: 0 */,
376};
377
378static struct rj54n1 *to_rj54n1(const struct i2c_client *client)
379{
380 return container_of(i2c_get_clientdata(client), struct rj54n1, subdev);
381}
382
383static int reg_read(struct i2c_client *client, const u16 reg)
384{
385 struct rj54n1 *rj54n1 = to_rj54n1(client);
386 int ret;
387
388 /* set bank */
389 if (rj54n1->bank != reg >> 8) {
390 dev_dbg(&client->dev, "[0x%x] = 0x%x\n", 0xff, reg >> 8);
391 ret = i2c_smbus_write_byte_data(client, 0xff, reg >> 8);
392 if (ret < 0)
393 return ret;
394 rj54n1->bank = reg >> 8;
395 }
396 return i2c_smbus_read_byte_data(client, reg & 0xff);
397}
398
399static int reg_write(struct i2c_client *client, const u16 reg,
400 const u8 data)
401{
402 struct rj54n1 *rj54n1 = to_rj54n1(client);
403 int ret;
404
405 /* set bank */
406 if (rj54n1->bank != reg >> 8) {
407 dev_dbg(&client->dev, "[0x%x] = 0x%x\n", 0xff, reg >> 8);
408 ret = i2c_smbus_write_byte_data(client, 0xff, reg >> 8);
409 if (ret < 0)
410 return ret;
411 rj54n1->bank = reg >> 8;
412 }
413 dev_dbg(&client->dev, "[0x%x] = 0x%x\n", reg & 0xff, data);
414 return i2c_smbus_write_byte_data(client, reg & 0xff, data);
415}
416
417static int reg_set(struct i2c_client *client, const u16 reg,
418 const u8 data, const u8 mask)
419{
420 int ret;
421
422 ret = reg_read(client, reg);
423 if (ret < 0)
424 return ret;
425 return reg_write(client, reg, (ret & ~mask) | (data & mask));
426}
427
428static int reg_write_multiple(struct i2c_client *client,
429 const struct rj54n1_reg_val *rv, const int n)
430{
431 int i, ret;
432
433 for (i = 0; i < n; i++) {
434 ret = reg_write(client, rv->reg, rv->val);
435 if (ret < 0)
436 return ret;
437 rv++;
438 }
439
440 return 0;
441}
442
443static int rj54n1_s_stream(struct v4l2_subdev *sd, int enable)
444{
445 /* TODO: start / stop streaming */
446 return 0;
447}
448
449static int rj54n1_set_bus_param(struct soc_camera_device *icd,
450 unsigned long flags)
451{
452 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
453 struct i2c_client *client = sd->priv;
454 /* Figures 2.5-1 to 2.5-3 - default falling pixclk edge */
455
456 if (flags & SOCAM_PCLK_SAMPLE_RISING)
457 return reg_write(client, RJ54N1_OUT_SIGPO, 1 << 4);
458 else
459 return reg_write(client, RJ54N1_OUT_SIGPO, 0);
460}
461
462static unsigned long rj54n1_query_bus_param(struct soc_camera_device *icd)
463{
464 struct soc_camera_link *icl = to_soc_camera_link(icd);
465 const unsigned long flags =
466 SOCAM_PCLK_SAMPLE_RISING | SOCAM_PCLK_SAMPLE_FALLING |
467 SOCAM_MASTER | SOCAM_DATAWIDTH_8 |
468 SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_HIGH |
469 SOCAM_DATA_ACTIVE_HIGH;
470
471 return soc_camera_apply_sensor_flags(icl, flags);
472}
473
474static int rj54n1_set_rect(struct i2c_client *client,
475 u16 reg_x, u16 reg_y, u16 reg_xy,
476 u32 width, u32 height)
477{
478 int ret;
479
480 ret = reg_write(client, reg_xy,
481 ((width >> 4) & 0x70) |
482 ((height >> 8) & 7));
483
484 if (!ret)
485 ret = reg_write(client, reg_x, width & 0xff);
486 if (!ret)
487 ret = reg_write(client, reg_y, height & 0xff);
488
489 return ret;
490}
491
492/*
493 * Some commands, specifically certain initialisation sequences, require
494 * a commit operation.
495 */
496static int rj54n1_commit(struct i2c_client *client)
497{
498 int ret = reg_write(client, RJ54N1_INIT_START, 1);
499 msleep(10);
500 if (!ret)
501 ret = reg_write(client, RJ54N1_INIT_START, 0);
502 return ret;
503}
504
505static int rj54n1_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
506{
507 struct i2c_client *client = sd->priv;
508 struct rj54n1 *rj54n1 = to_rj54n1(client);
509
510 a->c = rj54n1->rect;
511 a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
512
513 return 0;
514}
515
516static int rj54n1_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
517{
518 a->bounds.left = RJ54N1_COLUMN_SKIP;
519 a->bounds.top = RJ54N1_ROW_SKIP;
520 a->bounds.width = RJ54N1_MAX_WIDTH;
521 a->bounds.height = RJ54N1_MAX_HEIGHT;
522 a->defrect = a->bounds;
523 a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
524 a->pixelaspect.numerator = 1;
525 a->pixelaspect.denominator = 1;
526
527 return 0;
528}
529
530static int rj54n1_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
531{
532 struct i2c_client *client = sd->priv;
533 struct rj54n1 *rj54n1 = to_rj54n1(client);
534 struct v4l2_pix_format *pix = &f->fmt.pix;
535
536 pix->pixelformat = rj54n1->fourcc;
537 pix->field = V4L2_FIELD_NONE;
538 pix->width = rj54n1->width;
539 pix->height = rj54n1->height;
540
541 return 0;
542}
543
544/*
545 * The actual geometry configuration routine. It scales the input window into
546 * the output one, updates the window sizes and returns an error or the resize
547 * coefficient on success. Note: we only use the "Fixed Scaling" on this camera.
548 */
549static int rj54n1_sensor_scale(struct v4l2_subdev *sd, u32 *in_w, u32 *in_h,
550 u32 *out_w, u32 *out_h)
551{
552 struct i2c_client *client = sd->priv;
553 unsigned int skip, resize, input_w = *in_w, input_h = *in_h,
554 output_w = *out_w, output_h = *out_h;
555 u16 inc_sel;
556 int ret;
557
558 ret = rj54n1_set_rect(client, RJ54N1_X_OUTPUT_SIZE_S_L,
559 RJ54N1_Y_OUTPUT_SIZE_S_L,
560 RJ54N1_XY_OUTPUT_SIZE_S_H, output_w, output_h);
561 if (!ret)
562 ret = rj54n1_set_rect(client, RJ54N1_X_OUTPUT_SIZE_P_L,
563 RJ54N1_Y_OUTPUT_SIZE_P_L,
564 RJ54N1_XY_OUTPUT_SIZE_P_H, output_w, output_h);
565
566 if (ret < 0)
567 return ret;
568
569 if (output_w > input_w || output_h > input_h) {
570 input_w = output_w;
571 input_h = output_h;
572
573 resize = 1024;
574 } else {
575 unsigned int resize_x, resize_y;
576 resize_x = input_w * 1024 / output_w;
577 resize_y = input_h * 1024 / output_h;
578
579 resize = min(resize_x, resize_y);
580
581 /* Prohibited value ranges */
582 switch (resize) {
583 case 2040 ... 2047:
584 resize = 2039;
585 break;
586 case 4080 ... 4095:
587 resize = 4079;
588 break;
589 case 8160 ... 8191:
590 resize = 8159;
591 break;
592 case 16320 ... 16383:
593 resize = 16319;
594 }
595
596 input_w = output_w * resize / 1024;
597 input_h = output_h * resize / 1024;
598 }
599
600 /* Set scaling */
601 ret = reg_write(client, RJ54N1_RESIZE_HOLD_L, resize & 0xff);
602 if (!ret)
603 ret = reg_write(client, RJ54N1_RESIZE_HOLD_H, resize >> 8);
604
605 if (ret < 0)
606 return ret;
607
608 /*
609 * Configure a skipping bitmask. The sensor will select a skipping value
610 * among set bits automatically.
611 */
612 skip = min(resize / 1024, (unsigned)15);
613 inc_sel = 1 << skip;
614
615 if (inc_sel <= 2)
616 inc_sel = 0xc;
617 else if (resize & 1023 && skip < 15)
618 inc_sel |= 1 << (skip + 1);
619
620 ret = reg_write(client, RJ54N1_INC_USE_SEL_L, inc_sel & 0xfc);
621 if (!ret)
622 ret = reg_write(client, RJ54N1_INC_USE_SEL_H, inc_sel >> 8);
623
624 /* Start resizing */
625 if (!ret)
626 ret = reg_write(client, RJ54N1_RESIZE_CONTROL,
627 RESIZE_HOLD_SEL | RESIZE_GO | 1);
628
629 if (ret < 0)
630 return ret;
631
632 dev_dbg(&client->dev, "resize %u, skip %u\n", resize, skip);
633
634 /* Constant taken from manufacturer's example */
635 msleep(230);
636
637 ret = reg_write(client, RJ54N1_RESIZE_CONTROL, RESIZE_HOLD_SEL | 1);
638 if (ret < 0)
639 return ret;
640
641 *in_w = input_w;
642 *in_h = input_h;
643 *out_w = output_w;
644 *out_h = output_h;
645
646 return resize;
647}
648
649static int rj54n1_set_clock(struct i2c_client *client)
650{
651 struct rj54n1 *rj54n1 = to_rj54n1(client);
652 int ret;
653
654 /* Enable external clock */
655 ret = reg_write(client, RJ54N1_RESET_STANDBY, E_EXCLK | SOFT_STDBY);
656 /* Leave stand-by */
657 if (!ret)
658 ret = reg_write(client, RJ54N1_RESET_STANDBY, E_EXCLK);
659
660 if (!ret)
661 ret = reg_write(client, RJ54N1_PLL_L, 2);
662 if (!ret)
663 ret = reg_write(client, RJ54N1_PLL_N, 0x31);
664
665 /* TGCLK dividers */
666 if (!ret)
667 ret = reg_write(client, RJ54N1_RATIO_TG,
668 rj54n1->clk_div.ratio_tg);
669 if (!ret)
670 ret = reg_write(client, RJ54N1_RATIO_T,
671 rj54n1->clk_div.ratio_t);
672 if (!ret)
673 ret = reg_write(client, RJ54N1_RATIO_R,
674 rj54n1->clk_div.ratio_r);
675
676 /* Enable TGCLK & RAMP */
677 if (!ret)
678 ret = reg_write(client, RJ54N1_RAMP_TGCLK_EN, 3);
679
680 /* Disable clock output */
681 if (!ret)
682 ret = reg_write(client, RJ54N1_OCLK_DSP, 0);
683
684 /* Set divisors */
685 if (!ret)
686 ret = reg_write(client, RJ54N1_RATIO_OP,
687 rj54n1->clk_div.ratio_op);
688 if (!ret)
689 ret = reg_write(client, RJ54N1_RATIO_O,
690 rj54n1->clk_div.ratio_o);
691
692 /* Enable OCLK */
693 if (!ret)
694 ret = reg_write(client, RJ54N1_OCLK_SEL_EN, 1);
695
696 /* Use PLL for Timing Generator, write 2 to reserved bits */
697 if (!ret)
698 ret = reg_write(client, RJ54N1_TG_BYPASS, 2);
699
700 /* Take sensor out of reset */
701 if (!ret)
702 ret = reg_write(client, RJ54N1_RESET_STANDBY,
703 E_EXCLK | SEN_RSTX);
704 /* Enable PLL */
705 if (!ret)
706 ret = reg_write(client, RJ54N1_PLL_EN, 1);
707
708 /* Wait for PLL to stabilise */
709 msleep(10);
710
711 /* Enable clock to frequency divider */
712 if (!ret)
713 ret = reg_write(client, RJ54N1_CLK_RST, 1);
714
715 if (!ret)
716 ret = reg_read(client, RJ54N1_CLK_RST);
717 if (ret != 1) {
718 dev_err(&client->dev,
719 "Resetting RJ54N1CB0C clock failed: %d!\n", ret);
720 return -EIO;
721 }
722 /* Start the PLL */
723 ret = reg_set(client, RJ54N1_OCLK_DSP, 1, 1);
724
725 /* Enable OCLK */
726 if (!ret)
727 ret = reg_write(client, RJ54N1_OCLK_SEL_EN, 1);
728
729 return ret;
730}
731
732static int rj54n1_reg_init(struct i2c_client *client)
733{
734 int ret = rj54n1_set_clock(client);
735
736 if (!ret)
737 ret = reg_write_multiple(client, bank_7, ARRAY_SIZE(bank_7));
738 if (!ret)
739 ret = reg_write_multiple(client, bank_10, ARRAY_SIZE(bank_10));
740
741 /* Set binning divisors */
742 if (!ret)
743 ret = reg_write(client, RJ54N1_SCALE_1_2_LEV, 3 | (7 << 4));
744 if (!ret)
745 ret = reg_write(client, RJ54N1_SCALE_4_LEV, 0xf);
746
747 /* Switch to fixed resize mode */
748 if (!ret)
749 ret = reg_write(client, RJ54N1_RESIZE_CONTROL,
750 RESIZE_HOLD_SEL | 1);
751
752 /* Set gain */
753 if (!ret)
754 ret = reg_write(client, RJ54N1_Y_GAIN, 0x84);
755
756 /* Mirror the image back: default is upside down and left-to-right... */
757 if (!ret)
758 ret = reg_set(client, RJ54N1_MIRROR_STILL_MODE, 3, 3);
759
760 if (!ret)
761 ret = reg_write_multiple(client, bank_4, ARRAY_SIZE(bank_4));
762 if (!ret)
763 ret = reg_write_multiple(client, bank_5, ARRAY_SIZE(bank_5));
764 if (!ret)
765 ret = reg_write_multiple(client, bank_8, ARRAY_SIZE(bank_8));
766
767 if (!ret)
768 ret = reg_write(client, RJ54N1_RESET_STANDBY,
769 E_EXCLK | DSP_RSTX | SEN_RSTX);
770
771 /* Commit init */
772 if (!ret)
773 ret = rj54n1_commit(client);
774
775 /* Take DSP, TG, sensor out of reset */
776 if (!ret)
777 ret = reg_write(client, RJ54N1_RESET_STANDBY,
778 E_EXCLK | DSP_RSTX | TG_RSTX | SEN_RSTX);
779
780 if (!ret)
781 ret = reg_write(client, 0x7fe, 2);
782
783 /* Constant taken from manufacturer's example */
784 msleep(700);
785
786 return ret;
787}
788
789/* FIXME: streaming output only up to 800x600 is functional */
790static int rj54n1_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
791{
792 struct v4l2_pix_format *pix = &f->fmt.pix;
793
794 pix->field = V4L2_FIELD_NONE;
795
796 if (pix->width > 800)
797 pix->width = 800;
798 if (pix->height > 600)
799 pix->height = 600;
800
801 return 0;
802}
803
804static int rj54n1_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
805{
806 struct i2c_client *client = sd->priv;
807 struct rj54n1 *rj54n1 = to_rj54n1(client);
808 struct v4l2_pix_format *pix = &f->fmt.pix;
809 unsigned int output_w, output_h,
810 input_w = rj54n1->rect.width, input_h = rj54n1->rect.height;
811 int ret;
812
813 /*
814 * The host driver can call us without .try_fmt(), so, we have to take
815 * care ourseleves
816 */
817 ret = rj54n1_try_fmt(sd, f);
818
819 /*
820 * Verify if the sensor has just been powered on. TODO: replace this
821 * with proper PM, when a suitable API is available.
822 */
823 if (!ret)
824 ret = reg_read(client, RJ54N1_RESET_STANDBY);
825 if (ret < 0)
826 return ret;
827
828 if (!(ret & E_EXCLK)) {
829 ret = rj54n1_reg_init(client);
830 if (ret < 0)
831 return ret;
832 }
833
834 /* RA_SEL_UL is only relevant for raw modes, ignored otherwise. */
835 switch (pix->pixelformat) {
836 case V4L2_PIX_FMT_YUYV:
837 ret = reg_write(client, RJ54N1_OUT_SEL, 0);
838 if (!ret)
839 ret = reg_set(client, RJ54N1_BYTE_SWAP, 8, 8);
840 break;
841 case V4L2_PIX_FMT_RGB565:
842 ret = reg_write(client, RJ54N1_OUT_SEL, 0x11);
843 if (!ret)
844 ret = reg_set(client, RJ54N1_BYTE_SWAP, 8, 8);
845 break;
846 default:
847 ret = -EINVAL;
848 }
849
850 if (ret < 0)
851 return ret;
852
853 /* Supported scales 1:1 - 1:16 */
854 if (pix->width < input_w / 16)
855 pix->width = input_w / 16;
856 if (pix->height < input_h / 16)
857 pix->height = input_h / 16;
858
859 output_w = pix->width;
860 output_h = pix->height;
861
862 ret = rj54n1_sensor_scale(sd, &input_w, &input_h, &output_w, &output_h);
863 if (ret < 0)
864 return ret;
865
866 rj54n1->fourcc = pix->pixelformat;
867 rj54n1->resize = ret;
868 rj54n1->rect.width = input_w;
869 rj54n1->rect.height = input_h;
870 rj54n1->width = output_w;
871 rj54n1->height = output_h;
872
873 pix->width = output_w;
874 pix->height = output_h;
875 pix->field = V4L2_FIELD_NONE;
876
877 return ret;
878}
879
880static int rj54n1_g_chip_ident(struct v4l2_subdev *sd,
881 struct v4l2_dbg_chip_ident *id)
882{
883 struct i2c_client *client = sd->priv;
884
885 if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
886 return -EINVAL;
887
888 if (id->match.addr != client->addr)
889 return -ENODEV;
890
891 id->ident = V4L2_IDENT_RJ54N1CB0C;
892 id->revision = 0;
893
894 return 0;
895}
896
897#ifdef CONFIG_VIDEO_ADV_DEBUG
898static int rj54n1_g_register(struct v4l2_subdev *sd,
899 struct v4l2_dbg_register *reg)
900{
901 struct i2c_client *client = sd->priv;
902
903 if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR ||
904 reg->reg < 0x400 || reg->reg > 0x1fff)
905 /* Registers > 0x0800 are only available from Sharp support */
906 return -EINVAL;
907
908 if (reg->match.addr != client->addr)
909 return -ENODEV;
910
911 reg->size = 1;
912 reg->val = reg_read(client, reg->reg);
913
914 if (reg->val > 0xff)
915 return -EIO;
916
917 return 0;
918}
919
920static int rj54n1_s_register(struct v4l2_subdev *sd,
921 struct v4l2_dbg_register *reg)
922{
923 struct i2c_client *client = sd->priv;
924
925 if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR ||
926 reg->reg < 0x400 || reg->reg > 0x1fff)
927 /* Registers >= 0x0800 are only available from Sharp support */
928 return -EINVAL;
929
930 if (reg->match.addr != client->addr)
931 return -ENODEV;
932
933 if (reg_write(client, reg->reg, reg->val) < 0)
934 return -EIO;
935
936 return 0;
937}
938#endif
939
940static const struct v4l2_queryctrl rj54n1_controls[] = {
941 {
942 .id = V4L2_CID_VFLIP,
943 .type = V4L2_CTRL_TYPE_BOOLEAN,
944 .name = "Flip Vertically",
945 .minimum = 0,
946 .maximum = 1,
947 .step = 1,
948 .default_value = 0,
949 }, {
950 .id = V4L2_CID_HFLIP,
951 .type = V4L2_CTRL_TYPE_BOOLEAN,
952 .name = "Flip Horizontally",
953 .minimum = 0,
954 .maximum = 1,
955 .step = 1,
956 .default_value = 0,
957 }, {
958 .id = V4L2_CID_GAIN,
959 .type = V4L2_CTRL_TYPE_INTEGER,
960 .name = "Gain",
961 .minimum = 0,
962 .maximum = 127,
963 .step = 1,
964 .default_value = 66,
965 .flags = V4L2_CTRL_FLAG_SLIDER,
966 },
967};
968
969static struct soc_camera_ops rj54n1_ops = {
970 .set_bus_param = rj54n1_set_bus_param,
971 .query_bus_param = rj54n1_query_bus_param,
972 .controls = rj54n1_controls,
973 .num_controls = ARRAY_SIZE(rj54n1_controls),
974};
975
976static int rj54n1_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
977{
978 struct i2c_client *client = sd->priv;
979 int data;
980
981 switch (ctrl->id) {
982 case V4L2_CID_VFLIP:
983 data = reg_read(client, RJ54N1_MIRROR_STILL_MODE);
984 if (data < 0)
985 return -EIO;
986 ctrl->value = !(data & 1);
987 break;
988 case V4L2_CID_HFLIP:
989 data = reg_read(client, RJ54N1_MIRROR_STILL_MODE);
990 if (data < 0)
991 return -EIO;
992 ctrl->value = !(data & 2);
993 break;
994 case V4L2_CID_GAIN:
995 data = reg_read(client, RJ54N1_Y_GAIN);
996 if (data < 0)
997 return -EIO;
998
999 ctrl->value = data / 2;
1000 break;
1001 }
1002
1003 return 0;
1004}
1005
1006static int rj54n1_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
1007{
1008 int data;
1009 struct i2c_client *client = sd->priv;
1010 const struct v4l2_queryctrl *qctrl;
1011
1012 qctrl = soc_camera_find_qctrl(&rj54n1_ops, ctrl->id);
1013 if (!qctrl)
1014 return -EINVAL;
1015
1016 switch (ctrl->id) {
1017 case V4L2_CID_VFLIP:
1018 if (ctrl->value)
1019 data = reg_set(client, RJ54N1_MIRROR_STILL_MODE, 0, 1);
1020 else
1021 data = reg_set(client, RJ54N1_MIRROR_STILL_MODE, 1, 1);
1022 if (data < 0)
1023 return -EIO;
1024 break;
1025 case V4L2_CID_HFLIP:
1026 if (ctrl->value)
1027 data = reg_set(client, RJ54N1_MIRROR_STILL_MODE, 0, 2);
1028 else
1029 data = reg_set(client, RJ54N1_MIRROR_STILL_MODE, 2, 2);
1030 if (data < 0)
1031 return -EIO;
1032 break;
1033 case V4L2_CID_GAIN:
1034 if (ctrl->value > qctrl->maximum ||
1035 ctrl->value < qctrl->minimum)
1036 return -EINVAL;
1037 else if (reg_write(client, RJ54N1_Y_GAIN, ctrl->value * 2) < 0)
1038 return -EIO;
1039 break;
1040 }
1041
1042 return 0;
1043}
1044
1045static struct v4l2_subdev_core_ops rj54n1_subdev_core_ops = {
1046 .g_ctrl = rj54n1_g_ctrl,
1047 .s_ctrl = rj54n1_s_ctrl,
1048 .g_chip_ident = rj54n1_g_chip_ident,
1049#ifdef CONFIG_VIDEO_ADV_DEBUG
1050 .g_register = rj54n1_g_register,
1051 .s_register = rj54n1_s_register,
1052#endif
1053};
1054
1055static struct v4l2_subdev_video_ops rj54n1_subdev_video_ops = {
1056 .s_stream = rj54n1_s_stream,
1057 .s_fmt = rj54n1_s_fmt,
1058 .g_fmt = rj54n1_g_fmt,
1059 .try_fmt = rj54n1_try_fmt,
1060 .g_crop = rj54n1_g_crop,
1061 .cropcap = rj54n1_cropcap,
1062};
1063
1064static struct v4l2_subdev_ops rj54n1_subdev_ops = {
1065 .core = &rj54n1_subdev_core_ops,
1066 .video = &rj54n1_subdev_video_ops,
1067};
1068
1069static int rj54n1_pin_config(struct i2c_client *client)
1070{
1071 /*
1072 * Experimentally found out IOCTRL wired to 0. TODO: add to platform
1073 * data: 0 or 1 << 7.
1074 */
1075 return reg_write(client, RJ54N1_IOC, 0);
1076}
1077
1078/*
1079 * Interface active, can use i2c. If it fails, it can indeed mean, that
1080 * this wasn't our capture interface, so, we wait for the right one
1081 */
1082static int rj54n1_video_probe(struct soc_camera_device *icd,
1083 struct i2c_client *client)
1084{
1085 int data1, data2;
1086 int ret;
1087
1088 /* This could be a BUG_ON() or a WARN_ON(), or remove it completely */
1089 if (!icd->dev.parent ||
1090 to_soc_camera_host(icd->dev.parent)->nr != icd->iface)
1091 return -ENODEV;
1092
1093 /* Read out the chip version register */
1094 data1 = reg_read(client, RJ54N1_DEV_CODE);
1095 data2 = reg_read(client, RJ54N1_DEV_CODE2);
1096
1097 if (data1 != 0x51 || data2 != 0x10) {
1098 ret = -ENODEV;
1099 dev_info(&client->dev, "No RJ54N1CB0C found, read 0x%x:0x%x\n",
1100 data1, data2);
1101 goto ei2c;
1102 }
1103
1104 ret = rj54n1_pin_config(client);
1105 if (ret < 0)
1106 goto ei2c;
1107
1108 dev_info(&client->dev, "Detected a RJ54N1CB0C chip ID 0x%x:0x%x\n",
1109 data1, data2);
1110
1111ei2c:
1112 return ret;
1113}
1114
1115static int rj54n1_probe(struct i2c_client *client,
1116 const struct i2c_device_id *did)
1117{
1118 struct rj54n1 *rj54n1;
1119 struct soc_camera_device *icd = client->dev.platform_data;
1120 struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
1121 struct soc_camera_link *icl;
1122 int ret;
1123
1124 if (!icd) {
1125 dev_err(&client->dev, "RJ54N1CB0C: missing soc-camera data!\n");
1126 return -EINVAL;
1127 }
1128
1129 icl = to_soc_camera_link(icd);
1130 if (!icl) {
1131 dev_err(&client->dev, "RJ54N1CB0C: missing platform data!\n");
1132 return -EINVAL;
1133 }
1134
1135 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
1136 dev_warn(&adapter->dev,
1137 "I2C-Adapter doesn't support I2C_FUNC_SMBUS_BYTE\n");
1138 return -EIO;
1139 }
1140
1141 rj54n1 = kzalloc(sizeof(struct rj54n1), GFP_KERNEL);
1142 if (!rj54n1)
1143 return -ENOMEM;
1144
1145 v4l2_i2c_subdev_init(&rj54n1->subdev, client, &rj54n1_subdev_ops);
1146
1147 icd->ops = &rj54n1_ops;
1148
1149 rj54n1->clk_div = clk_div;
1150 rj54n1->rect.left = RJ54N1_COLUMN_SKIP;
1151 rj54n1->rect.top = RJ54N1_ROW_SKIP;
1152 rj54n1->rect.width = RJ54N1_MAX_WIDTH;
1153 rj54n1->rect.height = RJ54N1_MAX_HEIGHT;
1154 rj54n1->width = RJ54N1_MAX_WIDTH;
1155 rj54n1->height = RJ54N1_MAX_HEIGHT;
1156 rj54n1->fourcc = V4L2_PIX_FMT_YUYV;
1157 rj54n1->resize = 1024;
1158
1159 ret = rj54n1_video_probe(icd, client);
1160 if (ret < 0) {
1161 icd->ops = NULL;
1162 i2c_set_clientdata(client, NULL);
1163 kfree(rj54n1);
1164 return ret;
1165 }
1166
1167 icd->formats = rj54n1_colour_formats;
1168 icd->num_formats = ARRAY_SIZE(rj54n1_colour_formats);
1169
1170 return ret;
1171}
1172
1173static int rj54n1_remove(struct i2c_client *client)
1174{
1175 struct rj54n1 *rj54n1 = to_rj54n1(client);
1176 struct soc_camera_device *icd = client->dev.platform_data;
1177 struct soc_camera_link *icl = to_soc_camera_link(icd);
1178
1179 icd->ops = NULL;
1180 if (icl->free_bus)
1181 icl->free_bus(icl);
1182 i2c_set_clientdata(client, NULL);
1183 client->driver = NULL;
1184 kfree(rj54n1);
1185
1186 return 0;
1187}
1188
1189static const struct i2c_device_id rj54n1_id[] = {
1190 { "rj54n1cb0c", 0 },
1191 { }
1192};
1193MODULE_DEVICE_TABLE(i2c, rj54n1_id);
1194
1195static struct i2c_driver rj54n1_i2c_driver = {
1196 .driver = {
1197 .name = "rj54n1cb0c",
1198 },
1199 .probe = rj54n1_probe,
1200 .remove = rj54n1_remove,
1201 .id_table = rj54n1_id,
1202};
1203
1204static int __init rj54n1_mod_init(void)
1205{
1206 return i2c_add_driver(&rj54n1_i2c_driver);
1207}
1208
1209static void __exit rj54n1_mod_exit(void)
1210{
1211 i2c_del_driver(&rj54n1_i2c_driver);
1212}
1213
1214module_init(rj54n1_mod_init);
1215module_exit(rj54n1_mod_exit);
1216
1217MODULE_DESCRIPTION("Sharp RJ54N1CB0C Camera driver");
1218MODULE_AUTHOR("Guennadi Liakhovetski <g.liakhovetski@gmx.de>");
1219MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/s2255drv.c b/drivers/media/video/s2255drv.c
index 03d39266d293..41765f3c7c28 100644
--- a/drivers/media/video/s2255drv.c
+++ b/drivers/media/video/s2255drv.c
@@ -1958,7 +1958,7 @@ static int save_frame(struct s2255_dev *dev, struct s2255_pipeinfo *pipe_info)
1958 if (pdword[1] >= MAX_CHANNELS) 1958 if (pdword[1] >= MAX_CHANNELS)
1959 break; 1959 break;
1960 cc = G_chnmap[pdword[1]]; 1960 cc = G_chnmap[pdword[1]];
1961 if (!(cc >= 0 && cc < MAX_CHANNELS)) 1961 if (cc >= MAX_CHANNELS)
1962 break; 1962 break;
1963 switch (pdword[2]) { 1963 switch (pdword[2]) {
1964 case S2255_RESPONSE_SETMODE: 1964 case S2255_RESPONSE_SETMODE:
diff --git a/drivers/media/video/saa7110.c b/drivers/media/video/saa7110.c
index 5c24c993ac16..3bca744e43af 100644
--- a/drivers/media/video/saa7110.c
+++ b/drivers/media/video/saa7110.c
@@ -304,7 +304,7 @@ static int saa7110_s_routing(struct v4l2_subdev *sd,
304{ 304{
305 struct saa7110 *decoder = to_saa7110(sd); 305 struct saa7110 *decoder = to_saa7110(sd);
306 306
307 if (input < 0 || input >= SAA7110_MAX_INPUT) { 307 if (input >= SAA7110_MAX_INPUT) {
308 v4l2_dbg(1, debug, sd, "input=%d not available\n", input); 308 v4l2_dbg(1, debug, sd, "input=%d not available\n", input);
309 return -EINVAL; 309 return -EINVAL;
310 } 310 }
diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c
index 09013229d4aa..7e40d6d99dd0 100644
--- a/drivers/media/video/saa7134/saa7134-cards.c
+++ b/drivers/media/video/saa7134/saa7134-cards.c
@@ -5239,6 +5239,7 @@ struct saa7134_board saa7134_boards[] = {
5239 .radio_type = UNSET, 5239 .radio_type = UNSET,
5240 .tuner_addr = ADDR_UNSET, 5240 .tuner_addr = ADDR_UNSET,
5241 .radio_addr = ADDR_UNSET, 5241 .radio_addr = ADDR_UNSET,
5242 .mpeg = SAA7134_MPEG_DVB,
5242 .inputs = { { 5243 .inputs = { {
5243 .name = name_tv, 5244 .name = name_tv,
5244 .vmux = 2, 5245 .vmux = 2,
@@ -5279,6 +5280,46 @@ struct saa7134_board saa7134_boards[] = {
5279 .amux = TV, 5280 .amux = TV,
5280 }, 5281 },
5281 }, 5282 },
5283 [SAA7134_BOARD_ASUS_EUROPA_HYBRID] = {
5284 .name = "Asus Europa Hybrid OEM",
5285 .audio_clock = 0x00187de7,
5286 .tuner_type = TUNER_PHILIPS_TD1316,
5287 .radio_type = UNSET,
5288 .tuner_addr = 0x61,
5289 .radio_addr = ADDR_UNSET,
5290 .tda9887_conf = TDA9887_PRESENT | TDA9887_PORT1_ACTIVE,
5291 .mpeg = SAA7134_MPEG_DVB,
5292 .inputs = { {
5293 .name = name_tv,
5294 .vmux = 3,
5295 .amux = TV,
5296 .tv = 1,
5297 }, {
5298 .name = name_comp1,
5299 .vmux = 4,
5300 .amux = LINE2,
5301 }, {
5302 .name = name_svideo,
5303 .vmux = 8,
5304 .amux = LINE2,
5305 } },
5306 },
5307 [SAA7134_BOARD_LEADTEK_WINFAST_DTV1000S] = {
5308 .name = "Leadtek Winfast DTV1000S",
5309 .audio_clock = 0x00187de7,
5310 .tuner_type = TUNER_PHILIPS_TDA8290,
5311 .radio_type = UNSET,
5312 .tuner_addr = ADDR_UNSET,
5313 .radio_addr = ADDR_UNSET,
5314 .mpeg = SAA7134_MPEG_DVB,
5315 .inputs = { {
5316 .name = name_comp1,
5317 .vmux = 3,
5318 }, {
5319 .name = name_svideo,
5320 .vmux = 8,
5321 } },
5322 },
5282 5323
5283}; 5324};
5284 5325
@@ -6418,6 +6459,18 @@ struct pci_device_id saa7134_pci_tbl[] = {
6418 .subdevice = 0x2004, 6459 .subdevice = 0x2004,
6419 .driver_data = SAA7134_BOARD_ZOLID_HYBRID_PCI, 6460 .driver_data = SAA7134_BOARD_ZOLID_HYBRID_PCI,
6420 }, { 6461 }, {
6462 .vendor = PCI_VENDOR_ID_PHILIPS,
6463 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
6464 .subvendor = 0x1043,
6465 .subdevice = 0x4847,
6466 .driver_data = SAA7134_BOARD_ASUS_EUROPA_HYBRID,
6467 }, {
6468 .vendor = PCI_VENDOR_ID_PHILIPS,
6469 .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
6470 .subvendor = 0x107d,
6471 .subdevice = 0x6655,
6472 .driver_data = SAA7134_BOARD_LEADTEK_WINFAST_DTV1000S,
6473 }, {
6421 /* --- boards without eeprom + subsystem ID --- */ 6474 /* --- boards without eeprom + subsystem ID --- */
6422 .vendor = PCI_VENDOR_ID_PHILIPS, 6475 .vendor = PCI_VENDOR_ID_PHILIPS,
6423 .device = PCI_DEVICE_ID_PHILIPS_SAA7134, 6476 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
@@ -6748,6 +6801,7 @@ int saa7134_board_init1(struct saa7134_dev *dev)
6748 case SAA7134_BOARD_KWORLD_PLUS_TV_ANALOG: 6801 case SAA7134_BOARD_KWORLD_PLUS_TV_ANALOG:
6749 case SAA7134_BOARD_AVERMEDIA_GO_007_FM_PLUS: 6802 case SAA7134_BOARD_AVERMEDIA_GO_007_FM_PLUS:
6750 case SAA7134_BOARD_ROVERMEDIA_LINK_PRO_FM: 6803 case SAA7134_BOARD_ROVERMEDIA_LINK_PRO_FM:
6804 case SAA7134_BOARD_LEADTEK_WINFAST_DTV1000S:
6751 dev->has_remote = SAA7134_REMOTE_GPIO; 6805 dev->has_remote = SAA7134_REMOTE_GPIO;
6752 break; 6806 break;
6753 case SAA7134_BOARD_FLYDVBS_LR300: 6807 case SAA7134_BOARD_FLYDVBS_LR300:
@@ -7079,6 +7133,7 @@ int saa7134_board_init2(struct saa7134_dev *dev)
7079 /* break intentionally omitted */ 7133 /* break intentionally omitted */
7080 case SAA7134_BOARD_VIDEOMATE_DVBT_300: 7134 case SAA7134_BOARD_VIDEOMATE_DVBT_300:
7081 case SAA7134_BOARD_ASUS_EUROPA2_HYBRID: 7135 case SAA7134_BOARD_ASUS_EUROPA2_HYBRID:
7136 case SAA7134_BOARD_ASUS_EUROPA_HYBRID:
7082 { 7137 {
7083 7138
7084 /* The Philips EUROPA based hybrid boards have the tuner 7139 /* The Philips EUROPA based hybrid boards have the tuner
diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c
index c673901cb2b5..0ba7f5af0fc3 100644
--- a/drivers/media/video/saa7134/saa7134-core.c
+++ b/drivers/media/video/saa7134/saa7134-core.c
@@ -1032,7 +1032,7 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
1032 saa7134_irq_video_signalchange(dev); 1032 saa7134_irq_video_signalchange(dev);
1033 1033
1034 if (TUNER_ABSENT != dev->tuner_type) 1034 if (TUNER_ABSENT != dev->tuner_type)
1035 saa_call_all(dev, tuner, s_standby); 1035 saa_call_all(dev, core, s_power, 0);
1036 1036
1037 /* register v4l devices */ 1037 /* register v4l devices */
1038 if (saa7134_no_overlay > 0) 1038 if (saa7134_no_overlay > 0)
diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/video/saa7134/saa7134-dvb.c
index a26e997a9ce6..73739d2a63dd 100644
--- a/drivers/media/video/saa7134/saa7134-dvb.c
+++ b/drivers/media/video/saa7134/saa7134-dvb.c
@@ -40,6 +40,7 @@
40#include "tda1004x.h" 40#include "tda1004x.h"
41#include "nxt200x.h" 41#include "nxt200x.h"
42#include "tuner-xc2028.h" 42#include "tuner-xc2028.h"
43#include "xc5000.h"
43 44
44#include "tda10086.h" 45#include "tda10086.h"
45#include "tda826x.h" 46#include "tda826x.h"
@@ -871,6 +872,20 @@ static struct zl10353_config behold_h6_config = {
871 .disable_i2c_gate_ctrl = 1, 872 .disable_i2c_gate_ctrl = 1,
872}; 873};
873 874
875static struct xc5000_config behold_x7_tunerconfig = {
876 .i2c_address = 0xc2>>1,
877 .if_khz = 4560,
878 .radio_input = XC5000_RADIO_FM1,
879};
880
881static struct zl10353_config behold_x7_config = {
882 .demod_address = 0x1e>>1,
883 .if2 = 45600,
884 .no_tuner = 1,
885 .parallel_ts = 1,
886 .disable_i2c_gate_ctrl = 1,
887};
888
874/* ================================================================== 889/* ==================================================================
875 * tda10086 based DVB-S cards, helper functions 890 * tda10086 based DVB-S cards, helper functions
876 */ 891 */
@@ -1030,6 +1045,32 @@ static struct tda18271_config zolid_tda18271_config = {
1030 .gate = TDA18271_GATE_ANALOG, 1045 .gate = TDA18271_GATE_ANALOG,
1031}; 1046};
1032 1047
1048static struct tda10048_config dtv1000s_tda10048_config = {
1049 .demod_address = 0x10 >> 1,
1050 .output_mode = TDA10048_PARALLEL_OUTPUT,
1051 .fwbulkwritelen = TDA10048_BULKWRITE_200,
1052 .inversion = TDA10048_INVERSION_ON,
1053 .dtv6_if_freq_khz = TDA10048_IF_3300,
1054 .dtv7_if_freq_khz = TDA10048_IF_3800,
1055 .dtv8_if_freq_khz = TDA10048_IF_4300,
1056 .clk_freq_khz = TDA10048_CLK_16000,
1057 .disable_gate_access = 1,
1058};
1059
1060static struct tda18271_std_map dtv1000s_tda18271_std_map = {
1061 .dvbt_6 = { .if_freq = 3300, .agc_mode = 3, .std = 4,
1062 .if_lvl = 1, .rfagc_top = 0x37, },
1063 .dvbt_7 = { .if_freq = 3800, .agc_mode = 3, .std = 5,
1064 .if_lvl = 1, .rfagc_top = 0x37, },
1065 .dvbt_8 = { .if_freq = 4300, .agc_mode = 3, .std = 6,
1066 .if_lvl = 1, .rfagc_top = 0x37, },
1067};
1068
1069static struct tda18271_config dtv1000s_tda18271_config = {
1070 .std_map = &dtv1000s_tda18271_std_map,
1071 .gate = TDA18271_GATE_ANALOG,
1072};
1073
1033/* ================================================================== 1074/* ==================================================================
1034 * Core code 1075 * Core code
1035 */ 1076 */
@@ -1116,6 +1157,7 @@ static int dvb_init(struct saa7134_dev *dev)
1116 break; 1157 break;
1117 case SAA7134_BOARD_PHILIPS_EUROPA: 1158 case SAA7134_BOARD_PHILIPS_EUROPA:
1118 case SAA7134_BOARD_VIDEOMATE_DVBT_300: 1159 case SAA7134_BOARD_VIDEOMATE_DVBT_300:
1160 case SAA7134_BOARD_ASUS_EUROPA_HYBRID:
1119 fe0->dvb.frontend = dvb_attach(tda10046_attach, 1161 fe0->dvb.frontend = dvb_attach(tda10046_attach,
1120 &philips_europa_config, 1162 &philips_europa_config,
1121 &dev->i2c_adap); 1163 &dev->i2c_adap);
@@ -1482,6 +1524,15 @@ static int dvb_init(struct saa7134_dev *dev)
1482 TUNER_PHILIPS_FMD1216MEX_MK3); 1524 TUNER_PHILIPS_FMD1216MEX_MK3);
1483 } 1525 }
1484 break; 1526 break;
1527 case SAA7134_BOARD_BEHOLD_X7:
1528 fe0->dvb.frontend = dvb_attach(zl10353_attach,
1529 &behold_x7_config,
1530 &dev->i2c_adap);
1531 if (fe0->dvb.frontend) {
1532 dvb_attach(xc5000_attach, fe0->dvb.frontend,
1533 &dev->i2c_adap, &behold_x7_tunerconfig);
1534 }
1535 break;
1485 case SAA7134_BOARD_AVERMEDIA_A700_PRO: 1536 case SAA7134_BOARD_AVERMEDIA_A700_PRO:
1486 case SAA7134_BOARD_AVERMEDIA_A700_HYBRID: 1537 case SAA7134_BOARD_AVERMEDIA_A700_HYBRID:
1487 /* Zarlink ZL10313 */ 1538 /* Zarlink ZL10313 */
@@ -1518,6 +1569,19 @@ static int dvb_init(struct saa7134_dev *dev)
1518 &zolid_tda18271_config); 1569 &zolid_tda18271_config);
1519 } 1570 }
1520 break; 1571 break;
1572 case SAA7134_BOARD_LEADTEK_WINFAST_DTV1000S:
1573 fe0->dvb.frontend = dvb_attach(tda10048_attach,
1574 &dtv1000s_tda10048_config,
1575 &dev->i2c_adap);
1576 if (fe0->dvb.frontend != NULL) {
1577 dvb_attach(tda829x_attach, fe0->dvb.frontend,
1578 &dev->i2c_adap, 0x4b,
1579 &tda829x_no_probe);
1580 dvb_attach(tda18271_attach, fe0->dvb.frontend,
1581 0x60, &dev->i2c_adap,
1582 &dtv1000s_tda18271_config);
1583 }
1584 break;
1521 default: 1585 default:
1522 wprintk("Huh? unknown DVB card?\n"); 1586 wprintk("Huh? unknown DVB card?\n");
1523 break; 1587 break;
@@ -1550,7 +1614,7 @@ static int dvb_init(struct saa7134_dev *dev)
1550 1614
1551 /* register everything else */ 1615 /* register everything else */
1552 ret = videobuf_dvb_register_bus(&dev->frontends, THIS_MODULE, dev, 1616 ret = videobuf_dvb_register_bus(&dev->frontends, THIS_MODULE, dev,
1553 &dev->pci->dev, adapter_nr, 0); 1617 &dev->pci->dev, adapter_nr, 0, NULL);
1554 1618
1555 /* this sequence is necessary to make the tda1004x load its firmware 1619 /* this sequence is necessary to make the tda1004x load its firmware
1556 * and to enter analog mode of hybrid boards 1620 * and to enter analog mode of hybrid boards
diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c
index a0e8c62e6ae1..744918b1cd47 100644
--- a/drivers/media/video/saa7134/saa7134-input.c
+++ b/drivers/media/video/saa7134/saa7134-input.c
@@ -102,14 +102,14 @@ static int build_key(struct saa7134_dev *dev)
102 if (data == ir->mask_keycode) 102 if (data == ir->mask_keycode)
103 ir_input_nokey(ir->dev, &ir->ir); 103 ir_input_nokey(ir->dev, &ir->ir);
104 else 104 else
105 ir_input_keydown(ir->dev, &ir->ir, data, data); 105 ir_input_keydown(ir->dev, &ir->ir, data);
106 return 0; 106 return 0;
107 } 107 }
108 108
109 if (ir->polling) { 109 if (ir->polling) {
110 if ((ir->mask_keydown && (0 != (gpio & ir->mask_keydown))) || 110 if ((ir->mask_keydown && (0 != (gpio & ir->mask_keydown))) ||
111 (ir->mask_keyup && (0 == (gpio & ir->mask_keyup)))) { 111 (ir->mask_keyup && (0 == (gpio & ir->mask_keyup)))) {
112 ir_input_keydown(ir->dev, &ir->ir, data, data); 112 ir_input_keydown(ir->dev, &ir->ir, data);
113 } else { 113 } else {
114 ir_input_nokey(ir->dev, &ir->ir); 114 ir_input_nokey(ir->dev, &ir->ir);
115 } 115 }
@@ -117,7 +117,7 @@ static int build_key(struct saa7134_dev *dev)
117 else { /* IRQ driven mode - handle key press and release in one go */ 117 else { /* IRQ driven mode - handle key press and release in one go */
118 if ((ir->mask_keydown && (0 != (gpio & ir->mask_keydown))) || 118 if ((ir->mask_keydown && (0 != (gpio & ir->mask_keydown))) ||
119 (ir->mask_keyup && (0 == (gpio & ir->mask_keyup)))) { 119 (ir->mask_keyup && (0 == (gpio & ir->mask_keyup)))) {
120 ir_input_keydown(ir->dev, &ir->ir, data, data); 120 ir_input_keydown(ir->dev, &ir->ir, data);
121 ir_input_nokey(ir->dev, &ir->ir); 121 ir_input_nokey(ir->dev, &ir->ir);
122 } 122 }
123 } 123 }
@@ -616,6 +616,12 @@ int saa7134_input_init1(struct saa7134_dev *dev)
616 mask_keycode = 0x003f00; 616 mask_keycode = 0x003f00;
617 mask_keydown = 0x040000; 617 mask_keydown = 0x040000;
618 break; 618 break;
619 case SAA7134_BOARD_LEADTEK_WINFAST_DTV1000S:
620 ir_codes = &ir_codes_winfast_table;
621 mask_keycode = 0x5f00;
622 mask_keyup = 0x020000;
623 polling = 50; /* ms */
624 break;
619 } 625 }
620 if (NULL == ir_codes) { 626 if (NULL == ir_codes) {
621 printk("%s: Oops: IR config error [card=%d]\n", 627 printk("%s: Oops: IR config error [card=%d]\n",
@@ -646,7 +652,10 @@ int saa7134_input_init1(struct saa7134_dev *dev)
646 snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0", 652 snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0",
647 pci_name(dev->pci)); 653 pci_name(dev->pci));
648 654
649 ir_input_init(input_dev, &ir->ir, ir_type, ir_codes); 655 err = ir_input_init(input_dev, &ir->ir, ir_type, ir_codes);
656 if (err < 0)
657 goto err_out_free;
658
650 input_dev->name = ir->name; 659 input_dev->name = ir->name;
651 input_dev->phys = ir->phys; 660 input_dev->phys = ir->phys;
652 input_dev->id.bustype = BUS_PCI; 661 input_dev->id.bustype = BUS_PCI;
@@ -677,6 +686,7 @@ int saa7134_input_init1(struct saa7134_dev *dev)
677 saa7134_ir_stop(dev); 686 saa7134_ir_stop(dev);
678 dev->remote = NULL; 687 dev->remote = NULL;
679 err_out_free: 688 err_out_free:
689 ir_input_free(input_dev);
680 input_free_device(input_dev); 690 input_free_device(input_dev);
681 kfree(ir); 691 kfree(ir);
682 return err; 692 return err;
@@ -688,6 +698,7 @@ void saa7134_input_fini(struct saa7134_dev *dev)
688 return; 698 return;
689 699
690 saa7134_ir_stop(dev); 700 saa7134_ir_stop(dev);
701 ir_input_free(dev->remote->dev);
691 input_unregister_device(dev->remote->dev); 702 input_unregister_device(dev->remote->dev);
692 kfree(dev->remote); 703 kfree(dev->remote);
693 dev->remote = NULL; 704 dev->remote = NULL;
@@ -695,10 +706,7 @@ void saa7134_input_fini(struct saa7134_dev *dev)
695 706
696void saa7134_probe_i2c_ir(struct saa7134_dev *dev) 707void saa7134_probe_i2c_ir(struct saa7134_dev *dev)
697{ 708{
698 const unsigned short addr_list[] = { 709 struct i2c_board_info info;
699 0x7a, 0x47, 0x71, 0x2d,
700 I2C_CLIENT_END
701 };
702 710
703 struct i2c_msg msg_msi = { 711 struct i2c_msg msg_msi = {
704 .addr = 0x50, 712 .addr = 0x50,
@@ -714,9 +722,9 @@ void saa7134_probe_i2c_ir(struct saa7134_dev *dev)
714 return; 722 return;
715 } 723 }
716 724
717 memset(&dev->info, 0, sizeof(dev->info)); 725 memset(&info, 0, sizeof(struct i2c_board_info));
718 memset(&dev->init_data, 0, sizeof(dev->init_data)); 726 memset(&dev->init_data, 0, sizeof(dev->init_data));
719 strlcpy(dev->info.type, "ir_video", I2C_NAME_SIZE); 727 strlcpy(info.type, "ir_video", I2C_NAME_SIZE);
720 728
721 switch (dev->board) { 729 switch (dev->board) {
722 case SAA7134_BOARD_PINNACLE_PCTV_110i: 730 case SAA7134_BOARD_PINNACLE_PCTV_110i:
@@ -725,23 +733,24 @@ void saa7134_probe_i2c_ir(struct saa7134_dev *dev)
725 if (pinnacle_remote == 0) { 733 if (pinnacle_remote == 0) {
726 dev->init_data.get_key = get_key_pinnacle_color; 734 dev->init_data.get_key = get_key_pinnacle_color;
727 dev->init_data.ir_codes = &ir_codes_pinnacle_color_table; 735 dev->init_data.ir_codes = &ir_codes_pinnacle_color_table;
728 dev->info.addr = 0x47; 736 info.addr = 0x47;
729 } else { 737 } else {
730 dev->init_data.get_key = get_key_pinnacle_grey; 738 dev->init_data.get_key = get_key_pinnacle_grey;
731 dev->init_data.ir_codes = &ir_codes_pinnacle_grey_table; 739 dev->init_data.ir_codes = &ir_codes_pinnacle_grey_table;
732 dev->info.addr = 0x47; 740 info.addr = 0x47;
733 } 741 }
734 break; 742 break;
735 case SAA7134_BOARD_UPMOST_PURPLE_TV: 743 case SAA7134_BOARD_UPMOST_PURPLE_TV:
736 dev->init_data.name = "Purple TV"; 744 dev->init_data.name = "Purple TV";
737 dev->init_data.get_key = get_key_purpletv; 745 dev->init_data.get_key = get_key_purpletv;
738 dev->init_data.ir_codes = &ir_codes_purpletv_table; 746 dev->init_data.ir_codes = &ir_codes_purpletv_table;
747 info.addr = 0x7a;
739 break; 748 break;
740 case SAA7134_BOARD_MSI_TVATANYWHERE_PLUS: 749 case SAA7134_BOARD_MSI_TVATANYWHERE_PLUS:
741 dev->init_data.name = "MSI TV@nywhere Plus"; 750 dev->init_data.name = "MSI TV@nywhere Plus";
742 dev->init_data.get_key = get_key_msi_tvanywhere_plus; 751 dev->init_data.get_key = get_key_msi_tvanywhere_plus;
743 dev->init_data.ir_codes = &ir_codes_msi_tvanywhere_plus_table; 752 dev->init_data.ir_codes = &ir_codes_msi_tvanywhere_plus_table;
744 dev->info.addr = 0x30; 753 info.addr = 0x30;
745 /* MSI TV@nywhere Plus controller doesn't seem to 754 /* MSI TV@nywhere Plus controller doesn't seem to
746 respond to probes unless we read something from 755 respond to probes unless we read something from
747 an existing device. Weird... 756 an existing device. Weird...
@@ -755,6 +764,7 @@ void saa7134_probe_i2c_ir(struct saa7134_dev *dev)
755 dev->init_data.name = "HVR 1110"; 764 dev->init_data.name = "HVR 1110";
756 dev->init_data.get_key = get_key_hvr1110; 765 dev->init_data.get_key = get_key_hvr1110;
757 dev->init_data.ir_codes = &ir_codes_hauppauge_new_table; 766 dev->init_data.ir_codes = &ir_codes_hauppauge_new_table;
767 info.addr = 0x71;
758 break; 768 break;
759 case SAA7134_BOARD_BEHOLD_607FM_MK3: 769 case SAA7134_BOARD_BEHOLD_607FM_MK3:
760 case SAA7134_BOARD_BEHOLD_607FM_MK5: 770 case SAA7134_BOARD_BEHOLD_607FM_MK5:
@@ -772,23 +782,20 @@ void saa7134_probe_i2c_ir(struct saa7134_dev *dev)
772 dev->init_data.name = "BeholdTV"; 782 dev->init_data.name = "BeholdTV";
773 dev->init_data.get_key = get_key_beholdm6xx; 783 dev->init_data.get_key = get_key_beholdm6xx;
774 dev->init_data.ir_codes = &ir_codes_behold_table; 784 dev->init_data.ir_codes = &ir_codes_behold_table;
785 info.addr = 0x2d;
775 break; 786 break;
776 case SAA7134_BOARD_AVERMEDIA_CARDBUS_501: 787 case SAA7134_BOARD_AVERMEDIA_CARDBUS_501:
777 case SAA7134_BOARD_AVERMEDIA_CARDBUS_506: 788 case SAA7134_BOARD_AVERMEDIA_CARDBUS_506:
778 dev->info.addr = 0x40; 789 info.addr = 0x40;
779 break; 790 break;
780 } 791 default:
781 792 dprintk("No I2C IR support for board %x\n", dev->board);
782 if (dev->init_data.name)
783 dev->info.platform_data = &dev->init_data;
784 /* No need to probe if address is known */
785 if (dev->info.addr) {
786 i2c_new_device(&dev->i2c_adap, &dev->info);
787 return; 793 return;
788 } 794 }
789 795
790 /* Address not known, fallback to probing */ 796 if (dev->init_data.name)
791 i2c_new_probed_device(&dev->i2c_adap, &dev->info, addr_list); 797 info.platform_data = &dev->init_data;
798 i2c_new_device(&dev->i2c_adap, &info);
792} 799}
793 800
794static int saa7134_rc5_irq(struct saa7134_dev *dev) 801static int saa7134_rc5_irq(struct saa7134_dev *dev)
@@ -936,7 +943,7 @@ static void nec_task(unsigned long data)
936 dprintk("scancode = 0x%02x (code = 0x%02x, notcode= 0x%02x)\n", 943 dprintk("scancode = 0x%02x (code = 0x%02x, notcode= 0x%02x)\n",
937 ir->code, ircode, not_code); 944 ir->code, ircode, not_code);
938 945
939 ir_input_keydown(ir->dev, &ir->ir, ir->code, ir->code); 946 ir_input_keydown(ir->dev, &ir->ir, ir->code);
940 } else 947 } else
941 dprintk("Repeat last key\n"); 948 dprintk("Repeat last key\n");
942 949
diff --git a/drivers/media/video/saa7134/saa7134-video.c b/drivers/media/video/saa7134/saa7134-video.c
index da26f476a302..35f8daa3a359 100644
--- a/drivers/media/video/saa7134/saa7134-video.c
+++ b/drivers/media/video/saa7134/saa7134-video.c
@@ -1499,7 +1499,7 @@ static int video_release(struct file *file)
1499 saa_andorb(SAA7134_OFMT_DATA_A, 0x1f, 0); 1499 saa_andorb(SAA7134_OFMT_DATA_A, 0x1f, 0);
1500 saa_andorb(SAA7134_OFMT_DATA_B, 0x1f, 0); 1500 saa_andorb(SAA7134_OFMT_DATA_B, 0x1f, 0);
1501 1501
1502 saa_call_all(dev, tuner, s_standby); 1502 saa_call_all(dev, core, s_power, 0);
1503 if (fh->radio) 1503 if (fh->radio)
1504 saa_call_all(dev, core, ioctl, RDS_CMD_CLOSE, &cmd); 1504 saa_call_all(dev, core, ioctl, RDS_CMD_CLOSE, &cmd);
1505 1505
diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h
index f8697d46ff5f..53b7e0b8a2fb 100644
--- a/drivers/media/video/saa7134/saa7134.h
+++ b/drivers/media/video/saa7134/saa7134.h
@@ -297,6 +297,8 @@ struct saa7134_format {
297#define SAA7134_BOARD_BEHOLD_X7 171 297#define SAA7134_BOARD_BEHOLD_X7 171
298#define SAA7134_BOARD_ROVERMEDIA_LINK_PRO_FM 172 298#define SAA7134_BOARD_ROVERMEDIA_LINK_PRO_FM 172
299#define SAA7134_BOARD_ZOLID_HYBRID_PCI 173 299#define SAA7134_BOARD_ZOLID_HYBRID_PCI 173
300#define SAA7134_BOARD_ASUS_EUROPA_HYBRID 174
301#define SAA7134_BOARD_LEADTEK_WINFAST_DTV1000S 175
300 302
301#define SAA7134_MAXBOARDS 32 303#define SAA7134_MAXBOARDS 32
302#define SAA7134_INPUT_MAX 8 304#define SAA7134_INPUT_MAX 8
@@ -592,7 +594,6 @@ struct saa7134_dev {
592 unsigned int insuspend; 594 unsigned int insuspend;
593 595
594 /* I2C keyboard data */ 596 /* I2C keyboard data */
595 struct i2c_board_info info;
596 struct IR_i2c_init_data init_data; 597 struct IR_i2c_init_data init_data;
597 598
598 /* SAA7134_MPEG_* */ 599 /* SAA7134_MPEG_* */
diff --git a/drivers/media/video/saa7164/saa7164-dvb.c b/drivers/media/video/saa7164/saa7164-dvb.c
index 6a2d847d6a88..cf099c59b38e 100644
--- a/drivers/media/video/saa7164/saa7164-dvb.c
+++ b/drivers/media/video/saa7164/saa7164-dvb.c
@@ -68,6 +68,7 @@ static struct tda18271_config hauppauge_hvr22x0s_tuner_config = {
68 .std_map = &hauppauge_tda18271_std_map, 68 .std_map = &hauppauge_tda18271_std_map,
69 .gate = TDA18271_GATE_ANALOG, 69 .gate = TDA18271_GATE_ANALOG,
70 .role = TDA18271_SLAVE, 70 .role = TDA18271_SLAVE,
71 .output_opt = TDA18271_OUTPUT_LT_OFF,
71 .rf_cal_on_startup = 1 72 .rf_cal_on_startup = 1
72}; 73};
73 74
diff --git a/drivers/media/video/saa717x.c b/drivers/media/video/saa717x.c
index b15c40908e84..6818df571168 100644
--- a/drivers/media/video/saa717x.c
+++ b/drivers/media/video/saa717x.c
@@ -1115,7 +1115,7 @@ static int saa717x_s_video_routing(struct v4l2_subdev *sd,
1115 v4l2_dbg(1, debug, sd, "decoder set input (%d)\n", input); 1115 v4l2_dbg(1, debug, sd, "decoder set input (%d)\n", input);
1116 /* inputs from 0-9 are available*/ 1116 /* inputs from 0-9 are available*/
1117 /* saa717x have mode0-mode9 but mode5 is reserved. */ 1117 /* saa717x have mode0-mode9 but mode5 is reserved. */
1118 if (input < 0 || input > 9 || input == 5) 1118 if (input > 9 || input == 5)
1119 return -EINVAL; 1119 return -EINVAL;
1120 1120
1121 if (decoder->input != input) { 1121 if (decoder->input != input) {
@@ -1312,7 +1312,7 @@ static int saa717x_s_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
1312 "MONO", "STEREO", "LANG1", "LANG2/SAP" 1312 "MONO", "STEREO", "LANG1", "LANG2/SAP"
1313 }; 1313 };
1314 1314
1315 audio_mode = V4L2_TUNER_MODE_STEREO; 1315 audio_mode = TUNER_AUDIO_STEREO;
1316 1316
1317 switch (vt->audmode) { 1317 switch (vt->audmode) {
1318 case V4L2_TUNER_MODE_MONO: 1318 case V4L2_TUNER_MODE_MONO:
diff --git a/drivers/media/video/sh_mobile_ceu_camera.c b/drivers/media/video/sh_mobile_ceu_camera.c
index 9c8b7c7b89ee..a4f3472d4db8 100644
--- a/drivers/media/video/sh_mobile_ceu_camera.c
+++ b/drivers/media/video/sh_mobile_ceu_camera.c
@@ -153,6 +153,40 @@ static u32 ceu_read(struct sh_mobile_ceu_dev *priv, unsigned long reg_offs)
153 return ioread32(priv->base + reg_offs); 153 return ioread32(priv->base + reg_offs);
154} 154}
155 155
156static int sh_mobile_ceu_soft_reset(struct sh_mobile_ceu_dev *pcdev)
157{
158 int i, success = 0;
159 struct soc_camera_device *icd = pcdev->icd;
160
161 ceu_write(pcdev, CAPSR, 1 << 16); /* reset */
162
163 /* wait CSTSR.CPTON bit */
164 for (i = 0; i < 1000; i++) {
165 if (!(ceu_read(pcdev, CSTSR) & 1)) {
166 success++;
167 break;
168 }
169 udelay(1);
170 }
171
172 /* wait CAPSR.CPKIL bit */
173 for (i = 0; i < 1000; i++) {
174 if (!(ceu_read(pcdev, CAPSR) & (1 << 16))) {
175 success++;
176 break;
177 }
178 udelay(1);
179 }
180
181
182 if (2 != success) {
183 dev_warn(&icd->dev, "soft reset time out\n");
184 return -EIO;
185 }
186
187 return 0;
188}
189
156/* 190/*
157 * Videobuf operations 191 * Videobuf operations
158 */ 192 */
@@ -202,26 +236,45 @@ static void free_buffer(struct videobuf_queue *vq,
202#define CEU_CETCR_MAGIC 0x0317f313 /* acknowledge magical interrupt sources */ 236#define CEU_CETCR_MAGIC 0x0317f313 /* acknowledge magical interrupt sources */
203#define CEU_CETCR_IGRW (1 << 4) /* prohibited register access interrupt bit */ 237#define CEU_CETCR_IGRW (1 << 4) /* prohibited register access interrupt bit */
204#define CEU_CEIER_CPEIE (1 << 0) /* one-frame capture end interrupt */ 238#define CEU_CEIER_CPEIE (1 << 0) /* one-frame capture end interrupt */
239#define CEU_CEIER_VBP (1 << 20) /* vbp error */
205#define CEU_CAPCR_CTNCP (1 << 16) /* continuous capture mode (if set) */ 240#define CEU_CAPCR_CTNCP (1 << 16) /* continuous capture mode (if set) */
241#define CEU_CEIER_MASK (CEU_CEIER_CPEIE | CEU_CEIER_VBP)
206 242
207 243
208static void sh_mobile_ceu_capture(struct sh_mobile_ceu_dev *pcdev) 244/*
245 * return value doesn't reflex the success/failure to queue the new buffer,
246 * but rather the status of the previous buffer.
247 */
248static int sh_mobile_ceu_capture(struct sh_mobile_ceu_dev *pcdev)
209{ 249{
210 struct soc_camera_device *icd = pcdev->icd; 250 struct soc_camera_device *icd = pcdev->icd;
211 dma_addr_t phys_addr_top, phys_addr_bottom; 251 dma_addr_t phys_addr_top, phys_addr_bottom;
252 u32 status;
253 int ret = 0;
212 254
213 /* The hardware is _very_ picky about this sequence. Especially 255 /* The hardware is _very_ picky about this sequence. Especially
214 * the CEU_CETCR_MAGIC value. It seems like we need to acknowledge 256 * the CEU_CETCR_MAGIC value. It seems like we need to acknowledge
215 * several not-so-well documented interrupt sources in CETCR. 257 * several not-so-well documented interrupt sources in CETCR.
216 */ 258 */
217 ceu_write(pcdev, CEIER, ceu_read(pcdev, CEIER) & ~CEU_CEIER_CPEIE); 259 ceu_write(pcdev, CEIER, ceu_read(pcdev, CEIER) & ~CEU_CEIER_MASK);
218 ceu_write(pcdev, CETCR, ~ceu_read(pcdev, CETCR) & CEU_CETCR_MAGIC); 260 status = ceu_read(pcdev, CETCR);
219 ceu_write(pcdev, CEIER, ceu_read(pcdev, CEIER) | CEU_CEIER_CPEIE); 261 ceu_write(pcdev, CETCR, ~status & CEU_CETCR_MAGIC);
262 ceu_write(pcdev, CEIER, ceu_read(pcdev, CEIER) | CEU_CEIER_MASK);
220 ceu_write(pcdev, CAPCR, ceu_read(pcdev, CAPCR) & ~CEU_CAPCR_CTNCP); 263 ceu_write(pcdev, CAPCR, ceu_read(pcdev, CAPCR) & ~CEU_CAPCR_CTNCP);
221 ceu_write(pcdev, CETCR, CEU_CETCR_MAGIC ^ CEU_CETCR_IGRW); 264 ceu_write(pcdev, CETCR, CEU_CETCR_MAGIC ^ CEU_CETCR_IGRW);
222 265
266 /*
267 * When a VBP interrupt occurs, a capture end interrupt does not occur
268 * and the image of that frame is not captured correctly. So, soft reset
269 * is needed here.
270 */
271 if (status & CEU_CEIER_VBP) {
272 sh_mobile_ceu_soft_reset(pcdev);
273 ret = -EIO;
274 }
275
223 if (!pcdev->active) 276 if (!pcdev->active)
224 return; 277 return ret;
225 278
226 phys_addr_top = videobuf_to_dma_contig(pcdev->active); 279 phys_addr_top = videobuf_to_dma_contig(pcdev->active);
227 ceu_write(pcdev, CDAYR, phys_addr_top); 280 ceu_write(pcdev, CDAYR, phys_addr_top);
@@ -247,6 +300,8 @@ static void sh_mobile_ceu_capture(struct sh_mobile_ceu_dev *pcdev)
247 300
248 pcdev->active->state = VIDEOBUF_ACTIVE; 301 pcdev->active->state = VIDEOBUF_ACTIVE;
249 ceu_write(pcdev, CAPSR, 0x1); /* start capture */ 302 ceu_write(pcdev, CAPSR, 0x1); /* start capture */
303
304 return ret;
250} 305}
251 306
252static int sh_mobile_ceu_videobuf_prepare(struct videobuf_queue *vq, 307static int sh_mobile_ceu_videobuf_prepare(struct videobuf_queue *vq,
@@ -319,6 +374,11 @@ static void sh_mobile_ceu_videobuf_queue(struct videobuf_queue *vq,
319 list_add_tail(&vb->queue, &pcdev->capture); 374 list_add_tail(&vb->queue, &pcdev->capture);
320 375
321 if (!pcdev->active) { 376 if (!pcdev->active) {
377 /*
378 * Because there were no active buffer at this moment,
379 * we are not interested in the return value of
380 * sh_mobile_ceu_capture here.
381 */
322 pcdev->active = vb; 382 pcdev->active = vb;
323 sh_mobile_ceu_capture(pcdev); 383 sh_mobile_ceu_capture(pcdev);
324 } 384 }
@@ -379,9 +439,8 @@ static irqreturn_t sh_mobile_ceu_irq(int irq, void *data)
379 else 439 else
380 pcdev->active = NULL; 440 pcdev->active = NULL;
381 441
382 sh_mobile_ceu_capture(pcdev); 442 vb->state = (sh_mobile_ceu_capture(pcdev) < 0) ?
383 443 VIDEOBUF_ERROR : VIDEOBUF_DONE;
384 vb->state = VIDEOBUF_DONE;
385 do_gettimeofday(&vb->ts); 444 do_gettimeofday(&vb->ts);
386 vb->field_count++; 445 vb->field_count++;
387 wake_up(&vb->done); 446 wake_up(&vb->done);
@@ -407,13 +466,9 @@ static int sh_mobile_ceu_add_device(struct soc_camera_device *icd)
407 466
408 pm_runtime_get_sync(ici->v4l2_dev.dev); 467 pm_runtime_get_sync(ici->v4l2_dev.dev);
409 468
410 ceu_write(pcdev, CAPSR, 1 << 16); /* reset */
411 while (ceu_read(pcdev, CSTSR) & 1)
412 msleep(1);
413
414 pcdev->icd = icd; 469 pcdev->icd = icd;
415 470
416 return 0; 471 return sh_mobile_ceu_soft_reset(pcdev);
417} 472}
418 473
419/* Called with .video_lock held */ 474/* Called with .video_lock held */
@@ -427,7 +482,7 @@ static void sh_mobile_ceu_remove_device(struct soc_camera_device *icd)
427 482
428 /* disable capture, disable interrupts */ 483 /* disable capture, disable interrupts */
429 ceu_write(pcdev, CEIER, 0); 484 ceu_write(pcdev, CEIER, 0);
430 ceu_write(pcdev, CAPSR, 1 << 16); /* reset */ 485 sh_mobile_ceu_soft_reset(pcdev);
431 486
432 /* make sure active buffer is canceled */ 487 /* make sure active buffer is canceled */
433 spin_lock_irqsave(&pcdev->lock, flags); 488 spin_lock_irqsave(&pcdev->lock, flags);
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c
index aba92e2313d8..5b3eaa16afd2 100644
--- a/drivers/media/video/tuner-core.c
+++ b/drivers/media/video/tuner-core.c
@@ -320,6 +320,7 @@ static void set_type(struct i2c_client *c, unsigned int type,
320 struct dvb_tuner_ops *fe_tuner_ops = &t->fe.ops.tuner_ops; 320 struct dvb_tuner_ops *fe_tuner_ops = &t->fe.ops.tuner_ops;
321 struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops; 321 struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops;
322 unsigned char buffer[4]; 322 unsigned char buffer[4];
323 int tune_now = 1;
323 324
324 if (type == UNSET || type == TUNER_ABSENT) { 325 if (type == UNSET || type == TUNER_ABSENT) {
325 tuner_dbg ("tuner 0x%02x: Tuner type absent\n",c->addr); 326 tuner_dbg ("tuner 0x%02x: Tuner type absent\n",c->addr);
@@ -328,7 +329,7 @@ static void set_type(struct i2c_client *c, unsigned int type,
328 329
329 t->type = type; 330 t->type = type;
330 /* prevent invalid config values */ 331 /* prevent invalid config values */
331 t->config = ((new_config >= 0) && (new_config < 256)) ? new_config : 0; 332 t->config = new_config < 256 ? new_config : 0;
332 if (tuner_callback != NULL) { 333 if (tuner_callback != NULL) {
333 tuner_dbg("defining GPIO callback\n"); 334 tuner_dbg("defining GPIO callback\n");
334 t->fe.callback = tuner_callback; 335 t->fe.callback = tuner_callback;
@@ -404,6 +405,7 @@ static void set_type(struct i2c_client *c, unsigned int type,
404 }; 405 };
405 if (!dvb_attach(xc2028_attach, &t->fe, &cfg)) 406 if (!dvb_attach(xc2028_attach, &t->fe, &cfg))
406 goto attach_failed; 407 goto attach_failed;
408 tune_now = 0;
407 break; 409 break;
408 } 410 }
409 case TUNER_TDA9887: 411 case TUNER_TDA9887:
@@ -419,6 +421,7 @@ static void set_type(struct i2c_client *c, unsigned int type,
419 if (!dvb_attach(xc5000_attach, 421 if (!dvb_attach(xc5000_attach,
420 &t->fe, t->i2c->adapter, &xc5000_cfg)) 422 &t->fe, t->i2c->adapter, &xc5000_cfg))
421 goto attach_failed; 423 goto attach_failed;
424 tune_now = 0;
422 break; 425 break;
423 } 426 }
424 case TUNER_NXP_TDA18271: 427 case TUNER_NXP_TDA18271:
@@ -430,6 +433,7 @@ static void set_type(struct i2c_client *c, unsigned int type,
430 if (!dvb_attach(tda18271_attach, &t->fe, t->i2c->addr, 433 if (!dvb_attach(tda18271_attach, &t->fe, t->i2c->addr,
431 t->i2c->adapter, &cfg)) 434 t->i2c->adapter, &cfg))
432 goto attach_failed; 435 goto attach_failed;
436 tune_now = 0;
433 break; 437 break;
434 } 438 }
435 default: 439 default:
@@ -458,12 +462,13 @@ static void set_type(struct i2c_client *c, unsigned int type,
458 if (t->mode_mask == T_UNINITIALIZED) 462 if (t->mode_mask == T_UNINITIALIZED)
459 t->mode_mask = new_mode_mask; 463 t->mode_mask = new_mode_mask;
460 464
461 /* xc2028/3028 and xc5000 requires a firmware to be set-up later 465 /* Some tuners require more initialization setup before use,
466 such as firmware download or device calibration.
462 trying to set a frequency here will just fail 467 trying to set a frequency here will just fail
463 FIXME: better to move set_freq to the tuner code. This is needed 468 FIXME: better to move set_freq to the tuner code. This is needed
464 on analog tuners for PLL to properly work 469 on analog tuners for PLL to properly work
465 */ 470 */
466 if (t->type != TUNER_XC2028 && t->type != TUNER_XC5000) 471 if (tune_now)
467 set_freq(c, (V4L2_TUNER_RADIO == t->mode) ? 472 set_freq(c, (V4L2_TUNER_RADIO == t->mode) ?
468 t->radio_freq : t->tv_freq); 473 t->radio_freq : t->tv_freq);
469 474
@@ -752,14 +757,17 @@ static int tuner_s_radio(struct v4l2_subdev *sd)
752 return 0; 757 return 0;
753} 758}
754 759
755static int tuner_s_standby(struct v4l2_subdev *sd) 760static int tuner_s_power(struct v4l2_subdev *sd, int on)
756{ 761{
757 struct tuner *t = to_tuner(sd); 762 struct tuner *t = to_tuner(sd);
758 struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops; 763 struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops;
759 764
765 if (on)
766 return 0;
767
760 tuner_dbg("Putting tuner to sleep\n"); 768 tuner_dbg("Putting tuner to sleep\n");
761 769
762 if (check_mode(t, "s_standby") == -EINVAL) 770 if (check_mode(t, "s_power") == -EINVAL)
763 return 0; 771 return 0;
764 t->mode = T_STANDBY; 772 t->mode = T_STANDBY;
765 if (analog_ops->standby) 773 if (analog_ops->standby)
@@ -961,6 +969,7 @@ static int tuner_command(struct i2c_client *client, unsigned cmd, void *arg)
961static const struct v4l2_subdev_core_ops tuner_core_ops = { 969static const struct v4l2_subdev_core_ops tuner_core_ops = {
962 .log_status = tuner_log_status, 970 .log_status = tuner_log_status,
963 .s_std = tuner_s_std, 971 .s_std = tuner_s_std,
972 .s_power = tuner_s_power,
964}; 973};
965 974
966static const struct v4l2_subdev_tuner_ops tuner_tuner_ops = { 975static const struct v4l2_subdev_tuner_ops tuner_tuner_ops = {
@@ -971,7 +980,6 @@ static const struct v4l2_subdev_tuner_ops tuner_tuner_ops = {
971 .g_frequency = tuner_g_frequency, 980 .g_frequency = tuner_g_frequency,
972 .s_type_addr = tuner_s_type_addr, 981 .s_type_addr = tuner_s_type_addr,
973 .s_config = tuner_s_config, 982 .s_config = tuner_s_config,
974 .s_standby = tuner_s_standby,
975}; 983};
976 984
977static const struct v4l2_subdev_ops tuner_ops = { 985static const struct v4l2_subdev_ops tuner_ops = {
diff --git a/drivers/media/video/tvaudio.c b/drivers/media/video/tvaudio.c
index 0869bafc2b56..800fc1b111ef 100644
--- a/drivers/media/video/tvaudio.c
+++ b/drivers/media/video/tvaudio.c
@@ -1919,7 +1919,7 @@ static const struct v4l2_subdev_tuner_ops tvaudio_tuner_ops = {
1919 .s_radio = tvaudio_s_radio, 1919 .s_radio = tvaudio_s_radio,
1920 .s_frequency = tvaudio_s_frequency, 1920 .s_frequency = tvaudio_s_frequency,
1921 .s_tuner = tvaudio_s_tuner, 1921 .s_tuner = tvaudio_s_tuner,
1922 .s_tuner = tvaudio_g_tuner, 1922 .g_tuner = tvaudio_g_tuner,
1923}; 1923};
1924 1924
1925static const struct v4l2_subdev_audio_ops tvaudio_audio_ops = { 1925static const struct v4l2_subdev_audio_ops tvaudio_audio_ops = {
diff --git a/drivers/media/video/tvp514x.c b/drivers/media/video/tvp514x.c
index 244372627df2..26b4e718cd6d 100644
--- a/drivers/media/video/tvp514x.c
+++ b/drivers/media/video/tvp514x.c
@@ -272,7 +272,7 @@ static int tvp514x_read_reg(struct v4l2_subdev *sd, u8 reg)
272read_again: 272read_again:
273 273
274 err = i2c_smbus_read_byte_data(client, reg); 274 err = i2c_smbus_read_byte_data(client, reg);
275 if (err == -1) { 275 if (err < 0) {
276 if (retry <= I2C_RETRY_COUNT) { 276 if (retry <= I2C_RETRY_COUNT) {
277 v4l2_warn(sd, "Read: retry ... %d\n", retry); 277 v4l2_warn(sd, "Read: retry ... %d\n", retry);
278 retry++; 278 retry++;
diff --git a/drivers/media/video/usbvideo/konicawc.c b/drivers/media/video/usbvideo/konicawc.c
index 31d57f2d09e1..a0addcb04295 100644
--- a/drivers/media/video/usbvideo/konicawc.c
+++ b/drivers/media/video/usbvideo/konicawc.c
@@ -225,7 +225,7 @@ static void konicawc_register_input(struct konicawc *cam, struct usb_device *dev
225 int error; 225 int error;
226 226
227 usb_make_path(dev, cam->input_physname, sizeof(cam->input_physname)); 227 usb_make_path(dev, cam->input_physname, sizeof(cam->input_physname));
228 strncat(cam->input_physname, "/input0", sizeof(cam->input_physname)); 228 strlcat(cam->input_physname, "/input0", sizeof(cam->input_physname));
229 229
230 cam->input = input_dev = input_allocate_device(); 230 cam->input = input_dev = input_allocate_device();
231 if (!input_dev) { 231 if (!input_dev) {
diff --git a/drivers/media/video/usbvideo/quickcam_messenger.c b/drivers/media/video/usbvideo/quickcam_messenger.c
index 803d3e4e29a2..c4d1b96b5cee 100644
--- a/drivers/media/video/usbvideo/quickcam_messenger.c
+++ b/drivers/media/video/usbvideo/quickcam_messenger.c
@@ -89,7 +89,7 @@ static void qcm_register_input(struct qcm *cam, struct usb_device *dev)
89 int error; 89 int error;
90 90
91 usb_make_path(dev, cam->input_physname, sizeof(cam->input_physname)); 91 usb_make_path(dev, cam->input_physname, sizeof(cam->input_physname));
92 strncat(cam->input_physname, "/input0", sizeof(cam->input_physname)); 92 strlcat(cam->input_physname, "/input0", sizeof(cam->input_physname));
93 93
94 cam->input = input_dev = input_allocate_device(); 94 cam->input = input_dev = input_allocate_device();
95 if (!input_dev) { 95 if (!input_dev) {
diff --git a/drivers/media/video/usbvision/usbvision-video.c b/drivers/media/video/usbvision/usbvision-video.c
index a2a50d608a3f..c07b0ac452ab 100644
--- a/drivers/media/video/usbvision/usbvision-video.c
+++ b/drivers/media/video/usbvision/usbvision-video.c
@@ -601,7 +601,7 @@ static int vidioc_s_input (struct file *file, void *priv, unsigned int input)
601{ 601{
602 struct usb_usbvision *usbvision = video_drvdata(file); 602 struct usb_usbvision *usbvision = video_drvdata(file);
603 603
604 if ((input >= usbvision->video_inputs) || (input < 0) ) 604 if (input >= usbvision->video_inputs)
605 return -EINVAL; 605 return -EINVAL;
606 606
607 mutex_lock(&usbvision->lock); 607 mutex_lock(&usbvision->lock);
diff --git a/drivers/media/video/uvc/uvc_ctrl.c b/drivers/media/video/uvc/uvc_ctrl.c
index 1b89735e62fd..0469d7a876a8 100644
--- a/drivers/media/video/uvc/uvc_ctrl.c
+++ b/drivers/media/video/uvc/uvc_ctrl.c
@@ -742,17 +742,7 @@ struct uvc_control *uvc_find_control(struct uvc_video_chain *chain,
742 v4l2_id &= V4L2_CTRL_ID_MASK; 742 v4l2_id &= V4L2_CTRL_ID_MASK;
743 743
744 /* Find the control. */ 744 /* Find the control. */
745 __uvc_find_control(chain->processing, v4l2_id, mapping, &ctrl, next); 745 list_for_each_entry(entity, &chain->entities, chain) {
746 if (ctrl && !next)
747 return ctrl;
748
749 list_for_each_entry(entity, &chain->iterms, chain) {
750 __uvc_find_control(entity, v4l2_id, mapping, &ctrl, next);
751 if (ctrl && !next)
752 return ctrl;
753 }
754
755 list_for_each_entry(entity, &chain->extensions, chain) {
756 __uvc_find_control(entity, v4l2_id, mapping, &ctrl, next); 746 __uvc_find_control(entity, v4l2_id, mapping, &ctrl, next);
757 if (ctrl && !next) 747 if (ctrl && !next)
758 return ctrl; 748 return ctrl;
@@ -826,6 +816,13 @@ int uvc_query_v4l2_ctrl(struct uvc_video_chain *chain,
826 ret = 0; 816 ret = 0;
827 goto out; 817 goto out;
828 818
819 case V4L2_CTRL_TYPE_BUTTON:
820 v4l2_ctrl->minimum = 0;
821 v4l2_ctrl->maximum = 0;
822 v4l2_ctrl->step = 0;
823 ret = 0;
824 goto out;
825
829 default: 826 default:
830 break; 827 break;
831 } 828 }
@@ -944,17 +941,7 @@ int __uvc_ctrl_commit(struct uvc_video_chain *chain, int rollback)
944 int ret = 0; 941 int ret = 0;
945 942
946 /* Find the control. */ 943 /* Find the control. */
947 ret = uvc_ctrl_commit_entity(chain->dev, chain->processing, rollback); 944 list_for_each_entry(entity, &chain->entities, chain) {
948 if (ret < 0)
949 goto done;
950
951 list_for_each_entry(entity, &chain->iterms, chain) {
952 ret = uvc_ctrl_commit_entity(chain->dev, entity, rollback);
953 if (ret < 0)
954 goto done;
955 }
956
957 list_for_each_entry(entity, &chain->extensions, chain) {
958 ret = uvc_ctrl_commit_entity(chain->dev, entity, rollback); 945 ret = uvc_ctrl_commit_entity(chain->dev, entity, rollback);
959 if (ret < 0) 946 if (ret < 0)
960 goto done; 947 goto done;
@@ -1068,8 +1055,9 @@ int uvc_xu_ctrl_query(struct uvc_video_chain *chain,
1068 int ret; 1055 int ret;
1069 1056
1070 /* Find the extension unit. */ 1057 /* Find the extension unit. */
1071 list_for_each_entry(entity, &chain->extensions, chain) { 1058 list_for_each_entry(entity, &chain->entities, chain) {
1072 if (entity->id == xctrl->unit) 1059 if (UVC_ENTITY_TYPE(entity) == UVC_VC_EXTENSION_UNIT &&
1060 entity->id == xctrl->unit)
1073 break; 1061 break;
1074 } 1062 }
1075 1063
diff --git a/drivers/media/video/uvc/uvc_driver.c b/drivers/media/video/uvc/uvc_driver.c
index 8756be569154..c31bc50113bc 100644
--- a/drivers/media/video/uvc/uvc_driver.c
+++ b/drivers/media/video/uvc/uvc_driver.c
@@ -46,6 +46,7 @@
46unsigned int uvc_no_drop_param; 46unsigned int uvc_no_drop_param;
47static unsigned int uvc_quirks_param; 47static unsigned int uvc_quirks_param;
48unsigned int uvc_trace_param; 48unsigned int uvc_trace_param;
49unsigned int uvc_timeout_param = UVC_CTRL_STREAMING_TIMEOUT;
49 50
50/* ------------------------------------------------------------------------ 51/* ------------------------------------------------------------------------
51 * Video formats 52 * Video formats
@@ -248,29 +249,9 @@ static struct uvc_entity *uvc_entity_by_reference(struct uvc_device *dev,
248 entity = list_entry(&dev->entities, struct uvc_entity, list); 249 entity = list_entry(&dev->entities, struct uvc_entity, list);
249 250
250 list_for_each_entry_continue(entity, &dev->entities, list) { 251 list_for_each_entry_continue(entity, &dev->entities, list) {
251 switch (UVC_ENTITY_TYPE(entity)) { 252 for (i = 0; i < entity->bNrInPins; ++i)
252 case UVC_TT_STREAMING: 253 if (entity->baSourceID[i] == id)
253 if (entity->output.bSourceID == id)
254 return entity;
255 break;
256
257 case UVC_VC_PROCESSING_UNIT:
258 if (entity->processing.bSourceID == id)
259 return entity; 254 return entity;
260 break;
261
262 case UVC_VC_SELECTOR_UNIT:
263 for (i = 0; i < entity->selector.bNrInPins; ++i)
264 if (entity->selector.baSourceID[i] == id)
265 return entity;
266 break;
267
268 case UVC_VC_EXTENSION_UNIT:
269 for (i = 0; i < entity->extension.bNrInPins; ++i)
270 if (entity->extension.baSourceID[i] == id)
271 return entity;
272 break;
273 }
274 } 255 }
275 256
276 return NULL; 257 return NULL;
@@ -426,7 +407,8 @@ static int uvc_parse_format(struct uvc_device *dev,
426 /* Parse the frame descriptors. Only uncompressed, MJPEG and frame 407 /* Parse the frame descriptors. Only uncompressed, MJPEG and frame
427 * based formats have frame descriptors. 408 * based formats have frame descriptors.
428 */ 409 */
429 while (buflen > 2 && buffer[2] == ftype) { 410 while (buflen > 2 && buffer[1] == USB_DT_CS_INTERFACE &&
411 buffer[2] == ftype) {
430 frame = &format->frame[format->nframes]; 412 frame = &format->frame[format->nframes];
431 if (ftype != UVC_VS_FRAME_FRAME_BASED) 413 if (ftype != UVC_VS_FRAME_FRAME_BASED)
432 n = buflen > 25 ? buffer[25] : 0; 414 n = buflen > 25 ? buffer[25] : 0;
@@ -503,12 +485,14 @@ static int uvc_parse_format(struct uvc_device *dev,
503 buffer += buffer[0]; 485 buffer += buffer[0];
504 } 486 }
505 487
506 if (buflen > 2 && buffer[2] == UVC_VS_STILL_IMAGE_FRAME) { 488 if (buflen > 2 && buffer[1] == USB_DT_CS_INTERFACE &&
489 buffer[2] == UVC_VS_STILL_IMAGE_FRAME) {
507 buflen -= buffer[0]; 490 buflen -= buffer[0];
508 buffer += buffer[0]; 491 buffer += buffer[0];
509 } 492 }
510 493
511 if (buflen > 2 && buffer[2] == UVC_VS_COLORFORMAT) { 494 if (buflen > 2 && buffer[1] == USB_DT_CS_INTERFACE &&
495 buffer[2] == UVC_VS_COLORFORMAT) {
512 if (buflen < 6) { 496 if (buflen < 6) {
513 uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming " 497 uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming "
514 "interface %d COLORFORMAT error\n", 498 "interface %d COLORFORMAT error\n",
@@ -749,6 +733,11 @@ static int uvc_parse_streaming(struct uvc_device *dev,
749 buffer += buffer[0]; 733 buffer += buffer[0];
750 } 734 }
751 735
736 if (buflen)
737 uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming interface "
738 "%d has %u bytes of trailing descriptor garbage.\n",
739 dev->udev->devnum, alts->desc.bInterfaceNumber, buflen);
740
752 /* Parse the alternate settings to find the maximum bandwidth. */ 741 /* Parse the alternate settings to find the maximum bandwidth. */
753 for (i = 0; i < intf->num_altsetting; ++i) { 742 for (i = 0; i < intf->num_altsetting; ++i) {
754 struct usb_host_endpoint *ep; 743 struct usb_host_endpoint *ep;
@@ -776,6 +765,28 @@ error:
776 return ret; 765 return ret;
777} 766}
778 767
768static struct uvc_entity *uvc_alloc_entity(u16 type, u8 id,
769 unsigned int num_pads, unsigned int extra_size)
770{
771 struct uvc_entity *entity;
772 unsigned int num_inputs;
773 unsigned int size;
774
775 num_inputs = (type & UVC_TERM_OUTPUT) ? num_pads : num_pads - 1;
776 size = sizeof(*entity) + extra_size + num_inputs;
777 entity = kzalloc(size, GFP_KERNEL);
778 if (entity == NULL)
779 return NULL;
780
781 entity->id = id;
782 entity->type = type;
783
784 entity->bNrInPins = num_inputs;
785 entity->baSourceID = ((__u8 *)entity) + sizeof(*entity) + extra_size;
786
787 return entity;
788}
789
779/* Parse vendor-specific extensions. */ 790/* Parse vendor-specific extensions. */
780static int uvc_parse_vendor_control(struct uvc_device *dev, 791static int uvc_parse_vendor_control(struct uvc_device *dev,
781 const unsigned char *buffer, int buflen) 792 const unsigned char *buffer, int buflen)
@@ -827,21 +838,18 @@ static int uvc_parse_vendor_control(struct uvc_device *dev,
827 break; 838 break;
828 } 839 }
829 840
830 unit = kzalloc(sizeof *unit + p + 2*n, GFP_KERNEL); 841 unit = uvc_alloc_entity(UVC_VC_EXTENSION_UNIT, buffer[3],
842 p + 1, 2*n);
831 if (unit == NULL) 843 if (unit == NULL)
832 return -ENOMEM; 844 return -ENOMEM;
833 845
834 unit->id = buffer[3];
835 unit->type = UVC_VC_EXTENSION_UNIT;
836 memcpy(unit->extension.guidExtensionCode, &buffer[4], 16); 846 memcpy(unit->extension.guidExtensionCode, &buffer[4], 16);
837 unit->extension.bNumControls = buffer[20]; 847 unit->extension.bNumControls = buffer[20];
838 unit->extension.bNrInPins = get_unaligned_le16(&buffer[21]); 848 memcpy(unit->baSourceID, &buffer[22], p);
839 unit->extension.baSourceID = (__u8 *)unit + sizeof *unit;
840 memcpy(unit->extension.baSourceID, &buffer[22], p);
841 unit->extension.bControlSize = buffer[22+p]; 849 unit->extension.bControlSize = buffer[22+p];
842 unit->extension.bmControls = (__u8 *)unit + sizeof *unit + p; 850 unit->extension.bmControls = (__u8 *)unit + sizeof(*unit);
843 unit->extension.bmControlsType = (__u8 *)unit + sizeof *unit 851 unit->extension.bmControlsType = (__u8 *)unit + sizeof(*unit)
844 + p + n; 852 + n;
845 memcpy(unit->extension.bmControls, &buffer[23+p], 2*n); 853 memcpy(unit->extension.bmControls, &buffer[23+p], 2*n);
846 854
847 if (buffer[24+p+2*n] != 0) 855 if (buffer[24+p+2*n] != 0)
@@ -938,13 +946,11 @@ static int uvc_parse_standard_control(struct uvc_device *dev,
938 return -EINVAL; 946 return -EINVAL;
939 } 947 }
940 948
941 term = kzalloc(sizeof *term + n + p, GFP_KERNEL); 949 term = uvc_alloc_entity(type | UVC_TERM_INPUT, buffer[3],
950 1, n + p);
942 if (term == NULL) 951 if (term == NULL)
943 return -ENOMEM; 952 return -ENOMEM;
944 953
945 term->id = buffer[3];
946 term->type = type | UVC_TERM_INPUT;
947
948 if (UVC_ENTITY_TYPE(term) == UVC_ITT_CAMERA) { 954 if (UVC_ENTITY_TYPE(term) == UVC_ITT_CAMERA) {
949 term->camera.bControlSize = n; 955 term->camera.bControlSize = n;
950 term->camera.bmControls = (__u8 *)term + sizeof *term; 956 term->camera.bmControls = (__u8 *)term + sizeof *term;
@@ -999,13 +1005,12 @@ static int uvc_parse_standard_control(struct uvc_device *dev,
999 return 0; 1005 return 0;
1000 } 1006 }
1001 1007
1002 term = kzalloc(sizeof *term, GFP_KERNEL); 1008 term = uvc_alloc_entity(type | UVC_TERM_OUTPUT, buffer[3],
1009 1, 0);
1003 if (term == NULL) 1010 if (term == NULL)
1004 return -ENOMEM; 1011 return -ENOMEM;
1005 1012
1006 term->id = buffer[3]; 1013 memcpy(term->baSourceID, &buffer[7], 1);
1007 term->type = type | UVC_TERM_OUTPUT;
1008 term->output.bSourceID = buffer[7];
1009 1014
1010 if (buffer[8] != 0) 1015 if (buffer[8] != 0)
1011 usb_string(udev, buffer[8], term->name, 1016 usb_string(udev, buffer[8], term->name,
@@ -1026,15 +1031,11 @@ static int uvc_parse_standard_control(struct uvc_device *dev,
1026 return -EINVAL; 1031 return -EINVAL;
1027 } 1032 }
1028 1033
1029 unit = kzalloc(sizeof *unit + p, GFP_KERNEL); 1034 unit = uvc_alloc_entity(buffer[2], buffer[3], p + 1, 0);
1030 if (unit == NULL) 1035 if (unit == NULL)
1031 return -ENOMEM; 1036 return -ENOMEM;
1032 1037
1033 unit->id = buffer[3]; 1038 memcpy(unit->baSourceID, &buffer[5], p);
1034 unit->type = buffer[2];
1035 unit->selector.bNrInPins = buffer[4];
1036 unit->selector.baSourceID = (__u8 *)unit + sizeof *unit;
1037 memcpy(unit->selector.baSourceID, &buffer[5], p);
1038 1039
1039 if (buffer[5+p] != 0) 1040 if (buffer[5+p] != 0)
1040 usb_string(udev, buffer[5+p], unit->name, 1041 usb_string(udev, buffer[5+p], unit->name,
@@ -1056,13 +1057,11 @@ static int uvc_parse_standard_control(struct uvc_device *dev,
1056 return -EINVAL; 1057 return -EINVAL;
1057 } 1058 }
1058 1059
1059 unit = kzalloc(sizeof *unit + n, GFP_KERNEL); 1060 unit = uvc_alloc_entity(buffer[2], buffer[3], 2, n);
1060 if (unit == NULL) 1061 if (unit == NULL)
1061 return -ENOMEM; 1062 return -ENOMEM;
1062 1063
1063 unit->id = buffer[3]; 1064 memcpy(unit->baSourceID, &buffer[4], 1);
1064 unit->type = buffer[2];
1065 unit->processing.bSourceID = buffer[4];
1066 unit->processing.wMaxMultiplier = 1065 unit->processing.wMaxMultiplier =
1067 get_unaligned_le16(&buffer[5]); 1066 get_unaligned_le16(&buffer[5]);
1068 unit->processing.bControlSize = buffer[7]; 1067 unit->processing.bControlSize = buffer[7];
@@ -1091,19 +1090,15 @@ static int uvc_parse_standard_control(struct uvc_device *dev,
1091 return -EINVAL; 1090 return -EINVAL;
1092 } 1091 }
1093 1092
1094 unit = kzalloc(sizeof *unit + p + n, GFP_KERNEL); 1093 unit = uvc_alloc_entity(buffer[2], buffer[3], p + 1, n);
1095 if (unit == NULL) 1094 if (unit == NULL)
1096 return -ENOMEM; 1095 return -ENOMEM;
1097 1096
1098 unit->id = buffer[3];
1099 unit->type = buffer[2];
1100 memcpy(unit->extension.guidExtensionCode, &buffer[4], 16); 1097 memcpy(unit->extension.guidExtensionCode, &buffer[4], 16);
1101 unit->extension.bNumControls = buffer[20]; 1098 unit->extension.bNumControls = buffer[20];
1102 unit->extension.bNrInPins = get_unaligned_le16(&buffer[21]); 1099 memcpy(unit->baSourceID, &buffer[22], p);
1103 unit->extension.baSourceID = (__u8 *)unit + sizeof *unit;
1104 memcpy(unit->extension.baSourceID, &buffer[22], p);
1105 unit->extension.bControlSize = buffer[22+p]; 1100 unit->extension.bControlSize = buffer[22+p];
1106 unit->extension.bmControls = (__u8 *)unit + sizeof *unit + p; 1101 unit->extension.bmControls = (__u8 *)unit + sizeof *unit;
1107 memcpy(unit->extension.bmControls, &buffer[23+p], n); 1102 memcpy(unit->extension.bmControls, &buffer[23+p], n);
1108 1103
1109 if (buffer[23+p+n] != 0) 1104 if (buffer[23+p+n] != 0)
@@ -1209,13 +1204,12 @@ static int uvc_scan_chain_entity(struct uvc_video_chain *chain,
1209 if (uvc_trace_param & UVC_TRACE_PROBE) 1204 if (uvc_trace_param & UVC_TRACE_PROBE)
1210 printk(" <- XU %d", entity->id); 1205 printk(" <- XU %d", entity->id);
1211 1206
1212 if (entity->extension.bNrInPins != 1) { 1207 if (entity->bNrInPins != 1) {
1213 uvc_trace(UVC_TRACE_DESCR, "Extension unit %d has more " 1208 uvc_trace(UVC_TRACE_DESCR, "Extension unit %d has more "
1214 "than 1 input pin.\n", entity->id); 1209 "than 1 input pin.\n", entity->id);
1215 return -1; 1210 return -1;
1216 } 1211 }
1217 1212
1218 list_add_tail(&entity->chain, &chain->extensions);
1219 break; 1213 break;
1220 1214
1221 case UVC_VC_PROCESSING_UNIT: 1215 case UVC_VC_PROCESSING_UNIT:
@@ -1236,7 +1230,7 @@ static int uvc_scan_chain_entity(struct uvc_video_chain *chain,
1236 printk(" <- SU %d", entity->id); 1230 printk(" <- SU %d", entity->id);
1237 1231
1238 /* Single-input selector units are ignored. */ 1232 /* Single-input selector units are ignored. */
1239 if (entity->selector.bNrInPins == 1) 1233 if (entity->bNrInPins == 1)
1240 break; 1234 break;
1241 1235
1242 if (chain->selector != NULL) { 1236 if (chain->selector != NULL) {
@@ -1254,20 +1248,17 @@ static int uvc_scan_chain_entity(struct uvc_video_chain *chain,
1254 if (uvc_trace_param & UVC_TRACE_PROBE) 1248 if (uvc_trace_param & UVC_TRACE_PROBE)
1255 printk(" <- IT %d\n", entity->id); 1249 printk(" <- IT %d\n", entity->id);
1256 1250
1257 list_add_tail(&entity->chain, &chain->iterms);
1258 break; 1251 break;
1259 1252
1260 case UVC_TT_STREAMING: 1253 case UVC_TT_STREAMING:
1261 if (uvc_trace_param & UVC_TRACE_PROBE) 1254 if (UVC_ENTITY_IS_ITERM(entity)) {
1262 printk(" <- IT %d\n", entity->id); 1255 if (uvc_trace_param & UVC_TRACE_PROBE)
1263 1256 printk(" <- IT %d\n", entity->id);
1264 if (!UVC_ENTITY_IS_ITERM(entity)) { 1257 } else {
1265 uvc_trace(UVC_TRACE_DESCR, "Unsupported input " 1258 if (uvc_trace_param & UVC_TRACE_PROBE)
1266 "terminal %u.\n", entity->id); 1259 printk(" OT %d", entity->id);
1267 return -1;
1268 } 1260 }
1269 1261
1270 list_add_tail(&entity->chain, &chain->iterms);
1271 break; 1262 break;
1272 1263
1273 default: 1264 default:
@@ -1276,6 +1267,7 @@ static int uvc_scan_chain_entity(struct uvc_video_chain *chain,
1276 return -1; 1267 return -1;
1277 } 1268 }
1278 1269
1270 list_add_tail(&entity->chain, &chain->entities);
1279 return 0; 1271 return 0;
1280} 1272}
1281 1273
@@ -1299,14 +1291,14 @@ static int uvc_scan_chain_forward(struct uvc_video_chain *chain,
1299 1291
1300 switch (UVC_ENTITY_TYPE(forward)) { 1292 switch (UVC_ENTITY_TYPE(forward)) {
1301 case UVC_VC_EXTENSION_UNIT: 1293 case UVC_VC_EXTENSION_UNIT:
1302 if (forward->extension.bNrInPins != 1) { 1294 if (forward->bNrInPins != 1) {
1303 uvc_trace(UVC_TRACE_DESCR, "Extension unit %d " 1295 uvc_trace(UVC_TRACE_DESCR, "Extension unit %d "
1304 "has more than 1 input pin.\n", 1296 "has more than 1 input pin.\n",
1305 entity->id); 1297 entity->id);
1306 return -EINVAL; 1298 return -EINVAL;
1307 } 1299 }
1308 1300
1309 list_add_tail(&forward->chain, &chain->extensions); 1301 list_add_tail(&forward->chain, &chain->entities);
1310 if (uvc_trace_param & UVC_TRACE_PROBE) { 1302 if (uvc_trace_param & UVC_TRACE_PROBE) {
1311 if (!found) 1303 if (!found)
1312 printk(" (->"); 1304 printk(" (->");
@@ -1326,7 +1318,7 @@ static int uvc_scan_chain_forward(struct uvc_video_chain *chain,
1326 return -EINVAL; 1318 return -EINVAL;
1327 } 1319 }
1328 1320
1329 list_add_tail(&forward->chain, &chain->oterms); 1321 list_add_tail(&forward->chain, &chain->entities);
1330 if (uvc_trace_param & UVC_TRACE_PROBE) { 1322 if (uvc_trace_param & UVC_TRACE_PROBE) {
1331 if (!found) 1323 if (!found)
1332 printk(" (->"); 1324 printk(" (->");
@@ -1344,24 +1336,22 @@ static int uvc_scan_chain_forward(struct uvc_video_chain *chain,
1344} 1336}
1345 1337
1346static int uvc_scan_chain_backward(struct uvc_video_chain *chain, 1338static int uvc_scan_chain_backward(struct uvc_video_chain *chain,
1347 struct uvc_entity *entity) 1339 struct uvc_entity **_entity)
1348{ 1340{
1341 struct uvc_entity *entity = *_entity;
1349 struct uvc_entity *term; 1342 struct uvc_entity *term;
1350 int id = -1, i; 1343 int id = -EINVAL, i;
1351 1344
1352 switch (UVC_ENTITY_TYPE(entity)) { 1345 switch (UVC_ENTITY_TYPE(entity)) {
1353 case UVC_VC_EXTENSION_UNIT: 1346 case UVC_VC_EXTENSION_UNIT:
1354 id = entity->extension.baSourceID[0];
1355 break;
1356
1357 case UVC_VC_PROCESSING_UNIT: 1347 case UVC_VC_PROCESSING_UNIT:
1358 id = entity->processing.bSourceID; 1348 id = entity->baSourceID[0];
1359 break; 1349 break;
1360 1350
1361 case UVC_VC_SELECTOR_UNIT: 1351 case UVC_VC_SELECTOR_UNIT:
1362 /* Single-input selector units are ignored. */ 1352 /* Single-input selector units are ignored. */
1363 if (entity->selector.bNrInPins == 1) { 1353 if (entity->bNrInPins == 1) {
1364 id = entity->selector.baSourceID[0]; 1354 id = entity->baSourceID[0];
1365 break; 1355 break;
1366 } 1356 }
1367 1357
@@ -1369,8 +1359,8 @@ static int uvc_scan_chain_backward(struct uvc_video_chain *chain,
1369 printk(" <- IT"); 1359 printk(" <- IT");
1370 1360
1371 chain->selector = entity; 1361 chain->selector = entity;
1372 for (i = 0; i < entity->selector.bNrInPins; ++i) { 1362 for (i = 0; i < entity->bNrInPins; ++i) {
1373 id = entity->selector.baSourceID[i]; 1363 id = entity->baSourceID[i];
1374 term = uvc_entity_by_id(chain->dev, id); 1364 term = uvc_entity_by_id(chain->dev, id);
1375 if (term == NULL || !UVC_ENTITY_IS_ITERM(term)) { 1365 if (term == NULL || !UVC_ENTITY_IS_ITERM(term)) {
1376 uvc_trace(UVC_TRACE_DESCR, "Selector unit %d " 1366 uvc_trace(UVC_TRACE_DESCR, "Selector unit %d "
@@ -1382,7 +1372,7 @@ static int uvc_scan_chain_backward(struct uvc_video_chain *chain,
1382 if (uvc_trace_param & UVC_TRACE_PROBE) 1372 if (uvc_trace_param & UVC_TRACE_PROBE)
1383 printk(" %d", term->id); 1373 printk(" %d", term->id);
1384 1374
1385 list_add_tail(&term->chain, &chain->iterms); 1375 list_add_tail(&term->chain, &chain->entities);
1386 uvc_scan_chain_forward(chain, term, entity); 1376 uvc_scan_chain_forward(chain, term, entity);
1387 } 1377 }
1388 1378
@@ -1391,34 +1381,49 @@ static int uvc_scan_chain_backward(struct uvc_video_chain *chain,
1391 1381
1392 id = 0; 1382 id = 0;
1393 break; 1383 break;
1384
1385 case UVC_ITT_VENDOR_SPECIFIC:
1386 case UVC_ITT_CAMERA:
1387 case UVC_ITT_MEDIA_TRANSPORT_INPUT:
1388 case UVC_OTT_VENDOR_SPECIFIC:
1389 case UVC_OTT_DISPLAY:
1390 case UVC_OTT_MEDIA_TRANSPORT_OUTPUT:
1391 case UVC_TT_STREAMING:
1392 id = UVC_ENTITY_IS_OTERM(entity) ? entity->baSourceID[0] : 0;
1393 break;
1394 }
1395
1396 if (id <= 0) {
1397 *_entity = NULL;
1398 return id;
1394 } 1399 }
1395 1400
1396 return id; 1401 entity = uvc_entity_by_id(chain->dev, id);
1402 if (entity == NULL) {
1403 uvc_trace(UVC_TRACE_DESCR, "Found reference to "
1404 "unknown entity %d.\n", id);
1405 return -EINVAL;
1406 }
1407
1408 *_entity = entity;
1409 return 0;
1397} 1410}
1398 1411
1399static int uvc_scan_chain(struct uvc_video_chain *chain, 1412static int uvc_scan_chain(struct uvc_video_chain *chain,
1400 struct uvc_entity *oterm) 1413 struct uvc_entity *term)
1401{ 1414{
1402 struct uvc_entity *entity, *prev; 1415 struct uvc_entity *entity, *prev;
1403 int id;
1404 1416
1405 entity = oterm; 1417 uvc_trace(UVC_TRACE_PROBE, "Scanning UVC chain:");
1406 list_add_tail(&entity->chain, &chain->oterms);
1407 uvc_trace(UVC_TRACE_PROBE, "Scanning UVC chain: OT %d", entity->id);
1408 1418
1409 id = entity->output.bSourceID; 1419 entity = term;
1410 while (id != 0) { 1420 prev = NULL;
1411 prev = entity;
1412 entity = uvc_entity_by_id(chain->dev, id);
1413 if (entity == NULL) {
1414 uvc_trace(UVC_TRACE_DESCR, "Found reference to "
1415 "unknown entity %d.\n", id);
1416 return -EINVAL;
1417 }
1418 1421
1422 while (entity != NULL) {
1423 /* Entity must not be part of an existing chain */
1419 if (entity->chain.next || entity->chain.prev) { 1424 if (entity->chain.next || entity->chain.prev) {
1420 uvc_trace(UVC_TRACE_DESCR, "Found reference to " 1425 uvc_trace(UVC_TRACE_DESCR, "Found reference to "
1421 "entity %d already in chain.\n", id); 1426 "entity %d already in chain.\n", entity->id);
1422 return -EINVAL; 1427 return -EINVAL;
1423 } 1428 }
1424 1429
@@ -1430,34 +1435,34 @@ static int uvc_scan_chain(struct uvc_video_chain *chain,
1430 if (uvc_scan_chain_forward(chain, entity, prev) < 0) 1435 if (uvc_scan_chain_forward(chain, entity, prev) < 0)
1431 return -EINVAL; 1436 return -EINVAL;
1432 1437
1433 /* Stop when a terminal is found. */
1434 if (UVC_ENTITY_IS_TERM(entity))
1435 break;
1436
1437 /* Backward scan */ 1438 /* Backward scan */
1438 id = uvc_scan_chain_backward(chain, entity); 1439 prev = entity;
1439 if (id < 0) 1440 if (uvc_scan_chain_backward(chain, &entity) < 0)
1440 return id; 1441 return -EINVAL;
1441 } 1442 }
1442 1443
1443 return 0; 1444 return 0;
1444} 1445}
1445 1446
1446static unsigned int uvc_print_terms(struct list_head *terms, char *buffer) 1447static unsigned int uvc_print_terms(struct list_head *terms, u16 dir,
1448 char *buffer)
1447{ 1449{
1448 struct uvc_entity *term; 1450 struct uvc_entity *term;
1449 unsigned int nterms = 0; 1451 unsigned int nterms = 0;
1450 char *p = buffer; 1452 char *p = buffer;
1451 1453
1452 list_for_each_entry(term, terms, chain) { 1454 list_for_each_entry(term, terms, chain) {
1453 p += sprintf(p, "%u", term->id); 1455 if (!UVC_ENTITY_IS_TERM(term) ||
1454 if (term->chain.next != terms) { 1456 UVC_TERM_DIRECTION(term) != dir)
1457 continue;
1458
1459 if (nterms)
1455 p += sprintf(p, ","); 1460 p += sprintf(p, ",");
1456 if (++nterms >= 4) { 1461 if (++nterms >= 4) {
1457 p += sprintf(p, "..."); 1462 p += sprintf(p, "...");
1458 break; 1463 break;
1459 }
1460 } 1464 }
1465 p += sprintf(p, "%u", term->id);
1461 } 1466 }
1462 1467
1463 return p - buffer; 1468 return p - buffer;
@@ -1468,9 +1473,9 @@ static const char *uvc_print_chain(struct uvc_video_chain *chain)
1468 static char buffer[43]; 1473 static char buffer[43];
1469 char *p = buffer; 1474 char *p = buffer;
1470 1475
1471 p += uvc_print_terms(&chain->iterms, p); 1476 p += uvc_print_terms(&chain->entities, UVC_TERM_INPUT, p);
1472 p += sprintf(p, " -> "); 1477 p += sprintf(p, " -> ");
1473 uvc_print_terms(&chain->oterms, p); 1478 uvc_print_terms(&chain->entities, UVC_TERM_OUTPUT, p);
1474 1479
1475 return buffer; 1480 return buffer;
1476} 1481}
@@ -1501,9 +1506,7 @@ static int uvc_scan_device(struct uvc_device *dev)
1501 if (chain == NULL) 1506 if (chain == NULL)
1502 return -ENOMEM; 1507 return -ENOMEM;
1503 1508
1504 INIT_LIST_HEAD(&chain->iterms); 1509 INIT_LIST_HEAD(&chain->entities);
1505 INIT_LIST_HEAD(&chain->oterms);
1506 INIT_LIST_HEAD(&chain->extensions);
1507 mutex_init(&chain->ctrl_mutex); 1510 mutex_init(&chain->ctrl_mutex);
1508 chain->dev = dev; 1511 chain->dev = dev;
1509 1512
@@ -1531,22 +1534,92 @@ static int uvc_scan_device(struct uvc_device *dev)
1531 */ 1534 */
1532 1535
1533/* 1536/*
1537 * Delete the UVC device.
1538 *
1539 * Called by the kernel when the last reference to the uvc_device structure
1540 * is released.
1541 *
1542 * As this function is called after or during disconnect(), all URBs have
1543 * already been canceled by the USB core. There is no need to kill the
1544 * interrupt URB manually.
1545 */
1546static void uvc_delete(struct uvc_device *dev)
1547{
1548 struct list_head *p, *n;
1549
1550 usb_put_intf(dev->intf);
1551 usb_put_dev(dev->udev);
1552
1553 uvc_status_cleanup(dev);
1554 uvc_ctrl_cleanup_device(dev);
1555
1556 list_for_each_safe(p, n, &dev->chains) {
1557 struct uvc_video_chain *chain;
1558 chain = list_entry(p, struct uvc_video_chain, list);
1559 kfree(chain);
1560 }
1561
1562 list_for_each_safe(p, n, &dev->entities) {
1563 struct uvc_entity *entity;
1564 entity = list_entry(p, struct uvc_entity, list);
1565 kfree(entity);
1566 }
1567
1568 list_for_each_safe(p, n, &dev->streams) {
1569 struct uvc_streaming *streaming;
1570 streaming = list_entry(p, struct uvc_streaming, list);
1571 usb_driver_release_interface(&uvc_driver.driver,
1572 streaming->intf);
1573 usb_put_intf(streaming->intf);
1574 kfree(streaming->format);
1575 kfree(streaming->header.bmaControls);
1576 kfree(streaming);
1577 }
1578
1579 kfree(dev);
1580}
1581
1582static void uvc_release(struct video_device *vdev)
1583{
1584 struct uvc_streaming *stream = video_get_drvdata(vdev);
1585 struct uvc_device *dev = stream->dev;
1586
1587 video_device_release(vdev);
1588
1589 /* Decrement the registered streams count and delete the device when it
1590 * reaches zero.
1591 */
1592 if (atomic_dec_and_test(&dev->nstreams))
1593 uvc_delete(dev);
1594}
1595
1596/*
1534 * Unregister the video devices. 1597 * Unregister the video devices.
1535 */ 1598 */
1536static void uvc_unregister_video(struct uvc_device *dev) 1599static void uvc_unregister_video(struct uvc_device *dev)
1537{ 1600{
1538 struct uvc_streaming *stream; 1601 struct uvc_streaming *stream;
1539 1602
1603 /* Unregistering all video devices might result in uvc_delete() being
1604 * called from inside the loop if there's no open file handle. To avoid
1605 * that, increment the stream count before iterating over the streams
1606 * and decrement it when done.
1607 */
1608 atomic_inc(&dev->nstreams);
1609
1540 list_for_each_entry(stream, &dev->streams, list) { 1610 list_for_each_entry(stream, &dev->streams, list) {
1541 if (stream->vdev == NULL) 1611 if (stream->vdev == NULL)
1542 continue; 1612 continue;
1543 1613
1544 if (stream->vdev->minor == -1) 1614 video_unregister_device(stream->vdev);
1545 video_device_release(stream->vdev);
1546 else
1547 video_unregister_device(stream->vdev);
1548 stream->vdev = NULL; 1615 stream->vdev = NULL;
1549 } 1616 }
1617
1618 /* Decrement the stream count and call uvc_delete explicitly if there
1619 * are no stream left.
1620 */
1621 if (atomic_dec_and_test(&dev->nstreams))
1622 uvc_delete(dev);
1550} 1623}
1551 1624
1552static int uvc_register_video(struct uvc_device *dev, 1625static int uvc_register_video(struct uvc_device *dev,
@@ -1580,7 +1653,7 @@ static int uvc_register_video(struct uvc_device *dev,
1580 vdev->parent = &dev->intf->dev; 1653 vdev->parent = &dev->intf->dev;
1581 vdev->minor = -1; 1654 vdev->minor = -1;
1582 vdev->fops = &uvc_fops; 1655 vdev->fops = &uvc_fops;
1583 vdev->release = video_device_release; 1656 vdev->release = uvc_release;
1584 strlcpy(vdev->name, dev->name, sizeof vdev->name); 1657 strlcpy(vdev->name, dev->name, sizeof vdev->name);
1585 1658
1586 /* Set the driver data before calling video_register_device, otherwise 1659 /* Set the driver data before calling video_register_device, otherwise
@@ -1598,6 +1671,7 @@ static int uvc_register_video(struct uvc_device *dev,
1598 return ret; 1671 return ret;
1599 } 1672 }
1600 1673
1674 atomic_inc(&dev->nstreams);
1601 return 0; 1675 return 0;
1602} 1676}
1603 1677
@@ -1605,13 +1679,13 @@ static int uvc_register_video(struct uvc_device *dev,
1605 * Register all video devices in all chains. 1679 * Register all video devices in all chains.
1606 */ 1680 */
1607static int uvc_register_terms(struct uvc_device *dev, 1681static int uvc_register_terms(struct uvc_device *dev,
1608 struct uvc_video_chain *chain, struct list_head *terms) 1682 struct uvc_video_chain *chain)
1609{ 1683{
1610 struct uvc_streaming *stream; 1684 struct uvc_streaming *stream;
1611 struct uvc_entity *term; 1685 struct uvc_entity *term;
1612 int ret; 1686 int ret;
1613 1687
1614 list_for_each_entry(term, terms, chain) { 1688 list_for_each_entry(term, &chain->entities, chain) {
1615 if (UVC_ENTITY_TYPE(term) != UVC_TT_STREAMING) 1689 if (UVC_ENTITY_TYPE(term) != UVC_TT_STREAMING)
1616 continue; 1690 continue;
1617 1691
@@ -1637,11 +1711,7 @@ static int uvc_register_chains(struct uvc_device *dev)
1637 int ret; 1711 int ret;
1638 1712
1639 list_for_each_entry(chain, &dev->chains, list) { 1713 list_for_each_entry(chain, &dev->chains, list) {
1640 ret = uvc_register_terms(dev, chain, &chain->iterms); 1714 ret = uvc_register_terms(dev, chain);
1641 if (ret < 0)
1642 return ret;
1643
1644 ret = uvc_register_terms(dev, chain, &chain->oterms);
1645 if (ret < 0) 1715 if (ret < 0)
1646 return ret; 1716 return ret;
1647 } 1717 }
@@ -1653,61 +1723,6 @@ static int uvc_register_chains(struct uvc_device *dev)
1653 * USB probe, disconnect, suspend and resume 1723 * USB probe, disconnect, suspend and resume
1654 */ 1724 */
1655 1725
1656/*
1657 * Delete the UVC device.
1658 *
1659 * Called by the kernel when the last reference to the uvc_device structure
1660 * is released.
1661 *
1662 * Unregistering the video devices is done here because every opened instance
1663 * must be closed before the device can be unregistered. An alternative would
1664 * have been to use another reference count for uvc_v4l2_open/uvc_release, and
1665 * unregister the video devices on disconnect when that reference count drops
1666 * to zero.
1667 *
1668 * As this function is called after or during disconnect(), all URBs have
1669 * already been canceled by the USB core. There is no need to kill the
1670 * interrupt URB manually.
1671 */
1672void uvc_delete(struct kref *kref)
1673{
1674 struct uvc_device *dev = container_of(kref, struct uvc_device, kref);
1675 struct list_head *p, *n;
1676
1677 /* Unregister the video devices. */
1678 uvc_unregister_video(dev);
1679 usb_put_intf(dev->intf);
1680 usb_put_dev(dev->udev);
1681
1682 uvc_status_cleanup(dev);
1683 uvc_ctrl_cleanup_device(dev);
1684
1685 list_for_each_safe(p, n, &dev->chains) {
1686 struct uvc_video_chain *chain;
1687 chain = list_entry(p, struct uvc_video_chain, list);
1688 kfree(chain);
1689 }
1690
1691 list_for_each_safe(p, n, &dev->entities) {
1692 struct uvc_entity *entity;
1693 entity = list_entry(p, struct uvc_entity, list);
1694 kfree(entity);
1695 }
1696
1697 list_for_each_safe(p, n, &dev->streams) {
1698 struct uvc_streaming *streaming;
1699 streaming = list_entry(p, struct uvc_streaming, list);
1700 usb_driver_release_interface(&uvc_driver.driver,
1701 streaming->intf);
1702 usb_put_intf(streaming->intf);
1703 kfree(streaming->format);
1704 kfree(streaming->header.bmaControls);
1705 kfree(streaming);
1706 }
1707
1708 kfree(dev);
1709}
1710
1711static int uvc_probe(struct usb_interface *intf, 1726static int uvc_probe(struct usb_interface *intf,
1712 const struct usb_device_id *id) 1727 const struct usb_device_id *id)
1713{ 1728{
@@ -1730,7 +1745,7 @@ static int uvc_probe(struct usb_interface *intf,
1730 INIT_LIST_HEAD(&dev->entities); 1745 INIT_LIST_HEAD(&dev->entities);
1731 INIT_LIST_HEAD(&dev->chains); 1746 INIT_LIST_HEAD(&dev->chains);
1732 INIT_LIST_HEAD(&dev->streams); 1747 INIT_LIST_HEAD(&dev->streams);
1733 kref_init(&dev->kref); 1748 atomic_set(&dev->nstreams, 0);
1734 atomic_set(&dev->users, 0); 1749 atomic_set(&dev->users, 0);
1735 1750
1736 dev->udev = usb_get_dev(udev); 1751 dev->udev = usb_get_dev(udev);
@@ -1792,7 +1807,7 @@ static int uvc_probe(struct usb_interface *intf,
1792 return 0; 1807 return 0;
1793 1808
1794error: 1809error:
1795 kref_put(&dev->kref, uvc_delete); 1810 uvc_unregister_video(dev);
1796 return -ENODEV; 1811 return -ENODEV;
1797} 1812}
1798 1813
@@ -1809,21 +1824,9 @@ static void uvc_disconnect(struct usb_interface *intf)
1809 UVC_SC_VIDEOSTREAMING) 1824 UVC_SC_VIDEOSTREAMING)
1810 return; 1825 return;
1811 1826
1812 /* uvc_v4l2_open() might race uvc_disconnect(). A static driver-wide
1813 * lock is needed to prevent uvc_disconnect from releasing its
1814 * reference to the uvc_device instance after uvc_v4l2_open() received
1815 * the pointer to the device (video_devdata) but before it got the
1816 * chance to increase the reference count (kref_get).
1817 *
1818 * Note that the reference can't be released with the lock held,
1819 * otherwise a AB-BA deadlock can occur with videodev_lock that
1820 * videodev acquires in videodev_open() and video_unregister_device().
1821 */
1822 mutex_lock(&uvc_driver.open_mutex);
1823 dev->state |= UVC_DEV_DISCONNECTED; 1827 dev->state |= UVC_DEV_DISCONNECTED;
1824 mutex_unlock(&uvc_driver.open_mutex);
1825 1828
1826 kref_put(&dev->kref, uvc_delete); 1829 uvc_unregister_video(dev);
1827} 1830}
1828 1831
1829static int uvc_suspend(struct usb_interface *intf, pm_message_t message) 1832static int uvc_suspend(struct usb_interface *intf, pm_message_t message)
@@ -1899,6 +1902,15 @@ static int uvc_reset_resume(struct usb_interface *intf)
1899 * though they are compliant. 1902 * though they are compliant.
1900 */ 1903 */
1901static struct usb_device_id uvc_ids[] = { 1904static struct usb_device_id uvc_ids[] = {
1905 /* Genius eFace 2025 */
1906 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
1907 | USB_DEVICE_ID_MATCH_INT_INFO,
1908 .idVendor = 0x0458,
1909 .idProduct = 0x706e,
1910 .bInterfaceClass = USB_CLASS_VIDEO,
1911 .bInterfaceSubClass = 1,
1912 .bInterfaceProtocol = 0,
1913 .driver_info = UVC_QUIRK_PROBE_MINMAX },
1902 /* Microsoft Lifecam NX-6000 */ 1914 /* Microsoft Lifecam NX-6000 */
1903 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE 1915 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
1904 | USB_DEVICE_ID_MATCH_INT_INFO, 1916 | USB_DEVICE_ID_MATCH_INT_INFO,
@@ -2123,6 +2135,15 @@ static struct usb_device_id uvc_ids[] = {
2123 .bInterfaceSubClass = 1, 2135 .bInterfaceSubClass = 1,
2124 .bInterfaceProtocol = 0, 2136 .bInterfaceProtocol = 0,
2125 .driver_info = UVC_QUIRK_STATUS_INTERVAL }, 2137 .driver_info = UVC_QUIRK_STATUS_INTERVAL },
2138 /* MSI StarCam 370i */
2139 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2140 | USB_DEVICE_ID_MATCH_INT_INFO,
2141 .idVendor = 0x1b3b,
2142 .idProduct = 0x2951,
2143 .bInterfaceClass = USB_CLASS_VIDEO,
2144 .bInterfaceSubClass = 1,
2145 .bInterfaceProtocol = 0,
2146 .driver_info = UVC_QUIRK_PROBE_MINMAX },
2126 /* SiGma Micro USB Web Camera */ 2147 /* SiGma Micro USB Web Camera */
2127 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE 2148 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2128 | USB_DEVICE_ID_MATCH_INT_INFO, 2149 | USB_DEVICE_ID_MATCH_INT_INFO,
@@ -2159,7 +2180,6 @@ static int __init uvc_init(void)
2159 2180
2160 INIT_LIST_HEAD(&uvc_driver.devices); 2181 INIT_LIST_HEAD(&uvc_driver.devices);
2161 INIT_LIST_HEAD(&uvc_driver.controls); 2182 INIT_LIST_HEAD(&uvc_driver.controls);
2162 mutex_init(&uvc_driver.open_mutex);
2163 mutex_init(&uvc_driver.ctrl_mutex); 2183 mutex_init(&uvc_driver.ctrl_mutex);
2164 2184
2165 uvc_ctrl_init(); 2185 uvc_ctrl_init();
@@ -2184,6 +2204,8 @@ module_param_named(quirks, uvc_quirks_param, uint, S_IRUGO|S_IWUSR);
2184MODULE_PARM_DESC(quirks, "Forced device quirks"); 2204MODULE_PARM_DESC(quirks, "Forced device quirks");
2185module_param_named(trace, uvc_trace_param, uint, S_IRUGO|S_IWUSR); 2205module_param_named(trace, uvc_trace_param, uint, S_IRUGO|S_IWUSR);
2186MODULE_PARM_DESC(trace, "Trace level bitmask"); 2206MODULE_PARM_DESC(trace, "Trace level bitmask");
2207module_param_named(timeout, uvc_timeout_param, uint, S_IRUGO|S_IWUSR);
2208MODULE_PARM_DESC(timeout, "Streaming control requests timeout");
2187 2209
2188MODULE_AUTHOR(DRIVER_AUTHOR); 2210MODULE_AUTHOR(DRIVER_AUTHOR);
2189MODULE_DESCRIPTION(DRIVER_DESC); 2211MODULE_DESCRIPTION(DRIVER_DESC);
diff --git a/drivers/media/video/uvc/uvc_v4l2.c b/drivers/media/video/uvc/uvc_v4l2.c
index a2bdd806efab..23239a4adefe 100644
--- a/drivers/media/video/uvc/uvc_v4l2.c
+++ b/drivers/media/video/uvc/uvc_v4l2.c
@@ -364,37 +364,30 @@ static int uvc_v4l2_set_streamparm(struct uvc_streaming *stream,
364 * unprivileged state. Only a single instance can be in a privileged state at 364 * unprivileged state. Only a single instance can be in a privileged state at
365 * a given time. Trying to perform an operation that requires privileges will 365 * a given time. Trying to perform an operation that requires privileges will
366 * automatically acquire the required privileges if possible, or return -EBUSY 366 * automatically acquire the required privileges if possible, or return -EBUSY
367 * otherwise. Privileges are dismissed when closing the instance. 367 * otherwise. Privileges are dismissed when closing the instance or when
368 * freeing the video buffers using VIDIOC_REQBUFS.
368 * 369 *
369 * Operations that require privileges are: 370 * Operations that require privileges are:
370 * 371 *
371 * - VIDIOC_S_INPUT 372 * - VIDIOC_S_INPUT
372 * - VIDIOC_S_PARM 373 * - VIDIOC_S_PARM
373 * - VIDIOC_S_FMT 374 * - VIDIOC_S_FMT
374 * - VIDIOC_TRY_FMT
375 * - VIDIOC_REQBUFS 375 * - VIDIOC_REQBUFS
376 */ 376 */
377static int uvc_acquire_privileges(struct uvc_fh *handle) 377static int uvc_acquire_privileges(struct uvc_fh *handle)
378{ 378{
379 int ret = 0;
380
381 /* Always succeed if the handle is already privileged. */ 379 /* Always succeed if the handle is already privileged. */
382 if (handle->state == UVC_HANDLE_ACTIVE) 380 if (handle->state == UVC_HANDLE_ACTIVE)
383 return 0; 381 return 0;
384 382
385 /* Check if the device already has a privileged handle. */ 383 /* Check if the device already has a privileged handle. */
386 mutex_lock(&uvc_driver.open_mutex);
387 if (atomic_inc_return(&handle->stream->active) != 1) { 384 if (atomic_inc_return(&handle->stream->active) != 1) {
388 atomic_dec(&handle->stream->active); 385 atomic_dec(&handle->stream->active);
389 ret = -EBUSY; 386 return -EBUSY;
390 goto done;
391 } 387 }
392 388
393 handle->state = UVC_HANDLE_ACTIVE; 389 handle->state = UVC_HANDLE_ACTIVE;
394 390 return 0;
395done:
396 mutex_unlock(&uvc_driver.open_mutex);
397 return ret;
398} 391}
399 392
400static void uvc_dismiss_privileges(struct uvc_fh *handle) 393static void uvc_dismiss_privileges(struct uvc_fh *handle)
@@ -421,24 +414,20 @@ static int uvc_v4l2_open(struct file *file)
421 int ret = 0; 414 int ret = 0;
422 415
423 uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_open\n"); 416 uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_open\n");
424 mutex_lock(&uvc_driver.open_mutex);
425 stream = video_drvdata(file); 417 stream = video_drvdata(file);
426 418
427 if (stream->dev->state & UVC_DEV_DISCONNECTED) { 419 if (stream->dev->state & UVC_DEV_DISCONNECTED)
428 ret = -ENODEV; 420 return -ENODEV;
429 goto done;
430 }
431 421
432 ret = usb_autopm_get_interface(stream->dev->intf); 422 ret = usb_autopm_get_interface(stream->dev->intf);
433 if (ret < 0) 423 if (ret < 0)
434 goto done; 424 return ret;
435 425
436 /* Create the device handle. */ 426 /* Create the device handle. */
437 handle = kzalloc(sizeof *handle, GFP_KERNEL); 427 handle = kzalloc(sizeof *handle, GFP_KERNEL);
438 if (handle == NULL) { 428 if (handle == NULL) {
439 usb_autopm_put_interface(stream->dev->intf); 429 usb_autopm_put_interface(stream->dev->intf);
440 ret = -ENOMEM; 430 return -ENOMEM;
441 goto done;
442 } 431 }
443 432
444 if (atomic_inc_return(&stream->dev->users) == 1) { 433 if (atomic_inc_return(&stream->dev->users) == 1) {
@@ -447,7 +436,7 @@ static int uvc_v4l2_open(struct file *file)
447 usb_autopm_put_interface(stream->dev->intf); 436 usb_autopm_put_interface(stream->dev->intf);
448 atomic_dec(&stream->dev->users); 437 atomic_dec(&stream->dev->users);
449 kfree(handle); 438 kfree(handle);
450 goto done; 439 return ret;
451 } 440 }
452 } 441 }
453 442
@@ -456,11 +445,7 @@ static int uvc_v4l2_open(struct file *file)
456 handle->state = UVC_HANDLE_PASSIVE; 445 handle->state = UVC_HANDLE_PASSIVE;
457 file->private_data = handle; 446 file->private_data = handle;
458 447
459 kref_get(&stream->dev->kref); 448 return 0;
460
461done:
462 mutex_unlock(&uvc_driver.open_mutex);
463 return ret;
464} 449}
465 450
466static int uvc_v4l2_release(struct file *file) 451static int uvc_v4l2_release(struct file *file)
@@ -490,7 +475,6 @@ static int uvc_v4l2_release(struct file *file)
490 uvc_status_stop(stream->dev); 475 uvc_status_stop(stream->dev);
491 476
492 usb_autopm_put_interface(stream->dev->intf); 477 usb_autopm_put_interface(stream->dev->intf);
493 kref_put(&stream->dev->kref, uvc_delete);
494 return 0; 478 return 0;
495} 479}
496 480
@@ -636,12 +620,16 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
636 (chain->dev->quirks & UVC_QUIRK_IGNORE_SELECTOR_UNIT)) { 620 (chain->dev->quirks & UVC_QUIRK_IGNORE_SELECTOR_UNIT)) {
637 if (index != 0) 621 if (index != 0)
638 return -EINVAL; 622 return -EINVAL;
639 iterm = list_first_entry(&chain->iterms, 623 list_for_each_entry(iterm, &chain->entities, chain) {
640 struct uvc_entity, chain); 624 if (UVC_ENTITY_IS_ITERM(iterm))
625 break;
626 }
641 pin = iterm->id; 627 pin = iterm->id;
642 } else if (pin < selector->selector.bNrInPins) { 628 } else if (pin < selector->bNrInPins) {
643 pin = selector->selector.baSourceID[index]; 629 pin = selector->baSourceID[index];
644 list_for_each_entry(iterm, chain->iterms.next, chain) { 630 list_for_each_entry(iterm, &chain->entities, chain) {
631 if (!UVC_ENTITY_IS_ITERM(iterm))
632 continue;
645 if (iterm->id == pin) 633 if (iterm->id == pin)
646 break; 634 break;
647 } 635 }
@@ -692,7 +680,7 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
692 break; 680 break;
693 } 681 }
694 682
695 if (input == 0 || input > chain->selector->selector.bNrInPins) 683 if (input == 0 || input > chain->selector->bNrInPins)
696 return -EINVAL; 684 return -EINVAL;
697 685
698 return uvc_query_ctrl(chain->dev, UVC_SET_CUR, 686 return uvc_query_ctrl(chain->dev, UVC_SET_CUR,
@@ -731,9 +719,6 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
731 { 719 {
732 struct uvc_streaming_control probe; 720 struct uvc_streaming_control probe;
733 721
734 if ((ret = uvc_acquire_privileges(handle)) < 0)
735 return ret;
736
737 return uvc_v4l2_try_format(stream, arg, &probe, NULL, NULL); 722 return uvc_v4l2_try_format(stream, arg, &probe, NULL, NULL);
738 } 723 }
739 724
@@ -888,6 +873,9 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
888 if (ret < 0) 873 if (ret < 0)
889 return ret; 874 return ret;
890 875
876 if (ret == 0)
877 uvc_dismiss_privileges(handle);
878
891 rb->count = ret; 879 rb->count = ret;
892 ret = 0; 880 ret = 0;
893 break; 881 break;
@@ -1051,7 +1039,7 @@ static ssize_t uvc_v4l2_read(struct file *file, char __user *data,
1051 size_t count, loff_t *ppos) 1039 size_t count, loff_t *ppos)
1052{ 1040{
1053 uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_read: not implemented.\n"); 1041 uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_read: not implemented.\n");
1054 return -ENODEV; 1042 return -EINVAL;
1055} 1043}
1056 1044
1057/* 1045/*
diff --git a/drivers/media/video/uvc/uvc_video.c b/drivers/media/video/uvc/uvc_video.c
index a6e41d12b221..05139a4f14f6 100644
--- a/drivers/media/video/uvc/uvc_video.c
+++ b/drivers/media/video/uvc/uvc_video.c
@@ -135,7 +135,7 @@ static int uvc_get_video_ctrl(struct uvc_streaming *stream,
135 135
136 ret = __uvc_query_ctrl(stream->dev, query, 0, stream->intfnum, 136 ret = __uvc_query_ctrl(stream->dev, query, 0, stream->intfnum,
137 probe ? UVC_VS_PROBE_CONTROL : UVC_VS_COMMIT_CONTROL, data, 137 probe ? UVC_VS_PROBE_CONTROL : UVC_VS_COMMIT_CONTROL, data,
138 size, UVC_CTRL_STREAMING_TIMEOUT); 138 size, uvc_timeout_param);
139 139
140 if ((query == UVC_GET_MIN || query == UVC_GET_MAX) && ret == 2) { 140 if ((query == UVC_GET_MIN || query == UVC_GET_MAX) && ret == 2) {
141 /* Some cameras, mostly based on Bison Electronics chipsets, 141 /* Some cameras, mostly based on Bison Electronics chipsets,
@@ -239,7 +239,7 @@ static int uvc_set_video_ctrl(struct uvc_streaming *stream,
239 239
240 ret = __uvc_query_ctrl(stream->dev, UVC_SET_CUR, 0, stream->intfnum, 240 ret = __uvc_query_ctrl(stream->dev, UVC_SET_CUR, 0, stream->intfnum,
241 probe ? UVC_VS_PROBE_CONTROL : UVC_VS_COMMIT_CONTROL, data, 241 probe ? UVC_VS_PROBE_CONTROL : UVC_VS_COMMIT_CONTROL, data,
242 size, UVC_CTRL_STREAMING_TIMEOUT); 242 size, uvc_timeout_param);
243 if (ret != size) { 243 if (ret != size) {
244 uvc_printk(KERN_ERR, "Failed to set UVC %s control : " 244 uvc_printk(KERN_ERR, "Failed to set UVC %s control : "
245 "%d (exp. %u).\n", probe ? "probe" : "commit", 245 "%d (exp. %u).\n", probe ? "probe" : "commit",
@@ -770,8 +770,9 @@ static int uvc_alloc_urb_buffers(struct uvc_streaming *stream,
770 /* Retry allocations until one succeed. */ 770 /* Retry allocations until one succeed. */
771 for (; npackets > 1; npackets /= 2) { 771 for (; npackets > 1; npackets /= 2) {
772 for (i = 0; i < UVC_URBS; ++i) { 772 for (i = 0; i < UVC_URBS; ++i) {
773 stream->urb_size = psize * npackets;
773 stream->urb_buffer[i] = usb_buffer_alloc( 774 stream->urb_buffer[i] = usb_buffer_alloc(
774 stream->dev->udev, psize * npackets, 775 stream->dev->udev, stream->urb_size,
775 gfp_flags | __GFP_NOWARN, &stream->urb_dma[i]); 776 gfp_flags | __GFP_NOWARN, &stream->urb_dma[i]);
776 if (!stream->urb_buffer[i]) { 777 if (!stream->urb_buffer[i]) {
777 uvc_free_urb_buffers(stream); 778 uvc_free_urb_buffers(stream);
@@ -780,11 +781,15 @@ static int uvc_alloc_urb_buffers(struct uvc_streaming *stream,
780 } 781 }
781 782
782 if (i == UVC_URBS) { 783 if (i == UVC_URBS) {
783 stream->urb_size = psize * npackets; 784 uvc_trace(UVC_TRACE_VIDEO, "Allocated %u URB buffers "
785 "of %ux%u bytes each.\n", UVC_URBS, npackets,
786 psize);
784 return npackets; 787 return npackets;
785 } 788 }
786 } 789 }
787 790
791 uvc_trace(UVC_TRACE_VIDEO, "Failed to allocate URB buffers (%u bytes "
792 "per packet).\n", psize);
788 return 0; 793 return 0;
789} 794}
790 795
@@ -935,10 +940,12 @@ static int uvc_init_video(struct uvc_streaming *stream, gfp_t gfp_flags)
935 bandwidth = stream->ctrl.dwMaxPayloadTransferSize; 940 bandwidth = stream->ctrl.dwMaxPayloadTransferSize;
936 941
937 if (bandwidth == 0) { 942 if (bandwidth == 0) {
938 uvc_printk(KERN_WARNING, "device %s requested null " 943 uvc_trace(UVC_TRACE_VIDEO, "Device requested null "
939 "bandwidth, defaulting to lowest.\n", 944 "bandwidth, defaulting to lowest.\n");
940 stream->dev->name);
941 bandwidth = 1; 945 bandwidth = 1;
946 } else {
947 uvc_trace(UVC_TRACE_VIDEO, "Device requested %u "
948 "B/frame bandwidth.\n", bandwidth);
942 } 949 }
943 950
944 for (i = 0; i < intf->num_altsetting; ++i) { 951 for (i = 0; i < intf->num_altsetting; ++i) {
@@ -955,8 +962,11 @@ static int uvc_init_video(struct uvc_streaming *stream, gfp_t gfp_flags)
955 break; 962 break;
956 } 963 }
957 964
958 if (i >= intf->num_altsetting) 965 if (i >= intf->num_altsetting) {
966 uvc_trace(UVC_TRACE_VIDEO, "No fast enough alt setting "
967 "for requested bandwidth.\n");
959 return -EIO; 968 return -EIO;
969 }
960 970
961 ret = usb_set_interface(stream->dev->udev, intfnum, i); 971 ret = usb_set_interface(stream->dev->udev, intfnum, i);
962 if (ret < 0) 972 if (ret < 0)
diff --git a/drivers/media/video/uvc/uvcvideo.h b/drivers/media/video/uvc/uvcvideo.h
index e7958aa454ce..7ec9a04ced50 100644
--- a/drivers/media/video/uvc/uvcvideo.h
+++ b/drivers/media/video/uvc/uvcvideo.h
@@ -75,6 +75,7 @@ struct uvc_xu_control {
75 75
76#define UVC_TERM_INPUT 0x0000 76#define UVC_TERM_INPUT 0x0000
77#define UVC_TERM_OUTPUT 0x8000 77#define UVC_TERM_OUTPUT 0x8000
78#define UVC_TERM_DIRECTION(term) ((term)->type & 0x8000)
78 79
79#define UVC_ENTITY_TYPE(entity) ((entity)->type & 0x7fff) 80#define UVC_ENTITY_TYPE(entity) ((entity)->type & 0x7fff)
80#define UVC_ENTITY_IS_UNIT(entity) (((entity)->type & 0xff00) == 0) 81#define UVC_ENTITY_IS_UNIT(entity) (((entity)->type & 0xff00) == 0)
@@ -148,7 +149,7 @@ struct uvc_xu_control {
148#define UVC_MAX_STATUS_SIZE 16 149#define UVC_MAX_STATUS_SIZE 16
149 150
150#define UVC_CTRL_CONTROL_TIMEOUT 300 151#define UVC_CTRL_CONTROL_TIMEOUT 300
151#define UVC_CTRL_STREAMING_TIMEOUT 1000 152#define UVC_CTRL_STREAMING_TIMEOUT 3000
152 153
153/* Devices quirks */ 154/* Devices quirks */
154#define UVC_QUIRK_STATUS_INTERVAL 0x00000001 155#define UVC_QUIRK_STATUS_INTERVAL 0x00000001
@@ -292,11 +293,9 @@ struct uvc_entity {
292 } media; 293 } media;
293 294
294 struct { 295 struct {
295 __u8 bSourceID;
296 } output; 296 } output;
297 297
298 struct { 298 struct {
299 __u8 bSourceID;
300 __u16 wMaxMultiplier; 299 __u16 wMaxMultiplier;
301 __u8 bControlSize; 300 __u8 bControlSize;
302 __u8 *bmControls; 301 __u8 *bmControls;
@@ -304,21 +303,20 @@ struct uvc_entity {
304 } processing; 303 } processing;
305 304
306 struct { 305 struct {
307 __u8 bNrInPins;
308 __u8 *baSourceID;
309 } selector; 306 } selector;
310 307
311 struct { 308 struct {
312 __u8 guidExtensionCode[16]; 309 __u8 guidExtensionCode[16];
313 __u8 bNumControls; 310 __u8 bNumControls;
314 __u8 bNrInPins;
315 __u8 *baSourceID;
316 __u8 bControlSize; 311 __u8 bControlSize;
317 __u8 *bmControls; 312 __u8 *bmControls;
318 __u8 *bmControlsType; 313 __u8 *bmControlsType;
319 } extension; 314 } extension;
320 }; 315 };
321 316
317 __u8 bNrInPins;
318 __u8 *baSourceID;
319
322 unsigned int ncontrols; 320 unsigned int ncontrols;
323 struct uvc_control *controls; 321 struct uvc_control *controls;
324}; 322};
@@ -408,11 +406,9 @@ struct uvc_video_chain {
408 struct uvc_device *dev; 406 struct uvc_device *dev;
409 struct list_head list; 407 struct list_head list;
410 408
411 struct list_head iterms; /* Input terminals */ 409 struct list_head entities; /* All entities */
412 struct list_head oterms; /* Output terminals */
413 struct uvc_entity *processing; /* Processing unit */ 410 struct uvc_entity *processing; /* Processing unit */
414 struct uvc_entity *selector; /* Selector unit */ 411 struct uvc_entity *selector; /* Selector unit */
415 struct list_head extensions; /* Extension units */
416 412
417 struct mutex ctrl_mutex; 413 struct mutex ctrl_mutex;
418}; 414};
@@ -475,7 +471,6 @@ struct uvc_device {
475 char name[32]; 471 char name[32];
476 472
477 enum uvc_device_state state; 473 enum uvc_device_state state;
478 struct kref kref;
479 struct list_head list; 474 struct list_head list;
480 atomic_t users; 475 atomic_t users;
481 476
@@ -488,6 +483,7 @@ struct uvc_device {
488 483
489 /* Video Streaming interfaces */ 484 /* Video Streaming interfaces */
490 struct list_head streams; 485 struct list_head streams;
486 atomic_t nstreams;
491 487
492 /* Status Interrupt Endpoint */ 488 /* Status Interrupt Endpoint */
493 struct usb_host_endpoint *int_ep; 489 struct usb_host_endpoint *int_ep;
@@ -511,8 +507,6 @@ struct uvc_fh {
511struct uvc_driver { 507struct uvc_driver {
512 struct usb_driver driver; 508 struct usb_driver driver;
513 509
514 struct mutex open_mutex; /* protects from open/disconnect race */
515
516 struct list_head devices; /* struct uvc_device list */ 510 struct list_head devices; /* struct uvc_device list */
517 struct list_head controls; /* struct uvc_control_info list */ 511 struct list_head controls; /* struct uvc_control_info list */
518 struct mutex ctrl_mutex; /* protects controls and devices 512 struct mutex ctrl_mutex; /* protects controls and devices
@@ -533,12 +527,14 @@ struct uvc_driver {
533#define UVC_TRACE_FRAME (1 << 7) 527#define UVC_TRACE_FRAME (1 << 7)
534#define UVC_TRACE_SUSPEND (1 << 8) 528#define UVC_TRACE_SUSPEND (1 << 8)
535#define UVC_TRACE_STATUS (1 << 9) 529#define UVC_TRACE_STATUS (1 << 9)
530#define UVC_TRACE_VIDEO (1 << 10)
536 531
537#define UVC_WARN_MINMAX 0 532#define UVC_WARN_MINMAX 0
538#define UVC_WARN_PROBE_DEF 1 533#define UVC_WARN_PROBE_DEF 1
539 534
540extern unsigned int uvc_no_drop_param; 535extern unsigned int uvc_no_drop_param;
541extern unsigned int uvc_trace_param; 536extern unsigned int uvc_trace_param;
537extern unsigned int uvc_timeout_param;
542 538
543#define uvc_trace(flag, msg...) \ 539#define uvc_trace(flag, msg...) \
544 do { \ 540 do { \
@@ -571,7 +567,6 @@ extern unsigned int uvc_trace_param;
571 567
572/* Core driver */ 568/* Core driver */
573extern struct uvc_driver uvc_driver; 569extern struct uvc_driver uvc_driver;
574extern void uvc_delete(struct kref *kref);
575 570
576/* Video buffers queue management. */ 571/* Video buffers queue management. */
577extern void uvc_queue_init(struct uvc_video_queue *queue, 572extern void uvc_queue_init(struct uvc_video_queue *queue,
diff --git a/drivers/media/video/v4l2-common.c b/drivers/media/video/v4l2-common.c
index f5a93ae3cdf9..e8e5affbabce 100644
--- a/drivers/media/video/v4l2-common.c
+++ b/drivers/media/video/v4l2-common.c
@@ -431,6 +431,8 @@ const char *v4l2_ctrl_get_name(u32 id)
431 case V4L2_CID_CHROMA_AGC: return "Chroma AGC"; 431 case V4L2_CID_CHROMA_AGC: return "Chroma AGC";
432 case V4L2_CID_COLOR_KILLER: return "Color Killer"; 432 case V4L2_CID_COLOR_KILLER: return "Color Killer";
433 case V4L2_CID_COLORFX: return "Color Effects"; 433 case V4L2_CID_COLORFX: return "Color Effects";
434 case V4L2_CID_ROTATE: return "Rotate";
435 case V4L2_CID_BG_COLOR: return "Background color";
434 436
435 /* MPEG controls */ 437 /* MPEG controls */
436 case V4L2_CID_MPEG_CLASS: return "MPEG Encoder Controls"; 438 case V4L2_CID_MPEG_CLASS: return "MPEG Encoder Controls";
@@ -587,6 +589,13 @@ int v4l2_ctrl_query_fill(struct v4l2_queryctrl *qctrl, s32 min, s32 max, s32 ste
587 qctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY; 589 qctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
588 min = max = step = def = 0; 590 min = max = step = def = 0;
589 break; 591 break;
592 case V4L2_CID_BG_COLOR:
593 qctrl->type = V4L2_CTRL_TYPE_INTEGER;
594 step = 1;
595 min = 0;
596 /* Max is calculated as RGB888 that is 2^24 */
597 max = 0xFFFFFF;
598 break;
590 default: 599 default:
591 qctrl->type = V4L2_CTRL_TYPE_INTEGER; 600 qctrl->type = V4L2_CTRL_TYPE_INTEGER;
592 break; 601 break;
diff --git a/drivers/media/video/videobuf-core.c b/drivers/media/video/videobuf-core.c
index 8e93c6f25c83..bb0a1c8de414 100644
--- a/drivers/media/video/videobuf-core.c
+++ b/drivers/media/video/videobuf-core.c
@@ -110,7 +110,7 @@ EXPORT_SYMBOL_GPL(videobuf_queue_to_vmalloc);
110 110
111 111
112void videobuf_queue_core_init(struct videobuf_queue *q, 112void videobuf_queue_core_init(struct videobuf_queue *q,
113 struct videobuf_queue_ops *ops, 113 const struct videobuf_queue_ops *ops,
114 struct device *dev, 114 struct device *dev,
115 spinlock_t *irqlock, 115 spinlock_t *irqlock,
116 enum v4l2_buf_type type, 116 enum v4l2_buf_type type,
@@ -360,7 +360,7 @@ int __videobuf_mmap_setup(struct videobuf_queue *q,
360 q->bufs[i]->bsize = bsize; 360 q->bufs[i]->bsize = bsize;
361 switch (memory) { 361 switch (memory) {
362 case V4L2_MEMORY_MMAP: 362 case V4L2_MEMORY_MMAP:
363 q->bufs[i]->boff = bsize * i; 363 q->bufs[i]->boff = PAGE_ALIGN(bsize) * i;
364 break; 364 break;
365 case V4L2_MEMORY_USERPTR: 365 case V4L2_MEMORY_USERPTR:
366 case V4L2_MEMORY_OVERLAY: 366 case V4L2_MEMORY_OVERLAY:
@@ -430,9 +430,9 @@ int videobuf_reqbufs(struct videobuf_queue *q,
430 count = VIDEO_MAX_FRAME; 430 count = VIDEO_MAX_FRAME;
431 size = 0; 431 size = 0;
432 q->ops->buf_setup(q, &count, &size); 432 q->ops->buf_setup(q, &count, &size);
433 size = PAGE_ALIGN(size); 433 dprintk(1, "reqbufs: bufs=%d, size=0x%x [%u pages total]\n",
434 dprintk(1, "reqbufs: bufs=%d, size=0x%x [%d pages total]\n", 434 count, size,
435 count, size, (count*size)>>PAGE_SHIFT); 435 (unsigned int)((count*PAGE_ALIGN(size))>>PAGE_SHIFT) );
436 436
437 retval = __videobuf_mmap_setup(q, count, size, req->memory); 437 retval = __videobuf_mmap_setup(q, count, size, req->memory);
438 if (retval < 0) { 438 if (retval < 0) {
@@ -1099,7 +1099,7 @@ int videobuf_cgmbuf(struct videobuf_queue *q,
1099 mbuf->size = 0; 1099 mbuf->size = 0;
1100 for (i = 0; i < mbuf->frames; i++) { 1100 for (i = 0; i < mbuf->frames; i++) {
1101 mbuf->offsets[i] = q->bufs[i]->boff; 1101 mbuf->offsets[i] = q->bufs[i]->boff;
1102 mbuf->size += q->bufs[i]->bsize; 1102 mbuf->size += PAGE_ALIGN(q->bufs[i]->bsize);
1103 } 1103 }
1104 1104
1105 return 0; 1105 return 0;
diff --git a/drivers/media/video/videobuf-dma-contig.c b/drivers/media/video/videobuf-dma-contig.c
index c3065c4bcba9..d25f28461da1 100644
--- a/drivers/media/video/videobuf-dma-contig.c
+++ b/drivers/media/video/videobuf-dma-contig.c
@@ -429,7 +429,7 @@ static struct videobuf_qtype_ops qops = {
429}; 429};
430 430
431void videobuf_queue_dma_contig_init(struct videobuf_queue *q, 431void videobuf_queue_dma_contig_init(struct videobuf_queue *q,
432 struct videobuf_queue_ops *ops, 432 const struct videobuf_queue_ops *ops,
433 struct device *dev, 433 struct device *dev,
434 spinlock_t *irqlock, 434 spinlock_t *irqlock,
435 enum v4l2_buf_type type, 435 enum v4l2_buf_type type,
diff --git a/drivers/media/video/videobuf-dma-sg.c b/drivers/media/video/videobuf-dma-sg.c
index 032ebae0134a..fa78555b118b 100644
--- a/drivers/media/video/videobuf-dma-sg.c
+++ b/drivers/media/video/videobuf-dma-sg.c
@@ -588,7 +588,7 @@ static int __videobuf_mmap_mapper(struct videobuf_queue *q,
588 retval = -EBUSY; 588 retval = -EBUSY;
589 goto done; 589 goto done;
590 } 590 }
591 size += q->bufs[last]->bsize; 591 size += PAGE_ALIGN(q->bufs[last]->bsize);
592 if (size == (vma->vm_end - vma->vm_start)) 592 if (size == (vma->vm_end - vma->vm_start))
593 break; 593 break;
594 } 594 }
@@ -610,7 +610,7 @@ static int __videobuf_mmap_mapper(struct videobuf_queue *q,
610 continue; 610 continue;
611 q->bufs[i]->map = map; 611 q->bufs[i]->map = map;
612 q->bufs[i]->baddr = vma->vm_start + size; 612 q->bufs[i]->baddr = vma->vm_start + size;
613 size += q->bufs[i]->bsize; 613 size += PAGE_ALIGN(q->bufs[i]->bsize);
614 } 614 }
615 615
616 map->count = 1; 616 map->count = 1;
@@ -702,7 +702,7 @@ void *videobuf_sg_alloc(size_t size)
702} 702}
703 703
704void videobuf_queue_sg_init(struct videobuf_queue* q, 704void videobuf_queue_sg_init(struct videobuf_queue* q,
705 struct videobuf_queue_ops *ops, 705 const struct videobuf_queue_ops *ops,
706 struct device *dev, 706 struct device *dev,
707 spinlock_t *irqlock, 707 spinlock_t *irqlock,
708 enum v4l2_buf_type type, 708 enum v4l2_buf_type type,
diff --git a/drivers/media/video/videobuf-dvb.c b/drivers/media/video/videobuf-dvb.c
index 0e7dcba8e4ae..a56cf0d3a6d6 100644
--- a/drivers/media/video/videobuf-dvb.c
+++ b/drivers/media/video/videobuf-dvb.c
@@ -139,7 +139,9 @@ static int videobuf_dvb_register_adapter(struct videobuf_dvb_frontends *fe,
139 struct device *device, 139 struct device *device,
140 char *adapter_name, 140 char *adapter_name,
141 short *adapter_nr, 141 short *adapter_nr,
142 int mfe_shared) 142 int mfe_shared,
143 int (*fe_ioctl_override)(struct dvb_frontend *,
144 unsigned int, void *, unsigned int))
143{ 145{
144 int result; 146 int result;
145 147
@@ -154,6 +156,7 @@ static int videobuf_dvb_register_adapter(struct videobuf_dvb_frontends *fe,
154 } 156 }
155 fe->adapter.priv = adapter_priv; 157 fe->adapter.priv = adapter_priv;
156 fe->adapter.mfe_shared = mfe_shared; 158 fe->adapter.mfe_shared = mfe_shared;
159 fe->adapter.fe_ioctl_override = fe_ioctl_override;
157 160
158 return result; 161 return result;
159} 162}
@@ -253,7 +256,9 @@ int videobuf_dvb_register_bus(struct videobuf_dvb_frontends *f,
253 void *adapter_priv, 256 void *adapter_priv,
254 struct device *device, 257 struct device *device,
255 short *adapter_nr, 258 short *adapter_nr,
256 int mfe_shared) 259 int mfe_shared,
260 int (*fe_ioctl_override)(struct dvb_frontend *,
261 unsigned int, void *, unsigned int))
257{ 262{
258 struct list_head *list, *q; 263 struct list_head *list, *q;
259 struct videobuf_dvb_frontend *fe; 264 struct videobuf_dvb_frontend *fe;
@@ -267,7 +272,7 @@ int videobuf_dvb_register_bus(struct videobuf_dvb_frontends *f,
267 272
268 /* Bring up the adapter */ 273 /* Bring up the adapter */
269 res = videobuf_dvb_register_adapter(f, module, adapter_priv, device, 274 res = videobuf_dvb_register_adapter(f, module, adapter_priv, device,
270 fe->dvb.name, adapter_nr, mfe_shared); 275 fe->dvb.name, adapter_nr, mfe_shared, fe_ioctl_override);
271 if (res < 0) { 276 if (res < 0) {
272 printk(KERN_WARNING "videobuf_dvb_register_adapter failed (errno = %d)\n", res); 277 printk(KERN_WARNING "videobuf_dvb_register_adapter failed (errno = %d)\n", res);
273 return res; 278 return res;
diff --git a/drivers/media/video/videobuf-vmalloc.c b/drivers/media/video/videobuf-vmalloc.c
index 35f3900c5633..d6e6a28fb6b8 100644
--- a/drivers/media/video/videobuf-vmalloc.c
+++ b/drivers/media/video/videobuf-vmalloc.c
@@ -391,8 +391,8 @@ static struct videobuf_qtype_ops qops = {
391}; 391};
392 392
393void videobuf_queue_vmalloc_init(struct videobuf_queue* q, 393void videobuf_queue_vmalloc_init(struct videobuf_queue* q,
394 struct videobuf_queue_ops *ops, 394 const struct videobuf_queue_ops *ops,
395 void *dev, 395 struct device *dev,
396 spinlock_t *irqlock, 396 spinlock_t *irqlock,
397 enum v4l2_buf_type type, 397 enum v4l2_buf_type type,
398 enum v4l2_field field, 398 enum v4l2_field field,
diff --git a/drivers/media/video/vpx3220.c b/drivers/media/video/vpx3220.c
index 97e0ce28ff18..33205d7537d8 100644
--- a/drivers/media/video/vpx3220.c
+++ b/drivers/media/video/vpx3220.c
@@ -391,7 +391,7 @@ static int vpx3220_s_routing(struct v4l2_subdev *sd,
391 {0x0e, 1} 391 {0x0e, 1}
392 }; 392 };
393 393
394 if (input < 0 || input > 2) 394 if (input > 2)
395 return -EINVAL; 395 return -EINVAL;
396 396
397 v4l2_dbg(1, debug, sd, "input switched to %s\n", inputs[input]); 397 v4l2_dbg(1, debug, sd, "input switched to %s\n", inputs[input]);
diff --git a/drivers/media/video/zoran/zoran_driver.c b/drivers/media/video/zoran/zoran_driver.c
index 47137deafcfd..e9f72ca458f1 100644
--- a/drivers/media/video/zoran/zoran_driver.c
+++ b/drivers/media/video/zoran/zoran_driver.c
@@ -2764,7 +2764,7 @@ static int zoran_enum_input(struct file *file, void *__fh,
2764 struct zoran_fh *fh = __fh; 2764 struct zoran_fh *fh = __fh;
2765 struct zoran *zr = fh->zr; 2765 struct zoran *zr = fh->zr;
2766 2766
2767 if (inp->index < 0 || inp->index >= zr->card.inputs) 2767 if (inp->index >= zr->card.inputs)
2768 return -EINVAL; 2768 return -EINVAL;
2769 else { 2769 else {
2770 int id = inp->index; 2770 int id = inp->index;
diff --git a/drivers/media/video/zr364xx.c b/drivers/media/video/zr364xx.c
index 9aae011d92ab..2ef110b5221b 100644
--- a/drivers/media/video/zr364xx.c
+++ b/drivers/media/video/zr364xx.c
@@ -115,6 +115,7 @@ static struct usb_device_id device_table[] = {
115 {USB_DEVICE(0x0a17, 0x004e), .driver_info = METHOD2 }, 115 {USB_DEVICE(0x0a17, 0x004e), .driver_info = METHOD2 },
116 {USB_DEVICE(0x041e, 0x405d), .driver_info = METHOD2 }, 116 {USB_DEVICE(0x041e, 0x405d), .driver_info = METHOD2 },
117 {USB_DEVICE(0x08ca, 0x2102), .driver_info = METHOD2 }, 117 {USB_DEVICE(0x08ca, 0x2102), .driver_info = METHOD2 },
118 {USB_DEVICE(0x06d6, 0x003d), .driver_info = METHOD0 },
118 {} /* Terminating entry */ 119 {} /* Terminating entry */
119}; 120};
120 121
diff --git a/drivers/staging/go7007/Makefile b/drivers/staging/go7007/Makefile
index 1301caa7495d..d37b7edc2793 100644
--- a/drivers/staging/go7007/Makefile
+++ b/drivers/staging/go7007/Makefile
@@ -5,7 +5,7 @@
5 5
6obj-$(CONFIG_VIDEO_GO7007) += go7007.o 6obj-$(CONFIG_VIDEO_GO7007) += go7007.o
7obj-$(CONFIG_VIDEO_GO7007_USB) += go7007-usb.o 7obj-$(CONFIG_VIDEO_GO7007_USB) += go7007-usb.o
8obj-$(CONFIG_VIDEO_GO7007_USB_S2250_BOARD) += s2250.o 8obj-$(CONFIG_VIDEO_GO7007_USB_S2250_BOARD) += s2250.o s2250-loader.o
9obj-$(CONFIG_VIDEO_GO7007_SAA7113) += wis-saa7113.o 9obj-$(CONFIG_VIDEO_GO7007_SAA7113) += wis-saa7113.o
10obj-$(CONFIG_VIDEO_GO7007_OV7640) += wis-ov7640.o 10obj-$(CONFIG_VIDEO_GO7007_OV7640) += wis-ov7640.o
11obj-$(CONFIG_VIDEO_GO7007_SAA7115) += wis-saa7115.o 11obj-$(CONFIG_VIDEO_GO7007_SAA7115) += wis-saa7115.o
@@ -17,7 +17,7 @@ obj-$(CONFIG_VIDEO_GO7007_TW2804) += wis-tw2804.o
17go7007-objs += go7007-v4l2.o go7007-driver.o go7007-i2c.o go7007-fw.o \ 17go7007-objs += go7007-v4l2.o go7007-driver.o go7007-i2c.o go7007-fw.o \
18 snd-go7007.o 18 snd-go7007.o
19 19
20s2250-objs += s2250-board.o s2250-loader.o 20s2250-objs += s2250-board.o
21 21
22# Uncomment when the saa7134 patches get into upstream 22# Uncomment when the saa7134 patches get into upstream
23#ifneq ($(CONFIG_VIDEO_SAA7134),) 23#ifneq ($(CONFIG_VIDEO_SAA7134),)
diff --git a/drivers/staging/go7007/go7007-driver.c b/drivers/staging/go7007/go7007-driver.c
index 472f4bb08fdc..fb1345ffb858 100644
--- a/drivers/staging/go7007/go7007-driver.c
+++ b/drivers/staging/go7007/go7007-driver.c
@@ -49,7 +49,7 @@ int go7007_read_interrupt(struct go7007 *go, u16 *value, u16 *data)
49 go->hpi_ops->read_interrupt(go); 49 go->hpi_ops->read_interrupt(go);
50 if (wait_event_timeout(go->interrupt_waitq, 50 if (wait_event_timeout(go->interrupt_waitq,
51 go->interrupt_available, 5*HZ) < 0) { 51 go->interrupt_available, 5*HZ) < 0) {
52 v4l2_err(go->video_dev, "timeout waiting for read interrupt\n"); 52 v4l2_err(&go->v4l2_dev, "timeout waiting for read interrupt\n");
53 return -1; 53 return -1;
54 } 54 }
55 if (!go->interrupt_available) 55 if (!go->interrupt_available)
@@ -193,7 +193,8 @@ int go7007_reset_encoder(struct go7007 *go)
193static int init_i2c_module(struct i2c_adapter *adapter, const char *type, 193static int init_i2c_module(struct i2c_adapter *adapter, const char *type,
194 int id, int addr) 194 int id, int addr)
195{ 195{
196 struct i2c_board_info info; 196 struct go7007 *go = i2c_get_adapdata(adapter);
197 struct v4l2_device *v4l2_dev = &go->v4l2_dev;
197 char *modname; 198 char *modname;
198 199
199 switch (id) { 200 switch (id) {
@@ -219,20 +220,16 @@ static int init_i2c_module(struct i2c_adapter *adapter, const char *type,
219 modname = "wis-ov7640"; 220 modname = "wis-ov7640";
220 break; 221 break;
221 case I2C_DRIVERID_S2250: 222 case I2C_DRIVERID_S2250:
222 modname = "s2250-board"; 223 modname = "s2250";
223 break; 224 break;
224 default: 225 default:
225 modname = NULL; 226 modname = NULL;
226 break; 227 break;
227 } 228 }
228 if (modname != NULL)
229 request_module(modname);
230 229
231 memset(&info, 0, sizeof(struct i2c_board_info)); 230 if (v4l2_i2c_new_subdev(v4l2_dev, adapter, modname, type, addr, NULL))
232 info.addr = addr;
233 strlcpy(info.type, type, I2C_NAME_SIZE);
234 if (!i2c_new_device(adapter, &info))
235 return 0; 231 return 0;
232
236 if (modname != NULL) 233 if (modname != NULL)
237 printk(KERN_INFO 234 printk(KERN_INFO
238 "go7007: probing for module %s failed\n", modname); 235 "go7007: probing for module %s failed\n", modname);
@@ -262,6 +259,11 @@ int go7007_register_encoder(struct go7007 *go)
262 if (ret < 0) 259 if (ret < 0)
263 return -1; 260 return -1;
264 261
262 /* v4l2 init must happen before i2c subdevs */
263 ret = go7007_v4l2_init(go);
264 if (ret < 0)
265 return ret;
266
265 if (!go->i2c_adapter_online && 267 if (!go->i2c_adapter_online &&
266 go->board_info->flags & GO7007_BOARD_USE_ONBOARD_I2C) { 268 go->board_info->flags & GO7007_BOARD_USE_ONBOARD_I2C) {
267 if (go7007_i2c_init(go) < 0) 269 if (go7007_i2c_init(go) < 0)
@@ -282,7 +284,7 @@ int go7007_register_encoder(struct go7007 *go)
282 go->audio_enabled = 1; 284 go->audio_enabled = 1;
283 go7007_snd_init(go); 285 go7007_snd_init(go);
284 } 286 }
285 return go7007_v4l2_init(go); 287 return 0;
286} 288}
287EXPORT_SYMBOL(go7007_register_encoder); 289EXPORT_SYMBOL(go7007_register_encoder);
288 290
@@ -315,7 +317,7 @@ int go7007_start_encoder(struct go7007 *go)
315 317
316 if (go7007_send_firmware(go, fw, fw_len) < 0 || 318 if (go7007_send_firmware(go, fw, fw_len) < 0 ||
317 go7007_read_interrupt(go, &intr_val, &intr_data) < 0) { 319 go7007_read_interrupt(go, &intr_val, &intr_data) < 0) {
318 v4l2_err(go->video_dev, "error transferring firmware\n"); 320 v4l2_err(&go->v4l2_dev, "error transferring firmware\n");
319 rv = -1; 321 rv = -1;
320 goto start_error; 322 goto start_error;
321 } 323 }
@@ -324,7 +326,7 @@ int go7007_start_encoder(struct go7007 *go)
324 go->parse_length = 0; 326 go->parse_length = 0;
325 go->seen_frame = 0; 327 go->seen_frame = 0;
326 if (go7007_stream_start(go) < 0) { 328 if (go7007_stream_start(go) < 0) {
327 v4l2_err(go->video_dev, "error starting stream transfer\n"); 329 v4l2_err(&go->v4l2_dev, "error starting stream transfer\n");
328 rv = -1; 330 rv = -1;
329 goto start_error; 331 goto start_error;
330 } 332 }
@@ -420,7 +422,7 @@ void go7007_parse_video_stream(struct go7007 *go, u8 *buf, int length)
420 for (i = 0; i < length; ++i) { 422 for (i = 0; i < length; ++i) {
421 if (go->active_buf != NULL && 423 if (go->active_buf != NULL &&
422 go->active_buf->bytesused >= GO7007_BUF_SIZE - 3) { 424 go->active_buf->bytesused >= GO7007_BUF_SIZE - 3) {
423 v4l2_info(go->video_dev, "dropping oversized frame\n"); 425 v4l2_info(&go->v4l2_dev, "dropping oversized frame\n");
424 go->active_buf->offset -= go->active_buf->bytesused; 426 go->active_buf->offset -= go->active_buf->bytesused;
425 go->active_buf->bytesused = 0; 427 go->active_buf->bytesused = 0;
426 go->active_buf->modet_active = 0; 428 go->active_buf->modet_active = 0;
@@ -668,7 +670,7 @@ void go7007_remove(struct go7007 *go)
668 if (i2c_del_adapter(&go->i2c_adapter) == 0) 670 if (i2c_del_adapter(&go->i2c_adapter) == 0)
669 go->i2c_adapter_online = 0; 671 go->i2c_adapter_online = 0;
670 else 672 else
671 v4l2_err(go->video_dev, 673 v4l2_err(&go->v4l2_dev,
672 "error removing I2C adapter!\n"); 674 "error removing I2C adapter!\n");
673 } 675 }
674 676
diff --git a/drivers/staging/go7007/go7007-priv.h b/drivers/staging/go7007/go7007-priv.h
index ce9307e3e186..b58c394c6555 100644
--- a/drivers/staging/go7007/go7007-priv.h
+++ b/drivers/staging/go7007/go7007-priv.h
@@ -21,6 +21,8 @@
21 * user-space applications. 21 * user-space applications.
22 */ 22 */
23 23
24#include <media/v4l2-device.h>
25
24struct go7007; 26struct go7007;
25 27
26/* IDs to activate board-specific support code */ 28/* IDs to activate board-specific support code */
@@ -167,6 +169,7 @@ struct go7007 {
167 int channel_number; /* for multi-channel boards like Adlink PCI-MPG24 */ 169 int channel_number; /* for multi-channel boards like Adlink PCI-MPG24 */
168 char name[64]; 170 char name[64];
169 struct video_device *video_dev; 171 struct video_device *video_dev;
172 struct v4l2_device v4l2_dev;
170 int ref_count; 173 int ref_count;
171 enum { STATUS_INIT, STATUS_ONLINE, STATUS_SHUTDOWN } status; 174 enum { STATUS_INIT, STATUS_ONLINE, STATUS_SHUTDOWN } status;
172 spinlock_t spinlock; 175 spinlock_t spinlock;
@@ -240,6 +243,11 @@ struct go7007 {
240 unsigned short interrupt_data; 243 unsigned short interrupt_data;
241}; 244};
242 245
246static inline struct go7007 *to_go7007(struct v4l2_device *v4l2_dev)
247{
248 return container_of(v4l2_dev, struct go7007, v4l2_dev);
249}
250
243/* All of these must be called with the hpi_lock mutex held! */ 251/* All of these must be called with the hpi_lock mutex held! */
244#define go7007_interface_reset(go) \ 252#define go7007_interface_reset(go) \
245 ((go)->hpi_ops->interface_reset(go)) 253 ((go)->hpi_ops->interface_reset(go))
diff --git a/drivers/staging/go7007/go7007-usb.c b/drivers/staging/go7007/go7007-usb.c
index ecaa3c989cf4..1e89dc04ec23 100644
--- a/drivers/staging/go7007/go7007-usb.c
+++ b/drivers/staging/go7007/go7007-usb.c
@@ -425,7 +425,7 @@ static struct go7007_usb_board board_sensoray_2250 = {
425 .num_i2c_devs = 1, 425 .num_i2c_devs = 1,
426 .i2c_devs = { 426 .i2c_devs = {
427 { 427 {
428 .type = "s2250_board", 428 .type = "s2250",
429 .id = I2C_DRIVERID_S2250, 429 .id = I2C_DRIVERID_S2250,
430 .addr = 0x43, 430 .addr = 0x43,
431 }, 431 },
@@ -1057,7 +1057,7 @@ static int go7007_usb_probe(struct usb_interface *intf,
1057 usb_rcvintpipe(usb->usbdev, 4), 1057 usb_rcvintpipe(usb->usbdev, 4),
1058 usb->intr_urb->transfer_buffer, 2*sizeof(u16), 1058 usb->intr_urb->transfer_buffer, 2*sizeof(u16),
1059 go7007_usb_readinterrupt_complete, go, 8); 1059 go7007_usb_readinterrupt_complete, go, 8);
1060 usb_set_intfdata(intf, go); 1060 usb_set_intfdata(intf, &go->v4l2_dev);
1061 1061
1062 /* Boot the GO7007 */ 1062 /* Boot the GO7007 */
1063 if (go7007_boot_encoder(go, go->board_info->flags & 1063 if (go7007_boot_encoder(go, go->board_info->flags &
@@ -1233,7 +1233,7 @@ allocfail:
1233 1233
1234static void go7007_usb_disconnect(struct usb_interface *intf) 1234static void go7007_usb_disconnect(struct usb_interface *intf)
1235{ 1235{
1236 struct go7007 *go = usb_get_intfdata(intf); 1236 struct go7007 *go = to_go7007(usb_get_intfdata(intf));
1237 struct go7007_usb *usb = go->hpi_context; 1237 struct go7007_usb *usb = go->hpi_context;
1238 struct urb *vurb, *aurb; 1238 struct urb *vurb, *aurb;
1239 int i; 1239 int i;
diff --git a/drivers/staging/go7007/go7007-v4l2.c b/drivers/staging/go7007/go7007-v4l2.c
index 4bd353afa596..b18d8e2d4c5e 100644
--- a/drivers/staging/go7007/go7007-v4l2.c
+++ b/drivers/staging/go7007/go7007-v4l2.c
@@ -29,6 +29,7 @@
29#include <linux/videodev2.h> 29#include <linux/videodev2.h>
30#include <media/v4l2-common.h> 30#include <media/v4l2-common.h>
31#include <media/v4l2-ioctl.h> 31#include <media/v4l2-ioctl.h>
32#include <media/v4l2-subdev.h>
32#include <linux/i2c.h> 33#include <linux/i2c.h>
33#include <linux/mutex.h> 34#include <linux/mutex.h>
34#include <linux/uaccess.h> 35#include <linux/uaccess.h>
@@ -46,6 +47,9 @@
46#define V4L2_MPEG_VIDEO_ENCODING_MPEG_4 3 47#define V4L2_MPEG_VIDEO_ENCODING_MPEG_4 3
47#endif 48#endif
48 49
50#define call_all(dev, o, f, args...) \
51 v4l2_device_call_until_err(dev, 0, o, f, ##args)
52
49static void deactivate_buffer(struct go7007_buffer *gobuf) 53static void deactivate_buffer(struct go7007_buffer *gobuf)
50{ 54{
51 int i; 55 int i;
@@ -247,19 +251,23 @@ static int set_capture_size(struct go7007 *go, struct v4l2_format *fmt, int try)
247 go->modet_map[i] = 0; 251 go->modet_map[i] = 0;
248 252
249 if (go->board_info->sensor_flags & GO7007_SENSOR_SCALING) { 253 if (go->board_info->sensor_flags & GO7007_SENSOR_SCALING) {
250 struct video_decoder_resolution res; 254 struct v4l2_format res;
255
256 if (fmt != NULL) {
257 res = *fmt;
258 } else {
259 res.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
260 res.fmt.pix.width = width;
261 }
251 262
252 res.width = width;
253 if (height > sensor_height / 2) { 263 if (height > sensor_height / 2) {
254 res.height = height / 2; 264 res.fmt.pix.height = height / 2;
255 go->encoder_v_halve = 0; 265 go->encoder_v_halve = 0;
256 } else { 266 } else {
257 res.height = height; 267 res.fmt.pix.height = height;
258 go->encoder_v_halve = 1; 268 go->encoder_v_halve = 1;
259 } 269 }
260 if (go->i2c_adapter_online) 270 call_all(&go->v4l2_dev, video, s_fmt, &res);
261 i2c_clients_command(&go->i2c_adapter,
262 DECODER_SET_RESOLUTION, &res);
263 } else { 271 } else {
264 if (width <= sensor_width / 4) { 272 if (width <= sensor_width / 4) {
265 go->encoder_h_halve = 1; 273 go->encoder_h_halve = 1;
@@ -385,7 +393,7 @@ static int clip_to_modet_map(struct go7007 *go, int region,
385} 393}
386#endif 394#endif
387 395
388static int mpeg_queryctrl(struct v4l2_queryctrl *ctrl) 396static int mpeg_query_ctrl(struct v4l2_queryctrl *ctrl)
389{ 397{
390 static const u32 mpeg_ctrls[] = { 398 static const u32 mpeg_ctrls[] = {
391 V4L2_CID_MPEG_CLASS, 399 V4L2_CID_MPEG_CLASS,
@@ -973,51 +981,35 @@ static int vidioc_queryctrl(struct file *file, void *priv,
973 struct v4l2_queryctrl *query) 981 struct v4l2_queryctrl *query)
974{ 982{
975 struct go7007 *go = ((struct go7007_file *) priv)->go; 983 struct go7007 *go = ((struct go7007_file *) priv)->go;
984 int id = query->id;
976 985
977 if (!go->i2c_adapter_online) 986 if (0 == call_all(&go->v4l2_dev, core, queryctrl, query))
978 return -EIO; 987 return 0;
979
980 i2c_clients_command(&go->i2c_adapter, VIDIOC_QUERYCTRL, query);
981 988
982 return (!query->name[0]) ? mpeg_queryctrl(query) : 0; 989 query->id = id;
990 return mpeg_query_ctrl(query);
983} 991}
984 992
985static int vidioc_g_ctrl(struct file *file, void *priv, 993static int vidioc_g_ctrl(struct file *file, void *priv,
986 struct v4l2_control *ctrl) 994 struct v4l2_control *ctrl)
987{ 995{
988 struct go7007 *go = ((struct go7007_file *) priv)->go; 996 struct go7007 *go = ((struct go7007_file *) priv)->go;
989 struct v4l2_queryctrl query;
990 997
991 if (!go->i2c_adapter_online) 998 if (0 == call_all(&go->v4l2_dev, core, g_ctrl, ctrl))
992 return -EIO; 999 return 0;
993
994 memset(&query, 0, sizeof(query));
995 query.id = ctrl->id;
996 i2c_clients_command(&go->i2c_adapter, VIDIOC_QUERYCTRL, &query);
997 if (query.name[0] == 0)
998 return mpeg_g_ctrl(ctrl, go);
999 i2c_clients_command(&go->i2c_adapter, VIDIOC_G_CTRL, ctrl);
1000 1000
1001 return 0; 1001 return mpeg_g_ctrl(ctrl, go);
1002} 1002}
1003 1003
1004static int vidioc_s_ctrl(struct file *file, void *priv, 1004static int vidioc_s_ctrl(struct file *file, void *priv,
1005 struct v4l2_control *ctrl) 1005 struct v4l2_control *ctrl)
1006{ 1006{
1007 struct go7007 *go = ((struct go7007_file *) priv)->go; 1007 struct go7007 *go = ((struct go7007_file *) priv)->go;
1008 struct v4l2_queryctrl query;
1009 1008
1010 if (!go->i2c_adapter_online) 1009 if (0 == call_all(&go->v4l2_dev, core, s_ctrl, ctrl))
1011 return -EIO; 1010 return 0;
1012
1013 memset(&query, 0, sizeof(query));
1014 query.id = ctrl->id;
1015 i2c_clients_command(&go->i2c_adapter, VIDIOC_QUERYCTRL, &query);
1016 if (query.name[0] == 0)
1017 return mpeg_s_ctrl(ctrl, go);
1018 i2c_clients_command(&go->i2c_adapter, VIDIOC_S_CTRL, ctrl);
1019 1011
1020 return 0; 1012 return mpeg_s_ctrl(ctrl, go);
1021} 1013}
1022 1014
1023static int vidioc_g_parm(struct file *filp, void *priv, 1015static int vidioc_g_parm(struct file *filp, void *priv,
@@ -1135,8 +1127,7 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *std)
1135 if (go->streaming) 1127 if (go->streaming)
1136 return -EBUSY; 1128 return -EBUSY;
1137 1129
1138 if (!(go->board_info->sensor_flags & GO7007_SENSOR_TV) && 1130 if (!(go->board_info->sensor_flags & GO7007_SENSOR_TV) && *std != 0)
1139 *std != 0)
1140 return -EINVAL; 1131 return -EINVAL;
1141 1132
1142 if (*std == 0) 1133 if (*std == 0)
@@ -1146,9 +1137,7 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *std)
1146 go->input == go->board_info->num_inputs - 1) { 1137 go->input == go->board_info->num_inputs - 1) {
1147 if (!go->i2c_adapter_online) 1138 if (!go->i2c_adapter_online)
1148 return -EIO; 1139 return -EIO;
1149 i2c_clients_command(&go->i2c_adapter, 1140 if (call_all(&go->v4l2_dev, core, s_std, *std) < 0)
1150 VIDIOC_S_STD, std);
1151 if (!*std) /* hack to indicate EINVAL from tuner */
1152 return -EINVAL; 1141 return -EINVAL;
1153 } 1142 }
1154 1143
@@ -1164,9 +1153,7 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *std)
1164 } else 1153 } else
1165 return -EINVAL; 1154 return -EINVAL;
1166 1155
1167 if (go->i2c_adapter_online) 1156 call_all(&go->v4l2_dev, core, s_std, *std);
1168 i2c_clients_command(&go->i2c_adapter,
1169 VIDIOC_S_STD, std);
1170 set_capture_size(go, NULL, 0); 1157 set_capture_size(go, NULL, 0);
1171 1158
1172 return 0; 1159 return 0;
@@ -1180,7 +1167,7 @@ static int vidioc_querystd(struct file *file, void *priv, v4l2_std_id *std)
1180 go->input == go->board_info->num_inputs - 1) { 1167 go->input == go->board_info->num_inputs - 1) {
1181 if (!go->i2c_adapter_online) 1168 if (!go->i2c_adapter_online)
1182 return -EIO; 1169 return -EIO;
1183 i2c_clients_command(&go->i2c_adapter, VIDIOC_QUERYSTD, std); 1170 return call_all(&go->v4l2_dev, video, querystd, std);
1184 } else if (go->board_info->sensor_flags & GO7007_SENSOR_TV) 1171 } else if (go->board_info->sensor_flags & GO7007_SENSOR_TV)
1185 *std = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM; 1172 *std = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM;
1186 else 1173 else
@@ -1238,14 +1225,8 @@ static int vidioc_s_input(struct file *file, void *priv, unsigned int input)
1238 return -EBUSY; 1225 return -EBUSY;
1239 1226
1240 go->input = input; 1227 go->input = input;
1241 if (go->i2c_adapter_online) {
1242 i2c_clients_command(&go->i2c_adapter, VIDIOC_S_INPUT,
1243 &go->board_info->inputs[input].video_input);
1244 i2c_clients_command(&go->i2c_adapter, VIDIOC_S_AUDIO,
1245 &go->board_info->inputs[input].audio_input);
1246 }
1247 1228
1248 return 0; 1229 return call_all(&go->v4l2_dev, video, s_routing, input, 0, 0);
1249} 1230}
1250 1231
1251static int vidioc_g_tuner(struct file *file, void *priv, 1232static int vidioc_g_tuner(struct file *file, void *priv,
@@ -1260,10 +1241,7 @@ static int vidioc_g_tuner(struct file *file, void *priv,
1260 if (!go->i2c_adapter_online) 1241 if (!go->i2c_adapter_online)
1261 return -EIO; 1242 return -EIO;
1262 1243
1263 i2c_clients_command(&go->i2c_adapter, VIDIOC_G_TUNER, t); 1244 return call_all(&go->v4l2_dev, tuner, g_tuner, t);
1264
1265 t->index = 0;
1266 return 0;
1267} 1245}
1268 1246
1269static int vidioc_s_tuner(struct file *file, void *priv, 1247static int vidioc_s_tuner(struct file *file, void *priv,
@@ -1287,9 +1265,7 @@ static int vidioc_s_tuner(struct file *file, void *priv,
1287 break; 1265 break;
1288 } 1266 }
1289 1267
1290 i2c_clients_command(&go->i2c_adapter, VIDIOC_S_TUNER, t); 1268 return call_all(&go->v4l2_dev, tuner, s_tuner, t);
1291
1292 return 0;
1293} 1269}
1294 1270
1295static int vidioc_g_frequency(struct file *file, void *priv, 1271static int vidioc_g_frequency(struct file *file, void *priv,
@@ -1303,8 +1279,8 @@ static int vidioc_g_frequency(struct file *file, void *priv,
1303 return -EIO; 1279 return -EIO;
1304 1280
1305 f->type = V4L2_TUNER_ANALOG_TV; 1281 f->type = V4L2_TUNER_ANALOG_TV;
1306 i2c_clients_command(&go->i2c_adapter, VIDIOC_G_FREQUENCY, f); 1282
1307 return 0; 1283 return call_all(&go->v4l2_dev, tuner, g_frequency, f);
1308} 1284}
1309 1285
1310static int vidioc_s_frequency(struct file *file, void *priv, 1286static int vidioc_s_frequency(struct file *file, void *priv,
@@ -1317,9 +1293,7 @@ static int vidioc_s_frequency(struct file *file, void *priv,
1317 if (!go->i2c_adapter_online) 1293 if (!go->i2c_adapter_online)
1318 return -EIO; 1294 return -EIO;
1319 1295
1320 i2c_clients_command(&go->i2c_adapter, VIDIOC_S_FREQUENCY, f); 1296 return call_all(&go->v4l2_dev, tuner, s_frequency, f);
1321
1322 return 0;
1323} 1297}
1324 1298
1325static int vidioc_cropcap(struct file *file, void *priv, 1299static int vidioc_cropcap(struct file *file, void *priv,
@@ -1827,7 +1801,7 @@ int go7007_v4l2_init(struct go7007 *go)
1827 go->video_dev = video_device_alloc(); 1801 go->video_dev = video_device_alloc();
1828 if (go->video_dev == NULL) 1802 if (go->video_dev == NULL)
1829 return -ENOMEM; 1803 return -ENOMEM;
1830 memcpy(go->video_dev, &go7007_template, sizeof(go7007_template)); 1804 *go->video_dev = go7007_template;
1831 go->video_dev->parent = go->dev; 1805 go->video_dev->parent = go->dev;
1832 rv = video_register_device(go->video_dev, VFL_TYPE_GRABBER, -1); 1806 rv = video_register_device(go->video_dev, VFL_TYPE_GRABBER, -1);
1833 if (rv < 0) { 1807 if (rv < 0) {
@@ -1835,6 +1809,12 @@ int go7007_v4l2_init(struct go7007 *go)
1835 go->video_dev = NULL; 1809 go->video_dev = NULL;
1836 return rv; 1810 return rv;
1837 } 1811 }
1812 rv = v4l2_device_register(go->dev, &go->v4l2_dev);
1813 if (rv < 0) {
1814 video_device_release(go->video_dev);
1815 go->video_dev = NULL;
1816 return rv;
1817 }
1838 video_set_drvdata(go->video_dev, go); 1818 video_set_drvdata(go->video_dev, go);
1839 ++go->ref_count; 1819 ++go->ref_count;
1840 printk(KERN_INFO "%s: registered device video%d [v4l2]\n", 1820 printk(KERN_INFO "%s: registered device video%d [v4l2]\n",
@@ -1858,4 +1838,5 @@ void go7007_v4l2_remove(struct go7007 *go)
1858 mutex_unlock(&go->hw_lock); 1838 mutex_unlock(&go->hw_lock);
1859 if (go->video_dev) 1839 if (go->video_dev)
1860 video_unregister_device(go->video_dev); 1840 video_unregister_device(go->video_dev);
1841 v4l2_device_unregister(&go->v4l2_dev);
1861} 1842}
diff --git a/drivers/staging/go7007/s2250-board.c b/drivers/staging/go7007/s2250-board.c
index f4a6541c3e60..8cf7f2750b3f 100644
--- a/drivers/staging/go7007/s2250-board.c
+++ b/drivers/staging/go7007/s2250-board.c
@@ -20,10 +20,14 @@
20#include <linux/usb.h> 20#include <linux/usb.h>
21#include <linux/i2c.h> 21#include <linux/i2c.h>
22#include <linux/videodev2.h> 22#include <linux/videodev2.h>
23#include <media/v4l2-device.h>
23#include <media/v4l2-common.h> 24#include <media/v4l2-common.h>
24#include "s2250-loader.h" 25#include <media/v4l2-i2c-drv.h>
26#include <media/v4l2-subdev.h>
25#include "go7007-priv.h" 27#include "go7007-priv.h"
26#include "wis-i2c.h" 28
29MODULE_DESCRIPTION("Sensoray 2250/2251 i2c v4l2 subdev driver");
30MODULE_LICENSE("GPL v2");
27 31
28#define TLV320_ADDRESS 0x34 32#define TLV320_ADDRESS 0x34
29#define VPX322_ADDR_ANALOGCONTROL1 0x02 33#define VPX322_ADDR_ANALOGCONTROL1 0x02
@@ -112,6 +116,7 @@ static u16 vid_regs_fp_pal[] =
112}; 116};
113 117
114struct s2250 { 118struct s2250 {
119 struct v4l2_subdev sd;
115 v4l2_std_id std; 120 v4l2_std_id std;
116 int input; 121 int input;
117 int brightness; 122 int brightness;
@@ -123,6 +128,11 @@ struct s2250 {
123 struct i2c_client *audio; 128 struct i2c_client *audio;
124}; 129};
125 130
131static inline struct s2250 *to_state(struct v4l2_subdev *sd)
132{
133 return container_of(sd, struct s2250, sd);
134}
135
126/* from go7007-usb.c which is Copyright (C) 2005-2006 Micronas USA Inc.*/ 136/* from go7007-usb.c which is Copyright (C) 2005-2006 Micronas USA Inc.*/
127static int go7007_usb_vendor_request(struct go7007 *go, u16 request, 137static int go7007_usb_vendor_request(struct go7007 *go, u16 request,
128 u16 value, u16 index, void *transfer_buffer, int length, int in) 138 u16 value, u16 index, void *transfer_buffer, int length, int in)
@@ -306,253 +316,262 @@ static int write_regs_fp(struct i2c_client *client, u16 *regs)
306} 316}
307 317
308 318
309static int s2250_command(struct i2c_client *client, 319/* ------------------------------------------------------------------------- */
310 unsigned int cmd, void *arg) 320
321static int s2250_s_video_routing(struct v4l2_subdev *sd, u32 input, u32 output,
322 u32 config)
311{ 323{
312 struct s2250 *dec = i2c_get_clientdata(client); 324 struct s2250 *state = to_state(sd);
325 struct i2c_client *client = v4l2_get_subdevdata(sd);
326 int vidsys;
327
328 vidsys = (state->std == V4L2_STD_NTSC) ? 0x01 : 0x00;
329 if (input == 0) {
330 /* composite */
331 write_reg_fp(client, 0x20, 0x020 | vidsys);
332 write_reg_fp(client, 0x21, 0x662);
333 write_reg_fp(client, 0x140, 0x060);
334 } else if (input == 1) {
335 /* S-Video */
336 write_reg_fp(client, 0x20, 0x040 | vidsys);
337 write_reg_fp(client, 0x21, 0x666);
338 write_reg_fp(client, 0x140, 0x060);
339 } else {
340 return -EINVAL;
341 }
342 state->input = input;
343 return 0;
344}
313 345
314 switch (cmd) { 346static int s2250_s_std(struct v4l2_subdev *sd, v4l2_std_id norm)
315 case VIDIOC_S_INPUT: 347{
316 { 348 struct s2250 *state = to_state(sd);
317 int vidsys; 349 struct i2c_client *client = v4l2_get_subdevdata(sd);
318 int *input = arg; 350 u16 vidsource;
319 351
320 vidsys = (dec->std == V4L2_STD_NTSC) ? 0x01 : 0x00; 352 vidsource = (state->input == 1) ? 0x040 : 0x020;
321 if (*input == 0) { 353 switch (norm) {
322 /* composite */ 354 case V4L2_STD_NTSC:
323 write_reg_fp(client, 0x20, 0x020 | vidsys); 355 write_regs_fp(client, vid_regs_fp);
324 write_reg_fp(client, 0x21, 0x662); 356 write_reg_fp(client, 0x20, vidsource | 1);
325 write_reg_fp(client, 0x140, 0x060);
326 } else {
327 /* S-Video */
328 write_reg_fp(client, 0x20, 0x040 | vidsys);
329 write_reg_fp(client, 0x21, 0x666);
330 write_reg_fp(client, 0x140, 0x060);
331 }
332 dec->input = *input;
333 break; 357 break;
334 } 358 case V4L2_STD_PAL:
335 case VIDIOC_S_STD: 359 write_regs_fp(client, vid_regs_fp);
336 { 360 write_regs_fp(client, vid_regs_fp_pal);
337 v4l2_std_id *std = arg; 361 write_reg_fp(client, 0x20, vidsource);
338 u16 vidsource;
339
340 vidsource = (dec->input == 1) ? 0x040 : 0x020;
341 dec->std = *std;
342 switch (dec->std) {
343 case V4L2_STD_NTSC:
344 write_regs_fp(client, vid_regs_fp);
345 write_reg_fp(client, 0x20, vidsource | 1);
346 break;
347 case V4L2_STD_PAL:
348 write_regs_fp(client, vid_regs_fp);
349 write_regs_fp(client, vid_regs_fp_pal);
350 write_reg_fp(client, 0x20, vidsource);
351 break;
352 default:
353 return -EINVAL;
354 }
355 break; 362 break;
363 default:
364 return -EINVAL;
356 } 365 }
357 case VIDIOC_QUERYCTRL: 366 state->std = norm;
358 { 367 return 0;
359 struct v4l2_queryctrl *ctrl = arg; 368}
360 static const u32 user_ctrls[] = { 369
361 V4L2_CID_BRIGHTNESS, 370static int s2250_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *query)
362 V4L2_CID_CONTRAST, 371{
363 V4L2_CID_SATURATION, 372 switch (query->id) {
364 V4L2_CID_HUE, 373 case V4L2_CID_BRIGHTNESS:
365 0 374 return v4l2_ctrl_query_fill(query, 0, 100, 1, 50);
366 }; 375 case V4L2_CID_CONTRAST:
367 static const u32 *ctrl_classes[] = { 376 return v4l2_ctrl_query_fill(query, 0, 100, 1, 50);
368 user_ctrls, 377 case V4L2_CID_SATURATION:
369 NULL 378 return v4l2_ctrl_query_fill(query, 0, 100, 1, 50);
370 }; 379 case V4L2_CID_HUE:
371 380 return v4l2_ctrl_query_fill(query, -50, 50, 1, 0);
372 ctrl->id = v4l2_ctrl_next(ctrl_classes, ctrl->id); 381 default:
373 switch (ctrl->id) { 382 return -EINVAL;
374 case V4L2_CID_BRIGHTNESS:
375 v4l2_ctrl_query_fill(ctrl, 0, 100, 1, 50);
376 break;
377 case V4L2_CID_CONTRAST:
378 v4l2_ctrl_query_fill(ctrl, 0, 100, 1, 50);
379 break;
380 case V4L2_CID_SATURATION:
381 v4l2_ctrl_query_fill(ctrl, 0, 100, 1, 50);
382 break;
383 case V4L2_CID_HUE:
384 v4l2_ctrl_query_fill(ctrl, -50, 50, 1, 0);
385 break;
386 default:
387 ctrl->name[0] = '\0';
388 return -EINVAL;
389 }
390 break;
391 } 383 }
392 case VIDIOC_S_CTRL: 384 return 0;
393 { 385}
394 struct v4l2_control *ctrl = arg; 386
395 int value1; 387static int s2250_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
396 u16 oldvalue; 388{
397 389 struct s2250 *state = to_state(sd);
398 switch (ctrl->id) { 390 struct i2c_client *client = v4l2_get_subdevdata(sd);
399 case V4L2_CID_BRIGHTNESS: 391 int value1;
400 if (ctrl->value > 100) 392 u16 oldvalue;
401 dec->brightness = 100; 393
402 else if (ctrl->value < 0) 394 switch (ctrl->id) {
403 dec->brightness = 0; 395 case V4L2_CID_BRIGHTNESS:
404 else 396 if (ctrl->value > 100)
405 dec->brightness = ctrl->value; 397 state->brightness = 100;
406 value1 = (dec->brightness - 50) * 255 / 100; 398 else if (ctrl->value < 0)
407 read_reg_fp(client, VPX322_ADDR_BRIGHTNESS0, &oldvalue); 399 state->brightness = 0;
408 write_reg_fp(client, VPX322_ADDR_BRIGHTNESS0, 400 else
409 value1 | (oldvalue & ~0xff)); 401 state->brightness = ctrl->value;
410 read_reg_fp(client, VPX322_ADDR_BRIGHTNESS1, &oldvalue); 402 value1 = (state->brightness - 50) * 255 / 100;
411 write_reg_fp(client, VPX322_ADDR_BRIGHTNESS1, 403 read_reg_fp(client, VPX322_ADDR_BRIGHTNESS0, &oldvalue);
412 value1 | (oldvalue & ~0xff)); 404 write_reg_fp(client, VPX322_ADDR_BRIGHTNESS0,
413 write_reg_fp(client, 0x140, 0x60); 405 value1 | (oldvalue & ~0xff));
414 break; 406 read_reg_fp(client, VPX322_ADDR_BRIGHTNESS1, &oldvalue);
415 case V4L2_CID_CONTRAST: 407 write_reg_fp(client, VPX322_ADDR_BRIGHTNESS1,
416 if (ctrl->value > 100) 408 value1 | (oldvalue & ~0xff));
417 dec->contrast = 100; 409 write_reg_fp(client, 0x140, 0x60);
418 else if (ctrl->value < 0)
419 dec->contrast = 0;
420 else
421 dec->contrast = ctrl->value;
422 value1 = dec->contrast * 0x40 / 100;
423 if (value1 > 0x3f)
424 value1 = 0x3f; /* max */
425 read_reg_fp(client, VPX322_ADDR_CONTRAST0, &oldvalue);
426 write_reg_fp(client, VPX322_ADDR_CONTRAST0,
427 value1 | (oldvalue & ~0x3f));
428 read_reg_fp(client, VPX322_ADDR_CONTRAST1, &oldvalue);
429 write_reg_fp(client, VPX322_ADDR_CONTRAST1,
430 value1 | (oldvalue & ~0x3f));
431 write_reg_fp(client, 0x140, 0x60);
432 break;
433 case V4L2_CID_SATURATION:
434 if (ctrl->value > 127)
435 dec->saturation = 127;
436 else if (ctrl->value < 0)
437 dec->saturation = 0;
438 else
439 dec->saturation = ctrl->value;
440
441 value1 = dec->saturation * 4140 / 100;
442 if (value1 > 4094)
443 value1 = 4094;
444 write_reg_fp(client, VPX322_ADDR_SAT, value1);
445 break;
446 case V4L2_CID_HUE:
447 if (ctrl->value > 50)
448 dec->hue = 50;
449 else if (ctrl->value < -50)
450 dec->hue = -50;
451 else
452 dec->hue = ctrl->value;
453 /* clamp the hue range */
454 value1 = dec->hue * 280 / 50;
455 write_reg_fp(client, VPX322_ADDR_HUE, value1);
456 break;
457 }
458 break; 410 break;
459 } 411 case V4L2_CID_CONTRAST:
460 case VIDIOC_G_CTRL: 412 if (ctrl->value > 100)
461 { 413 state->contrast = 100;
462 struct v4l2_control *ctrl = arg; 414 else if (ctrl->value < 0)
463 415 state->contrast = 0;
464 switch (ctrl->id) { 416 else
465 case V4L2_CID_BRIGHTNESS: 417 state->contrast = ctrl->value;
466 ctrl->value = dec->brightness; 418 value1 = state->contrast * 0x40 / 100;
467 break; 419 if (value1 > 0x3f)
468 case V4L2_CID_CONTRAST: 420 value1 = 0x3f; /* max */
469 ctrl->value = dec->contrast; 421 read_reg_fp(client, VPX322_ADDR_CONTRAST0, &oldvalue);
470 break; 422 write_reg_fp(client, VPX322_ADDR_CONTRAST0,
471 case V4L2_CID_SATURATION: 423 value1 | (oldvalue & ~0x3f));
472 ctrl->value = dec->saturation; 424 read_reg_fp(client, VPX322_ADDR_CONTRAST1, &oldvalue);
473 break; 425 write_reg_fp(client, VPX322_ADDR_CONTRAST1,
474 case V4L2_CID_HUE: 426 value1 | (oldvalue & ~0x3f));
475 ctrl->value = dec->hue; 427 write_reg_fp(client, 0x140, 0x60);
476 break;
477 }
478 break; 428 break;
429 case V4L2_CID_SATURATION:
430 if (ctrl->value > 100)
431 state->saturation = 100;
432 else if (ctrl->value < 0)
433 state->saturation = 0;
434 else
435 state->saturation = ctrl->value;
436 value1 = state->saturation * 4140 / 100;
437 if (value1 > 4094)
438 value1 = 4094;
439 write_reg_fp(client, VPX322_ADDR_SAT, value1);
440 break;
441 case V4L2_CID_HUE:
442 if (ctrl->value > 50)
443 state->hue = 50;
444 else if (ctrl->value < -50)
445 state->hue = -50;
446 else
447 state->hue = ctrl->value;
448 /* clamp the hue range */
449 value1 = state->hue * 280 / 50;
450 write_reg_fp(client, VPX322_ADDR_HUE, value1);
451 break;
452 default:
453 return -EINVAL;
479 } 454 }
480 case VIDIOC_S_FMT: 455 return 0;
481 { 456}
482 struct v4l2_format *fmt = arg;
483 if (fmt->fmt.pix.height < 640) {
484 write_reg_fp(client, 0x12b, dec->reg12b_val | 0x400);
485 write_reg_fp(client, 0x140, 0x060);
486 } else {
487 write_reg_fp(client, 0x12b, dec->reg12b_val & ~0x400);
488 write_reg_fp(client, 0x140, 0x060);
489 }
490 return 0;
491 }
492 case VIDIOC_G_AUDIO:
493 {
494 struct v4l2_audio *audio = arg;
495 457
496 memset(audio, 0, sizeof(*audio)); 458static int s2250_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
497 audio->index = dec->audio_input; 459{
498 /* fall through */ 460 struct s2250 *state = to_state(sd);
499 } 461
500 case VIDIOC_ENUMAUDIO: 462 switch (ctrl->id) {
501 { 463 case V4L2_CID_BRIGHTNESS:
502 struct v4l2_audio *audio = arg; 464 ctrl->value = state->brightness;
503 465 break;
504 switch (audio->index) { 466 case V4L2_CID_CONTRAST:
505 case 0: 467 ctrl->value = state->contrast;
506 strcpy(audio->name, "Line In"); 468 break;
507 break; 469 case V4L2_CID_SATURATION:
508 case 1: 470 ctrl->value = state->saturation;
509 strcpy(audio->name, "Mic"); 471 break;
510 break; 472 case V4L2_CID_HUE:
511 case 2: 473 ctrl->value = state->hue;
512 strcpy(audio->name, "Mic Boost"); 474 break;
513 break; 475 default:
514 default: 476 return -EINVAL;
515 audio->name[0] = '\0';
516 return 0;
517 }
518 audio->capability = V4L2_AUDCAP_STEREO;
519 audio->mode = 0;
520 return 0;
521 } 477 }
522 case VIDIOC_S_AUDIO: 478 return 0;
523 { 479}
524 struct v4l2_audio *audio = arg; 480
525 481static int s2250_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
526 switch (audio->index) { 482{
527 case 0: 483 struct s2250 *state = to_state(sd);
528 write_reg(dec->audio, 0x08, 0x02); /* Line In */ 484 struct i2c_client *client = v4l2_get_subdevdata(sd);
529 break; 485
530 case 1: 486 if (fmt->fmt.pix.height < 640) {
531 write_reg(dec->audio, 0x08, 0x04); /* Mic */ 487 write_reg_fp(client, 0x12b, state->reg12b_val | 0x400);
532 break; 488 write_reg_fp(client, 0x140, 0x060);
533 case 2: 489 } else {
534 write_reg(dec->audio, 0x08, 0x05); /* Mic Boost */ 490 write_reg_fp(client, 0x12b, state->reg12b_val & ~0x400);
535 break; 491 write_reg_fp(client, 0x140, 0x060);
536 default:
537 return -EINVAL;
538 }
539 dec->audio_input = audio->index;
540 return 0;
541 } 492 }
493 return 0;
494}
542 495
543 default: 496static int s2250_s_audio_routing(struct v4l2_subdev *sd, u32 input, u32 output,
544 printk(KERN_INFO "s2250: unknown command 0x%x\n", cmd); 497 u32 config)
498{
499 struct s2250 *state = to_state(sd);
500
501 switch (input) {
502 case 0:
503 write_reg(state->audio, 0x08, 0x02); /* Line In */
504 break;
505 case 1:
506 write_reg(state->audio, 0x08, 0x04); /* Mic */
545 break; 507 break;
508 case 2:
509 write_reg(state->audio, 0x08, 0x05); /* Mic Boost */
510 break;
511 default:
512 return -EINVAL;
546 } 513 }
514 state->audio_input = input;
515 return 0;
516}
517
518
519static int s2250_log_status(struct v4l2_subdev *sd)
520{
521 struct s2250 *state = to_state(sd);
522
523 v4l2_info(sd, "Standard: %s\n", state->std == V4L2_STD_NTSC ? "NTSC" :
524 state->std == V4L2_STD_PAL ? "PAL" :
525 state->std == V4L2_STD_SECAM ? "SECAM" :
526 "unknown");
527 v4l2_info(sd, "Input: %s\n", state->input == 0 ? "Composite" :
528 state->input == 1 ? "S-video" :
529 "error");
530 v4l2_info(sd, "Brightness: %d\n", state->brightness);
531 v4l2_info(sd, "Contrast: %d\n", state->contrast);
532 v4l2_info(sd, "Saturation: %d\n", state->saturation);
533 v4l2_info(sd, "Hue: %d\n", state->hue); return 0;
534 v4l2_info(sd, "Audio input: %s\n", state->audio_input == 0 ? "Line In" :
535 state->audio_input == 1 ? "Mic" :
536 state->audio_input == 2 ? "Mic Boost" :
537 "error");
547 return 0; 538 return 0;
548} 539}
549 540
541/* --------------------------------------------------------------------------*/
542
543static const struct v4l2_subdev_core_ops s2250_core_ops = {
544 .log_status = s2250_log_status,
545 .g_ctrl = s2250_g_ctrl,
546 .s_ctrl = s2250_s_ctrl,
547 .queryctrl = s2250_queryctrl,
548 .s_std = s2250_s_std,
549};
550
551static const struct v4l2_subdev_audio_ops s2250_audio_ops = {
552 .s_routing = s2250_s_audio_routing,
553};
554
555static const struct v4l2_subdev_video_ops s2250_video_ops = {
556 .s_routing = s2250_s_video_routing,
557 .s_fmt = s2250_s_fmt,
558};
559
560static const struct v4l2_subdev_ops s2250_ops = {
561 .core = &s2250_core_ops,
562 .audio = &s2250_audio_ops,
563 .video = &s2250_video_ops,
564};
565
566/* --------------------------------------------------------------------------*/
567
550static int s2250_probe(struct i2c_client *client, 568static int s2250_probe(struct i2c_client *client,
551 const struct i2c_device_id *id) 569 const struct i2c_device_id *id)
552{ 570{
553 struct i2c_client *audio; 571 struct i2c_client *audio;
554 struct i2c_adapter *adapter = client->adapter; 572 struct i2c_adapter *adapter = client->adapter;
555 struct s2250 *dec; 573 struct s2250 *state;
574 struct v4l2_subdev *sd;
556 u8 *data; 575 u8 *data;
557 struct go7007 *go = i2c_get_adapdata(adapter); 576 struct go7007 *go = i2c_get_adapdata(adapter);
558 struct go7007_usb *usb = go->hpi_context; 577 struct go7007_usb *usb = go->hpi_context;
@@ -561,30 +580,31 @@ static int s2250_probe(struct i2c_client *client,
561 if (audio == NULL) 580 if (audio == NULL)
562 return -ENOMEM; 581 return -ENOMEM;
563 582
564 dec = kmalloc(sizeof(struct s2250), GFP_KERNEL); 583 state = kmalloc(sizeof(struct s2250), GFP_KERNEL);
565 if (dec == NULL) { 584 if (state == NULL) {
566 i2c_unregister_device(audio); 585 i2c_unregister_device(audio);
567 return -ENOMEM; 586 return -ENOMEM;
568 } 587 }
569 588
570 dec->std = V4L2_STD_NTSC; 589 sd = &state->sd;
571 dec->brightness = 50; 590 v4l2_i2c_subdev_init(sd, client, &s2250_ops);
572 dec->contrast = 50; 591
573 dec->saturation = 50; 592 v4l2_info(sd, "initializing %s at address 0x%x on %s\n",
574 dec->hue = 0; 593 "Sensoray 2250/2251", client->addr, client->adapter->name);
575 dec->audio = audio;
576 i2c_set_clientdata(client, dec);
577 594
578 printk(KERN_DEBUG 595 state->std = V4L2_STD_NTSC;
579 "s2250: initializing video decoder on %s\n", 596 state->brightness = 50;
580 adapter->name); 597 state->contrast = 50;
598 state->saturation = 50;
599 state->hue = 0;
600 state->audio = audio;
581 601
582 /* initialize the audio */ 602 /* initialize the audio */
583 if (write_regs(audio, aud_regs) < 0) { 603 if (write_regs(audio, aud_regs) < 0) {
584 printk(KERN_ERR 604 printk(KERN_ERR
585 "s2250: error initializing audio\n"); 605 "s2250: error initializing audio\n");
586 i2c_unregister_device(audio); 606 i2c_unregister_device(audio);
587 kfree(dec); 607 kfree(state);
588 return 0; 608 return 0;
589 } 609 }
590 610
@@ -592,14 +612,14 @@ static int s2250_probe(struct i2c_client *client,
592 printk(KERN_ERR 612 printk(KERN_ERR
593 "s2250: error initializing decoder\n"); 613 "s2250: error initializing decoder\n");
594 i2c_unregister_device(audio); 614 i2c_unregister_device(audio);
595 kfree(dec); 615 kfree(state);
596 return 0; 616 return 0;
597 } 617 }
598 if (write_regs_fp(client, vid_regs_fp) < 0) { 618 if (write_regs_fp(client, vid_regs_fp) < 0) {
599 printk(KERN_ERR 619 printk(KERN_ERR
600 "s2250: error initializing decoder\n"); 620 "s2250: error initializing decoder\n");
601 i2c_unregister_device(audio); 621 i2c_unregister_device(audio);
602 kfree(dec); 622 kfree(state);
603 return 0; 623 return 0;
604 } 624 }
605 /* set default channel */ 625 /* set default channel */
@@ -609,7 +629,7 @@ static int s2250_probe(struct i2c_client *client,
609 write_reg_fp(client, 0x140, 0x060); 629 write_reg_fp(client, 0x140, 0x060);
610 630
611 /* set default audio input */ 631 /* set default audio input */
612 dec->audio_input = 0; 632 state->audio_input = 0;
613 write_reg(client, 0x08, 0x02); /* Line In */ 633 write_reg(client, 0x08, 0x02); /* Line In */
614 634
615 if (mutex_lock_interruptible(&usb->i2c_lock) == 0) { 635 if (mutex_lock_interruptible(&usb->i2c_lock) == 0) {
@@ -634,60 +654,28 @@ static int s2250_probe(struct i2c_client *client,
634 mutex_unlock(&usb->i2c_lock); 654 mutex_unlock(&usb->i2c_lock);
635 } 655 }
636 656
637 printk("s2250: initialized successfully\n"); 657 v4l2_info(sd, "initialized successfully\n");
638 return 0; 658 return 0;
639} 659}
640 660
641static int s2250_remove(struct i2c_client *client) 661static int s2250_remove(struct i2c_client *client)
642{ 662{
643 struct s2250 *dec = i2c_get_clientdata(client); 663 struct v4l2_subdev *sd = i2c_get_clientdata(client);
644 664
645 i2c_set_clientdata(client, NULL); 665 v4l2_device_unregister_subdev(sd);
646 i2c_unregister_device(dec->audio); 666 kfree(to_state(sd));
647 kfree(dec);
648 return 0; 667 return 0;
649} 668}
650 669
651static struct i2c_device_id s2250_id[] = { 670static struct i2c_device_id s2250_id[] = {
652 { "s2250_board", 0 }, 671 { "s2250", 0 },
653 { } 672 { }
654}; 673};
674MODULE_DEVICE_TABLE(i2c, s2250_id);
655 675
656static struct i2c_driver s2250_driver = { 676static struct v4l2_i2c_driver_data v4l2_i2c_data = {
657 .driver = { 677 .name = "s2250",
658 .name = "Sensoray 2250 board driver", 678 .probe = s2250_probe,
659 }, 679 .remove = s2250_remove,
660 .probe = s2250_probe, 680 .id_table = s2250_id,
661 .remove = s2250_remove,
662 .command = s2250_command,
663 .id_table = s2250_id,
664}; 681};
665
666static int __init s2250_init(void)
667{
668 int r;
669
670 r = s2250loader_init();
671 if (r < 0)
672 return r;
673
674 r = i2c_add_driver(&s2250_driver);
675 if (r < 0)
676 s2250loader_cleanup();
677
678 return r;
679}
680
681static void __exit s2250_cleanup(void)
682{
683 i2c_del_driver(&s2250_driver);
684
685 s2250loader_cleanup();
686}
687
688module_init(s2250_init);
689module_exit(s2250_cleanup);
690
691MODULE_AUTHOR("");
692MODULE_DESCRIPTION("Board driver for Sensoryray 2250");
693MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/go7007/s2250-loader.c b/drivers/staging/go7007/s2250-loader.c
index d7bf82983274..c152ab9be2fb 100644
--- a/drivers/staging/go7007/s2250-loader.c
+++ b/drivers/staging/go7007/s2250-loader.c
@@ -162,7 +162,7 @@ static struct usb_driver s2250loader_driver = {
162 .id_table = s2250loader_ids, 162 .id_table = s2250loader_ids,
163}; 163};
164 164
165int s2250loader_init(void) 165static int __init s2250loader_init(void)
166{ 166{
167 int r; 167 int r;
168 unsigned i = 0; 168 unsigned i = 0;
@@ -179,11 +179,15 @@ int s2250loader_init(void)
179 printk(KERN_INFO "s2250loader_init: driver registered\n"); 179 printk(KERN_INFO "s2250loader_init: driver registered\n");
180 return 0; 180 return 0;
181} 181}
182EXPORT_SYMBOL(s2250loader_init); 182module_init(s2250loader_init);
183 183
184void s2250loader_cleanup(void) 184static void __exit s2250loader_cleanup(void)
185{ 185{
186 printk(KERN_INFO "s2250loader_cleanup\n"); 186 printk(KERN_INFO "s2250loader_cleanup\n");
187 usb_deregister(&s2250loader_driver); 187 usb_deregister(&s2250loader_driver);
188} 188}
189EXPORT_SYMBOL(s2250loader_cleanup); 189module_exit(s2250loader_cleanup);
190
191MODULE_AUTHOR("");
192MODULE_DESCRIPTION("firmware loader for Sensoray 2250/2251");
193MODULE_LICENSE("GPL v2");
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
index dfd4745a955f..32b92298fd79 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -361,6 +361,7 @@ struct v4l2_pix_format {
361#define V4L2_PIX_FMT_PJPG v4l2_fourcc('P', 'J', 'P', 'G') /* Pixart 73xx JPEG */ 361#define V4L2_PIX_FMT_PJPG v4l2_fourcc('P', 'J', 'P', 'G') /* Pixart 73xx JPEG */
362#define V4L2_PIX_FMT_OV511 v4l2_fourcc('O', '5', '1', '1') /* ov511 JPEG */ 362#define V4L2_PIX_FMT_OV511 v4l2_fourcc('O', '5', '1', '1') /* ov511 JPEG */
363#define V4L2_PIX_FMT_OV518 v4l2_fourcc('O', '5', '1', '8') /* ov518 JPEG */ 363#define V4L2_PIX_FMT_OV518 v4l2_fourcc('O', '5', '1', '8') /* ov518 JPEG */
364#define V4L2_PIX_FMT_STV0680 v4l2_fourcc('S', '6', '8', '0') /* stv0680 bayer */
364 365
365/* 366/*
366 * F O R M A T E N U M E R A T I O N 367 * F O R M A T E N U M E R A T I O N
@@ -563,6 +564,7 @@ struct v4l2_framebuffer {
563#define V4L2_FBUF_CAP_LOCAL_ALPHA 0x0010 564#define V4L2_FBUF_CAP_LOCAL_ALPHA 0x0010
564#define V4L2_FBUF_CAP_GLOBAL_ALPHA 0x0020 565#define V4L2_FBUF_CAP_GLOBAL_ALPHA 0x0020
565#define V4L2_FBUF_CAP_LOCAL_INV_ALPHA 0x0040 566#define V4L2_FBUF_CAP_LOCAL_INV_ALPHA 0x0040
567#define V4L2_FBUF_CAP_SRC_CHROMAKEY 0x0080
566/* Flags for the 'flags' field. */ 568/* Flags for the 'flags' field. */
567#define V4L2_FBUF_FLAG_PRIMARY 0x0001 569#define V4L2_FBUF_FLAG_PRIMARY 0x0001
568#define V4L2_FBUF_FLAG_OVERLAY 0x0002 570#define V4L2_FBUF_FLAG_OVERLAY 0x0002
@@ -570,6 +572,7 @@ struct v4l2_framebuffer {
570#define V4L2_FBUF_FLAG_LOCAL_ALPHA 0x0008 572#define V4L2_FBUF_FLAG_LOCAL_ALPHA 0x0008
571#define V4L2_FBUF_FLAG_GLOBAL_ALPHA 0x0010 573#define V4L2_FBUF_FLAG_GLOBAL_ALPHA 0x0010
572#define V4L2_FBUF_FLAG_LOCAL_INV_ALPHA 0x0020 574#define V4L2_FBUF_FLAG_LOCAL_INV_ALPHA 0x0020
575#define V4L2_FBUF_FLAG_SRC_CHROMAKEY 0x0040
573 576
574struct v4l2_clip { 577struct v4l2_clip {
575 struct v4l2_rect c; 578 struct v4l2_rect c;
@@ -912,8 +915,10 @@ enum v4l2_colorfx {
912#define V4L2_CID_AUTOBRIGHTNESS (V4L2_CID_BASE+32) 915#define V4L2_CID_AUTOBRIGHTNESS (V4L2_CID_BASE+32)
913#define V4L2_CID_BAND_STOP_FILTER (V4L2_CID_BASE+33) 916#define V4L2_CID_BAND_STOP_FILTER (V4L2_CID_BASE+33)
914 917
918#define V4L2_CID_ROTATE (V4L2_CID_BASE+34)
919#define V4L2_CID_BG_COLOR (V4L2_CID_BASE+35)
915/* last CID + 1 */ 920/* last CID + 1 */
916#define V4L2_CID_LASTP1 (V4L2_CID_BASE+34) 921#define V4L2_CID_LASTP1 (V4L2_CID_BASE+36)
917 922
918/* MPEG-class control IDs defined by V4L2 */ 923/* MPEG-class control IDs defined by V4L2 */
919#define V4L2_CID_MPEG_BASE (V4L2_CTRL_CLASS_MPEG | 0x900) 924#define V4L2_CID_MPEG_BASE (V4L2_CTRL_CLASS_MPEG | 0x900)
diff --git a/include/media/cx25840.h b/include/media/cx25840.h
index 2c3fbaa33f74..0b0cb1776796 100644
--- a/include/media/cx25840.h
+++ b/include/media/cx25840.h
@@ -84,6 +84,7 @@ enum cx25840_video_input {
84 CX25840_NONE0_CH3 = 0x80000080, 84 CX25840_NONE0_CH3 = 0x80000080,
85 CX25840_NONE1_CH3 = 0x800000c0, 85 CX25840_NONE1_CH3 = 0x800000c0,
86 CX25840_SVIDEO_ON = 0x80000100, 86 CX25840_SVIDEO_ON = 0x80000100,
87 CX25840_COMPONENT_ON = 0x80000200,
87}; 88};
88 89
89enum cx25840_audio_input { 90enum cx25840_audio_input {
diff --git a/include/media/davinci/vpfe_capture.h b/include/media/davinci/vpfe_capture.h
index 71d8982e13ff..d863e5e8426d 100644
--- a/include/media/davinci/vpfe_capture.h
+++ b/include/media/davinci/vpfe_capture.h
@@ -83,6 +83,8 @@ struct vpfe_subdev_info {
83struct vpfe_config { 83struct vpfe_config {
84 /* Number of sub devices connected to vpfe */ 84 /* Number of sub devices connected to vpfe */
85 int num_subdevs; 85 int num_subdevs;
86 /* i2c bus adapter no */
87 int i2c_adapter_id;
86 /* information about each subdev */ 88 /* information about each subdev */
87 struct vpfe_subdev_info *sub_devs; 89 struct vpfe_subdev_info *sub_devs;
88 /* evm card info */ 90 /* evm card info */
diff --git a/include/media/ir-common.h b/include/media/ir-common.h
index 29f0e53cff94..e41a99ee353e 100644
--- a/include/media/ir-common.h
+++ b/include/media/ir-common.h
@@ -26,14 +26,16 @@
26#include <linux/input.h> 26#include <linux/input.h>
27#include <linux/workqueue.h> 27#include <linux/workqueue.h>
28#include <linux/interrupt.h> 28#include <linux/interrupt.h>
29#include <linux/spinlock.h>
30
31extern int media_ir_debug; /* media_ir_debug level (0,1,2) */
32#define IR_dprintk(level, fmt, arg...) if (media_ir_debug >= level) \
33 printk(KERN_DEBUG "%s: " fmt , __func__, ## arg)
29 34
30#define IR_TYPE_RC5 1 35#define IR_TYPE_RC5 1
31#define IR_TYPE_PD 2 /* Pulse distance encoded IR */ 36#define IR_TYPE_PD 2 /* Pulse distance encoded IR */
32#define IR_TYPE_OTHER 99 37#define IR_TYPE_OTHER 99
33 38
34#define IR_KEYTAB_TYPE u32
35#define IR_KEYTAB_SIZE 128 /* enougth for rc5, probably need more some day */
36
37struct ir_scancode { 39struct ir_scancode {
38 u16 scancode; 40 u16 scancode;
39 u32 keycode; 41 u32 keycode;
@@ -42,11 +44,9 @@ struct ir_scancode {
42struct ir_scancode_table { 44struct ir_scancode_table {
43 struct ir_scancode *scan; 45 struct ir_scancode *scan;
44 int size; 46 int size;
47 spinlock_t lock;
45}; 48};
46 49
47#define IR_KEYCODE(tab,code) (((unsigned)code < IR_KEYTAB_SIZE) \
48 ? tab[code] : KEY_RESERVED)
49
50#define RC5_START(x) (((x)>>12)&3) 50#define RC5_START(x) (((x)>>12)&3)
51#define RC5_TOGGLE(x) (((x)>>11)&1) 51#define RC5_TOGGLE(x) (((x)>>11)&1)
52#define RC5_ADDR(x) (((x)>>6)&31) 52#define RC5_ADDR(x) (((x)>>6)&31)
@@ -55,11 +55,11 @@ struct ir_scancode_table {
55struct ir_input_state { 55struct ir_input_state {
56 /* configuration */ 56 /* configuration */
57 int ir_type; 57 int ir_type;
58 IR_KEYTAB_TYPE ir_codes[IR_KEYTAB_SIZE]; 58
59 struct ir_scancode_table keytable;
59 60
60 /* key info */ 61 /* key info */
61 u32 ir_raw; /* raw data */ 62 u32 ir_key; /* ir scancode */
62 u32 ir_key; /* ir key code */
63 u32 keycode; /* linux key code */ 63 u32 keycode; /* linux key code */
64 int keypressed; /* current state */ 64 int keypressed; /* current state */
65}; 65};
@@ -102,20 +102,36 @@ struct card_ir {
102 struct tasklet_struct tlet; 102 struct tasklet_struct tlet;
103}; 103};
104 104
105void ir_input_init(struct input_dev *dev, struct ir_input_state *ir, 105/* Routines from ir-functions.c */
106
107int ir_input_init(struct input_dev *dev, struct ir_input_state *ir,
106 int ir_type, struct ir_scancode_table *ir_codes); 108 int ir_type, struct ir_scancode_table *ir_codes);
107void ir_input_nokey(struct input_dev *dev, struct ir_input_state *ir); 109void ir_input_nokey(struct input_dev *dev, struct ir_input_state *ir);
108void ir_input_keydown(struct input_dev *dev, struct ir_input_state *ir, 110void ir_input_keydown(struct input_dev *dev, struct ir_input_state *ir,
109 u32 ir_key, u32 ir_raw); 111 u32 ir_key);
110u32 ir_extract_bits(u32 data, u32 mask); 112u32 ir_extract_bits(u32 data, u32 mask);
111int ir_dump_samples(u32 *samples, int count); 113int ir_dump_samples(u32 *samples, int count);
112int ir_decode_biphase(u32 *samples, int count, int low, int high); 114int ir_decode_biphase(u32 *samples, int count, int low, int high);
113int ir_decode_pulsedistance(u32 *samples, int count, int low, int high); 115int ir_decode_pulsedistance(u32 *samples, int count, int low, int high);
116u32 ir_rc5_decode(unsigned int code);
114 117
115void ir_rc5_timer_end(unsigned long data); 118void ir_rc5_timer_end(unsigned long data);
116void ir_rc5_timer_keyup(unsigned long data); 119void ir_rc5_timer_keyup(unsigned long data);
117 120
118/* Keymaps to be used by other modules */ 121/* Routines from ir-keytable.c */
122
123u32 ir_g_keycode_from_table(struct input_dev *input_dev,
124 u32 scancode);
125
126int ir_set_keycode_table(struct input_dev *input_dev,
127 struct ir_scancode_table *rc_tab);
128
129int ir_roundup_tablesize(int n_elems);
130int ir_copy_table(struct ir_scancode_table *destin,
131 const struct ir_scancode_table *origin);
132void ir_input_free(struct input_dev *input_dev);
133
134/* scancode->keycode map tables from ir-keymaps.c */
119 135
120extern struct ir_scancode_table ir_codes_empty_table; 136extern struct ir_scancode_table ir_codes_empty_table;
121extern struct ir_scancode_table ir_codes_avermedia_table; 137extern struct ir_scancode_table ir_codes_avermedia_table;
@@ -150,6 +166,7 @@ extern struct ir_scancode_table ir_codes_rc5_tv_table;
150extern struct ir_scancode_table ir_codes_winfast_table; 166extern struct ir_scancode_table ir_codes_winfast_table;
151extern struct ir_scancode_table ir_codes_pinnacle_color_table; 167extern struct ir_scancode_table ir_codes_pinnacle_color_table;
152extern struct ir_scancode_table ir_codes_hauppauge_new_table; 168extern struct ir_scancode_table ir_codes_hauppauge_new_table;
169extern struct ir_scancode_table ir_codes_rc5_hauppauge_new_table;
153extern struct ir_scancode_table ir_codes_npgtech_table; 170extern struct ir_scancode_table ir_codes_npgtech_table;
154extern struct ir_scancode_table ir_codes_norwood_table; 171extern struct ir_scancode_table ir_codes_norwood_table;
155extern struct ir_scancode_table ir_codes_proteus_2309_table; 172extern struct ir_scancode_table ir_codes_proteus_2309_table;
@@ -172,6 +189,8 @@ extern struct ir_scancode_table ir_codes_ati_tv_wonder_hd_600_table;
172extern struct ir_scancode_table ir_codes_kworld_plus_tv_analog_table; 189extern struct ir_scancode_table ir_codes_kworld_plus_tv_analog_table;
173extern struct ir_scancode_table ir_codes_kaiomy_table; 190extern struct ir_scancode_table ir_codes_kaiomy_table;
174extern struct ir_scancode_table ir_codes_dm1105_nec_table; 191extern struct ir_scancode_table ir_codes_dm1105_nec_table;
192extern struct ir_scancode_table ir_codes_tevii_nec_table;
193extern struct ir_scancode_table ir_codes_tbs_nec_table;
175extern struct ir_scancode_table ir_codes_evga_indtube_table; 194extern struct ir_scancode_table ir_codes_evga_indtube_table;
176extern struct ir_scancode_table ir_codes_terratec_cinergy_xs_table; 195extern struct ir_scancode_table ir_codes_terratec_cinergy_xs_table;
177extern struct ir_scancode_table ir_codes_videomate_s350_table; 196extern struct ir_scancode_table ir_codes_videomate_s350_table;
diff --git a/include/media/v4l2-chip-ident.h b/include/media/v4l2-chip-ident.h
index cf16689adba7..91942dbe64e3 100644
--- a/include/media/v4l2-chip-ident.h
+++ b/include/media/v4l2-chip-ident.h
@@ -64,6 +64,7 @@ enum {
64 V4L2_IDENT_OV9650 = 254, 64 V4L2_IDENT_OV9650 = 254,
65 V4L2_IDENT_OV9655 = 255, 65 V4L2_IDENT_OV9655 = 255,
66 V4L2_IDENT_SOI968 = 256, 66 V4L2_IDENT_SOI968 = 256,
67 V4L2_IDENT_OV9640 = 257,
67 68
68 /* module saa7146: reserved range 300-309 */ 69 /* module saa7146: reserved range 300-309 */
69 V4L2_IDENT_SAA7146 = 300, 70 V4L2_IDENT_SAA7146 = 300,
@@ -72,6 +73,7 @@ enum {
72 V4L2_IDENT_CX23418_843 = 403, /* Integrated A/V Decoder on the '418 */ 73 V4L2_IDENT_CX23418_843 = 403, /* Integrated A/V Decoder on the '418 */
73 V4L2_IDENT_CX23415 = 415, 74 V4L2_IDENT_CX23415 = 415,
74 V4L2_IDENT_CX23416 = 416, 75 V4L2_IDENT_CX23416 = 416,
76 V4L2_IDENT_CX23417 = 417,
75 V4L2_IDENT_CX23418 = 418, 77 V4L2_IDENT_CX23418 = 418,
76 78
77 /* module au0828 */ 79 /* module au0828 */
@@ -129,6 +131,9 @@ enum {
129 V4L2_IDENT_SAA6752HS = 6752, 131 V4L2_IDENT_SAA6752HS = 6752,
130 V4L2_IDENT_SAA6752HS_AC3 = 6753, 132 V4L2_IDENT_SAA6752HS_AC3 = 6753,
131 133
134 /* modules tef6862: just ident 6862 */
135 V4L2_IDENT_TEF6862 = 6862,
136
132 /* module adv7170: just ident 7170 */ 137 /* module adv7170: just ident 7170 */
133 V4L2_IDENT_ADV7170 = 7170, 138 V4L2_IDENT_ADV7170 = 7170,
134 139
@@ -165,12 +170,27 @@ enum {
165 /* module mt9v011, just ident 8243 */ 170 /* module mt9v011, just ident 8243 */
166 V4L2_IDENT_MT9V011 = 8243, 171 V4L2_IDENT_MT9V011 = 8243,
167 172
173 /* module cx23885 and cx25840 */
174 V4L2_IDENT_CX23885 = 8850,
175 V4L2_IDENT_CX23885_AV = 8851, /* Integrated A/V decoder */
176 V4L2_IDENT_CX23887 = 8870,
177 V4L2_IDENT_CX23887_AV = 8871, /* Integrated A/V decoder */
178 V4L2_IDENT_CX23888 = 8880,
179 V4L2_IDENT_CX23888_AV = 8881, /* Integrated A/V decoder */
180 V4L2_IDENT_CX23888_IR = 8882, /* Integrated infrared controller */
181
168 /* module tw9910: just ident 9910 */ 182 /* module tw9910: just ident 9910 */
169 V4L2_IDENT_TW9910 = 9910, 183 V4L2_IDENT_TW9910 = 9910,
170 184
171 /* module sn9c20x: just ident 10000 */ 185 /* module sn9c20x: just ident 10000 */
172 V4L2_IDENT_SN9C20X = 10000, 186 V4L2_IDENT_SN9C20X = 10000,
173 187
188 /* module cx231xx and cx25840 */
189 V4L2_IDENT_CX2310X_AV = 23099, /* Integrated A/V decoder; not in '100 */
190 V4L2_IDENT_CX23100 = 23100,
191 V4L2_IDENT_CX23101 = 23101,
192 V4L2_IDENT_CX23102 = 23102,
193
174 /* module msp3400: reserved range 34000-34999 and 44000-44999 */ 194 /* module msp3400: reserved range 34000-34999 and 44000-44999 */
175 V4L2_IDENT_MSPX4XX = 34000, /* generic MSPX4XX identifier, only 195 V4L2_IDENT_MSPX4XX = 34000, /* generic MSPX4XX identifier, only
176 use internally (tveeprom.c). */ 196 use internally (tveeprom.c). */
@@ -264,6 +284,9 @@ enum {
264 284
265 /* module m52790: just ident 52790 */ 285 /* module m52790: just ident 52790 */
266 V4L2_IDENT_M52790 = 52790, 286 V4L2_IDENT_M52790 = 52790,
287
288 /* Sharp RJ54N1CB0C, 0xCB0C = 51980 */
289 V4L2_IDENT_RJ54N1CB0C = 51980,
267}; 290};
268 291
269#endif 292#endif
diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h
index d411345f244b..00bf17608453 100644
--- a/include/media/v4l2-subdev.h
+++ b/include/media/v4l2-subdev.h
@@ -23,6 +23,16 @@
23 23
24#include <media/v4l2-common.h> 24#include <media/v4l2-common.h>
25 25
26/* generic v4l2_device notify callback notification values */
27#define V4L2_SUBDEV_IR_RX_NOTIFY _IOW('v', 0, u32)
28#define V4L2_SUBDEV_IR_RX_FIFO_SERVICE_REQ 0x00000001
29#define V4L2_SUBDEV_IR_RX_END_OF_RX_DETECTED 0x00000002
30#define V4L2_SUBDEV_IR_RX_HW_FIFO_OVERRUN 0x00000004
31#define V4L2_SUBDEV_IR_RX_SW_FIFO_OVERRUN 0x00000008
32
33#define V4L2_SUBDEV_IR_TX_NOTIFY _IOW('v', 1, u32)
34#define V4L2_SUBDEV_IR_TX_FIFO_SERVICE_REQ 0x00000001
35
26struct v4l2_device; 36struct v4l2_device;
27struct v4l2_subdev; 37struct v4l2_subdev;
28struct tuner_setup; 38struct tuner_setup;
@@ -96,6 +106,9 @@ struct v4l2_decode_vbi_line {
96 106
97 s_gpio: set GPIO pins. Very simple right now, might need to be extended with 107 s_gpio: set GPIO pins. Very simple right now, might need to be extended with
98 a direction argument if needed. 108 a direction argument if needed.
109
110 s_power: puts subdevice in power saving mode (on == 0) or normal operation
111 mode (on == 1).
99 */ 112 */
100struct v4l2_subdev_core_ops { 113struct v4l2_subdev_core_ops {
101 int (*g_chip_ident)(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip); 114 int (*g_chip_ident)(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip);
@@ -118,6 +131,7 @@ struct v4l2_subdev_core_ops {
118 int (*g_register)(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg); 131 int (*g_register)(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg);
119 int (*s_register)(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg); 132 int (*s_register)(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg);
120#endif 133#endif
134 int (*s_power)(struct v4l2_subdev *sd, int on);
121}; 135};
122 136
123/* s_mode: switch the tuner to a specific tuner mode. Replacement of s_radio. 137/* s_mode: switch the tuner to a specific tuner mode. Replacement of s_radio.
@@ -127,8 +141,6 @@ struct v4l2_subdev_core_ops {
127 s_type_addr: sets tuner type and its I2C addr. 141 s_type_addr: sets tuner type and its I2C addr.
128 142
129 s_config: sets tda9887 specific stuff, like port1, port2 and qss 143 s_config: sets tda9887 specific stuff, like port1, port2 and qss
130
131 s_standby: puts tuner on powersaving state, disabling it, except for i2c.
132 */ 144 */
133struct v4l2_subdev_tuner_ops { 145struct v4l2_subdev_tuner_ops {
134 int (*s_mode)(struct v4l2_subdev *sd, enum v4l2_tuner_type); 146 int (*s_mode)(struct v4l2_subdev *sd, enum v4l2_tuner_type);
@@ -141,7 +153,6 @@ struct v4l2_subdev_tuner_ops {
141 int (*s_modulator)(struct v4l2_subdev *sd, struct v4l2_modulator *vm); 153 int (*s_modulator)(struct v4l2_subdev *sd, struct v4l2_modulator *vm);
142 int (*s_type_addr)(struct v4l2_subdev *sd, struct tuner_setup *type); 154 int (*s_type_addr)(struct v4l2_subdev *sd, struct tuner_setup *type);
143 int (*s_config)(struct v4l2_subdev *sd, const struct v4l2_priv_tun_config *config); 155 int (*s_config)(struct v4l2_subdev *sd, const struct v4l2_priv_tun_config *config);
144 int (*s_standby)(struct v4l2_subdev *sd);
145}; 156};
146 157
147/* s_clock_freq: set the frequency (in Hz) of the audio clock output. 158/* s_clock_freq: set the frequency (in Hz) of the audio clock output.
@@ -231,11 +242,95 @@ struct v4l2_subdev_video_ops {
231 int (*enum_frameintervals)(struct v4l2_subdev *sd, struct v4l2_frmivalenum *fival); 242 int (*enum_frameintervals)(struct v4l2_subdev *sd, struct v4l2_frmivalenum *fival);
232}; 243};
233 244
245/*
246 interrupt_service_routine: Called by the bridge chip's interrupt service
247 handler, when an IR interrupt status has be raised due to this subdev,
248 so that this subdev can handle the details. It may schedule work to be
249 performed later. It must not sleep. *Called from an IRQ context*.
250
251 [rt]x_g_parameters: Get the current operating parameters and state of the
252 the IR receiver or transmitter.
253
254 [rt]x_s_parameters: Set the current operating parameters and state of the
255 the IR receiver or transmitter. It is recommended to call
256 [rt]x_g_parameters first to fill out the current state, and only change
257 the fields that need to be changed. Upon return, the actual device
258 operating parameters and state will be returned. Note that hardware
259 limitations may prevent the actual settings from matching the requested
260 settings - e.g. an actual carrier setting of 35,904 Hz when 36,000 Hz
261 was requested. An exception is when the shutdown parameter is true.
262 The last used operational parameters will be returned, but the actual
263 state of the hardware be different to minimize power consumption and
264 processing when shutdown is true.
265
266 rx_read: Reads received codes or pulse width data.
267 The semantics are similar to a non-blocking read() call.
268
269 tx_write: Writes codes or pulse width data for transmission.
270 The semantics are similar to a non-blocking write() call.
271 */
272
273enum v4l2_subdev_ir_mode {
274 V4L2_SUBDEV_IR_MODE_PULSE_WIDTH, /* space & mark widths in nanosecs */
275};
276
277/* Data format of data read or written for V4L2_SUBDEV_IR_MODE_PULSE_WIDTH */
278#define V4L2_SUBDEV_IR_PULSE_MAX_WIDTH_NS 0x7fffffff
279#define V4L2_SUBDEV_IR_PULSE_LEVEL_MASK 0x80000000
280#define V4L2_SUBDEV_IR_PULSE_RX_SEQ_END 0xffffffff
281
282struct v4l2_subdev_ir_parameters {
283 /* Either Rx or Tx */
284 unsigned int bytes_per_data_element; /* of data in read or write call */
285 enum v4l2_subdev_ir_mode mode;
286
287 bool enable;
288 bool interrupt_enable;
289 bool shutdown; /* true: set hardware to low/no power, false: normal */
290
291 bool modulation; /* true: uses carrier, false: baseband */
292 u32 max_pulse_width; /* ns, valid only for baseband signal */
293 unsigned int carrier_freq; /* Hz, valid only for modulated signal*/
294 unsigned int duty_cycle; /* percent, valid only for modulated signal*/
295 bool invert; /* logically invert sense of mark/space */
296
297 /* Rx only */
298 u32 noise_filter_min_width; /* ns, min time of a valid pulse */
299 unsigned int carrier_range_lower; /* Hz, valid only for modulated sig */
300 unsigned int carrier_range_upper; /* Hz, valid only for modulated sig */
301 u32 resolution; /* ns */
302};
303
304struct v4l2_subdev_ir_ops {
305 /* Common to receiver and transmitter */
306 int (*interrupt_service_routine)(struct v4l2_subdev *sd,
307 u32 status, bool *handled);
308
309 /* Receiver */
310 int (*rx_read)(struct v4l2_subdev *sd, u8 *buf, size_t count,
311 ssize_t *num);
312
313 int (*rx_g_parameters)(struct v4l2_subdev *sd,
314 struct v4l2_subdev_ir_parameters *params);
315 int (*rx_s_parameters)(struct v4l2_subdev *sd,
316 struct v4l2_subdev_ir_parameters *params);
317
318 /* Transmitter */
319 int (*tx_write)(struct v4l2_subdev *sd, u8 *buf, size_t count,
320 ssize_t *num);
321
322 int (*tx_g_parameters)(struct v4l2_subdev *sd,
323 struct v4l2_subdev_ir_parameters *params);
324 int (*tx_s_parameters)(struct v4l2_subdev *sd,
325 struct v4l2_subdev_ir_parameters *params);
326};
327
234struct v4l2_subdev_ops { 328struct v4l2_subdev_ops {
235 const struct v4l2_subdev_core_ops *core; 329 const struct v4l2_subdev_core_ops *core;
236 const struct v4l2_subdev_tuner_ops *tuner; 330 const struct v4l2_subdev_tuner_ops *tuner;
237 const struct v4l2_subdev_audio_ops *audio; 331 const struct v4l2_subdev_audio_ops *audio;
238 const struct v4l2_subdev_video_ops *video; 332 const struct v4l2_subdev_video_ops *video;
333 const struct v4l2_subdev_ir_ops *ir;
239}; 334};
240 335
241#define V4L2_SUBDEV_NAME_SIZE 32 336#define V4L2_SUBDEV_NAME_SIZE 32
@@ -290,7 +385,7 @@ static inline void v4l2_subdev_init(struct v4l2_subdev *sd,
290 Example: err = v4l2_subdev_call(sd, core, g_chip_ident, &chip); 385 Example: err = v4l2_subdev_call(sd, core, g_chip_ident, &chip);
291 */ 386 */
292#define v4l2_subdev_call(sd, o, f, args...) \ 387#define v4l2_subdev_call(sd, o, f, args...) \
293 (!(sd) ? -ENODEV : (((sd) && (sd)->ops->o && (sd)->ops->o->f) ? \ 388 (!(sd) ? -ENODEV : (((sd)->ops->o && (sd)->ops->o->f) ? \
294 (sd)->ops->o->f((sd) , ##args) : -ENOIOCTLCMD)) 389 (sd)->ops->o->f((sd) , ##args) : -ENOIOCTLCMD))
295 390
296/* Send a notification to v4l2_device. */ 391/* Send a notification to v4l2_device. */
diff --git a/include/media/videobuf-core.h b/include/media/videobuf-core.h
index 1c5946c44758..316fdccdcaa0 100644
--- a/include/media/videobuf-core.h
+++ b/include/media/videobuf-core.h
@@ -166,7 +166,7 @@ struct videobuf_queue {
166 enum v4l2_field field; 166 enum v4l2_field field;
167 enum v4l2_field last; /* for field=V4L2_FIELD_ALTERNATE */ 167 enum v4l2_field last; /* for field=V4L2_FIELD_ALTERNATE */
168 struct videobuf_buffer *bufs[VIDEO_MAX_FRAME]; 168 struct videobuf_buffer *bufs[VIDEO_MAX_FRAME];
169 struct videobuf_queue_ops *ops; 169 const struct videobuf_queue_ops *ops;
170 struct videobuf_qtype_ops *int_ops; 170 struct videobuf_qtype_ops *int_ops;
171 171
172 unsigned int streaming:1; 172 unsigned int streaming:1;
@@ -195,7 +195,7 @@ void *videobuf_queue_to_vmalloc (struct videobuf_queue* q,
195 struct videobuf_buffer *buf); 195 struct videobuf_buffer *buf);
196 196
197void videobuf_queue_core_init(struct videobuf_queue *q, 197void videobuf_queue_core_init(struct videobuf_queue *q,
198 struct videobuf_queue_ops *ops, 198 const struct videobuf_queue_ops *ops,
199 struct device *dev, 199 struct device *dev,
200 spinlock_t *irqlock, 200 spinlock_t *irqlock,
201 enum v4l2_buf_type type, 201 enum v4l2_buf_type type,
diff --git a/include/media/videobuf-dma-contig.h b/include/media/videobuf-dma-contig.h
index 549386681aab..ebaa9bc1ee8d 100644
--- a/include/media/videobuf-dma-contig.h
+++ b/include/media/videobuf-dma-contig.h
@@ -17,7 +17,7 @@
17#include <media/videobuf-core.h> 17#include <media/videobuf-core.h>
18 18
19void videobuf_queue_dma_contig_init(struct videobuf_queue *q, 19void videobuf_queue_dma_contig_init(struct videobuf_queue *q,
20 struct videobuf_queue_ops *ops, 20 const struct videobuf_queue_ops *ops,
21 struct device *dev, 21 struct device *dev,
22 spinlock_t *irqlock, 22 spinlock_t *irqlock,
23 enum v4l2_buf_type type, 23 enum v4l2_buf_type type,
diff --git a/include/media/videobuf-dma-sg.h b/include/media/videobuf-dma-sg.h
index dda47f0082e9..53e72f787175 100644
--- a/include/media/videobuf-dma-sg.h
+++ b/include/media/videobuf-dma-sg.h
@@ -103,7 +103,7 @@ struct videobuf_dmabuf *videobuf_to_dma (struct videobuf_buffer *buf);
103void *videobuf_sg_alloc(size_t size); 103void *videobuf_sg_alloc(size_t size);
104 104
105void videobuf_queue_sg_init(struct videobuf_queue* q, 105void videobuf_queue_sg_init(struct videobuf_queue* q,
106 struct videobuf_queue_ops *ops, 106 const struct videobuf_queue_ops *ops,
107 struct device *dev, 107 struct device *dev,
108 spinlock_t *irqlock, 108 spinlock_t *irqlock,
109 enum v4l2_buf_type type, 109 enum v4l2_buf_type type,
diff --git a/include/media/videobuf-dvb.h b/include/media/videobuf-dvb.h
index 6ba4f1271d23..07cf4b9d0a65 100644
--- a/include/media/videobuf-dvb.h
+++ b/include/media/videobuf-dvb.h
@@ -42,7 +42,9 @@ int videobuf_dvb_register_bus(struct videobuf_dvb_frontends *f,
42 void *adapter_priv, 42 void *adapter_priv,
43 struct device *device, 43 struct device *device,
44 short *adapter_nr, 44 short *adapter_nr,
45 int mfe_shared); 45 int mfe_shared,
46 int (*fe_ioctl_override)(struct dvb_frontend *,
47 unsigned int, void *, unsigned int));
46 48
47void videobuf_dvb_unregister_bus(struct videobuf_dvb_frontends *f); 49void videobuf_dvb_unregister_bus(struct videobuf_dvb_frontends *f);
48 50
diff --git a/include/media/videobuf-vmalloc.h b/include/media/videobuf-vmalloc.h
index e87222c6a125..4b419a257a7d 100644
--- a/include/media/videobuf-vmalloc.h
+++ b/include/media/videobuf-vmalloc.h
@@ -30,8 +30,8 @@ struct videobuf_vmalloc_memory
30}; 30};
31 31
32void videobuf_queue_vmalloc_init(struct videobuf_queue* q, 32void videobuf_queue_vmalloc_init(struct videobuf_queue* q,
33 struct videobuf_queue_ops *ops, 33 const struct videobuf_queue_ops *ops,
34 void *dev, 34 struct device *dev,
35 spinlock_t *irqlock, 35 spinlock_t *irqlock,
36 enum v4l2_buf_type type, 36 enum v4l2_buf_type type,
37 enum v4l2_field field, 37 enum v4l2_field field,