aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-12-30 20:41:32 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2008-12-30 20:41:32 -0500
commitf54a6ec0fd85002d94d05b4bb679508eeb066683 (patch)
tree0f24dd66cce563d2c5e7656c2489e5b96eef31f9
parent5ed1836814d908f45cafde0e79cb85314ab9d41d (diff)
parent134179823b3ca9c8b98e0631906459dbb022ff9b (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: (583 commits) V4L/DVB (10130): use USB API functions rather than constants V4L/DVB (10129): dvb: remove deprecated use of RW_LOCK_UNLOCKED in frontends V4L/DVB (10128): modify V4L documentation to be a valid XHTML V4L/DVB (10127): stv06xx: Avoid having y unitialized V4L/DVB (10125): em28xx: Don't do AC97 vendor detection for i2s audio devices V4L/DVB (10124): em28xx: expand output formats available V4L/DVB (10123): em28xx: fix reversed definitions of I2S audio modes V4L/DVB (10122): em28xx: don't load em28xx-alsa for em2870 based devices V4L/DVB (10121): em28xx: remove worthless Pinnacle PCTV HD Mini 80e device profile V4L/DVB (10120): em28xx: remove redundant Pinnacle Dazzle DVC 100 profile V4L/DVB (10119): em28xx: fix corrupted XCLK value V4L/DVB (10118): zoran: fix warning for a variable not used V4L/DVB (10116): af9013: Fix gcc false warnings V4L/DVB (10111a): usbvideo.h: remove an useless blank line V4L/DVB (10111): quickcam_messenger.c: fix a warning V4L/DVB (10110): v4l2-ioctl: Fix warnings when using .unlocked_ioctl = __video_ioctl2 V4L/DVB (10109): anysee: Fix usage of an unitialized function V4L/DVB (10104): uvcvideo: Add support for video output devices V4L/DVB (10102): uvcvideo: Ignore interrupt endpoint for built-in iSight webcams. V4L/DVB (10101): uvcvideo: Fix bulk URB processing when the header is erroneous ...
-rw-r--r--Documentation/dvb/technisat.txt69
-rw-r--r--Documentation/video4linux/API.html43
-rw-r--r--Documentation/video4linux/CARDLIST.bttv7
-rw-r--r--Documentation/video4linux/CARDLIST.cx238851
-rw-r--r--Documentation/video4linux/CARDLIST.cx885
-rw-r--r--Documentation/video4linux/CARDLIST.em28xx9
-rw-r--r--Documentation/video4linux/CARDLIST.saa71343
-rw-r--r--Documentation/video4linux/README.cx888
-rw-r--r--Documentation/video4linux/gspca.txt19
-rw-r--r--Documentation/video4linux/v4l2-framework.txt520
-rw-r--r--drivers/media/common/ir-keymaps.c93
-rw-r--r--drivers/media/common/saa7146_fops.c2
-rw-r--r--drivers/media/common/saa7146_video.c10
-rw-r--r--drivers/media/common/tuners/mxl5005s.c6
-rw-r--r--drivers/media/common/tuners/tda827x.c15
-rw-r--r--drivers/media/common/tuners/tda8290.c63
-rw-r--r--drivers/media/common/tuners/tda9887.c5
-rw-r--r--drivers/media/common/tuners/tuner-xc2028.c35
-rw-r--r--drivers/media/common/tuners/xc5000.c7
-rw-r--r--drivers/media/dvb/Kconfig13
-rw-r--r--drivers/media/dvb/b2c2/Kconfig1
-rw-r--r--drivers/media/dvb/dm1105/dm1105.c3
-rw-r--r--drivers/media/dvb/dvb-core/dvb_frontend.c77
-rw-r--r--drivers/media/dvb/dvb-core/dvb_frontend.h134
-rw-r--r--drivers/media/dvb/dvb-core/dvbdev.c71
-rw-r--r--drivers/media/dvb/dvb-core/dvbdev.h1
-rw-r--r--drivers/media/dvb/dvb-usb/af9015.c33
-rw-r--r--drivers/media/dvb/dvb-usb/af9015.h140
-rw-r--r--drivers/media/dvb/dvb-usb/anysee.c2
-rw-r--r--drivers/media/dvb/dvb-usb/cinergyT2-core.c3
-rw-r--r--drivers/media/dvb/dvb-usb/cinergyT2.h10
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-ids.h1
-rw-r--r--drivers/media/dvb/dvb-usb/dw2102.c15
-rw-r--r--drivers/media/dvb/dvb-usb/gp8psk-fe.c140
-rw-r--r--drivers/media/dvb/dvb-usb/gp8psk.c16
-rw-r--r--drivers/media/dvb/dvb-usb/gp8psk.h1
-rw-r--r--drivers/media/dvb/dvb-usb/usb-urb.c3
-rw-r--r--drivers/media/dvb/frontends/Kconfig53
-rw-r--r--drivers/media/dvb/frontends/Makefile10
-rw-r--r--drivers/media/dvb/frontends/af9013.c14
-rw-r--r--drivers/media/dvb/frontends/cx24113.c616
-rw-r--r--drivers/media/dvb/frontends/cx24113.h11
-rw-r--r--drivers/media/dvb/frontends/cx24116.c43
-rw-r--r--drivers/media/dvb/frontends/dib7000p.h9
-rw-r--r--drivers/media/dvb/frontends/drx397xD.c12
-rw-r--r--drivers/media/dvb/frontends/drx397xD_fw.h4
-rw-r--r--drivers/media/dvb/frontends/dvb-pll.c2
-rw-r--r--drivers/media/dvb/frontends/lgdt3304.c378
-rw-r--r--drivers/media/dvb/frontends/lgdt3304.h45
-rw-r--r--drivers/media/dvb/frontends/s5h1411.c3
-rw-r--r--drivers/media/dvb/frontends/s921_core.c216
-rw-r--r--drivers/media/dvb/frontends/s921_core.h114
-rw-r--r--drivers/media/dvb/frontends/s921_module.c190
-rw-r--r--drivers/media/dvb/frontends/s921_module.h49
-rw-r--r--drivers/media/dvb/frontends/si21xx.c1
-rw-r--r--drivers/media/dvb/frontends/stb0899_algo.c1519
-rw-r--r--drivers/media/dvb/frontends/stb0899_cfg.h287
-rw-r--r--drivers/media/dvb/frontends/stb0899_drv.c1684
-rw-r--r--drivers/media/dvb/frontends/stb0899_drv.h162
-rw-r--r--drivers/media/dvb/frontends/stb0899_priv.h267
-rw-r--r--drivers/media/dvb/frontends/stb0899_reg.h2027
-rw-r--r--drivers/media/dvb/frontends/stb6100.c545
-rw-r--r--drivers/media/dvb/frontends/stb6100.h115
-rw-r--r--drivers/media/dvb/frontends/stb6100_cfg.h108
-rw-r--r--drivers/media/dvb/frontends/tda8261.c230
-rw-r--r--drivers/media/dvb/frontends/tda8261.h55
-rw-r--r--drivers/media/dvb/frontends/tda8261_cfg.h84
-rw-r--r--drivers/media/dvb/frontends/zl10353.c3
-rw-r--r--drivers/media/dvb/siano/sms-cards.c110
-rw-r--r--drivers/media/dvb/siano/sms-cards.h13
-rw-r--r--drivers/media/dvb/siano/smscoreapi.c78
-rw-r--r--drivers/media/dvb/siano/smscoreapi.h36
-rw-r--r--drivers/media/dvb/siano/smsdvb.c56
-rw-r--r--drivers/media/dvb/siano/smsusb.c45
-rw-r--r--drivers/media/dvb/ttpci/Kconfig4
-rw-r--r--drivers/media/dvb/ttpci/budget-av.c298
-rw-r--r--drivers/media/dvb/ttpci/budget-ci.c311
-rw-r--r--drivers/media/dvb/ttpci/budget.h1
-rw-r--r--drivers/media/radio/dsbr100.c381
-rw-r--r--drivers/media/radio/radio-aimslab.c2
-rw-r--r--drivers/media/radio/radio-cadet.c2
-rw-r--r--drivers/media/radio/radio-gemtek.c2
-rw-r--r--drivers/media/radio/radio-mr800.c123
-rw-r--r--drivers/media/radio/radio-rtrack2.c2
-rw-r--r--drivers/media/radio/radio-sf16fmi.c2
-rw-r--r--drivers/media/video/Kconfig48
-rw-r--r--drivers/media/video/Makefile12
-rw-r--r--drivers/media/video/arv.c5
-rw-r--r--drivers/media/video/bt8xx/bt832.c274
-rw-r--r--drivers/media/video/bt8xx/bt832.h305
-rw-r--r--drivers/media/video/bt8xx/bttv-cards.c72
-rw-r--r--drivers/media/video/bt8xx/bttv-gpio.c7
-rw-r--r--drivers/media/video/bt8xx/bttv.h10
-rw-r--r--drivers/media/video/bt8xx/bttvp.h2
-rw-r--r--drivers/media/video/bw-qcam.c5
-rw-r--r--drivers/media/video/c-qcam.c7
-rw-r--r--drivers/media/video/cpia.c9
-rw-r--r--drivers/media/video/cpia2/cpia2_core.c2
-rw-r--r--drivers/media/video/cpia2/cpia2_usb.c2
-rw-r--r--drivers/media/video/cpia2/cpia2_v4l.c15
-rw-r--r--drivers/media/video/cs5345.c227
-rw-r--r--drivers/media/video/cs53l32a.c188
-rw-r--r--drivers/media/video/cx18/cx18-av-audio.c231
-rw-r--r--drivers/media/video/cx18/cx18-av-core.c106
-rw-r--r--drivers/media/video/cx18/cx18-av-core.h5
-rw-r--r--drivers/media/video/cx18/cx18-av-firmware.c28
-rw-r--r--drivers/media/video/cx18/cx18-av-vbi.c5
-rw-r--r--drivers/media/video/cx18/cx18-cards.c9
-rw-r--r--drivers/media/video/cx18/cx18-cards.h6
-rw-r--r--drivers/media/video/cx18/cx18-controls.c5
-rw-r--r--drivers/media/video/cx18/cx18-driver.c284
-rw-r--r--drivers/media/video/cx18/cx18-driver.h78
-rw-r--r--drivers/media/video/cx18/cx18-dvb.c59
-rw-r--r--drivers/media/video/cx18/cx18-dvb.h1
-rw-r--r--drivers/media/video/cx18/cx18-fileops.c38
-rw-r--r--drivers/media/video/cx18/cx18-firmware.c229
-rw-r--r--drivers/media/video/cx18/cx18-gpio.c23
-rw-r--r--drivers/media/video/cx18/cx18-gpio.h1
-rw-r--r--drivers/media/video/cx18/cx18-i2c.c31
-rw-r--r--drivers/media/video/cx18/cx18-io.c198
-rw-r--r--drivers/media/video/cx18/cx18-io.h326
-rw-r--r--drivers/media/video/cx18/cx18-ioctl.c12
-rw-r--r--drivers/media/video/cx18/cx18-ioctl.h1
-rw-r--r--drivers/media/video/cx18/cx18-irq.c163
-rw-r--r--drivers/media/video/cx18/cx18-irq.h4
-rw-r--r--drivers/media/video/cx18/cx18-mailbox.c527
-rw-r--r--drivers/media/video/cx18/cx18-mailbox.h29
-rw-r--r--drivers/media/video/cx18/cx18-queue.c118
-rw-r--r--drivers/media/video/cx18/cx18-queue.h22
-rw-r--r--drivers/media/video/cx18/cx18-scb.c2
-rw-r--r--drivers/media/video/cx18/cx18-scb.h9
-rw-r--r--drivers/media/video/cx18/cx18-streams.c140
-rw-r--r--drivers/media/video/cx18/cx18-streams.h5
-rw-r--r--drivers/media/video/cx18/cx18-vbi.c5
-rw-r--r--drivers/media/video/cx18/cx18-version.h2
-rw-r--r--drivers/media/video/cx18/cx23418.h6
-rw-r--r--drivers/media/video/cx23885/cx23885-417.c2
-rw-r--r--drivers/media/video/cx23885/cx23885-cards.c12
-rw-r--r--drivers/media/video/cx23885/cx23885-dvb.c1
-rw-r--r--drivers/media/video/cx23885/cx23885.h1
-rw-r--r--drivers/media/video/cx25840/Kconfig2
-rw-r--r--drivers/media/video/cx25840/cx25840-audio.c14
-rw-r--r--drivers/media/video/cx25840/cx25840-core.c447
-rw-r--r--drivers/media/video/cx25840/cx25840-core.h7
-rw-r--r--drivers/media/video/cx25840/cx25840-firmware.c2
-rw-r--r--drivers/media/video/cx25840/cx25840-vbi.c2
-rw-r--r--drivers/media/video/cx88/cx88-alsa.c3
-rw-r--r--drivers/media/video/cx88/cx88-blackbird.c16
-rw-r--r--drivers/media/video/cx88/cx88-cards.c86
-rw-r--r--drivers/media/video/cx88/cx88-core.c3
-rw-r--r--drivers/media/video/cx88/cx88-dvb.c230
-rw-r--r--drivers/media/video/cx88/cx88-mpeg.c4
-rw-r--r--drivers/media/video/cx88/cx88.h14
-rw-r--r--drivers/media/video/em28xx/em28xx-audio.c21
-rw-r--r--drivers/media/video/em28xx/em28xx-cards.c1464
-rw-r--r--drivers/media/video/em28xx/em28xx-core.c628
-rw-r--r--drivers/media/video/em28xx/em28xx-dvb.c14
-rw-r--r--drivers/media/video/em28xx/em28xx-i2c.c49
-rw-r--r--drivers/media/video/em28xx/em28xx-input.c311
-rw-r--r--drivers/media/video/em28xx/em28xx-reg.h153
-rw-r--r--drivers/media/video/em28xx/em28xx-video.c851
-rw-r--r--drivers/media/video/em28xx/em28xx.h148
-rw-r--r--drivers/media/video/et61x251/et61x251_core.c2
-rw-r--r--drivers/media/video/gspca/Kconfig23
-rw-r--r--drivers/media/video/gspca/Makefile4
-rw-r--r--drivers/media/video/gspca/conex.c2
-rw-r--r--drivers/media/video/gspca/etoms.c4
-rw-r--r--drivers/media/video/gspca/finepix.c5
-rw-r--r--drivers/media/video/gspca/gspca.c210
-rw-r--r--drivers/media/video/gspca/gspca.h25
-rw-r--r--drivers/media/video/gspca/m5602/m5602_bridge.h119
-rw-r--r--drivers/media/video/gspca/m5602/m5602_core.c100
-rw-r--r--drivers/media/video/gspca/m5602/m5602_mt9m111.c135
-rw-r--r--drivers/media/video/gspca/m5602/m5602_mt9m111.h14
-rw-r--r--drivers/media/video/gspca/m5602/m5602_ov9650.c316
-rw-r--r--drivers/media/video/gspca/m5602/m5602_ov9650.h195
-rw-r--r--drivers/media/video/gspca/m5602/m5602_po1030.c166
-rw-r--r--drivers/media/video/gspca/m5602/m5602_po1030.h10
-rw-r--r--drivers/media/video/gspca/m5602/m5602_s5k4aa.c235
-rw-r--r--drivers/media/video/gspca/m5602/m5602_s5k4aa.h47
-rw-r--r--drivers/media/video/gspca/m5602/m5602_s5k83a.c213
-rw-r--r--drivers/media/video/gspca/m5602/m5602_s5k83a.h25
-rw-r--r--drivers/media/video/gspca/m5602/m5602_sensor.h14
-rw-r--r--drivers/media/video/gspca/mars.c4
-rw-r--r--drivers/media/video/gspca/ov519.c172
-rw-r--r--drivers/media/video/gspca/ov534.c601
-rw-r--r--drivers/media/video/gspca/pac207.c8
-rw-r--r--drivers/media/video/gspca/pac7311.c5
-rw-r--r--drivers/media/video/gspca/sonixb.c25
-rw-r--r--drivers/media/video/gspca/sonixj.c508
-rw-r--r--drivers/media/video/gspca/spca500.c8
-rw-r--r--drivers/media/video/gspca/spca501.c148
-rw-r--r--drivers/media/video/gspca/spca505.c2
-rw-r--r--drivers/media/video/gspca/spca506.c2
-rw-r--r--drivers/media/video/gspca/spca508.c2
-rw-r--r--drivers/media/video/gspca/spca561.c522
-rw-r--r--drivers/media/video/gspca/stk014.c8
-rw-r--r--drivers/media/video/gspca/stv06xx/Kconfig9
-rw-r--r--drivers/media/video/gspca/stv06xx/Makefile9
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx.c522
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx.h107
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c535
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx_hdcs.h263
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c430
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx_pb0100.h275
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx_sensor.h92
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c251
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h315
-rw-r--r--drivers/media/video/gspca/sunplus.c6
-rw-r--r--drivers/media/video/gspca/t613.c4
-rw-r--r--drivers/media/video/gspca/tv8532.c142
-rw-r--r--drivers/media/video/gspca/vc032x.c819
-rw-r--r--drivers/media/video/gspca/zc3xx-reg.h8
-rw-r--r--drivers/media/video/gspca/zc3xx.c1012
-rw-r--r--drivers/media/video/ir-kbd-i2c.c6
-rw-r--r--drivers/media/video/ivtv/ivtv-cards.c16
-rw-r--r--drivers/media/video/ivtv/ivtv-controls.c16
-rw-r--r--drivers/media/video/ivtv/ivtv-driver.c214
-rw-r--r--drivers/media/video/ivtv/ivtv-driver.h52
-rw-r--r--drivers/media/video/ivtv/ivtv-fileops.c44
-rw-r--r--drivers/media/video/ivtv/ivtv-gpio.c324
-rw-r--r--drivers/media/video/ivtv/ivtv-gpio.h3
-rw-r--r--drivers/media/video/ivtv/ivtv-i2c.c314
-rw-r--r--drivers/media/video/ivtv/ivtv-i2c.h13
-rw-r--r--drivers/media/video/ivtv/ivtv-ioctl.c73
-rw-r--r--drivers/media/video/ivtv/ivtv-routing.c12
-rw-r--r--drivers/media/video/ivtv/ivtv-streams.c15
-rw-r--r--drivers/media/video/ivtv/ivtv-vbi.c17
-rw-r--r--drivers/media/video/ivtv/ivtvfb.c91
-rw-r--r--drivers/media/video/m52790.c176
-rw-r--r--drivers/media/video/msp3400-driver.c402
-rw-r--r--drivers/media/video/msp3400-driver.h7
-rw-r--r--drivers/media/video/msp3400-kthreads.c34
-rw-r--r--drivers/media/video/mt9m001.c60
-rw-r--r--drivers/media/video/mt9m111.c121
-rw-r--r--drivers/media/video/mt9t031.c736
-rw-r--r--drivers/media/video/mt9v022.c46
-rw-r--r--drivers/media/video/omap24xxcam-dma.c601
-rw-r--r--drivers/media/video/omap24xxcam.c1908
-rw-r--r--drivers/media/video/omap24xxcam.h593
-rw-r--r--drivers/media/video/ov511.c5
-rw-r--r--drivers/media/video/ov772x.c1012
-rw-r--r--drivers/media/video/pms.c9
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-hdw.c2
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-sysfs.c4
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-v4l2.c13
-rw-r--r--drivers/media/video/pwc/pwc-if.c2
-rw-r--r--drivers/media/video/pwc/pwc-v4l.c3
-rw-r--r--drivers/media/video/pwc/pwc.h3
-rw-r--r--drivers/media/video/pxa_camera.c541
-rw-r--r--drivers/media/video/saa5246a.c7
-rw-r--r--drivers/media/video/saa5249.c7
-rw-r--r--drivers/media/video/saa7115.c763
-rw-r--r--drivers/media/video/saa7127.c421
-rw-r--r--drivers/media/video/saa7134/saa7134-cards.c52
-rw-r--r--drivers/media/video/saa7134/saa7134-dvb.c24
-rw-r--r--drivers/media/video/saa7134/saa7134-input.c14
-rw-r--r--drivers/media/video/saa7134/saa7134-tvaudio.c2
-rw-r--r--drivers/media/video/saa7134/saa7134.h3
-rw-r--r--drivers/media/video/saa717x.c610
-rw-r--r--drivers/media/video/se401.c5
-rw-r--r--drivers/media/video/sh_mobile_ceu_camera.c309
-rw-r--r--drivers/media/video/sn9c102/sn9c102_core.c2
-rw-r--r--drivers/media/video/sn9c102/sn9c102_devtable.h8
-rw-r--r--drivers/media/video/soc_camera.c389
-rw-r--r--drivers/media/video/soc_camera_platform.c17
-rw-r--r--drivers/media/video/stk-webcam.c27
-rw-r--r--drivers/media/video/stv680.c5
-rw-r--r--drivers/media/video/tda7432.c252
-rw-r--r--drivers/media/video/tda9840.c188
-rw-r--r--drivers/media/video/tda9875.c348
-rw-r--r--drivers/media/video/tea6415c.c49
-rw-r--r--drivers/media/video/tea6420.c49
-rw-r--r--drivers/media/video/tlv320aic23b.c141
-rw-r--r--drivers/media/video/tuner-core.c397
-rw-r--r--drivers/media/video/tvaudio.c707
-rw-r--r--drivers/media/video/tvp514x.c1569
-rw-r--r--drivers/media/video/tvp514x_regs.h297
-rw-r--r--drivers/media/video/tvp5150.c827
-rw-r--r--drivers/media/video/tw9910.c951
-rw-r--r--drivers/media/video/upd64031a.c193
-rw-r--r--drivers/media/video/upd64083.c166
-rw-r--r--drivers/media/video/usbvideo/ibmcam.c4
-rw-r--r--drivers/media/video/usbvideo/konicawc.c4
-rw-r--r--drivers/media/video/usbvideo/quickcam_messenger.c9
-rw-r--r--drivers/media/video/usbvideo/ultracam.c4
-rw-r--r--drivers/media/video/usbvideo/usbvideo.c7
-rw-r--r--drivers/media/video/usbvideo/vicam.c3
-rw-r--r--drivers/media/video/usbvision/usbvision-video.c11
-rw-r--r--drivers/media/video/uvc/uvc_ctrl.c143
-rw-r--r--drivers/media/video/uvc/uvc_driver.c332
-rw-r--r--drivers/media/video/uvc/uvc_queue.c23
-rw-r--r--drivers/media/video/uvc/uvc_v4l2.c115
-rw-r--r--drivers/media/video/uvc/uvc_video.c214
-rw-r--r--drivers/media/video/uvc/uvcvideo.h34
-rw-r--r--drivers/media/video/v4l2-common.c203
-rw-r--r--drivers/media/video/v4l2-compat-ioctl32.c (renamed from drivers/media/video/compat_ioctl32.c)835
-rw-r--r--drivers/media/video/v4l2-dev.c365
-rw-r--r--drivers/media/video/v4l2-device.c86
-rw-r--r--drivers/media/video/v4l2-ioctl.c98
-rw-r--r--drivers/media/video/v4l2-subdev.c110
-rw-r--r--drivers/media/video/vino.c5
-rw-r--r--drivers/media/video/vp27smpx.c126
-rw-r--r--drivers/media/video/w9966.c5
-rw-r--r--drivers/media/video/wm8739.c188
-rw-r--r--drivers/media/video/wm8775.c221
-rw-r--r--drivers/media/video/zc0301/zc0301_core.c2
-rw-r--r--drivers/media/video/zoran/zoran_card.c6
-rw-r--r--drivers/media/video/zoran/zoran_driver.c8
-rw-r--r--firmware/Makefile16
-rw-r--r--include/linux/videodev2.h14
-rw-r--r--include/media/i2c-addr.h2
-rw-r--r--include/media/ir-common.h2
-rw-r--r--include/media/ov772x.h21
-rw-r--r--include/media/saa7146_vv.h3
-rw-r--r--include/media/soc_camera.h111
-rw-r--r--include/media/tvp514x.h118
-rw-r--r--include/media/tw9910.h39
-rw-r--r--include/media/v4l2-chip-ident.h10
-rw-r--r--include/media/v4l2-common.h41
-rw-r--r--include/media/v4l2-dev.h51
-rw-r--r--include/media/v4l2-device.h109
-rw-r--r--include/media/v4l2-int-device.h6
-rw-r--r--include/media/v4l2-ioctl.h14
-rw-r--r--include/media/v4l2-subdev.h189
-rw-r--r--sound/i2c/other/tea575x-tuner.c22
326 files changed, 38106 insertions, 11077 deletions
diff --git a/Documentation/dvb/technisat.txt b/Documentation/dvb/technisat.txt
new file mode 100644
index 000000000000..cdf6ee4b2da1
--- /dev/null
+++ b/Documentation/dvb/technisat.txt
@@ -0,0 +1,69 @@
1How to set up the Technisat devices
2===================================
3
41) Find out what device you have
5================================
6
7First start your linux box with a shipped kernel:
8lspci -vvv for a PCI device (lsusb -vvv for an USB device) will show you for example:
902:0b.0 Network controller: Techsan Electronics Co Ltd B2C2 FlexCopII DVB chip / Technisat SkyStar2 DVB card (rev 02)
10
11dmesg | grep frontend may show you for example:
12DVB: registering frontend 0 (Conexant CX24123/CX24109)...
13
142) Kernel compilation:
15======================
16
17If the Technisat is the only TV device in your box get rid of unnecessary modules and check this one:
18"Multimedia devices" => "Customise analog and hybrid tuner modules to build"
19In this directory uncheck every driver which is activated there.
20
21Then please activate:
222a) Main module part:
23
24a.)"Multimedia devices" => "DVB/ATSC adapters" => "Technisat/B2C2 FlexcopII(b) and FlexCopIII adapters"
25b.)"Multimedia devices" => "DVB/ATSC adapters" => "Technisat/B2C2 FlexcopII(b) and FlexCopIII adapters" => "Technisat/B2C2 Air/Sky/Cable2PC PCI" in case of a PCI card OR
26c.)"Multimedia devices" => "DVB/ATSC adapters" => "Technisat/B2C2 FlexcopII(b) and FlexCopIII adapters" => "Technisat/B2C2 Air/Sky/Cable2PC USB" in case of an USB 1.1 adapter
27d.)"Multimedia devices" => "DVB/ATSC adapters" => "Technisat/B2C2 FlexcopII(b) and FlexCopIII adapters" => "Enable debug for the B2C2 FlexCop drivers"
28Notice: d.) is helpful for troubleshooting
29
302b) Frontend module part:
31
321.) Revision 2.3:
33a.)"Multimedia devices" => "Customise DVB frontends" => "Customise the frontend modules to build"
34b.)"Multimedia devices" => "Customise DVB frontends" => "Zarlink VP310/MT312/ZL10313 based"
35
362.) Revision 2.6:
37a.)"Multimedia devices" => "Customise DVB frontends" => "Customise the frontend modules to build"
38b.)"Multimedia devices" => "Customise DVB frontends" => "ST STV0299 based"
39
403.) Revision 2.7:
41a.)"Multimedia devices" => "Customise DVB frontends" => "Customise the frontend modules to build"
42b.)"Multimedia devices" => "Customise DVB frontends" => "Samsung S5H1420 based"
43c.)"Multimedia devices" => "Customise DVB frontends" => "Integrant ITD1000 Zero IF tuner for DVB-S/DSS"
44d.)"Multimedia devices" => "Customise DVB frontends" => "ISL6421 SEC controller"
45
464.) Revision 2.8:
47a.)"Multimedia devices" => "Customise DVB frontends" => "Customise the frontend modules to build"
48b.)"Multimedia devices" => "Customise DVB frontends" => "Conexant CX24113/CX24128 tuner for DVB-S/DSS"
49c.)"Multimedia devices" => "Customise DVB frontends" => "Conexant CX24123 based"
50d.)"Multimedia devices" => "Customise DVB frontends" => "ISL6421 SEC controller"
51
525.) DVB-T card:
53a.)"Multimedia devices" => "Customise DVB frontends" => "Customise the frontend modules to build"
54b.)"Multimedia devices" => "Customise DVB frontends" => "Zarlink MT352 based"
55
566.) DVB-C card:
57a.)"Multimedia devices" => "Customise DVB frontends" => "Customise the frontend modules to build"
58b.)"Multimedia devices" => "Customise DVB frontends" => "ST STV0297 based"
59
607.) ATSC card 1st generation:
61a.)"Multimedia devices" => "Customise DVB frontends" => "Customise the frontend modules to build"
62b.)"Multimedia devices" => "Customise DVB frontends" => "Broadcom BCM3510"
63
648.) ATSC card 2nd generation:
65a.)"Multimedia devices" => "Customise DVB frontends" => "Customise the frontend modules to build"
66b.)"Multimedia devices" => "Customise DVB frontends" => "NxtWave Communications NXT2002/NXT2004 based"
67c.)"Multimedia devices" => "Customise DVB frontends" => "LG Electronics LGDT3302/LGDT3303 based"
68
69Author: Uwe Bugla <uwe.bugla@gmx.de> December 2008
diff --git a/Documentation/video4linux/API.html b/Documentation/video4linux/API.html
index afbe9ae7ee96..d749d41f647b 100644
--- a/Documentation/video4linux/API.html
+++ b/Documentation/video4linux/API.html
@@ -1,16 +1,27 @@
1<TITLE>V4L API</TITLE> 1<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
2<H1>Video For Linux APIs</H1> 2<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
3<table border=0> 3 <head>
4<tr> 4 <meta content="text/html;charset=ISO-8859-2" http-equiv="Content-Type" />
5<td> 5 <title>V4L API</title>
6<A HREF=http://www.linuxtv.org/downloads/video4linux/API/V4L1_API.html> 6 </head>
7V4L original API</a> 7 <body>
8</td><td> 8 <h1>Video For Linux APIs</h1>
9Obsoleted by V4L2 API 9 <table border="0">
10</td></tr><tr><td> 10 <tr>
11<A HREF=http://www.linuxtv.org/downloads/video4linux/API/V4L2_API> 11 <td>
12V4L2 API</a> 12 <a href="http://www.linuxtv.org/downloads/video4linux/API/V4L1_API.html">V4L original API</a>
13</td><td> 13 </td>
14Should be used for new projects 14 <td>
15</td></tr> 15 Obsoleted by V4L2 API
16</table> 16 </td>
17 </tr>
18 <tr>
19 <td>
20 <a href="http://www.linuxtv.org/downloads/video4linux/API/V4L2_API">V4L2 API</a>
21 </td>
22 <td>Should be used for new projects
23 </td>
24 </tr>
25 </table>
26 </body>
27</html>
diff --git a/Documentation/video4linux/CARDLIST.bttv b/Documentation/video4linux/CARDLIST.bttv
index 60ba66836038..0d93fa1ac25e 100644
--- a/Documentation/video4linux/CARDLIST.bttv
+++ b/Documentation/video4linux/CARDLIST.bttv
@@ -104,8 +104,8 @@
104103 -> Grand X-Guard / Trust 814PCI [0304:0102] 104103 -> Grand X-Guard / Trust 814PCI [0304:0102]
105104 -> Nebula Electronics DigiTV [0071:0101] 105104 -> Nebula Electronics DigiTV [0071:0101]
106105 -> ProVideo PV143 [aa00:1430,aa00:1431,aa00:1432,aa00:1433,aa03:1433] 106105 -> ProVideo PV143 [aa00:1430,aa00:1431,aa00:1432,aa00:1433,aa03:1433]
107106 -> PHYTEC VD-009-X1 MiniDIN (bt878) 107106 -> PHYTEC VD-009-X1 VD-011 MiniDIN (bt878)
108107 -> PHYTEC VD-009-X1 Combi (bt878) 108107 -> PHYTEC VD-009-X1 VD-011 Combi (bt878)
109108 -> PHYTEC VD-009 MiniDIN (bt878) 109108 -> PHYTEC VD-009 MiniDIN (bt878)
110109 -> PHYTEC VD-009 Combi (bt878) 110109 -> PHYTEC VD-009 Combi (bt878)
111110 -> IVC-100 [ff00:a132] 111110 -> IVC-100 [ff00:a132]
@@ -151,3 +151,6 @@
151150 -> Geovision GV-600 [008a:763c] 151150 -> Geovision GV-600 [008a:763c]
152151 -> Kozumi KTV-01C 152151 -> Kozumi KTV-01C
153152 -> Encore ENL TV-FM-2 [1000:1801] 153152 -> Encore ENL TV-FM-2 [1000:1801]
154153 -> PHYTEC VD-012 (bt878)
155154 -> PHYTEC VD-012-X1 (bt878)
156155 -> PHYTEC VD-012-X2 (bt878)
diff --git a/Documentation/video4linux/CARDLIST.cx23885 b/Documentation/video4linux/CARDLIST.cx23885
index 64823ccacd69..35ea130e9898 100644
--- a/Documentation/video4linux/CARDLIST.cx23885
+++ b/Documentation/video4linux/CARDLIST.cx23885
@@ -11,3 +11,4 @@
11 10 -> DViCO FusionHDTV7 Dual Express [18ac:d618] 11 10 -> DViCO FusionHDTV7 Dual Express [18ac:d618]
12 11 -> DViCO FusionHDTV DVB-T Dual Express [18ac:db78] 12 11 -> DViCO FusionHDTV DVB-T Dual Express [18ac:db78]
13 12 -> Leadtek Winfast PxDVR3200 H [107d:6681] 13 12 -> Leadtek Winfast PxDVR3200 H [107d:6681]
14 13 -> Compro VideoMate E650F [185b:e800]
diff --git a/Documentation/video4linux/CARDLIST.cx88 b/Documentation/video4linux/CARDLIST.cx88
index a5227e308f4a..0d08f1edcf6d 100644
--- a/Documentation/video4linux/CARDLIST.cx88
+++ b/Documentation/video4linux/CARDLIST.cx88
@@ -2,7 +2,7 @@
2 1 -> Hauppauge WinTV 34xxx models [0070:3400,0070:3401] 2 1 -> Hauppauge WinTV 34xxx models [0070:3400,0070:3401]
3 2 -> GDI Black Gold [14c7:0106,14c7:0107] 3 2 -> GDI Black Gold [14c7:0106,14c7:0107]
4 3 -> PixelView [1554:4811] 4 3 -> PixelView [1554:4811]
5 4 -> ATI TV Wonder Pro [1002:00f8] 5 4 -> ATI TV Wonder Pro [1002:00f8,1002:00f9]
6 5 -> Leadtek Winfast 2000XP Expert [107d:6611,107d:6613] 6 5 -> Leadtek Winfast 2000XP Expert [107d:6611,107d:6613]
7 6 -> AverTV Studio 303 (M126) [1461:000b] 7 6 -> AverTV Studio 303 (M126) [1461:000b]
8 7 -> MSI TV-@nywhere Master [1462:8606] 8 7 -> MSI TV-@nywhere Master [1462:8606]
@@ -74,3 +74,6 @@
74 73 -> TeVii S420 DVB-S [d420:9022] 74 73 -> TeVii S420 DVB-S [d420:9022]
75 74 -> Prolink Pixelview Global Extreme [1554:4976] 75 74 -> Prolink Pixelview Global Extreme [1554:4976]
76 75 -> PROF 7300 DVB-S/S2 [B033:3033] 76 75 -> PROF 7300 DVB-S/S2 [B033:3033]
77 76 -> SATTRADE ST4200 DVB-S/S2 [b200:4200]
78 77 -> TBS 8910 DVB-S [8910:8888]
79 78 -> Prof 6200 DVB-S [b022:3022]
diff --git a/Documentation/video4linux/CARDLIST.em28xx b/Documentation/video4linux/CARDLIST.em28xx
index 187cc48d0924..75bded8a4aa2 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:2820,eb1a:2860,eb1a:2861,eb1a:2870,eb1a:2881,eb1a:2883] 2 1 -> Unknown EM2750/28xx video grabber (em2820/em2840) [eb1a:2820,eb1a:2821,eb1a:2860,eb1a:2861,eb1a:2870,eb1a:2881,eb1a:2883]
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]
@@ -12,9 +12,9 @@
12 11 -> Terratec Hybrid XS (em2880) [0ccd:0042] 12 11 -> Terratec Hybrid XS (em2880) [0ccd:0042]
13 12 -> Kworld PVR TV 2800 RF (em2820/em2840) 13 12 -> Kworld PVR TV 2800 RF (em2820/em2840)
14 13 -> Terratec Prodigy XS (em2880) [0ccd:0047] 14 13 -> Terratec Prodigy XS (em2880) [0ccd:0047]
15 14 -> Pixelview Prolink PlayTV USB 2.0 (em2820/em2840) [eb1a:2821] 15 14 -> Pixelview Prolink PlayTV USB 2.0 (em2820/em2840)
16 15 -> V-Gear PocketTV (em2800) 16 15 -> V-Gear PocketTV (em2800)
17 16 -> Hauppauge WinTV HVR 950 (em2883) [2040:6513,2040:6517,2040:651b,2040:651f] 17 16 -> Hauppauge WinTV HVR 950 (em2883) [2040:6513,2040:6517,2040:651b]
18 17 -> Pinnacle PCTV HD Pro Stick (em2880) [2304:0227] 18 17 -> Pinnacle PCTV HD Pro Stick (em2880) [2304:0227]
19 18 -> Hauppauge WinTV HVR 900 (R2) (em2880) [2040:6502] 19 18 -> Hauppauge WinTV HVR 900 (R2) (em2880) [2040:6502]
20 19 -> PointNix Intra-Oral Camera (em2860) 20 19 -> PointNix Intra-Oral Camera (em2860)
@@ -27,7 +27,6 @@
27 26 -> Hercules Smart TV USB 2.0 (em2820/em2840) 27 26 -> Hercules Smart TV USB 2.0 (em2820/em2840)
28 27 -> Pinnacle PCTV USB 2 (Philips FM1216ME) (em2820/em2840) 28 27 -> Pinnacle PCTV USB 2 (Philips FM1216ME) (em2820/em2840)
29 28 -> Leadtek Winfast USB II Deluxe (em2820/em2840) 29 28 -> Leadtek Winfast USB II Deluxe (em2820/em2840)
30 29 -> Pinnacle Dazzle DVC 100 (em2820/em2840)
31 30 -> Videology 20K14XUSB USB2.0 (em2820/em2840) 30 30 -> Videology 20K14XUSB USB2.0 (em2820/em2840)
32 31 -> Usbgear VD204v9 (em2821) 31 31 -> Usbgear VD204v9 (em2821)
33 32 -> Supercomp USB 2.0 TV (em2821) 32 32 -> Supercomp USB 2.0 TV (em2821)
@@ -57,3 +56,5 @@
57 56 -> Pinnacle Hybrid Pro (2) (em2882) [2304:0226] 56 56 -> Pinnacle Hybrid Pro (2) (em2882) [2304:0226]
58 57 -> Kworld PlusTV HD Hybrid 330 (em2883) [eb1a:a316] 57 57 -> Kworld PlusTV HD Hybrid 330 (em2883) [eb1a:a316]
59 58 -> Compro VideoMate ForYou/Stereo (em2820/em2840) [185b:2041] 58 58 -> Compro VideoMate ForYou/Stereo (em2820/em2840) [185b:2041]
59 60 -> Hauppauge WinTV HVR 850 (em2883) [2040:651f]
60 61 -> Pixelview PlayTV Box 4 USB 2.0 (em2820/em2840)
diff --git a/Documentation/video4linux/CARDLIST.saa7134 b/Documentation/video4linux/CARDLIST.saa7134
index dc67eef38ff9..335aef4dcaeb 100644
--- a/Documentation/video4linux/CARDLIST.saa7134
+++ b/Documentation/video4linux/CARDLIST.saa7134
@@ -10,7 +10,7 @@
10 9 -> Medion 5044 10 9 -> Medion 5044
11 10 -> Kworld/KuroutoShikou SAA7130-TVPCI 11 10 -> Kworld/KuroutoShikou SAA7130-TVPCI
12 11 -> Terratec Cinergy 600 TV [153b:1143] 12 11 -> Terratec Cinergy 600 TV [153b:1143]
13 12 -> Medion 7134 [16be:0003] 13 12 -> Medion 7134 [16be:0003,16be:5000]
14 13 -> Typhoon TV+Radio 90031 14 13 -> Typhoon TV+Radio 90031
15 14 -> ELSA EX-VISION 300TV [1048:226b] 15 14 -> ELSA EX-VISION 300TV [1048:226b]
16 15 -> ELSA EX-VISION 500TV [1048:226a] 16 15 -> ELSA EX-VISION 500TV [1048:226a]
@@ -151,3 +151,4 @@
151150 -> Zogis Real Angel 220 151150 -> Zogis Real Angel 220
152151 -> ADS Tech Instant HDTV [1421:0380] 152151 -> ADS Tech Instant HDTV [1421:0380]
153152 -> Asus Tiger Rev:1.00 [1043:4857] 153152 -> Asus Tiger Rev:1.00 [1043:4857]
154153 -> Kworld Plus TV Analog Lite PCI [17de:7128]
diff --git a/Documentation/video4linux/README.cx88 b/Documentation/video4linux/README.cx88
index 166d5960b1a9..35fae23f883b 100644
--- a/Documentation/video4linux/README.cx88
+++ b/Documentation/video4linux/README.cx88
@@ -1,4 +1,3 @@
1
2cx8800 release notes 1cx8800 release notes
3==================== 2====================
4 3
@@ -10,21 +9,20 @@ current status
10 9
11video 10video
12 - Basically works. 11 - Basically works.
13 - Some minor image quality glitches. 12 - For now, only capture and read(). Overlay isn't supported.
14 - For now only capture, overlay support isn't completed yet.
15 13
16audio 14audio
17 - The chip specs for the on-chip TV sound decoder are next 15 - The chip specs for the on-chip TV sound decoder are next
18 to useless :-/ 16 to useless :-/
19 - Neverless the builtin TV sound decoder starts working now, 17 - Neverless the builtin TV sound decoder starts working now,
20 at least for PAL-BG. Other TV norms need other code ... 18 at least for some standards.
21 FOR ANY REPORTS ON THIS PLEASE MENTION THE TV NORM YOU ARE 19 FOR ANY REPORTS ON THIS PLEASE MENTION THE TV NORM YOU ARE
22 USING. 20 USING.
23 - Most tuner chips do provide mono sound, which may or may not 21 - Most tuner chips do provide mono sound, which may or may not
24 be useable depending on the board design. With the Hauppauge 22 be useable depending on the board design. With the Hauppauge
25 cards it works, so there is mono sound available as fallback. 23 cards it works, so there is mono sound available as fallback.
26 - audio data dma (i.e. recording without loopback cable to the 24 - audio data dma (i.e. recording without loopback cable to the
27 sound card) should be possible, but there is no code yet ... 25 sound card) is supported via cx88-alsa.
28 26
29vbi 27vbi
30 - Code present. Works for NTSC closed caption. PAL and other 28 - Code present. Works for NTSC closed caption. PAL and other
diff --git a/Documentation/video4linux/gspca.txt b/Documentation/video4linux/gspca.txt
index 004818fab040..1c58a7630146 100644
--- a/Documentation/video4linux/gspca.txt
+++ b/Documentation/video4linux/gspca.txt
@@ -50,9 +50,14 @@ ov519 045e:028c Micro$oft xbox cam
50spca508 0461:0815 Micro Innovation IC200 50spca508 0461:0815 Micro Innovation IC200
51sunplus 0461:0821 Fujifilm MV-1 51sunplus 0461:0821 Fujifilm MV-1
52zc3xx 0461:0a00 MicroInnovation WebCam320 52zc3xx 0461:0a00 MicroInnovation WebCam320
53stv06xx 046d:0840 QuickCam Express
54stv06xx 046d:0850 LEGO cam / QuickCam Web
55stv06xx 046d:0870 Dexxa WebCam USB
53spca500 046d:0890 Logitech QuickCam traveler 56spca500 046d:0890 Logitech QuickCam traveler
54vc032x 046d:0892 Logitech Orbicam 57vc032x 046d:0892 Logitech Orbicam
55vc032x 046d:0896 Logitech Orbicam 58vc032x 046d:0896 Logitech Orbicam
59vc032x 046d:0897 Logitech QuickCam for Dell notebooks
60zc3xx 046d:089d Logitech QuickCam E2500
56zc3xx 046d:08a0 Logitech QC IM 61zc3xx 046d:08a0 Logitech QC IM
57zc3xx 046d:08a1 Logitech QC IM 0x08A1 +sound 62zc3xx 046d:08a1 Logitech QC IM 0x08A1 +sound
58zc3xx 046d:08a2 Labtec Webcam Pro 63zc3xx 046d:08a2 Labtec Webcam Pro
@@ -169,6 +174,9 @@ spca500 06bd:0404 Agfa CL20
169spca500 06be:0800 Optimedia 174spca500 06be:0800 Optimedia
170sunplus 06d6:0031 Trust 610 LCD PowerC@m Zoom 175sunplus 06d6:0031 Trust 610 LCD PowerC@m Zoom
171spca506 06e1:a190 ADS Instant VCD 176spca506 06e1:a190 ADS Instant VCD
177ov534 06f8:3002 Hercules Blog Webcam
178ov534 06f8:3003 Hercules Dualpix HD Weblog
179sonixj 06f8:3004 Hercules Classic Silver
172spca508 0733:0110 ViewQuest VQ110 180spca508 0733:0110 ViewQuest VQ110
173spca508 0130:0130 Clone Digital Webcam 11043 181spca508 0130:0130 Clone Digital Webcam 11043
174spca501 0733:0401 Intel Create and Share 182spca501 0733:0401 Intel Create and Share
@@ -199,7 +207,8 @@ sunplus 08ca:2050 Medion MD 41437
199sunplus 08ca:2060 Aiptek PocketDV5300 207sunplus 08ca:2060 Aiptek PocketDV5300
200tv8532 0923:010f ICM532 cams 208tv8532 0923:010f ICM532 cams
201mars 093a:050f Mars-Semi Pc-Camera 209mars 093a:050f Mars-Semi Pc-Camera
202pac207 093a:2460 PAC207 Qtec Webcam 100 210pac207 093a:2460 Qtec Webcam 100
211pac207 093a:2461 HP Webcam
203pac207 093a:2463 Philips SPC 220 NC 212pac207 093a:2463 Philips SPC 220 NC
204pac207 093a:2464 Labtec Webcam 1200 213pac207 093a:2464 Labtec Webcam 1200
205pac207 093a:2468 PAC207 214pac207 093a:2468 PAC207
@@ -213,10 +222,13 @@ pac7311 093a:2603 PAC7312
213pac7311 093a:2608 Trust WB-3300p 222pac7311 093a:2608 Trust WB-3300p
214pac7311 093a:260e Gigaware VGA PC Camera, Trust WB-3350p, SIGMA cam 2350 223pac7311 093a:260e Gigaware VGA PC Camera, Trust WB-3350p, SIGMA cam 2350
215pac7311 093a:260f SnakeCam 224pac7311 093a:260f SnakeCam
225pac7311 093a:2620 Apollo AC-905
216pac7311 093a:2621 PAC731x 226pac7311 093a:2621 PAC731x
227pac7311 093a:2622 Genius Eye 312
217pac7311 093a:2624 PAC7302 228pac7311 093a:2624 PAC7302
218pac7311 093a:2626 Labtec 2200 229pac7311 093a:2626 Labtec 2200
219pac7311 093a:262a Webcam 300k 230pac7311 093a:262a Webcam 300k
231pac7311 093a:262c Philips SPC 230 NC
220zc3xx 0ac8:0302 Z-star Vimicro zc0302 232zc3xx 0ac8:0302 Z-star Vimicro zc0302
221vc032x 0ac8:0321 Vimicro generic vc0321 233vc032x 0ac8:0321 Vimicro generic vc0321
222vc032x 0ac8:0323 Vimicro Vc0323 234vc032x 0ac8:0323 Vimicro Vc0323
@@ -249,11 +261,13 @@ sonixj 0c45:60c0 Sangha Sn535
249sonixj 0c45:60ec SN9C105+MO4000 261sonixj 0c45:60ec SN9C105+MO4000
250sonixj 0c45:60fb Surfer NoName 262sonixj 0c45:60fb Surfer NoName
251sonixj 0c45:60fc LG-LIC300 263sonixj 0c45:60fc LG-LIC300
264sonixj 0c45:60fe Microdia Audio
252sonixj 0c45:6128 Microdia/Sonix SNP325 265sonixj 0c45:6128 Microdia/Sonix SNP325
253sonixj 0c45:612a Avant Camera 266sonixj 0c45:612a Avant Camera
254sonixj 0c45:612c Typhoon Rasy Cam 1.3MPix 267sonixj 0c45:612c Typhoon Rasy Cam 1.3MPix
255sonixj 0c45:6130 Sonix Pccam 268sonixj 0c45:6130 Sonix Pccam
256sonixj 0c45:6138 Sn9c120 Mo4000 269sonixj 0c45:6138 Sn9c120 Mo4000
270sonixj 0c45:613a Microdia Sonix PC Camera
257sonixj 0c45:613b Surfer SN-206 271sonixj 0c45:613b Surfer SN-206
258sonixj 0c45:613c Sonix Pccam168 272sonixj 0c45:613c Sonix Pccam168
259sonixj 0c45:6143 Sonix Pccam168 273sonixj 0c45:6143 Sonix Pccam168
@@ -263,6 +277,9 @@ etoms 102c:6251 Qcam xxxxxx VGA
263zc3xx 10fd:0128 Typhoon Webshot II USB 300k 0x0128 277zc3xx 10fd:0128 Typhoon Webshot II USB 300k 0x0128
264spca561 10fd:7e50 FlyCam Usb 100 278spca561 10fd:7e50 FlyCam Usb 100
265zc3xx 10fd:8050 Typhoon Webshot II USB 300k 279zc3xx 10fd:8050 Typhoon Webshot II USB 300k
280ov534 1415:2000 Sony HD Eye for PS3 (SLEH 00201)
281pac207 145f:013a Trust WB-1300N
282vc032x 15b8:6002 HP 2.0 Megapixel rz406aa
266spca501 1776:501c Arowana 300K CMOS Camera 283spca501 1776:501c Arowana 300K CMOS Camera
267t613 17a1:0128 TASCORP JPEG Webcam, NGS Cyclops 284t613 17a1:0128 TASCORP JPEG Webcam, NGS Cyclops
268vc032x 17ef:4802 Lenovo Vc0323+MI1310_SOC 285vc032x 17ef:4802 Lenovo Vc0323+MI1310_SOC
diff --git a/Documentation/video4linux/v4l2-framework.txt b/Documentation/video4linux/v4l2-framework.txt
new file mode 100644
index 000000000000..eeae76c22a93
--- /dev/null
+++ b/Documentation/video4linux/v4l2-framework.txt
@@ -0,0 +1,520 @@
1Overview of the V4L2 driver framework
2=====================================
3
4This text documents the various structures provided by the V4L2 framework and
5their relationships.
6
7
8Introduction
9------------
10
11The V4L2 drivers tend to be very complex due to the complexity of the
12hardware: most devices have multiple ICs, export multiple device nodes in
13/dev, and create also non-V4L2 devices such as DVB, ALSA, FB, I2C and input
14(IR) devices.
15
16Especially the fact that V4L2 drivers have to setup supporting ICs to
17do audio/video muxing/encoding/decoding makes it more complex than most.
18Usually these ICs are connected to the main bridge driver through one or
19more I2C busses, but other busses can also be used. Such devices are
20called 'sub-devices'.
21
22For a long time the framework was limited to the video_device struct for
23creating V4L device nodes and video_buf for handling the video buffers
24(note that this document does not discuss the video_buf framework).
25
26This meant that all drivers had to do the setup of device instances and
27connecting to sub-devices themselves. Some of this is quite complicated
28to do right and many drivers never did do it correctly.
29
30There is also a lot of common code that could never be refactored due to
31the lack of a framework.
32
33So this framework sets up the basic building blocks that all drivers
34need and this same framework should make it much easier to refactor
35common code into utility functions shared by all drivers.
36
37
38Structure of a driver
39---------------------
40
41All drivers have the following structure:
42
431) A struct for each device instance containing the device state.
44
452) A way of initializing and commanding sub-devices (if any).
46
473) Creating V4L2 device nodes (/dev/videoX, /dev/vbiX, /dev/radioX and
48 /dev/vtxX) and keeping track of device-node specific data.
49
504) Filehandle-specific structs containing per-filehandle data.
51
52This is a rough schematic of how it all relates:
53
54 device instances
55 |
56 +-sub-device instances
57 |
58 \-V4L2 device nodes
59 |
60 \-filehandle instances
61
62
63Structure of the framework
64--------------------------
65
66The framework closely resembles the driver structure: it has a v4l2_device
67struct for the device instance data, a v4l2_subdev struct to refer to
68sub-device instances, the video_device struct stores V4L2 device node data
69and in the future a v4l2_fh struct will keep track of filehandle instances
70(this is not yet implemented).
71
72
73struct v4l2_device
74------------------
75
76Each device instance is represented by a struct v4l2_device (v4l2-device.h).
77Very simple devices can just allocate this struct, but most of the time you
78would embed this struct inside a larger struct.
79
80You must register the device instance:
81
82 v4l2_device_register(struct device *dev, struct v4l2_device *v4l2_dev);
83
84Registration will initialize the v4l2_device struct and link dev->driver_data
85to v4l2_dev. Registration will also set v4l2_dev->name to a value derived from
86dev (driver name followed by the bus_id, to be precise). You may change the
87name after registration if you want.
88
89The first 'dev' argument is normally the struct device pointer of a pci_dev,
90usb_device or platform_device.
91
92You unregister with:
93
94 v4l2_device_unregister(struct v4l2_device *v4l2_dev);
95
96Unregistering will also automatically unregister all subdevs from the device.
97
98Sometimes you need to iterate over all devices registered by a specific
99driver. This is usually the case if multiple device drivers use the same
100hardware. E.g. the ivtvfb driver is a framebuffer driver that uses the ivtv
101hardware. The same is true for alsa drivers for example.
102
103You can iterate over all registered devices as follows:
104
105static int callback(struct device *dev, void *p)
106{
107 struct v4l2_device *v4l2_dev = dev_get_drvdata(dev);
108
109 /* test if this device was inited */
110 if (v4l2_dev == NULL)
111 return 0;
112 ...
113 return 0;
114}
115
116int iterate(void *p)
117{
118 struct device_driver *drv;
119 int err;
120
121 /* Find driver 'ivtv' on the PCI bus.
122 pci_bus_type is a global. For USB busses use usb_bus_type. */
123 drv = driver_find("ivtv", &pci_bus_type);
124 /* iterate over all ivtv device instances */
125 err = driver_for_each_device(drv, NULL, p, callback);
126 put_driver(drv);
127 return err;
128}
129
130Sometimes you need to keep a running counter of the device instance. This is
131commonly used to map a device instance to an index of a module option array.
132
133The recommended approach is as follows:
134
135static atomic_t drv_instance = ATOMIC_INIT(0);
136
137static int __devinit drv_probe(struct pci_dev *dev,
138 const struct pci_device_id *pci_id)
139{
140 ...
141 state->instance = atomic_inc_return(&drv_instance) - 1;
142}
143
144
145struct v4l2_subdev
146------------------
147
148Many drivers need to communicate with sub-devices. These devices can do all
149sort of tasks, but most commonly they handle audio and/or video muxing,
150encoding or decoding. For webcams common sub-devices are sensors and camera
151controllers.
152
153Usually these are I2C devices, but not necessarily. In order to provide the
154driver with a consistent interface to these sub-devices the v4l2_subdev struct
155(v4l2-subdev.h) was created.
156
157Each sub-device driver must have a v4l2_subdev struct. This struct can be
158stand-alone for simple sub-devices or it might be embedded in a larger struct
159if more state information needs to be stored. Usually there is a low-level
160device struct (e.g. i2c_client) that contains the device data as setup
161by the kernel. It is recommended to store that pointer in the private
162data of v4l2_subdev using v4l2_set_subdevdata(). That makes it easy to go
163from a v4l2_subdev to the actual low-level bus-specific device data.
164
165You also need a way to go from the low-level struct to v4l2_subdev. For the
166common i2c_client struct the i2c_set_clientdata() call is used to store a
167v4l2_subdev pointer, for other busses you may have to use other methods.
168
169From the bridge driver perspective you load the sub-device module and somehow
170obtain the v4l2_subdev pointer. For i2c devices this is easy: you call
171i2c_get_clientdata(). For other busses something similar needs to be done.
172Helper functions exists for sub-devices on an I2C bus that do most of this
173tricky work for you.
174
175Each v4l2_subdev contains function pointers that sub-device drivers can
176implement (or leave NULL if it is not applicable). Since sub-devices can do
177so many different things and you do not want to end up with a huge ops struct
178of which only a handful of ops are commonly implemented, the function pointers
179are sorted according to category and each category has its own ops struct.
180
181The top-level ops struct contains pointers to the category ops structs, which
182may be NULL if the subdev driver does not support anything from that category.
183
184It looks like this:
185
186struct v4l2_subdev_core_ops {
187 int (*g_chip_ident)(struct v4l2_subdev *sd, struct v4l2_chip_ident *chip);
188 int (*log_status)(struct v4l2_subdev *sd);
189 int (*init)(struct v4l2_subdev *sd, u32 val);
190 ...
191};
192
193struct v4l2_subdev_tuner_ops {
194 ...
195};
196
197struct v4l2_subdev_audio_ops {
198 ...
199};
200
201struct v4l2_subdev_video_ops {
202 ...
203};
204
205struct v4l2_subdev_ops {
206 const struct v4l2_subdev_core_ops *core;
207 const struct v4l2_subdev_tuner_ops *tuner;
208 const struct v4l2_subdev_audio_ops *audio;
209 const struct v4l2_subdev_video_ops *video;
210};
211
212The core ops are common to all subdevs, the other categories are implemented
213depending on the sub-device. E.g. a video device is unlikely to support the
214audio ops and vice versa.
215
216This setup limits the number of function pointers while still making it easy
217to add new ops and categories.
218
219A sub-device driver initializes the v4l2_subdev struct using:
220
221 v4l2_subdev_init(subdev, &ops);
222
223Afterwards you need to initialize subdev->name with a unique name and set the
224module owner. This is done for you if you use the i2c helper functions.
225
226A device (bridge) driver needs to register the v4l2_subdev with the
227v4l2_device:
228
229 int err = v4l2_device_register_subdev(device, subdev);
230
231This can fail if the subdev module disappeared before it could be registered.
232After this function was called successfully the subdev->dev field points to
233the v4l2_device.
234
235You can unregister a sub-device using:
236
237 v4l2_device_unregister_subdev(subdev);
238
239Afterwards the subdev module can be unloaded and subdev->dev == NULL.
240
241You can call an ops function either directly:
242
243 err = subdev->ops->core->g_chip_ident(subdev, &chip);
244
245but it is better and easier to use this macro:
246
247 err = v4l2_subdev_call(subdev, core, g_chip_ident, &chip);
248
249The macro will to the right NULL pointer checks and returns -ENODEV if subdev
250is NULL, -ENOIOCTLCMD if either subdev->core or subdev->core->g_chip_ident is
251NULL, or the actual result of the subdev->ops->core->g_chip_ident ops.
252
253It is also possible to call all or a subset of the sub-devices:
254
255 v4l2_device_call_all(dev, 0, core, g_chip_ident, &chip);
256
257Any subdev that does not support this ops is skipped and error results are
258ignored. If you want to check for errors use this:
259
260 err = v4l2_device_call_until_err(dev, 0, core, g_chip_ident, &chip);
261
262Any error except -ENOIOCTLCMD will exit the loop with that error. If no
263errors (except -ENOIOCTLCMD) occured, then 0 is returned.
264
265The second argument to both calls is a group ID. If 0, then all subdevs are
266called. If non-zero, then only those whose group ID match that value will
267be called. Before a bridge driver registers a subdev it can set subdev->grp_id
268to whatever value it wants (it's 0 by default). This value is owned by the
269bridge driver and the sub-device driver will never modify or use it.
270
271The group ID gives the bridge driver more control how callbacks are called.
272For example, there may be multiple audio chips on a board, each capable of
273changing the volume. But usually only one will actually be used when the
274user want to change the volume. You can set the group ID for that subdev to
275e.g. AUDIO_CONTROLLER and specify that as the group ID value when calling
276v4l2_device_call_all(). That ensures that it will only go to the subdev
277that needs it.
278
279The advantage of using v4l2_subdev is that it is a generic struct and does
280not contain any knowledge about the underlying hardware. So a driver might
281contain several subdevs that use an I2C bus, but also a subdev that is
282controlled through GPIO pins. This distinction is only relevant when setting
283up the device, but once the subdev is registered it is completely transparent.
284
285
286I2C sub-device drivers
287----------------------
288
289Since these drivers are so common, special helper functions are available to
290ease the use of these drivers (v4l2-common.h).
291
292The recommended method of adding v4l2_subdev support to an I2C driver is to
293embed the v4l2_subdev struct into the state struct that is created for each
294I2C device instance. Very simple devices have no state struct and in that case
295you can just create a v4l2_subdev directly.
296
297A typical state struct would look like this (where 'chipname' is replaced by
298the name of the chip):
299
300struct chipname_state {
301 struct v4l2_subdev sd;
302 ... /* additional state fields */
303};
304
305Initialize the v4l2_subdev struct as follows:
306
307 v4l2_i2c_subdev_init(&state->sd, client, subdev_ops);
308
309This function will fill in all the fields of v4l2_subdev and ensure that the
310v4l2_subdev and i2c_client both point to one another.
311
312You should also add a helper inline function to go from a v4l2_subdev pointer
313to a chipname_state struct:
314
315static inline struct chipname_state *to_state(struct v4l2_subdev *sd)
316{
317 return container_of(sd, struct chipname_state, sd);
318}
319
320Use this to go from the v4l2_subdev struct to the i2c_client struct:
321
322 struct i2c_client *client = v4l2_get_subdevdata(sd);
323
324And this to go from an i2c_client to a v4l2_subdev struct:
325
326 struct v4l2_subdev *sd = i2c_get_clientdata(client);
327
328Finally you need to make a command function to make driver->command()
329call the right subdev_ops functions:
330
331static int subdev_command(struct i2c_client *client, unsigned cmd, void *arg)
332{
333 return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
334}
335
336If driver->command is never used then you can leave this out. Eventually the
337driver->command usage should be removed from v4l.
338
339Make sure to call v4l2_device_unregister_subdev(sd) when the remove() callback
340is called. This will unregister the sub-device from the bridge driver. It is
341safe to call this even if the sub-device was never registered.
342
343
344The bridge driver also has some helper functions it can use:
345
346struct v4l2_subdev *sd = v4l2_i2c_new_subdev(adapter, "module_foo", "chipid", 0x36);
347
348This loads the given module (can be NULL if no module needs to be loaded) and
349calls i2c_new_device() with the given i2c_adapter and chip/address arguments.
350If all goes well, then it registers the subdev with the v4l2_device. It gets
351the v4l2_device by calling i2c_get_adapdata(adapter), so you should make sure
352that adapdata is set to v4l2_device when you setup the i2c_adapter in your
353driver.
354
355You can also use v4l2_i2c_new_probed_subdev() which is very similar to
356v4l2_i2c_new_subdev(), except that it has an array of possible I2C addresses
357that it should probe. Internally it calls i2c_new_probed_device().
358
359Both functions return NULL if something went wrong.
360
361
362struct video_device
363-------------------
364
365The actual device nodes in the /dev directory are created using the
366video_device struct (v4l2-dev.h). This struct can either be allocated
367dynamically or embedded in a larger struct.
368
369To allocate it dynamically use:
370
371 struct video_device *vdev = video_device_alloc();
372
373 if (vdev == NULL)
374 return -ENOMEM;
375
376 vdev->release = video_device_release;
377
378If you embed it in a larger struct, then you must set the release()
379callback to your own function:
380
381 struct video_device *vdev = &my_vdev->vdev;
382
383 vdev->release = my_vdev_release;
384
385The release callback must be set and it is called when the last user
386of the video device exits.
387
388The default video_device_release() callback just calls kfree to free the
389allocated memory.
390
391You should also set these fields:
392
393- parent: set to the parent device (same device as was used to register
394 v4l2_device).
395- name: set to something descriptive and unique.
396- fops: set to the file_operations struct.
397- ioctl_ops: if you use the v4l2_ioctl_ops to simplify ioctl maintenance
398 (highly recommended to use this and it might become compulsory in the
399 future!), then set this to your v4l2_ioctl_ops struct.
400
401If you use v4l2_ioctl_ops, then you should set .unlocked_ioctl to
402__video_ioctl2 or .ioctl to video_ioctl2 in your file_operations struct.
403
404
405video_device registration
406-------------------------
407
408Next you register the video device: this will create the character device
409for you.
410
411 err = video_register_device(vdev, VFL_TYPE_GRABBER, -1);
412 if (err) {
413 video_device_release(vdev); // or kfree(my_vdev);
414 return err;
415 }
416
417Which device is registered depends on the type argument. The following
418types exist:
419
420VFL_TYPE_GRABBER: videoX for video input/output devices
421VFL_TYPE_VBI: vbiX for vertical blank data (i.e. closed captions, teletext)
422VFL_TYPE_RADIO: radioX for radio tuners
423VFL_TYPE_VTX: vtxX for teletext devices (deprecated, don't use)
424
425The last argument gives you a certain amount of control over the device
426kernel number used (i.e. the X in videoX). Normally you will pass -1 to
427let the v4l2 framework pick the first free number. But if a driver creates
428many devices, then it can be useful to have different video devices in
429separate ranges. For example, video capture devices start at 0, video
430output devices start at 16.
431
432So you can use the last argument to specify a minimum kernel number and
433the v4l2 framework will try to pick the first free number that is equal
434or higher to what you passed. If that fails, then it will just pick the
435first free number.
436
437Whenever a device node is created some attributes are also created for you.
438If you look in /sys/class/video4linux you see the devices. Go into e.g.
439video0 and you will see 'name' and 'index' attributes. The 'name' attribute
440is the 'name' field of the video_device struct. The 'index' attribute is
441a device node index that can be assigned by the driver, or that is calculated
442for you.
443
444If you call video_register_device(), then the index is just increased by
4451 for each device node you register. The first video device node you register
446always starts off with 0.
447
448Alternatively you can call video_register_device_index() which is identical
449to video_register_device(), but with an extra index argument. Here you can
450pass a specific index value (between 0 and 31) that should be used.
451
452Users can setup udev rules that utilize the index attribute to make fancy
453device names (e.g. 'mpegX' for MPEG video capture device nodes).
454
455After the device was successfully registered, then you can use these fields:
456
457- vfl_type: the device type passed to video_register_device.
458- minor: the assigned device minor number.
459- num: the device kernel number (i.e. the X in videoX).
460- index: the device index number (calculated or set explicitly using
461 video_register_device_index).
462
463If the registration failed, then you need to call video_device_release()
464to free the allocated video_device struct, or free your own struct if the
465video_device was embedded in it. The vdev->release() callback will never
466be called if the registration failed, nor should you ever attempt to
467unregister the device if the registration failed.
468
469
470video_device cleanup
471--------------------
472
473When the video device nodes have to be removed, either during the unload
474of the driver or because the USB device was disconnected, then you should
475unregister them:
476
477 video_unregister_device(vdev);
478
479This will remove the device nodes from sysfs (causing udev to remove them
480from /dev).
481
482After video_unregister_device() returns no new opens can be done.
483
484However, in the case of USB devices some application might still have one
485of these device nodes open. You should block all new accesses to read,
486write, poll, etc. except possibly for certain ioctl operations like
487queueing buffers.
488
489When the last user of the video device node exits, then the vdev->release()
490callback is called and you can do the final cleanup there.
491
492
493video_device helper functions
494-----------------------------
495
496There are a few useful helper functions:
497
498You can set/get driver private data in the video_device struct using:
499
500void *video_get_drvdata(struct video_device *dev);
501void video_set_drvdata(struct video_device *dev, void *data);
502
503Note that you can safely call video_set_drvdata() before calling
504video_register_device().
505
506And this function:
507
508struct video_device *video_devdata(struct file *file);
509
510returns the video_device belonging to the file struct.
511
512The final helper function combines video_get_drvdata with
513video_devdata:
514
515void *video_drvdata(struct file *file);
516
517You can go from a video_device struct to the v4l2_device struct using:
518
519struct v4l2_device *v4l2_dev = dev_get_drvdata(vdev->parent);
520
diff --git a/drivers/media/common/ir-keymaps.c b/drivers/media/common/ir-keymaps.c
index 4952aeb5dd80..d8229a0e9a9c 100644
--- a/drivers/media/common/ir-keymaps.c
+++ b/drivers/media/common/ir-keymaps.c
@@ -2391,6 +2391,67 @@ IR_KEYTAB_TYPE ir_codes_powercolor_real_angel[IR_KEYTAB_SIZE] = {
2391}; 2391};
2392EXPORT_SYMBOL_GPL(ir_codes_powercolor_real_angel); 2392EXPORT_SYMBOL_GPL(ir_codes_powercolor_real_angel);
2393 2393
2394/* Kworld Plus TV Analog Lite PCI IR
2395 Mauro Carvalho Chehab <mchehab@infradead.org>
2396 */
2397IR_KEYTAB_TYPE ir_codes_kworld_plus_tv_analog[IR_KEYTAB_SIZE] = {
2398 [0x0c] = KEY_PROG1, /* Kworld key */
2399 [0x16] = KEY_CLOSECD, /* -> ) */
2400 [0x1d] = KEY_POWER2,
2401
2402 [0x00] = KEY_1,
2403 [0x01] = KEY_2,
2404 [0x02] = KEY_3, /* Two keys have the same code: 3 and left */
2405 [0x03] = KEY_4, /* Two keys have the same code: 3 and right */
2406 [0x04] = KEY_5,
2407 [0x05] = KEY_6,
2408 [0x06] = KEY_7,
2409 [0x07] = KEY_8,
2410 [0x08] = KEY_9,
2411 [0x0a] = KEY_0,
2412
2413 [0x09] = KEY_AGAIN,
2414 [0x14] = KEY_MUTE,
2415
2416 [0x20] = KEY_UP,
2417 [0x21] = KEY_DOWN,
2418 [0x0b] = KEY_ENTER,
2419
2420 [0x10] = KEY_CHANNELUP,
2421 [0x11] = KEY_CHANNELDOWN,
2422
2423 /* Couldn't map key left/key right since those
2424 conflict with '3' and '4' scancodes
2425 I dunno what the original driver does
2426 */
2427
2428 [0x13] = KEY_VOLUMEUP,
2429 [0x12] = KEY_VOLUMEDOWN,
2430
2431 /* The lower part of the IR
2432 There are several duplicated keycodes there.
2433 Most of them conflict with digits.
2434 Add mappings just to the unused scancodes.
2435 Somehow, the original driver has a way to know,
2436 but this doesn't seem to be on some GPIO.
2437 Also, it is not related to the time between keyup
2438 and keydown.
2439 */
2440 [0x19] = KEY_PAUSE, /* Timeshift */
2441 [0x1a] = KEY_STOP,
2442 [0x1b] = KEY_RECORD,
2443
2444 [0x22] = KEY_TEXT,
2445
2446 [0x15] = KEY_AUDIO, /* ((*)) */
2447 [0x0f] = KEY_ZOOM,
2448 [0x1c] = KEY_SHUFFLE, /* snapshot */
2449
2450 [0x18] = KEY_RED, /* B */
2451 [0x23] = KEY_GREEN, /* C */
2452};
2453EXPORT_SYMBOL_GPL(ir_codes_kworld_plus_tv_analog);
2454
2394IR_KEYTAB_TYPE ir_codes_avermedia_a16d[IR_KEYTAB_SIZE] = { 2455IR_KEYTAB_TYPE ir_codes_avermedia_a16d[IR_KEYTAB_SIZE] = {
2395 [0x20] = KEY_LIST, 2456 [0x20] = KEY_LIST,
2396 [0x00] = KEY_POWER, 2457 [0x00] = KEY_POWER,
@@ -2511,3 +2572,35 @@ IR_KEYTAB_TYPE ir_codes_real_audio_220_32_keys[IR_KEYTAB_SIZE] = {
2511 2572
2512}; 2573};
2513EXPORT_SYMBOL_GPL(ir_codes_real_audio_220_32_keys); 2574EXPORT_SYMBOL_GPL(ir_codes_real_audio_220_32_keys);
2575
2576/* ATI TV Wonder HD 600 USB
2577 Devin Heitmueller <devin.heitmueller@gmail.com>
2578 */
2579IR_KEYTAB_TYPE ir_codes_ati_tv_wonder_hd_600[IR_KEYTAB_SIZE] = {
2580 [0x00] = KEY_RECORD, /* Row 1 */
2581 [0x01] = KEY_PLAYPAUSE,
2582 [0x02] = KEY_STOP,
2583 [0x03] = KEY_POWER,
2584 [0x04] = KEY_PREVIOUS, /* Row 2 */
2585 [0x05] = KEY_REWIND,
2586 [0x06] = KEY_FORWARD,
2587 [0x07] = KEY_NEXT,
2588 [0x08] = KEY_EPG, /* Row 3 */
2589 [0x09] = KEY_HOME,
2590 [0x0a] = KEY_MENU,
2591 [0x0b] = KEY_CHANNELUP,
2592 [0x0c] = KEY_BACK, /* Row 4 */
2593 [0x0d] = KEY_UP,
2594 [0x0e] = KEY_INFO,
2595 [0x0f] = KEY_CHANNELDOWN,
2596 [0x10] = KEY_LEFT, /* Row 5 */
2597 [0x11] = KEY_SELECT,
2598 [0x12] = KEY_RIGHT,
2599 [0x13] = KEY_VOLUMEUP,
2600 [0x14] = KEY_LAST, /* Row 6 */
2601 [0x15] = KEY_DOWN,
2602 [0x16] = KEY_MUTE,
2603 [0x17] = KEY_VOLUMEDOWN,
2604};
2605
2606EXPORT_SYMBOL_GPL(ir_codes_ati_tv_wonder_hd_600);
diff --git a/drivers/media/common/saa7146_fops.c b/drivers/media/common/saa7146_fops.c
index 127b0526a727..7d844af88384 100644
--- a/drivers/media/common/saa7146_fops.c
+++ b/drivers/media/common/saa7146_fops.c
@@ -313,7 +313,7 @@ static int fops_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
313/* 313/*
314 DEB_EE(("inode:%p, file:%p, cmd:%d, arg:%li\n",inode, file, cmd, arg)); 314 DEB_EE(("inode:%p, file:%p, cmd:%d, arg:%li\n",inode, file, cmd, arg));
315*/ 315*/
316 return video_usercopy(inode, file, cmd, arg, saa7146_video_do_ioctl); 316 return video_usercopy(file, cmd, arg, saa7146_video_do_ioctl);
317} 317}
318 318
319static int fops_mmap(struct file *file, struct vm_area_struct * vma) 319static int fops_mmap(struct file *file, struct vm_area_struct * vma)
diff --git a/drivers/media/common/saa7146_video.c b/drivers/media/common/saa7146_video.c
index fe0bd55977e3..101b01dbb8ea 100644
--- a/drivers/media/common/saa7146_video.c
+++ b/drivers/media/common/saa7146_video.c
@@ -834,7 +834,7 @@ static int video_end(struct saa7146_fh *fh, struct file *file)
834 * copying is done already, arg is a kernel pointer. 834 * copying is done already, arg is a kernel pointer.
835 */ 835 */
836 836
837static int __saa7146_video_do_ioctl(struct file *file, unsigned int cmd, void *arg) 837int saa7146_video_do_ioctl(struct file *file, unsigned int cmd, void *arg)
838{ 838{
839 struct saa7146_fh *fh = file->private_data; 839 struct saa7146_fh *fh = file->private_data;
840 struct saa7146_dev *dev = fh->dev; 840 struct saa7146_dev *dev = fh->dev;
@@ -1216,17 +1216,11 @@ static int __saa7146_video_do_ioctl(struct file *file, unsigned int cmd, void *a
1216#endif 1216#endif
1217 default: 1217 default:
1218 return v4l_compat_translate_ioctl(file, cmd, arg, 1218 return v4l_compat_translate_ioctl(file, cmd, arg,
1219 __saa7146_video_do_ioctl); 1219 saa7146_video_do_ioctl);
1220 } 1220 }
1221 return 0; 1221 return 0;
1222} 1222}
1223 1223
1224int saa7146_video_do_ioctl(struct inode *inode, struct file *file,
1225 unsigned int cmd, void *arg)
1226{
1227 return __saa7146_video_do_ioctl(file, cmd, arg);
1228}
1229
1230/*********************************************************************************/ 1224/*********************************************************************************/
1231/* buffer handling functions */ 1225/* buffer handling functions */
1232 1226
diff --git a/drivers/media/common/tuners/mxl5005s.c b/drivers/media/common/tuners/mxl5005s.c
index a8878244bb3c..31522d2e318e 100644
--- a/drivers/media/common/tuners/mxl5005s.c
+++ b/drivers/media/common/tuners/mxl5005s.c
@@ -3598,7 +3598,7 @@ static u16 MXL_GetInitRegister(struct dvb_frontend *fe, u8 *RegNum,
3598 76, 77, 91, 134, 135, 137, 147, 3598 76, 77, 91, 134, 135, 137, 147,
3599 156, 166, 167, 168, 25 }; 3599 156, 166, 167, 168, 25 };
3600 3600
3601 *count = sizeof(RegAddr) / sizeof(u8); 3601 *count = ARRAY_SIZE(RegAddr);
3602 3602
3603 status += MXL_BlockInit(fe); 3603 status += MXL_BlockInit(fe);
3604 3604
@@ -3630,7 +3630,7 @@ static u16 MXL_GetCHRegister(struct dvb_frontend *fe, u8 *RegNum, u8 *RegVal,
3630 */ 3630 */
3631#endif 3631#endif
3632 3632
3633 *count = sizeof(RegAddr) / sizeof(u8); 3633 *count = ARRAY_SIZE(RegAddr);
3634 3634
3635 for (i = 0 ; i < *count; i++) { 3635 for (i = 0 ; i < *count; i++) {
3636 RegNum[i] = RegAddr[i]; 3636 RegNum[i] = RegAddr[i];
@@ -3648,7 +3648,7 @@ static u16 MXL_GetCHRegister_ZeroIF(struct dvb_frontend *fe, u8 *RegNum,
3648 3648
3649 u8 RegAddr[] = {43, 136}; 3649 u8 RegAddr[] = {43, 136};
3650 3650
3651 *count = sizeof(RegAddr) / sizeof(u8); 3651 *count = ARRAY_SIZE(RegAddr);
3652 3652
3653 for (i = 0; i < *count; i++) { 3653 for (i = 0; i < *count; i++) {
3654 RegNum[i] = RegAddr[i]; 3654 RegNum[i] = RegAddr[i];
diff --git a/drivers/media/common/tuners/tda827x.c b/drivers/media/common/tuners/tda827x.c
index 4a74f65e759a..f4d931f14fad 100644
--- a/drivers/media/common/tuners/tda827x.c
+++ b/drivers/media/common/tuners/tda827x.c
@@ -80,10 +80,11 @@ static void tda827x_set_std(struct dvb_frontend *fe,
80 mode = "xx"; 80 mode = "xx";
81 } 81 }
82 82
83 if (params->mode == V4L2_TUNER_RADIO) 83 if (params->mode == V4L2_TUNER_RADIO) {
84 priv->sgIF = 88; /* if frequency is 5.5 MHz */ 84 priv->sgIF = 88; /* if frequency is 5.5 MHz */
85 85 dprintk("setting tda827x to radio FM\n");
86 dprintk("setting tda827x to system %s\n", mode); 86 } else
87 dprintk("setting tda827x to system %s\n", mode);
87} 88}
88 89
89 90
@@ -199,7 +200,7 @@ static int tda827xo_set_params(struct dvb_frontend *fe,
199 fe->ops.i2c_gate_ctrl(fe, 1); 200 fe->ops.i2c_gate_ctrl(fe, 1);
200 i2c_transfer(priv->i2c_adap, &msg, 1); 201 i2c_transfer(priv->i2c_adap, &msg, 1);
201 202
202 priv->frequency = tuner_freq - if_freq; // FIXME 203 priv->frequency = params->frequency;
203 priv->bandwidth = (fe->ops.info.type == FE_OFDM) ? params->u.ofdm.bandwidth : 0; 204 priv->bandwidth = (fe->ops.info.type == FE_OFDM) ? params->u.ofdm.bandwidth : 0;
204 205
205 return 0; 206 return 0;
@@ -304,7 +305,7 @@ static int tda827xo_set_analog_params(struct dvb_frontend *fe,
304 reg2[1] = 0x08; /* Vsync en */ 305 reg2[1] = 0x08; /* Vsync en */
305 i2c_transfer(priv->i2c_adap, &msg, 1); 306 i2c_transfer(priv->i2c_adap, &msg, 1);
306 307
307 priv->frequency = freq * 62500; 308 priv->frequency = params->frequency;
308 309
309 return 0; 310 return 0;
310} 311}
@@ -591,7 +592,7 @@ static int tda827xa_set_params(struct dvb_frontend *fe,
591 fe->ops.i2c_gate_ctrl(fe, 1); 592 fe->ops.i2c_gate_ctrl(fe, 1);
592 i2c_transfer(priv->i2c_adap, &msg, 1); 593 i2c_transfer(priv->i2c_adap, &msg, 1);
593 594
594 priv->frequency = tuner_freq - if_freq; // FIXME 595 priv->frequency = params->frequency;
595 priv->bandwidth = (fe->ops.info.type == FE_OFDM) ? params->u.ofdm.bandwidth : 0; 596 priv->bandwidth = (fe->ops.info.type == FE_OFDM) ? params->u.ofdm.bandwidth : 0;
596 597
597 return 0; 598 return 0;
@@ -691,7 +692,7 @@ static int tda827xa_set_analog_params(struct dvb_frontend *fe,
691 tuner_reg[1] = 0x19 + (priv->lpsel << 1); 692 tuner_reg[1] = 0x19 + (priv->lpsel << 1);
692 i2c_transfer(priv->i2c_adap, &msg, 1); 693 i2c_transfer(priv->i2c_adap, &msg, 1);
693 694
694 priv->frequency = freq * 62500; 695 priv->frequency = params->frequency;
695 696
696 return 0; 697 return 0;
697} 698}
diff --git a/drivers/media/common/tuners/tda8290.c b/drivers/media/common/tuners/tda8290.c
index c112bdd4e0f0..0ee79fd7c7a9 100644
--- a/drivers/media/common/tuners/tda8290.c
+++ b/drivers/media/common/tuners/tda8290.c
@@ -32,6 +32,9 @@ static int debug;
32module_param(debug, int, 0644); 32module_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;
36MODULE_PARM_DESC(deemphasis_50, "0 - 75us deemphasis; 1 - 50us deemphasis");
37
35/* ---------------------------------------------------------------------- */ 38/* ---------------------------------------------------------------------- */
36 39
37struct tda8290_priv { 40struct tda8290_priv {
@@ -139,9 +142,34 @@ static void set_audio(struct dvb_frontend *fe,
139 mode = "xx"; 142 mode = "xx";
140 } 143 }
141 144
142 tuner_dbg("setting tda829x to system %s\n", mode); 145 if (params->mode == V4L2_TUNER_RADIO) {
146 priv->tda8290_easy_mode = 0x01; /* Start with MN values */
147 tuner_dbg("setting to radio FM\n");
148 } else {
149 tuner_dbg("setting tda829x to system %s\n", mode);
150 }
143} 151}
144 152
153struct {
154 unsigned char seq[2];
155} fm_mode[] = {
156 { { 0x01, 0x81} }, /* Put device into expert mode */
157 { { 0x03, 0x48} }, /* Disable NOTCH and VIDEO filters */
158 { { 0x04, 0x04} }, /* Disable color carrier filter (SSIF) */
159 { { 0x05, 0x04} }, /* ADC headroom */
160 { { 0x06, 0x10} }, /* group delay flat */
161
162 { { 0x07, 0x00} }, /* use the same radio DTO values as a tda8295 */
163 { { 0x08, 0x00} },
164 { { 0x09, 0x80} },
165 { { 0x0a, 0xda} },
166 { { 0x0b, 0x4b} },
167 { { 0x0c, 0x68} },
168
169 { { 0x0d, 0x00} }, /* PLL off, no video carrier detect */
170 { { 0x14, 0x00} }, /* disable auto mute if no video */
171};
172
145static void tda8290_set_params(struct dvb_frontend *fe, 173static void tda8290_set_params(struct dvb_frontend *fe,
146 struct analog_parameters *params) 174 struct analog_parameters *params)
147{ 175{
@@ -178,15 +206,30 @@ static void tda8290_set_params(struct dvb_frontend *fe,
178 tuner_i2c_xfer_send(&priv->i2c_props, soft_reset, 2); 206 tuner_i2c_xfer_send(&priv->i2c_props, soft_reset, 2);
179 msleep(1); 207 msleep(1);
180 208
181 expert_mode[1] = priv->tda8290_easy_mode + 0x80; 209 if (params->mode == V4L2_TUNER_RADIO) {
182 tuner_i2c_xfer_send(&priv->i2c_props, expert_mode, 2); 210 int i;
183 tuner_i2c_xfer_send(&priv->i2c_props, gainset_off, 2); 211 unsigned char deemphasis[] = { 0x13, 1 };
184 tuner_i2c_xfer_send(&priv->i2c_props, if_agc_spd, 2); 212
185 if (priv->tda8290_easy_mode & 0x60) 213 /* FIXME: allow using a different deemphasis */
186 tuner_i2c_xfer_send(&priv->i2c_props, adc_head_9, 2); 214
187 else 215 if (deemphasis_50)
188 tuner_i2c_xfer_send(&priv->i2c_props, adc_head_6, 2); 216 deemphasis[1] = 2;
189 tuner_i2c_xfer_send(&priv->i2c_props, pll_bw_nom, 2); 217
218 for (i = 0; i < ARRAY_SIZE(fm_mode); i++)
219 tuner_i2c_xfer_send(&priv->i2c_props, fm_mode[i].seq, 2);
220
221 tuner_i2c_xfer_send(&priv->i2c_props, deemphasis, 2);
222 } else {
223 expert_mode[1] = priv->tda8290_easy_mode + 0x80;
224 tuner_i2c_xfer_send(&priv->i2c_props, expert_mode, 2);
225 tuner_i2c_xfer_send(&priv->i2c_props, gainset_off, 2);
226 tuner_i2c_xfer_send(&priv->i2c_props, if_agc_spd, 2);
227 if (priv->tda8290_easy_mode & 0x60)
228 tuner_i2c_xfer_send(&priv->i2c_props, adc_head_9, 2);
229 else
230 tuner_i2c_xfer_send(&priv->i2c_props, adc_head_6, 2);
231 tuner_i2c_xfer_send(&priv->i2c_props, pll_bw_nom, 2);
232 }
190 233
191 tda8290_i2c_bridge(fe, 1); 234 tda8290_i2c_bridge(fe, 1);
192 235
diff --git a/drivers/media/common/tuners/tda9887.c b/drivers/media/common/tuners/tda9887.c
index ff1788cc5d48..544cdbe88a6c 100644
--- a/drivers/media/common/tuners/tda9887.c
+++ b/drivers/media/common/tuners/tda9887.c
@@ -180,11 +180,10 @@ static struct tvnorm tvnorms[] = {
180 },{ 180 },{
181 .std = V4L2_STD_SECAM_B | V4L2_STD_SECAM_G | V4L2_STD_SECAM_H, 181 .std = V4L2_STD_SECAM_B | V4L2_STD_SECAM_G | V4L2_STD_SECAM_H,
182 .name = "SECAM-BGH", 182 .name = "SECAM-BGH",
183 .b = ( cPositiveAmTV | 183 .b = ( cNegativeFmTV |
184 cQSS ), 184 cQSS ),
185 .c = ( cTopDefault), 185 .c = ( cTopDefault),
186 .e = ( cGating_36 | 186 .e = ( cAudioIF_5_5 |
187 cAudioIF_5_5 |
188 cVideoIF_38_90 ), 187 cVideoIF_38_90 ),
189 },{ 188 },{
190 .std = V4L2_STD_SECAM_L, 189 .std = V4L2_STD_SECAM_L,
diff --git a/drivers/media/common/tuners/tuner-xc2028.c b/drivers/media/common/tuners/tuner-xc2028.c
index b65e6803e6c6..1adce9ff52ce 100644
--- a/drivers/media/common/tuners/tuner-xc2028.c
+++ b/drivers/media/common/tuners/tuner-xc2028.c
@@ -28,6 +28,12 @@ static int debug;
28module_param(debug, int, 0644); 28module_param(debug, int, 0644);
29MODULE_PARM_DESC(debug, "enable verbose debug messages"); 29MODULE_PARM_DESC(debug, "enable verbose debug messages");
30 30
31static int no_poweroff;
32module_param(no_poweroff, int, 0644);
33MODULE_PARM_DESC(debug, "0 (default) powers device off when not used.\n"
34 "1 keep device energized and with tuner ready all the times.\n"
35 " Faster, but consumes more power and keeps the device hotter\n");
36
31static char audio_std[8]; 37static char audio_std[8];
32module_param_string(audio_std, audio_std, sizeof(audio_std), 0); 38module_param_string(audio_std, audio_std, sizeof(audio_std), 0);
33MODULE_PARM_DESC(audio_std, 39MODULE_PARM_DESC(audio_std,
@@ -1091,6 +1097,34 @@ static int xc2028_set_params(struct dvb_frontend *fe,
1091 T_DIGITAL_TV, type, 0, demod); 1097 T_DIGITAL_TV, type, 0, demod);
1092} 1098}
1093 1099
1100static int xc2028_sleep(struct dvb_frontend *fe)
1101{
1102 struct xc2028_data *priv = fe->tuner_priv;
1103 int rc = 0;
1104
1105 /* Avoid firmware reload on slow devices */
1106 if (no_poweroff)
1107 return 0;
1108
1109 tuner_dbg("Putting xc2028/3028 into poweroff mode.\n");
1110 if (debug > 1) {
1111 tuner_dbg("Printing sleep stack trace:\n");
1112 dump_stack();
1113 }
1114
1115 mutex_lock(&priv->lock);
1116
1117 if (priv->firm_version < 0x0202)
1118 rc = send_seq(priv, {0x00, 0x08, 0x00, 0x00});
1119 else
1120 rc = send_seq(priv, {0x80, 0x08, 0x00, 0x00});
1121
1122 priv->cur_fw.type = 0; /* need firmware reload */
1123
1124 mutex_unlock(&priv->lock);
1125
1126 return rc;
1127}
1094 1128
1095static int xc2028_dvb_release(struct dvb_frontend *fe) 1129static int xc2028_dvb_release(struct dvb_frontend *fe)
1096{ 1130{
@@ -1171,6 +1205,7 @@ static const struct dvb_tuner_ops xc2028_dvb_tuner_ops = {
1171 .get_frequency = xc2028_get_frequency, 1205 .get_frequency = xc2028_get_frequency,
1172 .get_rf_strength = xc2028_signal, 1206 .get_rf_strength = xc2028_signal,
1173 .set_params = xc2028_set_params, 1207 .set_params = xc2028_set_params,
1208 .sleep = xc2028_sleep,
1174}; 1209};
1175 1210
1176struct dvb_frontend *xc2028_attach(struct dvb_frontend *fe, 1211struct dvb_frontend *xc2028_attach(struct dvb_frontend *fe,
diff --git a/drivers/media/common/tuners/xc5000.c b/drivers/media/common/tuners/xc5000.c
index e12d13e0cbe9..493ce93caf43 100644
--- a/drivers/media/common/tuners/xc5000.c
+++ b/drivers/media/common/tuners/xc5000.c
@@ -36,10 +36,6 @@ static int debug;
36module_param(debug, int, 0644); 36module_param(debug, int, 0644);
37MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off)."); 37MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
38 38
39static int xc5000_load_fw_on_attach;
40module_param_named(init_fw, xc5000_load_fw_on_attach, int, 0644);
41MODULE_PARM_DESC(init_fw, "Load firmware during driver initialization.");
42
43static DEFINE_MUTEX(xc5000_list_mutex); 39static DEFINE_MUTEX(xc5000_list_mutex);
44static LIST_HEAD(hybrid_tuner_instance_list); 40static LIST_HEAD(hybrid_tuner_instance_list);
45 41
@@ -1017,9 +1013,6 @@ struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe,
1017 memcpy(&fe->ops.tuner_ops, &xc5000_tuner_ops, 1013 memcpy(&fe->ops.tuner_ops, &xc5000_tuner_ops,
1018 sizeof(struct dvb_tuner_ops)); 1014 sizeof(struct dvb_tuner_ops));
1019 1015
1020 if (xc5000_load_fw_on_attach)
1021 xc5000_init(fe);
1022
1023 return fe; 1016 return fe;
1024fail: 1017fail:
1025 mutex_unlock(&xc5000_list_mutex); 1018 mutex_unlock(&xc5000_list_mutex);
diff --git a/drivers/media/dvb/Kconfig b/drivers/media/dvb/Kconfig
index 0bcd852576d6..40ebde53b3ce 100644
--- a/drivers/media/dvb/Kconfig
+++ b/drivers/media/dvb/Kconfig
@@ -2,6 +2,19 @@
2# DVB device configuration 2# DVB device configuration
3# 3#
4 4
5config DVB_DYNAMIC_MINORS
6 bool "Dynamic DVB minor allocation"
7 depends on DVB_CORE
8 default n
9 help
10 If you say Y here, the DVB subsystem will use dynamic minor
11 allocation for any device that uses the DVB major number.
12 This means that you can have more than 4 of a single type
13 of device (like demuxes and frontends) per adapter, but udev
14 will be required to manage the device nodes.
15
16 If you are unsure about this, say N here.
17
5menuconfig DVB_CAPTURE_DRIVERS 18menuconfig DVB_CAPTURE_DRIVERS
6 bool "DVB/ATSC adapters" 19 bool "DVB/ATSC adapters"
7 depends on DVB_CORE 20 depends on DVB_CORE
diff --git a/drivers/media/dvb/b2c2/Kconfig b/drivers/media/dvb/b2c2/Kconfig
index b34301d56cd2..a8c6249c4099 100644
--- a/drivers/media/dvb/b2c2/Kconfig
+++ b/drivers/media/dvb/b2c2/Kconfig
@@ -14,6 +14,7 @@ config DVB_B2C2_FLEXCOP
14 select DVB_ISL6421 if !DVB_FE_CUSTOMISE 14 select DVB_ISL6421 if !DVB_FE_CUSTOMISE
15 select DVB_CX24123 if !DVB_FE_CUSTOMISE 15 select DVB_CX24123 if !DVB_FE_CUSTOMISE
16 select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMIZE 16 select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMIZE
17 select DVB_TUNER_CX24113 if !DVB_FE_CUSTOMISE
17 help 18 help
18 Support for the digital TV receiver chip made by B2C2 Inc. included in 19 Support for the digital TV receiver chip made by B2C2 Inc. included in
19 Technisats PCI cards and USB boxes. 20 Technisats PCI cards and USB boxes.
diff --git a/drivers/media/dvb/dm1105/dm1105.c b/drivers/media/dvb/dm1105/dm1105.c
index a21ce9edcc7e..f48f73aff195 100644
--- a/drivers/media/dvb/dm1105/dm1105.c
+++ b/drivers/media/dvb/dm1105/dm1105.c
@@ -19,7 +19,6 @@
19 * 19 *
20 */ 20 */
21 21
22#include <linux/version.h>
23#include <linux/i2c.h> 22#include <linux/i2c.h>
24#include <linux/init.h> 23#include <linux/init.h>
25#include <linux/kernel.h> 24#include <linux/kernel.h>
@@ -368,7 +367,7 @@ static int __devinit dm1105dvb_dma_map(struct dm1105dvb *dm1105dvb)
368{ 367{
369 dm1105dvb->ts_buf = pci_alloc_consistent(dm1105dvb->pdev, 6*DM1105_DMA_BYTES, &dm1105dvb->dma_addr); 368 dm1105dvb->ts_buf = pci_alloc_consistent(dm1105dvb->pdev, 6*DM1105_DMA_BYTES, &dm1105dvb->dma_addr);
370 369
371 return pci_dma_mapping_error(dm1105dvb->pdev, dm1105dvb->dma_addr); 370 return !dm1105dvb->ts_buf;
372} 371}
373 372
374static void dm1105dvb_dma_unmap(struct dm1105dvb *dm1105dvb) 373static void dm1105dvb_dma_unmap(struct dm1105dvb *dm1105dvb)
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c
index 7a421e9dba5a..171f9ca124f7 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.c
@@ -128,6 +128,7 @@ struct dvb_frontend_private {
128 unsigned int step_size; 128 unsigned int step_size;
129 int quality; 129 int quality;
130 unsigned int check_wrapped; 130 unsigned int check_wrapped;
131 enum dvbfe_search algo_status;
131}; 132};
132 133
133static void dvb_frontend_wakeup(struct dvb_frontend *fe); 134static void dvb_frontend_wakeup(struct dvb_frontend *fe);
@@ -516,6 +517,8 @@ static int dvb_frontend_thread(void *data)
516 struct dvb_frontend_private *fepriv = fe->frontend_priv; 517 struct dvb_frontend_private *fepriv = fe->frontend_priv;
517 unsigned long timeout; 518 unsigned long timeout;
518 fe_status_t s; 519 fe_status_t s;
520 enum dvbfe_algo algo;
521
519 struct dvb_frontend_parameters *params; 522 struct dvb_frontend_parameters *params;
520 523
521 dprintk("%s\n", __func__); 524 dprintk("%s\n", __func__);
@@ -562,23 +565,80 @@ restart:
562 565
563 /* do an iteration of the tuning loop */ 566 /* do an iteration of the tuning loop */
564 if (fe->ops.get_frontend_algo) { 567 if (fe->ops.get_frontend_algo) {
565 if (fe->ops.get_frontend_algo(fe) == FE_ALGO_HW) { 568 algo = fe->ops.get_frontend_algo(fe);
566 /* have we been asked to retune? */ 569 switch (algo) {
567 params = NULL; 570 case DVBFE_ALGO_HW:
571 dprintk("%s: Frontend ALGO = DVBFE_ALGO_HW\n", __func__);
572 params = NULL; /* have we been asked to RETUNE ? */
573
568 if (fepriv->state & FESTATE_RETUNE) { 574 if (fepriv->state & FESTATE_RETUNE) {
575 dprintk("%s: Retune requested, FESTATE_RETUNE\n", __func__);
569 params = &fepriv->parameters; 576 params = &fepriv->parameters;
570 fepriv->state = FESTATE_TUNED; 577 fepriv->state = FESTATE_TUNED;
571 } 578 }
572 579
573 fe->ops.tune(fe, params, fepriv->tune_mode_flags, &fepriv->delay, &s); 580 if (fe->ops.tune)
574 if (s != fepriv->status) { 581 fe->ops.tune(fe, params, fepriv->tune_mode_flags, &fepriv->delay, &s);
582
583 if (s != fepriv->status && !(fepriv->tune_mode_flags & FE_TUNE_MODE_ONESHOT)) {
584 dprintk("%s: state changed, adding current state\n", __func__);
575 dvb_frontend_add_event(fe, s); 585 dvb_frontend_add_event(fe, s);
576 fepriv->status = s; 586 fepriv->status = s;
577 } 587 }
578 } else 588 break;
589 case DVBFE_ALGO_SW:
590 dprintk("%s: Frontend ALGO = DVBFE_ALGO_SW\n", __func__);
579 dvb_frontend_swzigzag(fe); 591 dvb_frontend_swzigzag(fe);
580 } else 592 break;
593 case DVBFE_ALGO_CUSTOM:
594 params = NULL; /* have we been asked to RETUNE ? */
595 dprintk("%s: Frontend ALGO = DVBFE_ALGO_CUSTOM, state=%d\n", __func__, fepriv->state);
596 if (fepriv->state & FESTATE_RETUNE) {
597 dprintk("%s: Retune requested, FESTAT_RETUNE\n", __func__);
598 params = &fepriv->parameters;
599 fepriv->state = FESTATE_TUNED;
600 }
601 /* Case where we are going to search for a carrier
602 * User asked us to retune again for some reason, possibly
603 * requesting a search with a new set of parameters
604 */
605 if (fepriv->algo_status & DVBFE_ALGO_SEARCH_AGAIN) {
606 if (fe->ops.search) {
607 fepriv->algo_status = fe->ops.search(fe, &fepriv->parameters);
608 /* We did do a search as was requested, the flags are
609 * now unset as well and has the flags wrt to search.
610 */
611 } else {
612 fepriv->algo_status &= ~DVBFE_ALGO_SEARCH_AGAIN;
613 }
614 }
615 /* Track the carrier if the search was successful */
616 if (fepriv->algo_status == DVBFE_ALGO_SEARCH_SUCCESS) {
617 if (fe->ops.track)
618 fe->ops.track(fe, &fepriv->parameters);
619 } else {
620 fepriv->algo_status |= DVBFE_ALGO_SEARCH_AGAIN;
621 fepriv->delay = HZ / 2;
622 }
623 fe->ops.read_status(fe, &s);
624 if (s != fepriv->status) {
625 dvb_frontend_add_event(fe, s); /* update event list */
626 fepriv->status = s;
627 if (!(s & FE_HAS_LOCK)) {
628 fepriv->delay = HZ / 10;
629 fepriv->algo_status |= DVBFE_ALGO_SEARCH_AGAIN;
630 } else {
631 fepriv->delay = 60 * HZ;
632 }
633 }
634 break;
635 default:
636 dprintk("%s: UNDEFINED ALGO !\n", __func__);
637 break;
638 }
639 } else {
581 dvb_frontend_swzigzag(fe); 640 dvb_frontend_swzigzag(fe);
641 }
582 } 642 }
583 643
584 if (dvb_powerdown_on_sleep) { 644 if (dvb_powerdown_on_sleep) {
@@ -1226,6 +1286,9 @@ int dtv_property_process_set(struct dvb_frontend *fe, struct dtv_property *tvp,
1226 dprintk("%s() Finalised property cache\n", __func__); 1286 dprintk("%s() Finalised property cache\n", __func__);
1227 dtv_property_cache_submit(fe); 1287 dtv_property_cache_submit(fe);
1228 1288
1289 /* Request the search algorithm to search */
1290 fepriv->algo_status |= DVBFE_ALGO_SEARCH_AGAIN;
1291
1229 r |= dvb_frontend_ioctl_legacy(inode, file, FE_SET_FRONTEND, 1292 r |= dvb_frontend_ioctl_legacy(inode, file, FE_SET_FRONTEND,
1230 &fepriv->parameters); 1293 &fepriv->parameters);
1231 break; 1294 break;
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.h b/drivers/media/dvb/dvb-core/dvb_frontend.h
index db4a63b0a32e..e176da472d7a 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.h
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.h
@@ -69,6 +69,125 @@ struct analog_parameters {
69 u64 std; 69 u64 std;
70}; 70};
71 71
72enum dvbfe_modcod {
73 DVBFE_MODCOD_DUMMY_PLFRAME = 0,
74 DVBFE_MODCOD_QPSK_1_4,
75 DVBFE_MODCOD_QPSK_1_3,
76 DVBFE_MODCOD_QPSK_2_5,
77 DVBFE_MODCOD_QPSK_1_2,
78 DVBFE_MODCOD_QPSK_3_5,
79 DVBFE_MODCOD_QPSK_2_3,
80 DVBFE_MODCOD_QPSK_3_4,
81 DVBFE_MODCOD_QPSK_4_5,
82 DVBFE_MODCOD_QPSK_5_6,
83 DVBFE_MODCOD_QPSK_8_9,
84 DVBFE_MODCOD_QPSK_9_10,
85 DVBFE_MODCOD_8PSK_3_5,
86 DVBFE_MODCOD_8PSK_2_3,
87 DVBFE_MODCOD_8PSK_3_4,
88 DVBFE_MODCOD_8PSK_5_6,
89 DVBFE_MODCOD_8PSK_8_9,
90 DVBFE_MODCOD_8PSK_9_10,
91 DVBFE_MODCOD_16APSK_2_3,
92 DVBFE_MODCOD_16APSK_3_4,
93 DVBFE_MODCOD_16APSK_4_5,
94 DVBFE_MODCOD_16APSK_5_6,
95 DVBFE_MODCOD_16APSK_8_9,
96 DVBFE_MODCOD_16APSK_9_10,
97 DVBFE_MODCOD_32APSK_3_4,
98 DVBFE_MODCOD_32APSK_4_5,
99 DVBFE_MODCOD_32APSK_5_6,
100 DVBFE_MODCOD_32APSK_8_9,
101 DVBFE_MODCOD_32APSK_9_10,
102 DVBFE_MODCOD_RESERVED_1,
103 DVBFE_MODCOD_BPSK_1_3,
104 DVBFE_MODCOD_BPSK_1_4,
105 DVBFE_MODCOD_RESERVED_2
106};
107
108enum tuner_param {
109 DVBFE_TUNER_FREQUENCY = (1 << 0),
110 DVBFE_TUNER_TUNERSTEP = (1 << 1),
111 DVBFE_TUNER_IFFREQ = (1 << 2),
112 DVBFE_TUNER_BANDWIDTH = (1 << 3),
113 DVBFE_TUNER_REFCLOCK = (1 << 4),
114 DVBFE_TUNER_IQSENSE = (1 << 5),
115 DVBFE_TUNER_DUMMY = (1 << 31)
116};
117
118/*
119 * ALGO_HW: (Hardware Algorithm)
120 * ----------------------------------------------------------------
121 * Devices that support this algorithm do everything in hardware
122 * and no software support is needed to handle them.
123 * Requesting these devices to LOCK is the only thing required,
124 * device is supposed to do everything in the hardware.
125 *
126 * ALGO_SW: (Software Algorithm)
127 * ----------------------------------------------------------------
128 * These are dumb devices, that require software to do everything
129 *
130 * ALGO_CUSTOM: (Customizable Agorithm)
131 * ----------------------------------------------------------------
132 * Devices having this algorithm can be customized to have specific
133 * algorithms in the frontend driver, rather than simply doing a
134 * software zig-zag. In this case the zigzag maybe hardware assisted
135 * or it maybe completely done in hardware. In all cases, usage of
136 * this algorithm, in conjunction with the search and track
137 * callbacks, utilizes the driver specific algorithm.
138 *
139 * ALGO_RECOVERY: (Recovery Algorithm)
140 * ----------------------------------------------------------------
141 * These devices have AUTO recovery capabilities from LOCK failure
142 */
143enum dvbfe_algo {
144 DVBFE_ALGO_HW = (1 << 0),
145 DVBFE_ALGO_SW = (1 << 1),
146 DVBFE_ALGO_CUSTOM = (1 << 2),
147 DVBFE_ALGO_RECOVERY = (1 << 31)
148};
149
150struct tuner_state {
151 u32 frequency;
152 u32 tunerstep;
153 u32 ifreq;
154 u32 bandwidth;
155 u32 iqsense;
156 u32 refclock;
157};
158
159/*
160 * search callback possible return status
161 *
162 * DVBFE_ALGO_SEARCH_SUCCESS
163 * The frontend search algorithm completed and returned succesfully
164 *
165 * DVBFE_ALGO_SEARCH_ASLEEP
166 * The frontend search algorithm is sleeping
167 *
168 * DVBFE_ALGO_SEARCH_FAILED
169 * The frontend search for a signal failed
170 *
171 * DVBFE_ALGO_SEARCH_INVALID
172 * The frontend search algorith was probably supplied with invalid
173 * parameters and the search is an invalid one
174 *
175 * DVBFE_ALGO_SEARCH_ERROR
176 * The frontend search algorithm failed due to some error
177 *
178 * DVBFE_ALGO_SEARCH_AGAIN
179 * The frontend search algorithm was requested to search again
180 */
181enum dvbfe_search {
182 DVBFE_ALGO_SEARCH_SUCCESS = (1 << 0),
183 DVBFE_ALGO_SEARCH_ASLEEP = (1 << 1),
184 DVBFE_ALGO_SEARCH_FAILED = (1 << 2),
185 DVBFE_ALGO_SEARCH_INVALID = (1 << 3),
186 DVBFE_ALGO_SEARCH_AGAIN = (1 << 4),
187 DVBFE_ALGO_SEARCH_ERROR = (1 << 31),
188};
189
190
72struct dvb_tuner_ops { 191struct dvb_tuner_ops {
73 192
74 struct dvb_tuner_info info; 193 struct dvb_tuner_info info;
@@ -99,6 +218,13 @@ struct dvb_tuner_ops {
99 * tuners which require sophisticated tuning loops, controlling each parameter seperately. */ 218 * tuners which require sophisticated tuning loops, controlling each parameter seperately. */
100 int (*set_frequency)(struct dvb_frontend *fe, u32 frequency); 219 int (*set_frequency)(struct dvb_frontend *fe, u32 frequency);
101 int (*set_bandwidth)(struct dvb_frontend *fe, u32 bandwidth); 220 int (*set_bandwidth)(struct dvb_frontend *fe, u32 bandwidth);
221
222 /*
223 * These are provided seperately from set_params in order to facilitate silicon
224 * tuners which require sophisticated tuning loops, controlling each parameter seperately.
225 */
226 int (*set_state)(struct dvb_frontend *fe, enum tuner_param param, struct tuner_state *state);
227 int (*get_state)(struct dvb_frontend *fe, enum tuner_param param, struct tuner_state *state);
102}; 228};
103 229
104struct analog_demod_info { 230struct analog_demod_info {
@@ -142,7 +268,7 @@ struct dvb_frontend_ops {
142 unsigned int *delay, 268 unsigned int *delay,
143 fe_status_t *status); 269 fe_status_t *status);
144 /* get frontend tuning algorithm from the module */ 270 /* get frontend tuning algorithm from the module */
145 int (*get_frontend_algo)(struct dvb_frontend *fe); 271 enum dvbfe_algo (*get_frontend_algo)(struct dvb_frontend *fe);
146 272
147 /* these two are only used for the swzigzag code */ 273 /* these two are only used for the swzigzag code */
148 int (*set_frontend)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); 274 int (*set_frontend)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
@@ -167,6 +293,12 @@ struct dvb_frontend_ops {
167 int (*i2c_gate_ctrl)(struct dvb_frontend* fe, int enable); 293 int (*i2c_gate_ctrl)(struct dvb_frontend* fe, int enable);
168 int (*ts_bus_ctrl)(struct dvb_frontend* fe, int acquire); 294 int (*ts_bus_ctrl)(struct dvb_frontend* fe, int acquire);
169 295
296 /* These callbacks are for devices that implement their own
297 * tuning algorithms, rather than a simple swzigzag
298 */
299 enum dvbfe_search (*search)(struct dvb_frontend *fe, struct dvb_frontend_parameters *p);
300 int (*track)(struct dvb_frontend *fe, struct dvb_frontend_parameters *p);
301
170 struct dvb_tuner_ops tuner_ops; 302 struct dvb_tuner_ops tuner_ops;
171 struct analog_demod_ops analog_ops; 303 struct analog_demod_ops analog_ops;
172 304
diff --git a/drivers/media/dvb/dvb-core/dvbdev.c b/drivers/media/dvb/dvb-core/dvbdev.c
index a113744a56cc..6c571d9f011c 100644
--- a/drivers/media/dvb/dvb-core/dvbdev.c
+++ b/drivers/media/dvb/dvb-core/dvbdev.c
@@ -50,33 +50,27 @@ static const char * const dnames[] = {
50 "net", "osd" 50 "net", "osd"
51}; 51};
52 52
53#ifdef CONFIG_DVB_DYNAMIC_MINORS
54#define MAX_DVB_MINORS 256
55#define DVB_MAX_IDS MAX_DVB_MINORS
56#else
53#define DVB_MAX_IDS 4 57#define DVB_MAX_IDS 4
54#define nums2minor(num,type,id) ((num << 6) | (id << 4) | type) 58#define nums2minor(num,type,id) ((num << 6) | (id << 4) | type)
55#define MAX_DVB_MINORS (DVB_MAX_ADAPTERS*64) 59#define MAX_DVB_MINORS (DVB_MAX_ADAPTERS*64)
60#endif
56 61
57static struct class *dvb_class; 62static struct class *dvb_class;
58 63
59static struct dvb_device* dvbdev_find_device (int minor) 64static struct dvb_device *dvb_minors[MAX_DVB_MINORS];
60{ 65static DECLARE_RWSEM(minor_rwsem);
61 struct dvb_adapter *adap;
62
63 list_for_each_entry(adap, &dvb_adapter_list, list_head) {
64 struct dvb_device *dev;
65 list_for_each_entry(dev, &adap->device_list, list_head)
66 if (nums2minor(adap->num, dev->type, dev->id) == minor)
67 return dev;
68 }
69
70 return NULL;
71}
72
73 66
74static int dvb_device_open(struct inode *inode, struct file *file) 67static int dvb_device_open(struct inode *inode, struct file *file)
75{ 68{
76 struct dvb_device *dvbdev; 69 struct dvb_device *dvbdev;
77 70
78 lock_kernel(); 71 lock_kernel();
79 dvbdev = dvbdev_find_device (iminor(inode)); 72 down_read(&minor_rwsem);
73 dvbdev = dvb_minors[iminor(inode)];
80 74
81 if (dvbdev && dvbdev->fops) { 75 if (dvbdev && dvbdev->fops) {
82 int err = 0; 76 int err = 0;
@@ -92,9 +86,11 @@ static int dvb_device_open(struct inode *inode, struct file *file)
92 file->f_op = fops_get(old_fops); 86 file->f_op = fops_get(old_fops);
93 } 87 }
94 fops_put(old_fops); 88 fops_put(old_fops);
89 up_read(&minor_rwsem);
95 unlock_kernel(); 90 unlock_kernel();
96 return err; 91 return err;
97 } 92 }
93 up_read(&minor_rwsem);
98 unlock_kernel(); 94 unlock_kernel();
99 return -ENODEV; 95 return -ENODEV;
100} 96}
@@ -192,6 +188,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
192 struct dvb_device *dvbdev; 188 struct dvb_device *dvbdev;
193 struct file_operations *dvbdevfops; 189 struct file_operations *dvbdevfops;
194 struct device *clsdev; 190 struct device *clsdev;
191 int minor;
195 int id; 192 int id;
196 193
197 mutex_lock(&dvbdev_register_lock); 194 mutex_lock(&dvbdev_register_lock);
@@ -231,11 +228,31 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
231 228
232 list_add_tail (&dvbdev->list_head, &adap->device_list); 229 list_add_tail (&dvbdev->list_head, &adap->device_list);
233 230
231 down_write(&minor_rwsem);
232#ifdef CONFIG_DVB_DYNAMIC_MINORS
233 for (minor = 0; minor < MAX_DVB_MINORS; minor++)
234 if (dvb_minors[minor] == NULL)
235 break;
236
237 if (minor == MAX_DVB_MINORS) {
238 kfree(dvbdevfops);
239 kfree(dvbdev);
240 mutex_unlock(&dvbdev_register_lock);
241 return -EINVAL;
242 }
243#else
244 minor = nums2minor(adap->num, type, id);
245#endif
246
247 dvbdev->minor = minor;
248 dvb_minors[minor] = dvbdev;
249 up_write(&minor_rwsem);
250
234 mutex_unlock(&dvbdev_register_lock); 251 mutex_unlock(&dvbdev_register_lock);
235 252
236 clsdev = device_create(dvb_class, adap->device, 253 clsdev = device_create(dvb_class, adap->device,
237 MKDEV(DVB_MAJOR, nums2minor(adap->num, type, id)), 254 MKDEV(DVB_MAJOR, minor),
238 NULL, "dvb%d.%s%d", adap->num, dnames[type], id); 255 dvbdev, "dvb%d.%s%d", adap->num, dnames[type], id);
239 if (IS_ERR(clsdev)) { 256 if (IS_ERR(clsdev)) {
240 printk(KERN_ERR "%s: failed to create device dvb%d.%s%d (%ld)\n", 257 printk(KERN_ERR "%s: failed to create device dvb%d.%s%d (%ld)\n",
241 __func__, adap->num, dnames[type], id, PTR_ERR(clsdev)); 258 __func__, adap->num, dnames[type], id, PTR_ERR(clsdev));
@@ -243,8 +260,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
243 } 260 }
244 261
245 dprintk(KERN_DEBUG "DVB: register adapter%d/%s%d @ minor: %i (0x%02x)\n", 262 dprintk(KERN_DEBUG "DVB: register adapter%d/%s%d @ minor: %i (0x%02x)\n",
246 adap->num, dnames[type], id, nums2minor(adap->num, type, id), 263 adap->num, dnames[type], id, minor, minor);
247 nums2minor(adap->num, type, id));
248 264
249 return 0; 265 return 0;
250} 266}
@@ -256,8 +272,11 @@ void dvb_unregister_device(struct dvb_device *dvbdev)
256 if (!dvbdev) 272 if (!dvbdev)
257 return; 273 return;
258 274
259 device_destroy(dvb_class, MKDEV(DVB_MAJOR, nums2minor(dvbdev->adapter->num, 275 down_write(&minor_rwsem);
260 dvbdev->type, dvbdev->id))); 276 dvb_minors[dvbdev->minor] = NULL;
277 up_write(&minor_rwsem);
278
279 device_destroy(dvb_class, MKDEV(DVB_MAJOR, dvbdev->minor));
261 280
262 list_del (&dvbdev->list_head); 281 list_del (&dvbdev->list_head);
263 kfree (dvbdev->fops); 282 kfree (dvbdev->fops);
@@ -413,6 +432,15 @@ out:
413 return err; 432 return err;
414} 433}
415 434
435static int dvb_uevent(struct device *dev, struct kobj_uevent_env *env)
436{
437 struct dvb_device *dvbdev = dev_get_drvdata(dev);
438
439 add_uevent_var(env, "DVB_DEVICE_NUM=%d", dvbdev->id);
440 add_uevent_var(env, "DVB_ADAPTER_NUM=%d", dvbdev->adapter->num);
441 return 0;
442}
443
416static int __init init_dvbdev(void) 444static int __init init_dvbdev(void)
417{ 445{
418 int retval; 446 int retval;
@@ -434,6 +462,7 @@ static int __init init_dvbdev(void)
434 retval = PTR_ERR(dvb_class); 462 retval = PTR_ERR(dvb_class);
435 goto error; 463 goto error;
436 } 464 }
465 dvb_class->dev_uevent = dvb_uevent;
437 return 0; 466 return 0;
438 467
439error: 468error:
diff --git a/drivers/media/dvb/dvb-core/dvbdev.h b/drivers/media/dvb/dvb-core/dvbdev.h
index 574e336bac35..dca49cf962e8 100644
--- a/drivers/media/dvb/dvb-core/dvbdev.h
+++ b/drivers/media/dvb/dvb-core/dvbdev.h
@@ -74,6 +74,7 @@ struct dvb_device {
74 struct file_operations *fops; 74 struct file_operations *fops;
75 struct dvb_adapter *adapter; 75 struct dvb_adapter *adapter;
76 int type; 76 int type;
77 int minor;
77 u32 id; 78 u32 id;
78 79
79 /* in theory, 'users' can vanish now, 80 /* in theory, 'users' can vanish now,
diff --git a/drivers/media/dvb/dvb-usb/af9015.c b/drivers/media/dvb/dvb-usb/af9015.c
index e9ab0249d133..e1e9aa5c6b84 100644
--- a/drivers/media/dvb/dvb-usb/af9015.c
+++ b/drivers/media/dvb/dvb-usb/af9015.c
@@ -733,9 +733,19 @@ static int af9015_read_config(struct usb_device *udev)
733 af9015_config.ir_table_size = 733 af9015_config.ir_table_size =
734 ARRAY_SIZE(af9015_ir_table_mygictv); 734 ARRAY_SIZE(af9015_ir_table_mygictv);
735 break; 735 break;
736 case AF9015_REMOTE_DIGITTRADE_DVB_T:
737 af9015_properties[i].rc_key_map =
738 af9015_rc_keys_digittrade;
739 af9015_properties[i].rc_key_map_size =
740 ARRAY_SIZE(af9015_rc_keys_digittrade);
741 af9015_config.ir_table =
742 af9015_ir_table_digittrade;
743 af9015_config.ir_table_size =
744 ARRAY_SIZE(af9015_ir_table_digittrade);
745 break;
736 } 746 }
737 } else { 747 } else {
738 switch (udev->descriptor.idVendor) { 748 switch (le16_to_cpu(udev->descriptor.idVendor)) {
739 case USB_VID_LEADTEK: 749 case USB_VID_LEADTEK:
740 af9015_properties[i].rc_key_map = 750 af9015_properties[i].rc_key_map =
741 af9015_rc_keys_leadtek; 751 af9015_rc_keys_leadtek;
@@ -748,7 +758,7 @@ static int af9015_read_config(struct usb_device *udev)
748 break; 758 break;
749 case USB_VID_VISIONPLUS: 759 case USB_VID_VISIONPLUS:
750 if (udev->descriptor.idProduct == 760 if (udev->descriptor.idProduct ==
751 USB_PID_AZUREWAVE_AD_TU700) { 761 cpu_to_le16(USB_PID_AZUREWAVE_AD_TU700)) {
752 af9015_properties[i].rc_key_map = 762 af9015_properties[i].rc_key_map =
753 af9015_rc_keys_twinhan; 763 af9015_rc_keys_twinhan;
754 af9015_properties[i].rc_key_map_size = 764 af9015_properties[i].rc_key_map_size =
@@ -800,6 +810,16 @@ static int af9015_read_config(struct usb_device *udev)
800 ARRAY_SIZE(af9015_ir_table_msi); 810 ARRAY_SIZE(af9015_ir_table_msi);
801 } 811 }
802 break; 812 break;
813 case USB_VID_AVERMEDIA:
814 af9015_properties[i].rc_key_map =
815 af9015_rc_keys_avermedia;
816 af9015_properties[i].rc_key_map_size =
817 ARRAY_SIZE(af9015_rc_keys_avermedia);
818 af9015_config.ir_table =
819 af9015_ir_table_avermedia;
820 af9015_config.ir_table_size =
821 ARRAY_SIZE(af9015_ir_table_avermedia);
822 break;
803 } 823 }
804 } 824 }
805 } 825 }
@@ -1191,6 +1211,7 @@ static struct usb_device_id af9015_usb_table[] = {
1191 {USB_DEVICE(USB_VID_TELESTAR, USB_PID_TELESTAR_STARSTICK_2)}, 1211 {USB_DEVICE(USB_VID_TELESTAR, USB_PID_TELESTAR_STARSTICK_2)},
1192 {USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A309)}, 1212 {USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A309)},
1193/* 15 */{USB_DEVICE(USB_VID_MSI_2, USB_PID_MSI_DIGI_VOX_MINI_III)}, 1213/* 15 */{USB_DEVICE(USB_VID_MSI_2, USB_PID_MSI_DIGI_VOX_MINI_III)},
1214 {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U)},
1194 {0}, 1215 {0},
1195}; 1216};
1196MODULE_DEVICE_TABLE(usb, af9015_usb_table); 1217MODULE_DEVICE_TABLE(usb, af9015_usb_table);
@@ -1343,7 +1364,7 @@ static struct dvb_usb_device_properties af9015_properties[] = {
1343 1364
1344 .i2c_algo = &af9015_i2c_algo, 1365 .i2c_algo = &af9015_i2c_algo,
1345 1366
1346 .num_device_descs = 6, 1367 .num_device_descs = 7,
1347 .devices = { 1368 .devices = {
1348 { 1369 {
1349 .name = "Xtensions XD-380", 1370 .name = "Xtensions XD-380",
@@ -1375,6 +1396,12 @@ static struct dvb_usb_device_properties af9015_properties[] = {
1375 .cold_ids = {&af9015_usb_table[15], NULL}, 1396 .cold_ids = {&af9015_usb_table[15], NULL},
1376 .warm_ids = {NULL}, 1397 .warm_ids = {NULL},
1377 }, 1398 },
1399 {
1400 .name = "KWorld USB DVB-T TV Stick II " \
1401 "(VS-DVB-T 395U)",
1402 .cold_ids = {&af9015_usb_table[16], NULL},
1403 .warm_ids = {NULL},
1404 },
1378 } 1405 }
1379 } 1406 }
1380}; 1407};
diff --git a/drivers/media/dvb/dvb-usb/af9015.h b/drivers/media/dvb/dvb-usb/af9015.h
index 6c3c97293316..21c7782f4889 100644
--- a/drivers/media/dvb/dvb-usb/af9015.h
+++ b/drivers/media/dvb/dvb-usb/af9015.h
@@ -123,6 +123,7 @@ enum af9015_remote {
123 AF9015_REMOTE_A_LINK_DTU_M, 123 AF9015_REMOTE_A_LINK_DTU_M,
124 AF9015_REMOTE_MSI_DIGIVOX_MINI_II_V3, 124 AF9015_REMOTE_MSI_DIGIVOX_MINI_II_V3,
125 AF9015_REMOTE_MYGICTV_U718, 125 AF9015_REMOTE_MYGICTV_U718,
126 AF9015_REMOTE_DIGITTRADE_DVB_T,
126}; 127};
127 128
128/* Leadtek WinFast DTV Dongle Gold */ 129/* Leadtek WinFast DTV Dongle Gold */
@@ -520,4 +521,143 @@ static u8 af9015_ir_table_kworld[] = {
520 0x86, 0x6b, 0x23, 0xdc, 0x45, 0x07, 0x00, 521 0x86, 0x6b, 0x23, 0xdc, 0x45, 0x07, 0x00,
521}; 522};
522 523
524/* AverMedia Volar X */
525static struct dvb_usb_rc_key af9015_rc_keys_avermedia[] = {
526 { 0x05, 0x3d, KEY_PROG1 }, /* SOURCE */
527 { 0x05, 0x12, KEY_POWER }, /* POWER */
528 { 0x05, 0x1e, KEY_1 }, /* 1 */
529 { 0x05, 0x1f, KEY_2 }, /* 2 */
530 { 0x05, 0x20, KEY_3 }, /* 3 */
531 { 0x05, 0x21, KEY_4 }, /* 4 */
532 { 0x05, 0x22, KEY_5 }, /* 5 */
533 { 0x05, 0x23, KEY_6 }, /* 6 */
534 { 0x05, 0x24, KEY_7 }, /* 7 */
535 { 0x05, 0x25, KEY_8 }, /* 8 */
536 { 0x05, 0x26, KEY_9 }, /* 9 */
537 { 0x05, 0x3f, KEY_LEFT }, /* L / DISPLAY */
538 { 0x05, 0x27, KEY_0 }, /* 0 */
539 { 0x05, 0x0f, KEY_RIGHT }, /* R / CH RTN */
540 { 0x05, 0x18, KEY_PROG2 }, /* SNAP SHOT */
541 { 0x05, 0x1c, KEY_PROG3 }, /* 16-CH PREV */
542 { 0x05, 0x2d, KEY_VOLUMEDOWN }, /* VOL DOWN */
543 { 0x05, 0x3e, KEY_ZOOM }, /* FULL SCREEN */
544 { 0x05, 0x2e, KEY_VOLUMEUP }, /* VOL UP */
545 { 0x05, 0x10, KEY_MUTE }, /* MUTE */
546 { 0x05, 0x04, KEY_AUDIO }, /* AUDIO */
547 { 0x05, 0x15, KEY_RECORD }, /* RECORD */
548 { 0x05, 0x11, KEY_PLAY }, /* PLAY */
549 { 0x05, 0x16, KEY_STOP }, /* STOP */
550 { 0x05, 0x0c, KEY_PLAYPAUSE }, /* TIMESHIFT / PAUSE */
551 { 0x05, 0x05, KEY_BACK }, /* << / RED */
552 { 0x05, 0x09, KEY_FORWARD }, /* >> / YELLOW */
553 { 0x05, 0x17, KEY_TEXT }, /* TELETEXT */
554 { 0x05, 0x0a, KEY_EPG }, /* EPG */
555 { 0x05, 0x13, KEY_MENU }, /* MENU */
556
557 { 0x05, 0x0e, KEY_CHANNELUP }, /* CH UP */
558 { 0x05, 0x0d, KEY_CHANNELDOWN }, /* CH DOWN */
559 { 0x05, 0x19, KEY_FIRST }, /* |<< / GREEN */
560 { 0x05, 0x08, KEY_LAST }, /* >>| / BLUE */
561};
562
563static u8 af9015_ir_table_avermedia[] = {
564 0x02, 0xfd, 0x00, 0xff, 0x12, 0x05, 0x00,
565 0x02, 0xfd, 0x01, 0xfe, 0x3d, 0x05, 0x00,
566 0x02, 0xfd, 0x03, 0xfc, 0x17, 0x05, 0x00,
567 0x02, 0xfd, 0x04, 0xfb, 0x0a, 0x05, 0x00,
568 0x02, 0xfd, 0x05, 0xfa, 0x1e, 0x05, 0x00,
569 0x02, 0xfd, 0x06, 0xf9, 0x1f, 0x05, 0x00,
570 0x02, 0xfd, 0x07, 0xf8, 0x20, 0x05, 0x00,
571 0x02, 0xfd, 0x09, 0xf6, 0x21, 0x05, 0x00,
572 0x02, 0xfd, 0x0a, 0xf5, 0x22, 0x05, 0x00,
573 0x02, 0xfd, 0x0b, 0xf4, 0x23, 0x05, 0x00,
574 0x02, 0xfd, 0x0d, 0xf2, 0x24, 0x05, 0x00,
575 0x02, 0xfd, 0x0e, 0xf1, 0x25, 0x05, 0x00,
576 0x02, 0xfd, 0x0f, 0xf0, 0x26, 0x05, 0x00,
577 0x02, 0xfd, 0x11, 0xee, 0x27, 0x05, 0x00,
578 0x02, 0xfd, 0x08, 0xf7, 0x04, 0x05, 0x00,
579 0x02, 0xfd, 0x0c, 0xf3, 0x3e, 0x05, 0x00,
580 0x02, 0xfd, 0x10, 0xef, 0x1c, 0x05, 0x00,
581 0x02, 0xfd, 0x12, 0xed, 0x3f, 0x05, 0x00,
582 0x02, 0xfd, 0x13, 0xec, 0x0f, 0x05, 0x00,
583 0x02, 0xfd, 0x14, 0xeb, 0x10, 0x05, 0x00,
584 0x02, 0xfd, 0x15, 0xea, 0x13, 0x05, 0x00,
585 0x02, 0xfd, 0x17, 0xe8, 0x18, 0x05, 0x00,
586 0x02, 0xfd, 0x18, 0xe7, 0x11, 0x05, 0x00,
587 0x02, 0xfd, 0x19, 0xe6, 0x15, 0x05, 0x00,
588 0x02, 0xfd, 0x1a, 0xe5, 0x0c, 0x05, 0x00,
589 0x02, 0xfd, 0x1b, 0xe4, 0x16, 0x05, 0x00,
590 0x02, 0xfd, 0x1c, 0xe3, 0x09, 0x05, 0x00,
591 0x02, 0xfd, 0x1d, 0xe2, 0x05, 0x05, 0x00,
592 0x02, 0xfd, 0x1e, 0xe1, 0x2d, 0x05, 0x00,
593 0x02, 0xfd, 0x1f, 0xe0, 0x2e, 0x05, 0x00,
594 0x03, 0xfc, 0x00, 0xff, 0x08, 0x05, 0x00,
595 0x03, 0xfc, 0x01, 0xfe, 0x19, 0x05, 0x00,
596 0x03, 0xfc, 0x02, 0xfd, 0x0d, 0x05, 0x00,
597 0x03, 0xfc, 0x03, 0xfc, 0x0e, 0x05, 0x00,
598};
599
600/* Digittrade DVB-T USB Stick */
601static struct dvb_usb_rc_key af9015_rc_keys_digittrade[] = {
602 { 0x01, 0x0f, KEY_LAST }, /* RETURN */
603 { 0x05, 0x17, KEY_TEXT }, /* TELETEXT */
604 { 0x01, 0x08, KEY_EPG }, /* EPG */
605 { 0x05, 0x13, KEY_POWER }, /* POWER */
606 { 0x01, 0x09, KEY_ZOOM }, /* FULLSCREEN */
607 { 0x00, 0x40, KEY_AUDIO }, /* DUAL SOUND */
608 { 0x00, 0x2c, KEY_PRINT }, /* SNAPSHOT */
609 { 0x05, 0x16, KEY_SUBTITLE }, /* SUBTITLE */
610 { 0x00, 0x52, KEY_CHANNELUP }, /* CH Up */
611 { 0x00, 0x51, KEY_CHANNELDOWN },/* Ch Dn */
612 { 0x00, 0x57, KEY_VOLUMEUP }, /* Vol Up */
613 { 0x00, 0x56, KEY_VOLUMEDOWN }, /* Vol Dn */
614 { 0x01, 0x10, KEY_MUTE }, /* MUTE */
615 { 0x00, 0x27, KEY_0 },
616 { 0x00, 0x1e, KEY_1 },
617 { 0x00, 0x1f, KEY_2 },
618 { 0x00, 0x20, KEY_3 },
619 { 0x00, 0x21, KEY_4 },
620 { 0x00, 0x22, KEY_5 },
621 { 0x00, 0x23, KEY_6 },
622 { 0x00, 0x24, KEY_7 },
623 { 0x00, 0x25, KEY_8 },
624 { 0x00, 0x26, KEY_9 },
625 { 0x01, 0x17, KEY_PLAYPAUSE }, /* TIMESHIFT */
626 { 0x01, 0x15, KEY_RECORD }, /* RECORD */
627 { 0x03, 0x13, KEY_PLAY }, /* PLAY */
628 { 0x01, 0x16, KEY_STOP }, /* STOP */
629 { 0x01, 0x13, KEY_PAUSE }, /* PAUSE */
630};
631
632static u8 af9015_ir_table_digittrade[] = {
633 0x00, 0xff, 0x06, 0xf9, 0x13, 0x05, 0x00,
634 0x00, 0xff, 0x4d, 0xb2, 0x17, 0x01, 0x00,
635 0x00, 0xff, 0x1f, 0xe0, 0x2c, 0x00, 0x00,
636 0x00, 0xff, 0x0a, 0xf5, 0x15, 0x01, 0x00,
637 0x00, 0xff, 0x0e, 0xf1, 0x16, 0x01, 0x00,
638 0x00, 0xff, 0x09, 0xf6, 0x09, 0x01, 0x00,
639 0x00, 0xff, 0x01, 0xfe, 0x08, 0x01, 0x00,
640 0x00, 0xff, 0x05, 0xfa, 0x10, 0x01, 0x00,
641 0x00, 0xff, 0x02, 0xfd, 0x56, 0x00, 0x00,
642 0x00, 0xff, 0x40, 0xbf, 0x57, 0x00, 0x00,
643 0x00, 0xff, 0x19, 0xe6, 0x52, 0x00, 0x00,
644 0x00, 0xff, 0x17, 0xe8, 0x51, 0x00, 0x00,
645 0x00, 0xff, 0x10, 0xef, 0x0f, 0x01, 0x00,
646 0x00, 0xff, 0x54, 0xab, 0x27, 0x00, 0x00,
647 0x00, 0xff, 0x1b, 0xe4, 0x1e, 0x00, 0x00,
648 0x00, 0xff, 0x11, 0xee, 0x1f, 0x00, 0x00,
649 0x00, 0xff, 0x15, 0xea, 0x20, 0x00, 0x00,
650 0x00, 0xff, 0x12, 0xed, 0x21, 0x00, 0x00,
651 0x00, 0xff, 0x16, 0xe9, 0x22, 0x00, 0x00,
652 0x00, 0xff, 0x4c, 0xb3, 0x23, 0x00, 0x00,
653 0x00, 0xff, 0x48, 0xb7, 0x24, 0x00, 0x00,
654 0x00, 0xff, 0x04, 0xfb, 0x25, 0x00, 0x00,
655 0x00, 0xff, 0x00, 0xff, 0x26, 0x00, 0x00,
656 0x00, 0xff, 0x1e, 0xe1, 0x13, 0x03, 0x00,
657 0x00, 0xff, 0x1a, 0xe5, 0x13, 0x01, 0x00,
658 0x00, 0xff, 0x03, 0xfc, 0x17, 0x05, 0x00,
659 0x00, 0xff, 0x0d, 0xf2, 0x16, 0x05, 0x00,
660 0x00, 0xff, 0x1d, 0xe2, 0x40, 0x00, 0x00,
661};
662
523#endif 663#endif
diff --git a/drivers/media/dvb/dvb-usb/anysee.c b/drivers/media/dvb/dvb-usb/anysee.c
index cd2edbcaa097..5017f08b14a6 100644
--- a/drivers/media/dvb/dvb-usb/anysee.c
+++ b/drivers/media/dvb/dvb-usb/anysee.c
@@ -153,7 +153,7 @@ static int anysee_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msg,
153 int num) 153 int num)
154{ 154{
155 struct dvb_usb_device *d = i2c_get_adapdata(adap); 155 struct dvb_usb_device *d = i2c_get_adapdata(adap);
156 int ret, inc, i = 0; 156 int ret = 0, inc, i = 0;
157 157
158 if (mutex_lock_interruptible(&d->i2c_mutex) < 0) 158 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
159 return -EAGAIN; 159 return -EAGAIN;
diff --git a/drivers/media/dvb/dvb-usb/cinergyT2-core.c b/drivers/media/dvb/dvb-usb/cinergyT2-core.c
index 3ac9f74e9fbf..80e37a0d0892 100644
--- a/drivers/media/dvb/dvb-usb/cinergyT2-core.c
+++ b/drivers/media/dvb/dvb-usb/cinergyT2-core.c
@@ -32,7 +32,6 @@
32 32
33/* debug */ 33/* debug */
34int dvb_usb_cinergyt2_debug; 34int dvb_usb_cinergyt2_debug;
35int disable_remote;
36 35
37module_param_named(debug, dvb_usb_cinergyt2_debug, int, 0644); 36module_param_named(debug, dvb_usb_cinergyt2_debug, int, 0644);
38MODULE_PARM_DESC(debug, "set debugging level (1=info, xfer=2, rc=4 " 37MODULE_PARM_DESC(debug, "set debugging level (1=info, xfer=2, rc=4 "
@@ -45,7 +44,7 @@ struct cinergyt2_state {
45}; 44};
46 45
47/* We are missing a release hook with usb_device data */ 46/* We are missing a release hook with usb_device data */
48struct dvb_usb_device *cinergyt2_usb_device; 47static struct dvb_usb_device *cinergyt2_usb_device;
49 48
50static struct dvb_usb_device_properties cinergyt2_properties; 49static struct dvb_usb_device_properties cinergyt2_properties;
51 50
diff --git a/drivers/media/dvb/dvb-usb/cinergyT2.h b/drivers/media/dvb/dvb-usb/cinergyT2.h
index 11d79eb384c8..84efe03771eb 100644
--- a/drivers/media/dvb/dvb-usb/cinergyT2.h
+++ b/drivers/media/dvb/dvb-usb/cinergyT2.h
@@ -70,11 +70,11 @@ struct dvbt_get_status_msg {
70 uint8_t bandwidth; 70 uint8_t bandwidth;
71 uint16_t tps; 71 uint16_t tps;
72 uint8_t flags; 72 uint8_t flags;
73 uint16_t gain; 73 __le16 gain;
74 uint8_t snr; 74 uint8_t snr;
75 uint32_t viterbi_error_rate; 75 __le32 viterbi_error_rate;
76 uint32_t rs_error_rate; 76 uint32_t rs_error_rate;
77 uint32_t uncorrected_block_count; 77 __le32 uncorrected_block_count;
78 uint8_t lock_bits; 78 uint8_t lock_bits;
79 uint8_t prev_lock_bits; 79 uint8_t prev_lock_bits;
80} __attribute__((packed)); 80} __attribute__((packed));
@@ -82,9 +82,9 @@ struct dvbt_get_status_msg {
82 82
83struct dvbt_set_parameters_msg { 83struct dvbt_set_parameters_msg {
84 uint8_t cmd; 84 uint8_t cmd;
85 uint32_t freq; 85 __le32 freq;
86 uint8_t bandwidth; 86 uint8_t bandwidth;
87 uint16_t tps; 87 __le16 tps;
88 uint8_t flags; 88 uint8_t flags;
89} __attribute__((packed)); 89} __attribute__((packed));
90 90
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
index 7380b94b3b36..a4fca3fca5ee 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
@@ -96,6 +96,7 @@
96#define USB_PID_GRANDTEC_DVBT_USB_COLD 0x0fa0 96#define USB_PID_GRANDTEC_DVBT_USB_COLD 0x0fa0
97#define USB_PID_GRANDTEC_DVBT_USB_WARM 0x0fa1 97#define USB_PID_GRANDTEC_DVBT_USB_WARM 0x0fa1
98#define USB_PID_KWORLD_399U 0xe399 98#define USB_PID_KWORLD_399U 0xe399
99#define USB_PID_KWORLD_395U 0xe396
99#define USB_PID_KWORLD_PC160_2T 0xc160 100#define USB_PID_KWORLD_PC160_2T 0xc160
100#define USB_PID_KWORLD_VSTREAM_COLD 0x17de 101#define USB_PID_KWORLD_VSTREAM_COLD 0x17de
101#define USB_PID_KWORLD_VSTREAM_WARM 0x17df 102#define USB_PID_KWORLD_VSTREAM_WARM 0x17df
diff --git a/drivers/media/dvb/dvb-usb/dw2102.c b/drivers/media/dvb/dvb-usb/dw2102.c
index 6286fbbe7fb5..c65f273ff313 100644
--- a/drivers/media/dvb/dvb-usb/dw2102.c
+++ b/drivers/media/dvb/dvb-usb/dw2102.c
@@ -9,7 +9,6 @@
9* 9*
10* see Documentation/dvb/README.dvb-usb for more information 10* see Documentation/dvb/README.dvb-usb for more information
11*/ 11*/
12#include <linux/version.h>
13#include "dw2102.h" 12#include "dw2102.h"
14#include "si21xx.h" 13#include "si21xx.h"
15#include "stv0299.h" 14#include "stv0299.h"
@@ -27,6 +26,10 @@
27#define USB_PID_DW2104 0x2104 26#define USB_PID_DW2104 0x2104
28#endif 27#endif
29 28
29#ifndef USB_PID_CINERGY_S
30#define USB_PID_CINERGY_S 0x0064
31#endif
32
30#define DW210X_READ_MSG 0 33#define DW210X_READ_MSG 0
31#define DW210X_WRITE_MSG 1 34#define DW210X_WRITE_MSG 1
32 35
@@ -578,6 +581,7 @@ static struct usb_device_id dw2102_table[] = {
578 {USB_DEVICE(USB_VID_CYPRESS, 0x2101)}, 581 {USB_DEVICE(USB_VID_CYPRESS, 0x2101)},
579 {USB_DEVICE(USB_VID_CYPRESS, 0x2104)}, 582 {USB_DEVICE(USB_VID_CYPRESS, 0x2104)},
580 {USB_DEVICE(0x9022, 0xd650)}, 583 {USB_DEVICE(0x9022, 0xd650)},
584 {USB_DEVICE(USB_VID_TERRATEC, USB_PID_CINERGY_S)},
581 { } 585 { }
582}; 586};
583 587
@@ -647,6 +651,7 @@ static int dw2102_load_firmware(struct usb_device *dev,
647 dw210x_op_rw(dev, 0xbf, 0x0040, 0, &reset, 0, 651 dw210x_op_rw(dev, 0xbf, 0x0040, 0, &reset, 0,
648 DW210X_WRITE_MSG); 652 DW210X_WRITE_MSG);
649 break; 653 break;
654 case USB_PID_CINERGY_S:
650 case USB_PID_DW2102: 655 case USB_PID_DW2102:
651 dw210x_op_rw(dev, 0xbf, 0x0040, 0, &reset, 0, 656 dw210x_op_rw(dev, 0xbf, 0x0040, 0, &reset, 0,
652 DW210X_WRITE_MSG); 657 DW210X_WRITE_MSG);
@@ -655,7 +660,7 @@ static int dw2102_load_firmware(struct usb_device *dev,
655 /* check STV0299 frontend */ 660 /* check STV0299 frontend */
656 dw210x_op_rw(dev, 0xb5, 0, 0, &reset16[0], 2, 661 dw210x_op_rw(dev, 0xb5, 0, 0, &reset16[0], 2,
657 DW210X_READ_MSG); 662 DW210X_READ_MSG);
658 if (reset16[0] == 0xa1) { 663 if ((reset16[0] == 0xa1) || (reset16[0] == 0x80)) {
659 dw2102_properties.i2c_algo = &dw2102_i2c_algo; 664 dw2102_properties.i2c_algo = &dw2102_i2c_algo;
660 dw2102_properties.adapter->tuner_attach = &dw2102_tuner_attach; 665 dw2102_properties.adapter->tuner_attach = &dw2102_tuner_attach;
661 break; 666 break;
@@ -726,7 +731,7 @@ static struct dvb_usb_device_properties dw2102_properties = {
726 }, 731 },
727 } 732 }
728 }, 733 },
729 .num_device_descs = 2, 734 .num_device_descs = 3,
730 .devices = { 735 .devices = {
731 {"DVBWorld DVB-S 2102 USB2.0", 736 {"DVBWorld DVB-S 2102 USB2.0",
732 {&dw2102_table[0], NULL}, 737 {&dw2102_table[0], NULL},
@@ -736,6 +741,10 @@ static struct dvb_usb_device_properties dw2102_properties = {
736 {&dw2102_table[1], NULL}, 741 {&dw2102_table[1], NULL},
737 {NULL}, 742 {NULL},
738 }, 743 },
744 {"TerraTec Cinergy S USB",
745 {&dw2102_table[4], NULL},
746 {NULL},
747 },
739 } 748 }
740}; 749};
741 750
diff --git a/drivers/media/dvb/dvb-usb/gp8psk-fe.c b/drivers/media/dvb/dvb-usb/gp8psk-fe.c
index 262a858c3068..20eadf9318e0 100644
--- a/drivers/media/dvb/dvb-usb/gp8psk-fe.c
+++ b/drivers/media/dvb/dvb-usb/gp8psk-fe.c
@@ -25,6 +25,20 @@ struct gp8psk_fe_state {
25 unsigned long status_check_interval; 25 unsigned long status_check_interval;
26}; 26};
27 27
28static int gp8psk_tuned_to_DCII(struct dvb_frontend *fe)
29{
30 struct gp8psk_fe_state *st = fe->demodulator_priv;
31 u8 status;
32 gp8psk_usb_in_op(st->d, GET_8PSK_CONFIG, 0, 0, &status, 1);
33 return status & bmDCtuned;
34}
35
36static int gp8psk_set_tuner_mode(struct dvb_frontend *fe, int mode)
37{
38 struct gp8psk_fe_state *state = fe->demodulator_priv;
39 return gp8psk_usb_out_op(state->d, SET_8PSK_CONFIG, mode, 0, NULL, 0);
40}
41
28static int gp8psk_fe_update_status(struct gp8psk_fe_state *st) 42static int gp8psk_fe_update_status(struct gp8psk_fe_state *st)
29{ 43{
30 u8 buf[6]; 44 u8 buf[6];
@@ -99,39 +113,114 @@ static int gp8psk_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_front
99 return 0; 113 return 0;
100} 114}
101 115
116static int gp8psk_fe_set_property(struct dvb_frontend *fe,
117 struct dtv_property *tvp)
118{
119 deb_fe("%s(..)\n", __func__);
120 return 0;
121}
122
123static int gp8psk_fe_get_property(struct dvb_frontend *fe,
124 struct dtv_property *tvp)
125{
126 deb_fe("%s(..)\n", __func__);
127 return 0;
128}
129
130
102static int gp8psk_fe_set_frontend(struct dvb_frontend* fe, 131static int gp8psk_fe_set_frontend(struct dvb_frontend* fe,
103 struct dvb_frontend_parameters *fep) 132 struct dvb_frontend_parameters *fep)
104{ 133{
105 struct gp8psk_fe_state *state = fe->demodulator_priv; 134 struct gp8psk_fe_state *state = fe->demodulator_priv;
135 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
106 u8 cmd[10]; 136 u8 cmd[10];
107 u32 freq = fep->frequency * 1000; 137 u32 freq = fep->frequency * 1000;
138 int gp_product_id = le16_to_cpu(state->d->udev->descriptor.idProduct);
139
140 deb_fe("%s()\n", __func__);
108 141
109 cmd[4] = freq & 0xff; 142 cmd[4] = freq & 0xff;
110 cmd[5] = (freq >> 8) & 0xff; 143 cmd[5] = (freq >> 8) & 0xff;
111 cmd[6] = (freq >> 16) & 0xff; 144 cmd[6] = (freq >> 16) & 0xff;
112 cmd[7] = (freq >> 24) & 0xff; 145 cmd[7] = (freq >> 24) & 0xff;
113 146
114 switch(fe->ops.info.type) { 147 switch (c->delivery_system) {
115 case FE_QPSK: 148 case SYS_DVBS:
116 cmd[0] = fep->u.qpsk.symbol_rate & 0xff; 149 /* Only QPSK is supported for DVB-S */
117 cmd[1] = (fep->u.qpsk.symbol_rate >> 8) & 0xff; 150 if (c->modulation != QPSK) {
118 cmd[2] = (fep->u.qpsk.symbol_rate >> 16) & 0xff; 151 deb_fe("%s: unsupported modulation selected (%d)\n",
119 cmd[3] = (fep->u.qpsk.symbol_rate >> 24) & 0xff; 152 __func__, c->modulation);
120 cmd[8] = ADV_MOD_DVB_QPSK; 153 return -EOPNOTSUPP;
121 cmd[9] = 0x03; /*ADV_MOD_FEC_XXX*/ 154 }
155 c->fec_inner = FEC_AUTO;
122 break; 156 break;
157 case SYS_DVBS2:
158 deb_fe("%s: DVB-S2 delivery system selected\n", __func__);
159 break;
160
123 default: 161 default:
124 // other modes are unsuported right now 162 deb_fe("%s: unsupported delivery system selected (%d)\n",
125 cmd[0] = 0; 163 __func__, c->delivery_system);
126 cmd[1] = 0; 164 return -EOPNOTSUPP;
127 cmd[2] = 0; 165 }
128 cmd[3] = 0; 166
129 cmd[8] = 0; 167 cmd[0] = c->symbol_rate & 0xff;
168 cmd[1] = (c->symbol_rate >> 8) & 0xff;
169 cmd[2] = (c->symbol_rate >> 16) & 0xff;
170 cmd[3] = (c->symbol_rate >> 24) & 0xff;
171 switch (c->modulation) {
172 case QPSK:
173 if (gp_product_id == USB_PID_GENPIX_8PSK_REV_1_WARM)
174 if (gp8psk_tuned_to_DCII(fe))
175 gp8psk_bcm4500_reload(state->d);
176 switch (c->fec_inner) {
177 case FEC_1_2:
178 cmd[9] = 0; break;
179 case FEC_2_3:
180 cmd[9] = 1; break;
181 case FEC_3_4:
182 cmd[9] = 2; break;
183 case FEC_5_6:
184 cmd[9] = 3; break;
185 case FEC_7_8:
186 cmd[9] = 4; break;
187 case FEC_AUTO:
188 cmd[9] = 5; break;
189 default:
190 cmd[9] = 5; break;
191 }
192 cmd[8] = ADV_MOD_DVB_QPSK;
193 break;
194 case PSK_8: /* PSK_8 is for compatibility with DN */
195 cmd[8] = ADV_MOD_TURBO_8PSK;
196 switch (c->fec_inner) {
197 case FEC_2_3:
198 cmd[9] = 0; break;
199 case FEC_3_4:
200 cmd[9] = 1; break;
201 case FEC_3_5:
202 cmd[9] = 2; break;
203 case FEC_5_6:
204 cmd[9] = 3; break;
205 case FEC_8_9:
206 cmd[9] = 4; break;
207 default:
208 cmd[9] = 0; break;
209 }
210 break;
211 case QAM_16: /* QAM_16 is for compatibility with DN */
212 cmd[8] = ADV_MOD_TURBO_16QAM;
130 cmd[9] = 0; 213 cmd[9] = 0;
131 break; 214 break;
215 default: /* Unknown modulation */
216 deb_fe("%s: unsupported modulation selected (%d)\n",
217 __func__, c->modulation);
218 return -EOPNOTSUPP;
132 } 219 }
133 220
134 gp8psk_usb_out_op(state->d,TUNE_8PSK,0,0,cmd,10); 221 if (gp_product_id == USB_PID_GENPIX_8PSK_REV_1_WARM)
222 gp8psk_set_tuner_mode(fe, 0);
223 gp8psk_usb_out_op(state->d, TUNE_8PSK, 0, 0, cmd, 10);
135 224
136 state->lock = 0; 225 state->lock = 0;
137 state->next_status_check = jiffies; 226 state->next_status_check = jiffies;
@@ -140,13 +229,6 @@ static int gp8psk_fe_set_frontend(struct dvb_frontend* fe,
140 return 0; 229 return 0;
141} 230}
142 231
143static int gp8psk_fe_get_frontend(struct dvb_frontend* fe,
144 struct dvb_frontend_parameters *fep)
145{
146 return 0;
147}
148
149
150static int gp8psk_fe_send_diseqc_msg (struct dvb_frontend* fe, 232static int gp8psk_fe_send_diseqc_msg (struct dvb_frontend* fe,
151 struct dvb_diseqc_master_cmd *m) 233 struct dvb_diseqc_master_cmd *m)
152{ 234{
@@ -261,9 +343,13 @@ static struct dvb_frontend_ops gp8psk_fe_ops = {
261 .symbol_rate_max = 45000000, 343 .symbol_rate_max = 45000000,
262 .symbol_rate_tolerance = 500, /* ppm */ 344 .symbol_rate_tolerance = 500, /* ppm */
263 .caps = FE_CAN_INVERSION_AUTO | 345 .caps = FE_CAN_INVERSION_AUTO |
264 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | 346 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
265 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | 347 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
266 FE_CAN_QPSK 348 /*
349 * FE_CAN_QAM_16 is for compatibility
350 * (Myth incorrectly detects Turbo-QPSK as plain QAM-16)
351 */
352 FE_CAN_QPSK | FE_CAN_QAM_16
267 }, 353 },
268 354
269 .release = gp8psk_fe_release, 355 .release = gp8psk_fe_release,
@@ -271,8 +357,10 @@ static struct dvb_frontend_ops gp8psk_fe_ops = {
271 .init = NULL, 357 .init = NULL,
272 .sleep = NULL, 358 .sleep = NULL,
273 359
360 .set_property = gp8psk_fe_set_property,
361 .get_property = gp8psk_fe_get_property,
274 .set_frontend = gp8psk_fe_set_frontend, 362 .set_frontend = gp8psk_fe_set_frontend,
275 .get_frontend = gp8psk_fe_get_frontend, 363
276 .get_tune_settings = gp8psk_fe_get_tune_settings, 364 .get_tune_settings = gp8psk_fe_get_tune_settings,
277 365
278 .read_status = gp8psk_fe_read_status, 366 .read_status = gp8psk_fe_read_status,
diff --git a/drivers/media/dvb/dvb-usb/gp8psk.c b/drivers/media/dvb/dvb-usb/gp8psk.c
index d965a923f391..c1da962cc886 100644
--- a/drivers/media/dvb/dvb-usb/gp8psk.c
+++ b/drivers/media/dvb/dvb-usb/gp8psk.c
@@ -174,6 +174,22 @@ static int gp8psk_power_ctrl(struct dvb_usb_device *d, int onoff)
174 return 0; 174 return 0;
175} 175}
176 176
177int gp8psk_bcm4500_reload(struct dvb_usb_device *d)
178{
179 u8 buf;
180 int gp_product_id = le16_to_cpu(d->udev->descriptor.idProduct);
181 /* Turn off 8psk power */
182 if (gp8psk_usb_in_op(d, BOOT_8PSK, 0, 0, &buf, 1))
183 return -EINVAL;
184 /* Turn On 8psk power */
185 if (gp8psk_usb_in_op(d, BOOT_8PSK, 1, 0, &buf, 1))
186 return -EINVAL;
187 /* load BCM4500 firmware */
188 if (gp_product_id == USB_PID_GENPIX_8PSK_REV_1_WARM)
189 if (gp8psk_load_bcm4500fw(d))
190 return EINVAL;
191 return 0;
192}
177 193
178static int gp8psk_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) 194static int gp8psk_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
179{ 195{
diff --git a/drivers/media/dvb/dvb-usb/gp8psk.h b/drivers/media/dvb/dvb-usb/gp8psk.h
index e5cd8149c23d..e83a57506cfa 100644
--- a/drivers/media/dvb/dvb-usb/gp8psk.h
+++ b/drivers/media/dvb/dvb-usb/gp8psk.h
@@ -92,5 +92,6 @@ extern struct dvb_frontend * gp8psk_fe_attach(struct dvb_usb_device *d);
92extern int gp8psk_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen); 92extern int gp8psk_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen);
93extern int gp8psk_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value, 93extern int gp8psk_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value,
94 u16 index, u8 *b, int blen); 94 u16 index, u8 *b, int blen);
95extern int gp8psk_bcm4500_reload(struct dvb_usb_device *d);
95 96
96#endif 97#endif
diff --git a/drivers/media/dvb/dvb-usb/usb-urb.c b/drivers/media/dvb/dvb-usb/usb-urb.c
index da93b9e982c0..9da2cc95ca13 100644
--- a/drivers/media/dvb/dvb-usb/usb-urb.c
+++ b/drivers/media/dvb/dvb-usb/usb-urb.c
@@ -156,7 +156,8 @@ static int usb_bulk_urb_init(struct usb_data_stream *stream)
156 stream->props.u.bulk.buffersize, 156 stream->props.u.bulk.buffersize,
157 usb_urb_complete, stream); 157 usb_urb_complete, stream);
158 158
159 stream->urb_list[i]->transfer_flags = 0; 159 stream->urb_list[i]->transfer_flags = URB_NO_TRANSFER_DMA_MAP;
160 stream->urb_list[i]->transfer_dma = stream->dma_addr[i];
160 stream->urbs_initialized++; 161 stream->urbs_initialized++;
161 } 162 }
162 return 0; 163 return 0;
diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig
index 96b93e21a84b..00269560793a 100644
--- a/drivers/media/dvb/frontends/Kconfig
+++ b/drivers/media/dvb/frontends/Kconfig
@@ -12,6 +12,25 @@ config DVB_FE_CUSTOMISE
12 12
13 If unsure say N. 13 If unsure say N.
14 14
15comment "Multistandard (satellite) frontends"
16 depends on DVB_CORE
17
18config DVB_STB0899
19 tristate "STB0899 based"
20 depends on DVB_CORE && I2C
21 default m if DVB_FE_CUSTOMISE
22 help
23 A DVB-S/S2/DSS Multistandard demodulator. Say Y when you want
24 to support this demodulator based frontends
25
26config DVB_STB6100
27 tristate "STB6100 based tuners"
28 depends on DVB_CORE && I2C
29 default m if DVB_FE_CUSTOMISE
30 help
31 A Silicon tuner from ST used in conjunction with the STB0899
32 demodulator. Say Y when you want to support this tuner.
33
15comment "DVB-S (satellite) frontends" 34comment "DVB-S (satellite) frontends"
16 depends on DVB_CORE 35 depends on DVB_CORE
17 36
@@ -78,6 +97,13 @@ config DVB_TDA10086
78 help 97 help
79 A DVB-S tuner module. Say Y when you want to support this frontend. 98 A DVB-S tuner module. Say Y when you want to support this frontend.
80 99
100config DVB_TDA8261
101 tristate "Philips TDA8261 based"
102 depends on DVB_CORE && I2C
103 default m if DVB_FE_CUSTOMISE
104 help
105 A DVB-S tuner module. Say Y when you want to support this frontend.
106
81config DVB_VES1X93 107config DVB_VES1X93
82 tristate "VLSI VES1893 or VES1993 based" 108 tristate "VLSI VES1893 or VES1993 based"
83 depends on DVB_CORE && I2C 109 depends on DVB_CORE && I2C
@@ -92,6 +118,14 @@ config DVB_TUNER_ITD1000
92 help 118 help
93 A DVB-S tuner module. Say Y when you want to support this frontend. 119 A DVB-S tuner module. Say Y when you want to support this frontend.
94 120
121config DVB_TUNER_CX24113
122 tristate "Conexant CX24113/CX24128 tuner for DVB-S/DSS"
123 depends on DVB_CORE && I2C
124 default m if DVB_FE_CUSTOMISE
125 help
126 A DVB-S tuner module. Say Y when you want to support this frontend.
127
128
95config DVB_TDA826X 129config DVB_TDA826X
96 tristate "Philips TDA826X silicon tuner" 130 tristate "Philips TDA826X silicon tuner"
97 depends on DVB_CORE && I2C 131 depends on DVB_CORE && I2C
@@ -345,6 +379,14 @@ config DVB_LGDT330X
345 An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want 379 An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
346 to support this frontend. 380 to support this frontend.
347 381
382config DVB_LGDT3304
383 tristate "LG Electronics LGDT3304"
384 depends on DVB_CORE && I2C
385 default m if DVB_FE_CUSTOMISE
386 help
387 An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
388 to support this frontend.
389
348config DVB_S5H1409 390config DVB_S5H1409
349 tristate "Samsung S5H1409 based" 391 tristate "Samsung S5H1409 based"
350 depends on DVB_CORE && I2C 392 depends on DVB_CORE && I2C
@@ -369,6 +411,17 @@ config DVB_S5H1411
369 An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want 411 An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
370 to support this frontend. 412 to support this frontend.
371 413
414comment "ISDB-T (terrestrial) frontends"
415 depends on DVB_CORE
416
417config DVB_S921
418 tristate "Sharp S921 tuner"
419 depends on DVB_CORE && I2C
420 default m if DVB_FE_CUSTOMISE
421 help
422 AN ISDB-T DQPSK, QPSK, 16QAM and 64QAM 1seg tuner module.
423 Say Y when you want to support this frontend.
424
372comment "Digital terrestrial only tuners/PLL" 425comment "Digital terrestrial only tuners/PLL"
373 depends on DVB_CORE 426 depends on DVB_CORE
374 427
diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile
index aba79f4a63a7..af7bdf0ad4c7 100644
--- a/drivers/media/dvb/frontends/Makefile
+++ b/drivers/media/dvb/frontends/Makefile
@@ -5,8 +5,13 @@
5EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ 5EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/
6EXTRA_CFLAGS += -Idrivers/media/common/tuners/ 6EXTRA_CFLAGS += -Idrivers/media/common/tuners/
7 7
8s921-objs := s921_module.o s921_core.o
9stb0899-objs = stb0899_drv.o stb0899_algo.o
10
8obj-$(CONFIG_DVB_PLL) += dvb-pll.o 11obj-$(CONFIG_DVB_PLL) += dvb-pll.o
9obj-$(CONFIG_DVB_STV0299) += stv0299.o 12obj-$(CONFIG_DVB_STV0299) += stv0299.o
13obj-$(CONFIG_DVB_STB0899) += stb0899.o
14obj-$(CONFIG_DVB_STB6100) += stb6100.o
10obj-$(CONFIG_DVB_SP8870) += sp8870.o 15obj-$(CONFIG_DVB_SP8870) += sp8870.o
11obj-$(CONFIG_DVB_CX22700) += cx22700.o 16obj-$(CONFIG_DVB_CX22700) += cx22700.o
12obj-$(CONFIG_DVB_CX24110) += cx24110.o 17obj-$(CONFIG_DVB_CX24110) += cx24110.o
@@ -35,18 +40,21 @@ obj-$(CONFIG_DVB_OR51132) += or51132.o
35obj-$(CONFIG_DVB_BCM3510) += bcm3510.o 40obj-$(CONFIG_DVB_BCM3510) += bcm3510.o
36obj-$(CONFIG_DVB_S5H1420) += s5h1420.o 41obj-$(CONFIG_DVB_S5H1420) += s5h1420.o
37obj-$(CONFIG_DVB_LGDT330X) += lgdt330x.o 42obj-$(CONFIG_DVB_LGDT330X) += lgdt330x.o
43obj-$(CONFIG_DVB_LGDT3304) += lgdt3304.o
38obj-$(CONFIG_DVB_CX24123) += cx24123.o 44obj-$(CONFIG_DVB_CX24123) += cx24123.o
39obj-$(CONFIG_DVB_LNBP21) += lnbp21.o 45obj-$(CONFIG_DVB_LNBP21) += lnbp21.o
40obj-$(CONFIG_DVB_ISL6405) += isl6405.o 46obj-$(CONFIG_DVB_ISL6405) += isl6405.o
41obj-$(CONFIG_DVB_ISL6421) += isl6421.o 47obj-$(CONFIG_DVB_ISL6421) += isl6421.o
42obj-$(CONFIG_DVB_TDA10086) += tda10086.o 48obj-$(CONFIG_DVB_TDA10086) += tda10086.o
43obj-$(CONFIG_DVB_TDA826X) += tda826x.o 49obj-$(CONFIG_DVB_TDA826X) += tda826x.o
50obj-$(CONFIG_DVB_TDA8261) += tda8261.o
44obj-$(CONFIG_DVB_TUNER_DIB0070) += dib0070.o 51obj-$(CONFIG_DVB_TUNER_DIB0070) += dib0070.o
45obj-$(CONFIG_DVB_TUA6100) += tua6100.o 52obj-$(CONFIG_DVB_TUA6100) += tua6100.o
46obj-$(CONFIG_DVB_S5H1409) += s5h1409.o 53obj-$(CONFIG_DVB_S5H1409) += s5h1409.o
47obj-$(CONFIG_DVB_TUNER_ITD1000) += itd1000.o 54obj-$(CONFIG_DVB_TUNER_ITD1000) += itd1000.o
48obj-$(CONFIG_DVB_AU8522) += au8522.o 55obj-$(CONFIG_DVB_AU8522) += au8522.o
49obj-$(CONFIG_DVB_TDA10048) += tda10048.o 56obj-$(CONFIG_DVB_TDA10048) += tda10048.o
57obj-$(CONFIG_DVB_TUNER_CX24113) += cx24113.o
50obj-$(CONFIG_DVB_S5H1411) += s5h1411.o 58obj-$(CONFIG_DVB_S5H1411) += s5h1411.o
51obj-$(CONFIG_DVB_LGS8GL5) += lgs8gl5.o 59obj-$(CONFIG_DVB_LGS8GL5) += lgs8gl5.o
52obj-$(CONFIG_DVB_DUMMY_FE) += dvb_dummy_fe.o 60obj-$(CONFIG_DVB_DUMMY_FE) += dvb_dummy_fe.o
@@ -55,3 +63,5 @@ obj-$(CONFIG_DVB_CX24116) += cx24116.o
55obj-$(CONFIG_DVB_SI21XX) += si21xx.o 63obj-$(CONFIG_DVB_SI21XX) += si21xx.o
56obj-$(CONFIG_DVB_STV0288) += stv0288.o 64obj-$(CONFIG_DVB_STV0288) += stv0288.o
57obj-$(CONFIG_DVB_STB6000) += stb6000.o 65obj-$(CONFIG_DVB_STB6000) += stb6000.o
66obj-$(CONFIG_DVB_S921) += s921.o
67
diff --git a/drivers/media/dvb/frontends/af9013.c b/drivers/media/dvb/frontends/af9013.c
index 692b68a9e73b..b2b50fb4cfd3 100644
--- a/drivers/media/dvb/frontends/af9013.c
+++ b/drivers/media/dvb/frontends/af9013.c
@@ -223,12 +223,12 @@ static int af9013_set_coeff(struct af9013_state *state, fe_bandwidth_t bw)
223 int ret = 0; 223 int ret = 0;
224 u8 i = 0; 224 u8 i = 0;
225 u8 buf[24]; 225 u8 buf[24];
226 u32 ns_coeff1_2048nu; 226 u32 uninitialized_var(ns_coeff1_2048nu);
227 u32 ns_coeff1_8191nu; 227 u32 uninitialized_var(ns_coeff1_8191nu);
228 u32 ns_coeff1_8192nu; 228 u32 uninitialized_var(ns_coeff1_8192nu);
229 u32 ns_coeff1_8193nu; 229 u32 uninitialized_var(ns_coeff1_8193nu);
230 u32 ns_coeff2_2k; 230 u32 uninitialized_var(ns_coeff2_2k);
231 u32 ns_coeff2_8k; 231 u32 uninitialized_var(ns_coeff2_8k);
232 232
233 deb_info("%s: adc_clock:%d bw:%d\n", __func__, 233 deb_info("%s: adc_clock:%d bw:%d\n", __func__,
234 state->config.adc_clock, bw); 234 state->config.adc_clock, bw);
@@ -1009,7 +1009,7 @@ static int af9013_update_snr(struct dvb_frontend *fe)
1009 int ret; 1009 int ret;
1010 u8 buf[3], i, len; 1010 u8 buf[3], i, len;
1011 u32 quant = 0; 1011 u32 quant = 0;
1012 struct snr_table *snr_table; 1012 struct snr_table *uninitialized_var(snr_table);
1013 1013
1014 /* check if quantizer ready (for snr) */ 1014 /* check if quantizer ready (for snr) */
1015 ret = af9013_read_reg_bits(state, 0xd2e1, 3, 1, &buf[0]); 1015 ret = af9013_read_reg_bits(state, 0xd2e1, 3, 1, &buf[0]);
diff --git a/drivers/media/dvb/frontends/cx24113.c b/drivers/media/dvb/frontends/cx24113.c
new file mode 100644
index 000000000000..f6e7b0380a5a
--- /dev/null
+++ b/drivers/media/dvb/frontends/cx24113.c
@@ -0,0 +1,616 @@
1/*
2 * Driver for Conexant CX24113/CX24128 Tuner (Satellite)
3 *
4 * Copyright (C) 2007-8 Patrick Boettcher <pb@linuxtv.org>
5 *
6 * Developed for BBTI / Technisat
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 <linux/slab.h>
25#include <linux/kernel.h>
26#include <linux/module.h>
27#include <linux/init.h>
28
29#include "dvb_frontend.h"
30#include "cx24113.h"
31
32static int debug;
33
34#define info(args...) do { printk(KERN_INFO "CX24113: " args); } while (0)
35#define err(args...) do { printk(KERN_ERR "CX24113: " args); } while (0)
36
37#define dprintk(args...) \
38 do { \
39 if (debug) { \
40 printk(KERN_DEBUG "CX24113: %s: ", __func__); \
41 printk(args); \
42 } \
43 } while (0)
44
45struct cx24113_state {
46 struct i2c_adapter *i2c;
47 const struct cx24113_config *config;
48
49#define REV_CX24113 0x23
50 u8 rev;
51 u8 ver;
52
53 u8 icp_mode:1;
54
55#define ICP_LEVEL1 0
56#define ICP_LEVEL2 1
57#define ICP_LEVEL3 2
58#define ICP_LEVEL4 3
59 u8 icp_man:2;
60 u8 icp_auto_low:2;
61 u8 icp_auto_mlow:2;
62 u8 icp_auto_mhi:2;
63 u8 icp_auto_hi:2;
64 u8 icp_dig;
65
66#define LNA_MIN_GAIN 0
67#define LNA_MID_GAIN 1
68#define LNA_MAX_GAIN 2
69 u8 lna_gain:2;
70
71 u8 acp_on:1;
72
73 u8 vco_mode:2;
74 u8 vco_shift:1;
75#define VCOBANDSEL_6 0x80
76#define VCOBANDSEL_5 0x01
77#define VCOBANDSEL_4 0x02
78#define VCOBANDSEL_3 0x04
79#define VCOBANDSEL_2 0x08
80#define VCOBANDSEL_1 0x10
81 u8 vco_band;
82
83#define VCODIV4 4
84#define VCODIV2 2
85 u8 vcodiv;
86
87 u8 bs_delay:4;
88 u16 bs_freqcnt:13;
89 u16 bs_rdiv;
90 u8 prescaler_mode:1;
91
92 u8 rfvga_bias_ctrl;
93
94 s16 tuner_gain_thres;
95 u8 gain_level;
96
97 u32 frequency;
98
99 u8 refdiv;
100
101 u8 Fwindow_enabled;
102};
103
104static int cx24113_writereg(struct cx24113_state *state, int reg, int data)
105{
106 u8 buf[] = { reg, data };
107 struct i2c_msg msg = { .addr = state->config->i2c_addr,
108 .flags = 0, .buf = buf, .len = 2 };
109 int err = i2c_transfer(state->i2c, &msg, 1);
110 if (err != 1) {
111 printk(KERN_DEBUG "%s: writereg error(err == %i, reg == 0x%02x,"
112 " data == 0x%02x)\n", __func__, err, reg, data);
113 return err;
114 }
115
116 return 0;
117}
118
119static int cx24113_readreg(struct cx24113_state *state, u8 reg)
120{
121 int ret;
122 u8 b;
123 struct i2c_msg msg[] = {
124 { .addr = state->config->i2c_addr,
125 .flags = 0, .buf = &reg, .len = 1 },
126 { .addr = state->config->i2c_addr,
127 .flags = I2C_M_RD, .buf = &b, .len = 1 }
128 };
129
130 ret = i2c_transfer(state->i2c, msg, 2);
131
132 if (ret != 2) {
133 printk(KERN_DEBUG "%s: reg=0x%x (error=%d)\n",
134 __func__, reg, ret);
135 return ret;
136 }
137
138 return b;
139}
140
141static void cx24113_set_parameters(struct cx24113_state *state)
142{
143 u8 r;
144
145 r = cx24113_readreg(state, 0x10) & 0x82;
146 r |= state->icp_mode;
147 r |= state->icp_man << 4;
148 r |= state->icp_dig << 2;
149 r |= state->prescaler_mode << 5;
150 cx24113_writereg(state, 0x10, r);
151
152 r = (state->icp_auto_low << 0) | (state->icp_auto_mlow << 2)
153 | (state->icp_auto_mhi << 4) | (state->icp_auto_hi << 6);
154 cx24113_writereg(state, 0x11, r);
155
156 if (state->rev == REV_CX24113) {
157 r = cx24113_readreg(state, 0x20) & 0xec;
158 r |= state->lna_gain;
159 r |= state->rfvga_bias_ctrl << 4;
160 cx24113_writereg(state, 0x20, r);
161 }
162
163 r = cx24113_readreg(state, 0x12) & 0x03;
164 r |= state->acp_on << 2;
165 r |= state->bs_delay << 4;
166 cx24113_writereg(state, 0x12, r);
167
168 r = cx24113_readreg(state, 0x18) & 0x40;
169 r |= state->vco_shift;
170 if (state->vco_band == VCOBANDSEL_6)
171 r |= (1 << 7);
172 else
173 r |= (state->vco_band << 1);
174 cx24113_writereg(state, 0x18, r);
175
176 r = cx24113_readreg(state, 0x14) & 0x20;
177 r |= (state->vco_mode << 6) | ((state->bs_freqcnt >> 8) & 0x1f);
178 cx24113_writereg(state, 0x14, r);
179 cx24113_writereg(state, 0x15, (state->bs_freqcnt & 0xff));
180
181 cx24113_writereg(state, 0x16, (state->bs_rdiv >> 4) & 0xff);
182 r = (cx24113_readreg(state, 0x17) & 0x0f) |
183 ((state->bs_rdiv & 0x0f) << 4);
184 cx24113_writereg(state, 0x17, r);
185}
186
187#define VGA_0 0x00
188#define VGA_1 0x04
189#define VGA_2 0x02
190#define VGA_3 0x06
191#define VGA_4 0x01
192#define VGA_5 0x05
193#define VGA_6 0x03
194#define VGA_7 0x07
195
196#define RFVGA_0 0x00
197#define RFVGA_1 0x01
198#define RFVGA_2 0x02
199#define RFVGA_3 0x03
200
201static int cx24113_set_gain_settings(struct cx24113_state *state,
202 s16 power_estimation)
203{
204 u8 ampout = cx24113_readreg(state, 0x1d) & 0xf0,
205 vga = cx24113_readreg(state, 0x1f) & 0x3f,
206 rfvga = cx24113_readreg(state, 0x20) & 0xf3;
207 u8 gain_level = power_estimation >= state->tuner_gain_thres;
208
209 dprintk("power estimation: %d, thres: %d, gain_level: %d/%d\n",
210 power_estimation, state->tuner_gain_thres,
211 state->gain_level, gain_level);
212
213 if (gain_level == state->gain_level)
214 return 0; /* nothing to be done */
215
216 ampout |= 0xf;
217
218 if (gain_level) {
219 rfvga |= RFVGA_0 << 2;
220 vga |= (VGA_7 << 3) | VGA_7;
221 } else {
222 rfvga |= RFVGA_2 << 2;
223 vga |= (VGA_6 << 3) | VGA_2;
224 }
225 state->gain_level = gain_level;
226
227 cx24113_writereg(state, 0x1d, ampout);
228 cx24113_writereg(state, 0x1f, vga);
229 cx24113_writereg(state, 0x20, rfvga);
230
231 return 1; /* did something */
232}
233
234static int cx24113_set_Fref(struct cx24113_state *state, u8 high)
235{
236 u8 xtal = cx24113_readreg(state, 0x02);
237 if (state->rev == 0x43 && state->vcodiv == VCODIV4)
238 high = 1;
239
240 xtal &= ~0x2;
241 if (high)
242 xtal |= high << 1;
243 return cx24113_writereg(state, 0x02, xtal);
244}
245
246static int cx24113_enable(struct cx24113_state *state, u8 enable)
247{
248 u8 r21 = (cx24113_readreg(state, 0x21) & 0xc0) | enable;
249 if (state->rev == REV_CX24113)
250 r21 |= (1 << 1);
251 return cx24113_writereg(state, 0x21, r21);
252}
253
254static int cx24113_set_bandwidth(struct cx24113_state *state, u32 bandwidth_khz)
255{
256 u8 r;
257
258 if (bandwidth_khz <= 19000)
259 r = 0x03 << 6;
260 else if (bandwidth_khz <= 25000)
261 r = 0x02 << 6;
262 else
263 r = 0x01 << 6;
264
265 dprintk("bandwidth to be set: %d\n", bandwidth_khz);
266 bandwidth_khz *= 10;
267 bandwidth_khz -= 10000;
268 bandwidth_khz /= 1000;
269 bandwidth_khz += 5;
270 bandwidth_khz /= 10;
271
272 dprintk("bandwidth: %d %d\n", r >> 6, bandwidth_khz);
273
274 r |= bandwidth_khz & 0x3f;
275
276 return cx24113_writereg(state, 0x1e, r);
277}
278
279static int cx24113_set_clk_inversion(struct cx24113_state *state, u8 on)
280{
281 u8 r = (cx24113_readreg(state, 0x10) & 0x7f) | ((on & 0x1) << 7);
282 return cx24113_writereg(state, 0x10, r);
283}
284
285static int cx24113_get_status(struct dvb_frontend *fe, u32 *status)
286{
287 struct cx24113_state *state = fe->tuner_priv;
288 u8 r = (cx24113_readreg(state, 0x10) & 0x02) >> 1;
289 if (r)
290 *status |= TUNER_STATUS_LOCKED;
291 dprintk("PLL locked: %d\n", r);
292 return 0;
293}
294
295static u8 cx24113_set_ref_div(struct cx24113_state *state, u8 refdiv)
296{
297 if (state->rev == 0x43 && state->vcodiv == VCODIV4)
298 refdiv = 2;
299 return state->refdiv = refdiv;
300}
301
302static void cx24113_calc_pll_nf(struct cx24113_state *state, u16 *n, s32 *f)
303{
304 s32 N;
305 s64 F;
306 u8 R, r;
307 u8 vcodiv;
308 u8 factor;
309 s32 freq_hz = state->frequency * 1000;
310
311 if (state->config->xtal_khz < 20000)
312 factor = 1;
313 else
314 factor = 2;
315
316 if (state->rev == REV_CX24113) {
317 if (state->frequency >= 1100000)
318 vcodiv = VCODIV2;
319 else
320 vcodiv = VCODIV4;
321 } else {
322 if (state->frequency >= 1165000)
323 vcodiv = VCODIV2;
324 else
325 vcodiv = VCODIV4;
326 }
327 state->vcodiv = vcodiv;
328
329 dprintk("calculating N/F for %dHz with vcodiv %d\n", freq_hz, vcodiv);
330 R = 0;
331 do {
332 R = cx24113_set_ref_div(state, R + 1);
333
334 /* calculate tuner PLL settings: */
335 N = (freq_hz / 100 * vcodiv) * R;
336 N /= (state->config->xtal_khz) * factor * 2;
337 N += 5; /* For round up. */
338 N /= 10;
339 N -= 32;
340 } while (N < 6 && R < 3);
341
342 if (N < 6) {
343 err("strange frequency: N < 6\n");
344 return;
345 }
346 F = freq_hz;
347 F *= (u64) (R * vcodiv * 262144);
348 dprintk("1 N: %d, F: %lld, R: %d\n", N, (long long)F, R);
349 do_div(F, state->config->xtal_khz*1000 * factor * 2);
350 dprintk("2 N: %d, F: %lld, R: %d\n", N, (long long)F, R);
351 F -= (N + 32) * 262144;
352
353 dprintk("3 N: %d, F: %lld, R: %d\n", N, (long long)F, R);
354
355 if (state->Fwindow_enabled) {
356 if (F > (262144 / 2 - 1638))
357 F = 262144 / 2 - 1638;
358 if (F < (-262144 / 2 + 1638))
359 F = -262144 / 2 + 1638;
360 if ((F < 3277 && F > 0) || (F > -3277 && F < 0)) {
361 F = 0;
362 r = cx24113_readreg(state, 0x10);
363 cx24113_writereg(state, 0x10, r | (1 << 6));
364 }
365 }
366 dprintk("4 N: %d, F: %lld, R: %d\n", N, (long long)F, R);
367
368 *n = (u16) N;
369 *f = (s32) F;
370}
371
372
373static void cx24113_set_nfr(struct cx24113_state *state, u16 n, s32 f, u8 r)
374{
375 u8 reg;
376 cx24113_writereg(state, 0x19, (n >> 1) & 0xff);
377
378 reg = ((n & 0x1) << 7) | ((f >> 11) & 0x7f);
379 cx24113_writereg(state, 0x1a, reg);
380
381 cx24113_writereg(state, 0x1b, (f >> 3) & 0xff);
382
383 reg = cx24113_readreg(state, 0x1c) & 0x1f;
384 cx24113_writereg(state, 0x1c, reg | ((f & 0x7) << 5));
385
386 cx24113_set_Fref(state, r - 1);
387}
388
389static int cx24113_set_frequency(struct cx24113_state *state, u32 frequency)
390{
391 u8 r = 1; /* or 2 */
392 u16 n = 6;
393 s32 f = 0;
394
395 r = cx24113_readreg(state, 0x14);
396 cx24113_writereg(state, 0x14, r & 0x3f);
397
398 r = cx24113_readreg(state, 0x10);
399 cx24113_writereg(state, 0x10, r & 0xbf);
400
401 state->frequency = frequency;
402
403 dprintk("tuning to frequency: %d\n", frequency);
404
405 cx24113_calc_pll_nf(state, &n, &f);
406 cx24113_set_nfr(state, n, f, state->refdiv);
407
408 r = cx24113_readreg(state, 0x18) & 0xbf;
409 if (state->vcodiv != VCODIV2)
410 r |= 1 << 6;
411 cx24113_writereg(state, 0x18, r);
412
413 /* The need for this sleep is not clear. But helps in some cases */
414 msleep(5);
415
416 r = cx24113_readreg(state, 0x1c) & 0xef;
417 cx24113_writereg(state, 0x1c, r | (1 << 4));
418 return 0;
419}
420
421static int cx24113_init(struct dvb_frontend *fe)
422{
423 struct cx24113_state *state = fe->tuner_priv;
424 int ret;
425
426 state->tuner_gain_thres = -50;
427 state->gain_level = 255; /* to force a gain-setting initialization */
428 state->icp_mode = 0;
429
430 if (state->config->xtal_khz < 11000) {
431 state->icp_auto_hi = ICP_LEVEL4;
432 state->icp_auto_mhi = ICP_LEVEL4;
433 state->icp_auto_mlow = ICP_LEVEL3;
434 state->icp_auto_low = ICP_LEVEL3;
435 } else {
436 state->icp_auto_hi = ICP_LEVEL4;
437 state->icp_auto_mhi = ICP_LEVEL4;
438 state->icp_auto_mlow = ICP_LEVEL3;
439 state->icp_auto_low = ICP_LEVEL2;
440 }
441
442 state->icp_dig = ICP_LEVEL3;
443 state->icp_man = ICP_LEVEL1;
444 state->acp_on = 1;
445 state->vco_mode = 0;
446 state->vco_shift = 0;
447 state->vco_band = VCOBANDSEL_1;
448 state->bs_delay = 8;
449 state->bs_freqcnt = 0x0fff;
450 state->bs_rdiv = 0x0fff;
451 state->prescaler_mode = 0;
452 state->lna_gain = LNA_MAX_GAIN;
453 state->rfvga_bias_ctrl = 1;
454 state->Fwindow_enabled = 1;
455
456 cx24113_set_Fref(state, 0);
457 cx24113_enable(state, 0x3d);
458 cx24113_set_parameters(state);
459
460 cx24113_set_gain_settings(state, -30);
461
462 cx24113_set_bandwidth(state, 18025);
463 cx24113_set_clk_inversion(state, 1);
464
465 if (state->config->xtal_khz >= 40000)
466 ret = cx24113_writereg(state, 0x02,
467 (cx24113_readreg(state, 0x02) & 0xfb) | (1 << 2));
468 else
469 ret = cx24113_writereg(state, 0x02,
470 (cx24113_readreg(state, 0x02) & 0xfb) | (0 << 2));
471
472 return ret;
473}
474
475static int cx24113_set_params(struct dvb_frontend *fe,
476 struct dvb_frontend_parameters *p)
477{
478 struct cx24113_state *state = fe->tuner_priv;
479 /* for a ROLL-OFF factor of 0.35, 0.2: 600, 0.25: 625 */
480 u32 roll_off = 675;
481 u32 bw;
482
483 bw = ((p->u.qpsk.symbol_rate/100) * roll_off) / 1000;
484 bw += (10000000/100) + 5;
485 bw /= 10;
486 bw += 1000;
487 cx24113_set_bandwidth(state, bw);
488
489 cx24113_set_frequency(state, p->frequency);
490 msleep(5);
491 return cx24113_get_status(fe, &bw);
492}
493
494static s8 cx24113_agc_table[2][10] = {
495 {-54, -41, -35, -30, -25, -21, -16, -10, -6, -2},
496 {-39, -35, -30, -25, -19, -15, -11, -5, 1, 9},
497};
498
499void cx24113_agc_callback(struct dvb_frontend *fe)
500{
501 struct cx24113_state *state = fe->tuner_priv;
502 s16 s, i;
503 if (!fe->ops.read_signal_strength)
504 return;
505
506 do {
507 /* this only works with the current CX24123 implementation */
508 fe->ops.read_signal_strength(fe, (u16 *) &s);
509 s >>= 8;
510 dprintk("signal strength: %d\n", s);
511 for (i = 0; i < sizeof(cx24113_agc_table[0]); i++)
512 if (cx24113_agc_table[state->gain_level][i] > s)
513 break;
514 s = -25 - i*5;
515 } while (cx24113_set_gain_settings(state, s));
516}
517EXPORT_SYMBOL(cx24113_agc_callback);
518
519static int cx24113_get_frequency(struct dvb_frontend *fe, u32 *frequency)
520{
521 struct cx24113_state *state = fe->tuner_priv;
522 *frequency = state->frequency;
523 return 0;
524}
525
526static int cx24113_release(struct dvb_frontend *fe)
527{
528 struct cx24113_state *state = fe->tuner_priv;
529 dprintk("\n");
530 fe->tuner_priv = NULL;
531 kfree(state);
532 return 0;
533}
534
535static const struct dvb_tuner_ops cx24113_tuner_ops = {
536 .info = {
537 .name = "Conexant CX24113",
538 .frequency_min = 950000,
539 .frequency_max = 2150000,
540 .frequency_step = 125,
541 },
542
543 .release = cx24113_release,
544
545 .init = cx24113_init,
546 .sleep = NULL,
547
548 .set_params = cx24113_set_params,
549 .get_frequency = cx24113_get_frequency,
550 .get_bandwidth = NULL,
551 .get_status = cx24113_get_status,
552};
553
554struct dvb_frontend *cx24113_attach(struct dvb_frontend *fe,
555 const struct cx24113_config *config, struct i2c_adapter *i2c)
556{
557 /* allocate memory for the internal state */
558 struct cx24113_state *state =
559 kzalloc(sizeof(struct cx24113_state), GFP_KERNEL);
560 int rc;
561 if (state == NULL) {
562 err("Unable to kmalloc\n");
563 goto error;
564 }
565
566 /* setup the state */
567 state->config = config;
568 state->i2c = i2c;
569
570 info("trying to detect myself\n");
571
572 /* making a dummy read, because of some expected troubles
573 * after power on */
574 cx24113_readreg(state, 0x00);
575
576 rc = cx24113_readreg(state, 0x00);
577 if (rc < 0) {
578 info("CX24113 not found.\n");
579 goto error;
580 }
581 state->rev = rc;
582
583 switch (rc) {
584 case 0x43:
585 info("detected CX24113 variant\n");
586 break;
587 case REV_CX24113:
588 info("sucessfully detected\n");
589 break;
590 default:
591 err("unsupported device id: %x\n", state->rev);
592 goto error;
593 }
594 state->ver = cx24113_readreg(state, 0x01);
595 info("version: %x\n", state->ver);
596
597 /* create dvb_frontend */
598 memcpy(&fe->ops.tuner_ops, &cx24113_tuner_ops,
599 sizeof(struct dvb_tuner_ops));
600 fe->tuner_priv = state;
601 return fe;
602
603error:
604 kfree(state);
605
606 return NULL;
607}
608EXPORT_SYMBOL(cx24113_attach);
609
610module_param(debug, int, 0644);
611MODULE_PARM_DESC(debug, "Activates frontend debugging (default:0)");
612
613MODULE_AUTHOR("Patrick Boettcher <pb@linuxtv.org>");
614MODULE_DESCRIPTION("DVB Frontend module for Conexant CX24113/CX24128hardware");
615MODULE_LICENSE("GPL");
616
diff --git a/drivers/media/dvb/frontends/cx24113.h b/drivers/media/dvb/frontends/cx24113.h
index 5ab3dd11076b..5de0f7ffd8d2 100644
--- a/drivers/media/dvb/frontends/cx24113.h
+++ b/drivers/media/dvb/frontends/cx24113.h
@@ -16,7 +16,7 @@
16 * 16 *
17 * You should have received a copy of the GNU General Public License 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 18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.= 19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */ 20 */
21 21
22#ifndef CX24113_H 22#ifndef CX24113_H
@@ -30,9 +30,13 @@ struct cx24113_config {
30 u32 xtal_khz; 30 u32 xtal_khz;
31}; 31};
32 32
33/* TODO: #if defined(CONFIG_DVB_TUNER_CX24113) || \ 33#if defined(CONFIG_DVB_TUNER_CX24113) || \
34 * (defined(CONFIG_DVB_TUNER_CX24113_MODULE) && defined(MODULE)) */ 34 (defined(CONFIG_DVB_TUNER_CX24113_MODULE) && defined(MODULE))
35extern struct dvb_frontend *cx24113_attach(struct dvb_frontend *,
36 const struct cx24113_config *config, struct i2c_adapter *i2c);
35 37
38extern void cx24113_agc_callback(struct dvb_frontend *fe);
39#else
36static inline struct dvb_frontend *cx24113_attach(struct dvb_frontend *fe, 40static inline struct dvb_frontend *cx24113_attach(struct dvb_frontend *fe,
37 const struct cx24113_config *config, struct i2c_adapter *i2c) 41 const struct cx24113_config *config, struct i2c_adapter *i2c)
38{ 42{
@@ -44,5 +48,6 @@ static inline void cx24113_agc_callback(struct dvb_frontend *fe)
44{ 48{
45 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); 49 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
46} 50}
51#endif
47 52
48#endif /* CX24113_H */ 53#endif /* CX24113_H */
diff --git a/drivers/media/dvb/frontends/cx24116.c b/drivers/media/dvb/frontends/cx24116.c
index b144b308a4dd..9b6c89e93f16 100644
--- a/drivers/media/dvb/frontends/cx24116.c
+++ b/drivers/media/dvb/frontends/cx24116.c
@@ -106,7 +106,7 @@ MODULE_PARM_DESC(debug, "Activates frontend debugging (default:0)");
106#define CX24116_HAS_SYNCLOCK (0x08) 106#define CX24116_HAS_SYNCLOCK (0x08)
107#define CX24116_HAS_UNKNOWN1 (0x10) 107#define CX24116_HAS_UNKNOWN1 (0x10)
108#define CX24116_HAS_UNKNOWN2 (0x20) 108#define CX24116_HAS_UNKNOWN2 (0x20)
109#define CX24116_STATUS_MASK (0x3f) 109#define CX24116_STATUS_MASK (0x0f)
110#define CX24116_SIGNAL_MASK (0xc0) 110#define CX24116_SIGNAL_MASK (0xc0)
111 111
112#define CX24116_DISEQC_TONEOFF (0) /* toneburst never sent */ 112#define CX24116_DISEQC_TONEOFF (0) /* toneburst never sent */
@@ -160,6 +160,7 @@ struct cx24116_tuning {
160 fe_spectral_inversion_t inversion; 160 fe_spectral_inversion_t inversion;
161 fe_code_rate_t fec; 161 fe_code_rate_t fec;
162 162
163 fe_delivery_system_t delsys;
163 fe_modulation_t modulation; 164 fe_modulation_t modulation;
164 fe_pilot_t pilot; 165 fe_pilot_t pilot;
165 fe_rolloff_t rolloff; 166 fe_rolloff_t rolloff;
@@ -411,14 +412,15 @@ struct cx24116_modfec {
411}; 412};
412 413
413static int cx24116_lookup_fecmod(struct cx24116_state *state, 414static int cx24116_lookup_fecmod(struct cx24116_state *state,
414 fe_modulation_t m, fe_code_rate_t f) 415 fe_delivery_system_t d, fe_modulation_t m, fe_code_rate_t f)
415{ 416{
416 int i, ret = -EOPNOTSUPP; 417 int i, ret = -EOPNOTSUPP;
417 418
418 dprintk("%s(0x%02x,0x%02x)\n", __func__, m, f); 419 dprintk("%s(0x%02x,0x%02x)\n", __func__, m, f);
419 420
420 for (i = 0; i < ARRAY_SIZE(CX24116_MODFEC_MODES); i++) { 421 for (i = 0; i < ARRAY_SIZE(CX24116_MODFEC_MODES); i++) {
421 if ((m == CX24116_MODFEC_MODES[i].modulation) && 422 if ((d == CX24116_MODFEC_MODES[i].delivery_system) &&
423 (m == CX24116_MODFEC_MODES[i].modulation) &&
422 (f == CX24116_MODFEC_MODES[i].fec)) { 424 (f == CX24116_MODFEC_MODES[i].fec)) {
423 ret = i; 425 ret = i;
424 break; 426 break;
@@ -429,13 +431,13 @@ static int cx24116_lookup_fecmod(struct cx24116_state *state,
429} 431}
430 432
431static int cx24116_set_fec(struct cx24116_state *state, 433static int cx24116_set_fec(struct cx24116_state *state,
432 fe_modulation_t mod, fe_code_rate_t fec) 434 fe_delivery_system_t delsys, fe_modulation_t mod, fe_code_rate_t fec)
433{ 435{
434 int ret = 0; 436 int ret = 0;
435 437
436 dprintk("%s(0x%02x,0x%02x)\n", __func__, mod, fec); 438 dprintk("%s(0x%02x,0x%02x)\n", __func__, mod, fec);
437 439
438 ret = cx24116_lookup_fecmod(state, mod, fec); 440 ret = cx24116_lookup_fecmod(state, delsys, mod, fec);
439 441
440 if (ret < 0) 442 if (ret < 0)
441 return ret; 443 return ret;
@@ -679,7 +681,8 @@ static int cx24116_read_status(struct dvb_frontend *fe, fe_status_t *status)
679{ 681{
680 struct cx24116_state *state = fe->demodulator_priv; 682 struct cx24116_state *state = fe->demodulator_priv;
681 683
682 int lock = cx24116_readreg(state, CX24116_REG_SSTATUS); 684 int lock = cx24116_readreg(state, CX24116_REG_SSTATUS) &
685 CX24116_STATUS_MASK;
683 686
684 dprintk("%s: status = 0x%02x\n", __func__, lock); 687 dprintk("%s: status = 0x%02x\n", __func__, lock);
685 688
@@ -1205,7 +1208,7 @@ static int cx24116_set_frontend(struct dvb_frontend *fe,
1205 struct dtv_frontend_properties *c = &fe->dtv_property_cache; 1208 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
1206 struct cx24116_cmd cmd; 1209 struct cx24116_cmd cmd;
1207 fe_status_t tunerstat; 1210 fe_status_t tunerstat;
1208 int i, status, ret, retune; 1211 int i, status, ret, retune = 1;
1209 1212
1210 dprintk("%s()\n", __func__); 1213 dprintk("%s()\n", __func__);
1211 1214
@@ -1222,7 +1225,6 @@ static int cx24116_set_frontend(struct dvb_frontend *fe,
1222 1225
1223 /* Pilot doesn't exist in DVB-S, turn bit off */ 1226 /* Pilot doesn't exist in DVB-S, turn bit off */
1224 state->dnxt.pilot_val = CX24116_PILOT_OFF; 1227 state->dnxt.pilot_val = CX24116_PILOT_OFF;
1225 retune = 1;
1226 1228
1227 /* DVB-S only supports 0.35 */ 1229 /* DVB-S only supports 0.35 */
1228 if (c->rolloff != ROLLOFF_35) { 1230 if (c->rolloff != ROLLOFF_35) {
@@ -1250,7 +1252,7 @@ static int cx24116_set_frontend(struct dvb_frontend *fe,
1250 case PILOT_AUTO: /* Not supported but emulated */ 1252 case PILOT_AUTO: /* Not supported but emulated */
1251 state->dnxt.pilot_val = (c->modulation == QPSK) 1253 state->dnxt.pilot_val = (c->modulation == QPSK)
1252 ? CX24116_PILOT_OFF : CX24116_PILOT_ON; 1254 ? CX24116_PILOT_OFF : CX24116_PILOT_ON;
1253 retune = 2; 1255 retune++;
1254 break; 1256 break;
1255 case PILOT_OFF: 1257 case PILOT_OFF:
1256 state->dnxt.pilot_val = CX24116_PILOT_OFF; 1258 state->dnxt.pilot_val = CX24116_PILOT_OFF;
@@ -1287,6 +1289,7 @@ static int cx24116_set_frontend(struct dvb_frontend *fe,
1287 __func__, c->delivery_system); 1289 __func__, c->delivery_system);
1288 return -EOPNOTSUPP; 1290 return -EOPNOTSUPP;
1289 } 1291 }
1292 state->dnxt.delsys = c->delivery_system;
1290 state->dnxt.modulation = c->modulation; 1293 state->dnxt.modulation = c->modulation;
1291 state->dnxt.frequency = c->frequency; 1294 state->dnxt.frequency = c->frequency;
1292 state->dnxt.pilot = c->pilot; 1295 state->dnxt.pilot = c->pilot;
@@ -1297,7 +1300,7 @@ static int cx24116_set_frontend(struct dvb_frontend *fe,
1297 return ret; 1300 return ret;
1298 1301
1299 /* FEC_NONE/AUTO for DVB-S2 is not supported and detected here */ 1302 /* FEC_NONE/AUTO for DVB-S2 is not supported and detected here */
1300 ret = cx24116_set_fec(state, c->modulation, c->fec_inner); 1303 ret = cx24116_set_fec(state, c->delivery_system, c->modulation, c->fec_inner);
1301 if (ret != 0) 1304 if (ret != 0)
1302 return ret; 1305 return ret;
1303 1306
@@ -1308,6 +1311,7 @@ static int cx24116_set_frontend(struct dvb_frontend *fe,
1308 /* discard the 'current' tuning parameters and prepare to tune */ 1311 /* discard the 'current' tuning parameters and prepare to tune */
1309 cx24116_clone_params(fe); 1312 cx24116_clone_params(fe);
1310 1313
1314 dprintk("%s: delsys = %d\n", __func__, state->dcur.delsys);
1311 dprintk("%s: modulation = %d\n", __func__, state->dcur.modulation); 1315 dprintk("%s: modulation = %d\n", __func__, state->dcur.modulation);
1312 dprintk("%s: frequency = %d\n", __func__, state->dcur.frequency); 1316 dprintk("%s: frequency = %d\n", __func__, state->dcur.frequency);
1313 dprintk("%s: pilot = %d (val = 0x%02x)\n", __func__, 1317 dprintk("%s: pilot = %d (val = 0x%02x)\n", __func__,
@@ -1427,6 +1431,23 @@ tuned: /* Set/Reset B/W */
1427 return ret; 1431 return ret;
1428} 1432}
1429 1433
1434static int cx24116_tune(struct dvb_frontend *fe, struct dvb_frontend_parameters *params,
1435 unsigned int mode_flags, unsigned int *delay, fe_status_t *status)
1436{
1437 *delay = HZ / 5;
1438 if (params) {
1439 int ret = cx24116_set_frontend(fe, params);
1440 if (ret)
1441 return ret;
1442 }
1443 return cx24116_read_status(fe, status);
1444}
1445
1446static int cx24116_get_algo(struct dvb_frontend *fe)
1447{
1448 return DVBFE_ALGO_HW;
1449}
1450
1430static struct dvb_frontend_ops cx24116_ops = { 1451static struct dvb_frontend_ops cx24116_ops = {
1431 1452
1432 .info = { 1453 .info = {
@@ -1458,6 +1479,8 @@ static struct dvb_frontend_ops cx24116_ops = {
1458 .set_voltage = cx24116_set_voltage, 1479 .set_voltage = cx24116_set_voltage,
1459 .diseqc_send_master_cmd = cx24116_send_diseqc_msg, 1480 .diseqc_send_master_cmd = cx24116_send_diseqc_msg,
1460 .diseqc_send_burst = cx24116_diseqc_send_burst, 1481 .diseqc_send_burst = cx24116_diseqc_send_burst,
1482 .get_frontend_algo = cx24116_get_algo,
1483 .tune = cx24116_tune,
1461 1484
1462 .set_property = cx24116_set_property, 1485 .set_property = cx24116_set_property,
1463 .get_property = cx24116_get_property, 1486 .get_property = cx24116_get_property,
diff --git a/drivers/media/dvb/frontends/dib7000p.h b/drivers/media/dvb/frontends/dib7000p.h
index 3e8126857127..aab8112e2db2 100644
--- a/drivers/media/dvb/frontends/dib7000p.h
+++ b/drivers/media/dvb/frontends/dib7000p.h
@@ -66,7 +66,8 @@ struct i2c_adapter *dib7000p_get_i2c_master(struct dvb_frontend *fe,
66 return NULL; 66 return NULL;
67} 67}
68 68
69extern int dib7000p_i2c_enumeration(struct i2c_adapter *i2c, 69static inline
70int dib7000p_i2c_enumeration(struct i2c_adapter *i2c,
70 int no_of_demods, u8 default_addr, 71 int no_of_demods, u8 default_addr,
71 struct dib7000p_config cfg[]) 72 struct dib7000p_config cfg[])
72{ 73{
@@ -74,13 +75,15 @@ extern int dib7000p_i2c_enumeration(struct i2c_adapter *i2c,
74 return -ENODEV; 75 return -ENODEV;
75} 76}
76 77
77extern int dib7000p_set_gpio(struct dvb_frontend *fe, u8 num, u8 dir, u8 val) 78static inline
79int dib7000p_set_gpio(struct dvb_frontend *fe, u8 num, u8 dir, u8 val)
78{ 80{
79 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); 81 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
80 return -ENODEV; 82 return -ENODEV;
81} 83}
82 84
83extern int dib7000p_set_wbd_ref(struct dvb_frontend *fe, u16 value) 85static inline
86int dib7000p_set_wbd_ref(struct dvb_frontend *fe, u16 value)
84{ 87{
85 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); 88 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
86 return -ENODEV; 89 return -ENODEV;
diff --git a/drivers/media/dvb/frontends/drx397xD.c b/drivers/media/dvb/frontends/drx397xD.c
index b9ca5c8d2dd9..ec4e08dbc699 100644
--- a/drivers/media/dvb/frontends/drx397xD.c
+++ b/drivers/media/dvb/frontends/drx397xD.c
@@ -39,7 +39,7 @@ static const char mod_name[] = "drx397xD";
39#define F_SET_0D4h 2 39#define F_SET_0D4h 2
40 40
41enum fw_ix { 41enum fw_ix {
42#define _FW_ENTRY(a, b) b 42#define _FW_ENTRY(a, b, c) b
43#include "drx397xD_fw.h" 43#include "drx397xD_fw.h"
44}; 44};
45 45
@@ -72,11 +72,11 @@ static struct {
72 int refcnt; 72 int refcnt;
73 const u8 *data[ARRAY_SIZE(blob_name)]; 73 const u8 *data[ARRAY_SIZE(blob_name)];
74} fw[] = { 74} fw[] = {
75#define _FW_ENTRY(a, b) { \ 75#define _FW_ENTRY(a, b, c) { \
76 .name = a, \ 76 .name = a, \
77 .file = 0, \ 77 .file = 0, \
78 .lock = RW_LOCK_UNLOCKED, \ 78 .lock = __RW_LOCK_UNLOCKED(fw[c].lock), \
79 .refcnt = 0, \ 79 .refcnt = 0, \
80 .data = { } } 80 .data = { } }
81#include "drx397xD_fw.h" 81#include "drx397xD_fw.h"
82}; 82};
diff --git a/drivers/media/dvb/frontends/drx397xD_fw.h b/drivers/media/dvb/frontends/drx397xD_fw.h
index 01de02a81cd4..c8b44c1e807f 100644
--- a/drivers/media/dvb/frontends/drx397xD_fw.h
+++ b/drivers/media/dvb/frontends/drx397xD_fw.h
@@ -18,8 +18,8 @@
18 */ 18 */
19 19
20#ifdef _FW_ENTRY 20#ifdef _FW_ENTRY
21 _FW_ENTRY("drx397xD.A2.fw", DRXD_FW_A2 = 0 ), 21 _FW_ENTRY("drx397xD.A2.fw", DRXD_FW_A2 = 0, DRXD_FW_A2 ),
22 _FW_ENTRY("drx397xD.B1.fw", DRXD_FW_B1 ), 22 _FW_ENTRY("drx397xD.B1.fw", DRXD_FW_B1, DRXD_FW_B1 ),
23#undef _FW_ENTRY 23#undef _FW_ENTRY
24#endif /* _FW_ENTRY */ 24#endif /* _FW_ENTRY */
25 25
diff --git a/drivers/media/dvb/frontends/dvb-pll.c b/drivers/media/dvb/frontends/dvb-pll.c
index ea058153ebfa..9f6349964cda 100644
--- a/drivers/media/dvb/frontends/dvb-pll.c
+++ b/drivers/media/dvb/frontends/dvb-pll.c
@@ -311,7 +311,7 @@ static struct dvb_pll_desc dvb_pll_philips_sd1878_tda8261 = {
311 .count = 4, 311 .count = 4,
312 .entries = { 312 .entries = {
313 { 1250000, 500, 0xc4, 0x00}, 313 { 1250000, 500, 0xc4, 0x00},
314 { 1550000, 500, 0xc4, 0x40}, 314 { 1450000, 500, 0xc4, 0x40},
315 { 2050000, 500, 0xc4, 0x80}, 315 { 2050000, 500, 0xc4, 0x80},
316 { 2150000, 500, 0xc4, 0xc0}, 316 { 2150000, 500, 0xc4, 0xc0},
317 }, 317 },
diff --git a/drivers/media/dvb/frontends/lgdt3304.c b/drivers/media/dvb/frontends/lgdt3304.c
new file mode 100644
index 000000000000..469ace5692c6
--- /dev/null
+++ b/drivers/media/dvb/frontends/lgdt3304.c
@@ -0,0 +1,378 @@
1/*
2 * Driver for LG ATSC lgdt3304 driver
3 *
4 * Copyright (C) 2008 Markus Rechberger <mrechberger@sundtek.de>
5 *
6 */
7
8#include <linux/kernel.h>
9#include <linux/module.h>
10#include <linux/delay.h>
11#include "dvb_frontend.h"
12#include "lgdt3304.h"
13
14static unsigned int debug = 0;
15module_param(debug, int, 0644);
16MODULE_PARM_DESC(debug,"lgdt3304 debugging (default off)");
17
18#define dprintk(fmt, args...) if (debug) do {\
19 printk("lgdt3304 debug: " fmt, ##args); } while (0)
20
21struct lgdt3304_state
22{
23 struct dvb_frontend frontend;
24 fe_modulation_t current_modulation;
25 __u32 snr;
26 __u32 current_frequency;
27 __u8 addr;
28 struct i2c_adapter *i2c;
29};
30
31static int i2c_write_demod_bytes (struct dvb_frontend *fe, __u8 *buf, int len)
32{
33 struct lgdt3304_state *state = fe->demodulator_priv;
34 struct i2c_msg i2cmsgs = {
35 .addr = state->addr,
36 .flags = 0,
37 .len = 3,
38 .buf = buf
39 };
40 int i;
41 int err;
42
43 for (i=0; i<len-1; i+=3){
44 if((err = i2c_transfer(state->i2c, &i2cmsgs, 1))<0) {
45 printk("%s i2c_transfer error %d\n", __FUNCTION__, err);
46 if (err < 0)
47 return err;
48 else
49 return -EREMOTEIO;
50 }
51 i2cmsgs.buf += 3;
52 }
53 return 0;
54}
55
56static int lgdt3304_i2c_read_reg(struct dvb_frontend *fe, unsigned int reg)
57{
58 struct lgdt3304_state *state = fe->demodulator_priv;
59 struct i2c_msg i2cmsgs[2];
60 int ret;
61 __u8 buf;
62
63 __u8 regbuf[2] = { reg>>8, reg&0xff };
64
65 i2cmsgs[0].addr = state->addr;
66 i2cmsgs[0].flags = 0;
67 i2cmsgs[0].len = 2;
68 i2cmsgs[0].buf = regbuf;
69
70 i2cmsgs[1].addr = state->addr;
71 i2cmsgs[1].flags = I2C_M_RD;
72 i2cmsgs[1].len = 1;
73 i2cmsgs[1].buf = &buf;
74
75 if((ret = i2c_transfer(state->i2c, i2cmsgs, 2))<0) {
76 printk("%s i2c_transfer error %d\n", __FUNCTION__, ret);
77 return ret;
78 }
79
80 return buf;
81}
82
83static int lgdt3304_i2c_write_reg(struct dvb_frontend *fe, int reg, int val)
84{
85 struct lgdt3304_state *state = fe->demodulator_priv;
86 char buffer[3] = { reg>>8, reg&0xff, val };
87 int ret;
88
89 struct i2c_msg i2cmsgs = {
90 .addr = state->addr,
91 .flags = 0,
92 .len = 3,
93 .buf=buffer
94 };
95 ret = i2c_transfer(state->i2c, &i2cmsgs, 1);
96 if (ret != 1) {
97 printk("%s i2c_transfer error %d\n", __FUNCTION__, ret);
98 return ret;
99 }
100
101 return 0;
102}
103
104
105static int lgdt3304_soft_Reset(struct dvb_frontend *fe)
106{
107 lgdt3304_i2c_write_reg(fe, 0x0002, 0x9a);
108 lgdt3304_i2c_write_reg(fe, 0x0002, 0x9b);
109 mdelay(200);
110 return 0;
111}
112
113static int lgdt3304_set_parameters(struct dvb_frontend *fe, struct dvb_frontend_parameters *param) {
114 int err = 0;
115
116 static __u8 lgdt3304_vsb8_data[] = {
117 /* 16bit , 8bit */
118 /* regs , val */
119 0x00, 0x00, 0x02,
120 0x00, 0x00, 0x13,
121 0x00, 0x0d, 0x02,
122 0x00, 0x0e, 0x02,
123 0x00, 0x12, 0x32,
124 0x00, 0x13, 0xc4,
125 0x01, 0x12, 0x17,
126 0x01, 0x13, 0x15,
127 0x01, 0x14, 0x18,
128 0x01, 0x15, 0xff,
129 0x01, 0x16, 0x2c,
130 0x02, 0x14, 0x67,
131 0x02, 0x24, 0x8d,
132 0x04, 0x27, 0x12,
133 0x04, 0x28, 0x4f,
134 0x03, 0x08, 0x80,
135 0x03, 0x09, 0x00,
136 0x03, 0x0d, 0x00,
137 0x03, 0x0e, 0x1c,
138 0x03, 0x14, 0xe1,
139 0x05, 0x0e, 0x5b,
140 };
141
142 /* not yet tested .. */
143 static __u8 lgdt3304_qam64_data[] = {
144 /* 16bit , 8bit */
145 /* regs , val */
146 0x00, 0x00, 0x18,
147 0x00, 0x0d, 0x02,
148 //0x00, 0x0e, 0x02,
149 0x00, 0x12, 0x2a,
150 0x00, 0x13, 0x00,
151 0x03, 0x14, 0xe3,
152 0x03, 0x0e, 0x1c,
153 0x03, 0x08, 0x66,
154 0x03, 0x09, 0x66,
155 0x03, 0x0a, 0x08,
156 0x03, 0x0b, 0x9b,
157 0x05, 0x0e, 0x5b,
158 };
159
160
161 /* tested with KWorld a340 */
162 static __u8 lgdt3304_qam256_data[] = {
163 /* 16bit , 8bit */
164 /* regs , val */
165 0x00, 0x00, 0x01, //0x19,
166 0x00, 0x12, 0x2a,
167 0x00, 0x13, 0x80,
168 0x00, 0x0d, 0x02,
169 0x03, 0x14, 0xe3,
170
171 0x03, 0x0e, 0x1c,
172 0x03, 0x08, 0x66,
173 0x03, 0x09, 0x66,
174 0x03, 0x0a, 0x08,
175 0x03, 0x0b, 0x9b,
176
177 0x03, 0x0d, 0x14,
178 //0x05, 0x0e, 0x5b,
179 0x01, 0x06, 0x4a,
180 0x01, 0x07, 0x3d,
181 0x01, 0x08, 0x70,
182 0x01, 0x09, 0xa3,
183
184 0x05, 0x04, 0xfd,
185
186 0x00, 0x0d, 0x82,
187
188 0x05, 0x0e, 0x5b,
189
190 0x05, 0x0e, 0x5b,
191
192 0x00, 0x02, 0x9a,
193
194 0x00, 0x02, 0x9b,
195
196 0x00, 0x00, 0x01,
197 0x00, 0x12, 0x2a,
198 0x00, 0x13, 0x80,
199 0x00, 0x0d, 0x02,
200 0x03, 0x14, 0xe3,
201
202 0x03, 0x0e, 0x1c,
203 0x03, 0x08, 0x66,
204 0x03, 0x09, 0x66,
205 0x03, 0x0a, 0x08,
206 0x03, 0x0b, 0x9b,
207
208 0x03, 0x0d, 0x14,
209 0x01, 0x06, 0x4a,
210 0x01, 0x07, 0x3d,
211 0x01, 0x08, 0x70,
212 0x01, 0x09, 0xa3,
213
214 0x05, 0x04, 0xfd,
215
216 0x00, 0x0d, 0x82,
217
218 0x05, 0x0e, 0x5b,
219 };
220
221 struct lgdt3304_state *state = fe->demodulator_priv;
222 if (state->current_modulation != param->u.vsb.modulation) {
223 switch(param->u.vsb.modulation) {
224 case VSB_8:
225 err = i2c_write_demod_bytes(fe, lgdt3304_vsb8_data,
226 sizeof(lgdt3304_vsb8_data));
227 break;
228 case QAM_64:
229 err = i2c_write_demod_bytes(fe, lgdt3304_qam64_data,
230 sizeof(lgdt3304_qam64_data));
231 break;
232 case QAM_256:
233 err = i2c_write_demod_bytes(fe, lgdt3304_qam256_data,
234 sizeof(lgdt3304_qam256_data));
235 break;
236 default:
237 break;
238 }
239
240 if (err) {
241 printk("%s error setting modulation\n", __FUNCTION__);
242 } else {
243 state->current_modulation = param->u.vsb.modulation;
244 }
245 }
246 state->current_frequency = param->frequency;
247
248 lgdt3304_soft_Reset(fe);
249
250
251 if (fe->ops.tuner_ops.set_params)
252 fe->ops.tuner_ops.set_params(fe, param);
253
254 return 0;
255}
256
257static int lgdt3304_init(struct dvb_frontend *fe) {
258 return 0;
259}
260
261static int lgdt3304_sleep(struct dvb_frontend *fe) {
262 return 0;
263}
264
265
266static int lgdt3304_read_status(struct dvb_frontend *fe, fe_status_t *status)
267{
268 struct lgdt3304_state *state = fe->demodulator_priv;
269 int r011d;
270 int qam_lck;
271
272 *status = 0;
273 dprintk("lgdt read status\n");
274
275 r011d = lgdt3304_i2c_read_reg(fe, 0x011d);
276
277 dprintk("%02x\n", r011d);
278
279 switch(state->current_modulation) {
280 case VSB_8:
281 if (r011d & 0x80) {
282 dprintk("VSB Locked\n");
283 *status |= FE_HAS_CARRIER;
284 *status |= FE_HAS_LOCK;
285 *status |= FE_HAS_SYNC;
286 *status |= FE_HAS_SIGNAL;
287 }
288 break;
289 case QAM_64:
290 case QAM_256:
291 qam_lck = r011d & 0x7;
292 switch(qam_lck) {
293 case 0x0: dprintk("Unlock\n");
294 break;
295 case 0x4: dprintk("1st Lock in acquisition state\n");
296 break;
297 case 0x6: dprintk("2nd Lock in acquisition state\n");
298 break;
299 case 0x7: dprintk("Final Lock in good reception state\n");
300 *status |= FE_HAS_CARRIER;
301 *status |= FE_HAS_LOCK;
302 *status |= FE_HAS_SYNC;
303 *status |= FE_HAS_SIGNAL;
304 break;
305 }
306 break;
307 default:
308 printk("%s unhandled modulation\n", __FUNCTION__);
309 }
310
311
312 return 0;
313}
314
315static int lgdt3304_read_ber(struct dvb_frontend *fe, __u32 *ber)
316{
317 dprintk("read ber\n");
318 return 0;
319}
320
321static int lgdt3304_read_snr(struct dvb_frontend *fe, __u16 *snr)
322{
323 dprintk("read snr\n");
324 return 0;
325}
326
327static int lgdt3304_read_ucblocks(struct dvb_frontend *fe, __u32 *ucblocks)
328{
329 dprintk("read ucblocks\n");
330 return 0;
331}
332
333static void lgdt3304_release(struct dvb_frontend *fe)
334{
335 struct lgdt3304_state *state = (struct lgdt3304_state *)fe->demodulator_priv;
336 kfree(state);
337}
338
339static struct dvb_frontend_ops demod_lgdt3304={
340 .info = {
341 .name = "LG 3304",
342 .type = FE_ATSC,
343 .frequency_min = 54000000,
344 .frequency_max = 858000000,
345 .frequency_stepsize = 62500,
346 .symbol_rate_min = 5056941,
347 .symbol_rate_max = 10762000,
348 .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
349 },
350 .init = lgdt3304_init,
351 .sleep = lgdt3304_sleep,
352 .set_frontend = lgdt3304_set_parameters,
353 .read_snr = lgdt3304_read_snr,
354 .read_ber = lgdt3304_read_ber,
355 .read_status = lgdt3304_read_status,
356 .read_ucblocks = lgdt3304_read_ucblocks,
357 .release = lgdt3304_release,
358};
359
360struct dvb_frontend* lgdt3304_attach(const struct lgdt3304_config *config,
361 struct i2c_adapter *i2c)
362{
363
364 struct lgdt3304_state *state;
365 state = kzalloc(sizeof(struct lgdt3304_state), GFP_KERNEL);
366 memset(state, 0x0, sizeof(struct lgdt3304_state));
367 state->addr = config->i2c_address;
368 state->i2c = i2c;
369
370 memcpy(&state->frontend.ops, &demod_lgdt3304, sizeof(struct dvb_frontend_ops));
371 state->frontend.demodulator_priv = state;
372 return &state->frontend;
373}
374
375EXPORT_SYMBOL_GPL(lgdt3304_attach);
376MODULE_AUTHOR("Markus Rechberger <mrechberger@empiatech.com>");
377MODULE_DESCRIPTION("LGE LGDT3304 DVB-T demodulator driver");
378MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/lgdt3304.h b/drivers/media/dvb/frontends/lgdt3304.h
new file mode 100644
index 000000000000..fc409fe59acb
--- /dev/null
+++ b/drivers/media/dvb/frontends/lgdt3304.h
@@ -0,0 +1,45 @@
1/*
2 * Driver for DVB-T lgdt3304 demodulator
3 *
4 * Copyright (C) 2008 Markus Rechberger <mrechberger@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 LGDT3304_H
23#define LGDT3304_H
24
25#include <linux/dvb/frontend.h>
26
27struct lgdt3304_config
28{
29 /* demodulator's I2C address */
30 u8 i2c_address;
31};
32
33#if defined(CONFIG_DVB_LGDT3304) || (defined(CONFIG_DVB_LGDT3304_MODULE) && defined(MODULE))
34extern struct dvb_frontend* lgdt3304_attach(const struct lgdt3304_config *config,
35 struct i2c_adapter *i2c);
36#else
37static inline struct dvb_frontend* lgdt3304_attach(const struct lgdt3304_config *config,
38 struct i2c_adapter *i2c)
39{
40 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
41 return NULL;
42}
43#endif /* CONFIG_DVB_LGDT */
44
45#endif /* LGDT3304_H */
diff --git a/drivers/media/dvb/frontends/s5h1411.c b/drivers/media/dvb/frontends/s5h1411.c
index 40644aacffcb..66e2dd6d6fe4 100644
--- a/drivers/media/dvb/frontends/s5h1411.c
+++ b/drivers/media/dvb/frontends/s5h1411.c
@@ -874,6 +874,9 @@ struct dvb_frontend *s5h1411_attach(const struct s5h1411_config *config,
874 /* Note: Leaving the I2C gate open here. */ 874 /* Note: Leaving the I2C gate open here. */
875 s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xf5, 1); 875 s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xf5, 1);
876 876
877 /* Put the device into low-power mode until first use */
878 s5h1411_set_powerstate(&state->frontend, 1);
879
877 return &state->frontend; 880 return &state->frontend;
878 881
879error: 882error:
diff --git a/drivers/media/dvb/frontends/s921_core.c b/drivers/media/dvb/frontends/s921_core.c
new file mode 100644
index 000000000000..974b52be9aea
--- /dev/null
+++ b/drivers/media/dvb/frontends/s921_core.c
@@ -0,0 +1,216 @@
1/*
2 * Driver for Sharp s921 driver
3 *
4 * Copyright (C) 2008 Markus Rechberger <mrechberger@sundtek.de>
5 *
6 */
7
8
9#include <linux/kernel.h>
10#include <linux/module.h>
11#include <linux/delay.h>
12#include "s921_core.h"
13
14static int s921_isdb_init(struct s921_isdb_t *dev);
15static int s921_isdb_set_parameters(struct s921_isdb_t *dev, struct s921_isdb_t_transmission_mode_params *params);
16static int s921_isdb_tune(struct s921_isdb_t *dev, struct s921_isdb_t_tune_params *params);
17static int s921_isdb_get_status(struct s921_isdb_t *dev, void *data);
18
19static u8 init_table[]={ 0x01, 0x40, 0x02, 0x00, 0x03, 0x40, 0x04, 0x01,
20 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08, 0x00,
21 0x09, 0x00, 0x0a, 0x00, 0x0b, 0x5a, 0x0c, 0x00,
22 0x0d, 0x00, 0x0f, 0x00, 0x13, 0x1b, 0x14, 0x80,
23 0x15, 0x40, 0x17, 0x70, 0x18, 0x01, 0x19, 0x12,
24 0x1a, 0x01, 0x1b, 0x12, 0x1c, 0xa0, 0x1d, 0x00,
25 0x1e, 0x0a, 0x1f, 0x08, 0x20, 0x40, 0x21, 0xff,
26 0x22, 0x4c, 0x23, 0x4e, 0x24, 0x4c, 0x25, 0x00,
27 0x26, 0x00, 0x27, 0xf4, 0x28, 0x60, 0x29, 0x88,
28 0x2a, 0x40, 0x2b, 0x40, 0x2c, 0xff, 0x2d, 0x00,
29 0x2e, 0xff, 0x2f, 0x00, 0x30, 0x20, 0x31, 0x06,
30 0x32, 0x0c, 0x34, 0x0f, 0x37, 0xfe, 0x38, 0x00,
31 0x39, 0x63, 0x3a, 0x10, 0x3b, 0x10, 0x47, 0x00,
32 0x49, 0xe5, 0x4b, 0x00, 0x50, 0xc0, 0x52, 0x20,
33 0x54, 0x5a, 0x55, 0x5b, 0x56, 0x40, 0x57, 0x70,
34 0x5c, 0x50, 0x5d, 0x00, 0x62, 0x17, 0x63, 0x2f,
35 0x64, 0x6f, 0x68, 0x00, 0x69, 0x89, 0x6a, 0x00,
36 0x6b, 0x00, 0x6c, 0x00, 0x6d, 0x00, 0x6e, 0x00,
37 0x70, 0x00, 0x71, 0x00, 0x75, 0x00, 0x76, 0x30,
38 0x77, 0x01, 0xaf, 0x00, 0xb0, 0xa0, 0xb2, 0x3d,
39 0xb3, 0x25, 0xb4, 0x8b, 0xb5, 0x4b, 0xb6, 0x3f,
40 0xb7, 0xff, 0xb8, 0xff, 0xb9, 0xfc, 0xba, 0x00,
41 0xbb, 0x00, 0xbc, 0x00, 0xd0, 0x30, 0xe4, 0x84,
42 0xf0, 0x48, 0xf1, 0x19, 0xf2, 0x5a, 0xf3, 0x8e,
43 0xf4, 0x2d, 0xf5, 0x07, 0xf6, 0x5a, 0xf7, 0xba,
44 0xf8, 0xd7 };
45
46static u8 c_table[]={ 0x58, 0x8a, 0x7b, 0x59, 0x8c, 0x7b, 0x5a, 0x8e, 0x5b,
47 0x5b, 0x90, 0x5b, 0x5c, 0x92, 0x5b, 0x5d, 0x94, 0x5b,
48 0x5e, 0x96, 0x5b, 0x5f, 0x98, 0x3b, 0x60, 0x9a, 0x3b,
49 0x61, 0x9c, 0x3b, 0x62, 0x9e, 0x3b, 0x63, 0xa0, 0x3b,
50 0x64, 0xa2, 0x1b, 0x65, 0xa4, 0x1b, 0x66, 0xa6, 0x1b,
51 0x67, 0xa8, 0x1b, 0x68, 0xaa, 0x1b, 0x69, 0xac, 0x1b,
52 0x6a, 0xae, 0x1b, 0x6b, 0xb0, 0x1b, 0x6c, 0xb2, 0x1b,
53 0x6d, 0xb4, 0xfb, 0x6e, 0xb6, 0xfb, 0x6f, 0xb8, 0xfb,
54 0x70, 0xba, 0xfb, 0x71, 0xbc, 0xdb, 0x72, 0xbe, 0xdb,
55 0x73, 0xc0, 0xdb, 0x74, 0xc2, 0xdb, 0x75, 0xc4, 0xdb,
56 0x76, 0xc6, 0xdb, 0x77, 0xc8, 0xbb, 0x78, 0xca, 0xbb,
57 0x79, 0xcc, 0xbb, 0x7a, 0xce, 0xbb, 0x7b, 0xd0, 0xbb,
58 0x7c, 0xd2, 0xbb, 0x7d, 0xd4, 0xbb, 0x7e, 0xd6, 0xbb,
59 0x7f, 0xd8, 0xbb, 0x80, 0xda, 0x9b, 0x81, 0xdc, 0x9b,
60 0x82, 0xde, 0x9b, 0x83, 0xe0, 0x9b, 0x84, 0xe2, 0x9b,
61 0x85, 0xe4, 0x9b, 0x86, 0xe6, 0x9b, 0x87, 0xe8, 0x9b,
62 0x88, 0xea, 0x9b, 0x89, 0xec, 0x9b };
63
64int s921_isdb_cmd(struct s921_isdb_t *dev, u32 cmd, void *data) {
65 switch(cmd) {
66 case ISDB_T_CMD_INIT:
67 s921_isdb_init(dev);
68 break;
69 case ISDB_T_CMD_SET_PARAM:
70 s921_isdb_set_parameters(dev, data);
71 break;
72 case ISDB_T_CMD_TUNE:
73 s921_isdb_tune(dev, data);
74 break;
75 case ISDB_T_CMD_GET_STATUS:
76 s921_isdb_get_status(dev, data);
77 break;
78 default:
79 printk("unhandled command\n");
80 return -EINVAL;
81 }
82 return 0;
83}
84
85static int s921_isdb_init(struct s921_isdb_t *dev) {
86 unsigned int i;
87 unsigned int ret;
88 printk("isdb_init\n");
89 for (i = 0; i < sizeof(init_table); i+=2) {
90 ret = dev->i2c_write(dev->priv_dev, init_table[i], init_table[i+1]);
91 if (ret != 0) {
92 printk("i2c write failed\n");
93 return ret;
94 }
95 }
96 return 0;
97}
98
99static int s921_isdb_set_parameters(struct s921_isdb_t *dev, struct s921_isdb_t_transmission_mode_params *params) {
100
101 int ret;
102 /* auto is sufficient for now, lateron this should be reflected in an extra interface */
103
104
105
106 ret = dev->i2c_write(dev->priv_dev, 0xb0, 0xa0); //mod_b2);
107 ret = dev->i2c_write(dev->priv_dev, 0xb2, 0x3d); //mod_b2);
108
109 if (ret < 0)
110 return -EINVAL;
111
112 ret = dev->i2c_write(dev->priv_dev, 0xb3, 0x25); //mod_b3);
113 if (ret < 0)
114 return -EINVAL;
115
116 ret = dev->i2c_write(dev->priv_dev, 0xb4, 0x8b); //mod_b4);
117 if (ret < 0)
118 return -EINVAL;
119
120 ret = dev->i2c_write(dev->priv_dev, 0xb5, 0x4b); //mod_b5);
121 if (ret < 0)
122 return -EINVAL;
123
124 ret = dev->i2c_write(dev->priv_dev, 0xb6, 0x3f); //mod_b6);
125 if (ret < 0)
126 return -EINVAL;
127
128 ret = dev->i2c_write(dev->priv_dev, 0xb7, 0x3f); //mod_b7);
129 if (ret < 0)
130 return -EINVAL;
131
132 return E_OK;
133}
134
135static int s921_isdb_tune(struct s921_isdb_t *dev, struct s921_isdb_t_tune_params *params) {
136
137 int ret;
138 int index;
139
140 index = (params->frequency - 473143000)/6000000;
141
142 if (index > 48) {
143 return -EINVAL;
144 }
145
146 dev->i2c_write(dev->priv_dev, 0x47, 0x60);
147
148 ret = dev->i2c_write(dev->priv_dev, 0x68, 0x00);
149 if (ret < 0)
150 return -EINVAL;
151
152 ret = dev->i2c_write(dev->priv_dev, 0x69, 0x89);
153 if (ret < 0)
154 return -EINVAL;
155
156 ret = dev->i2c_write(dev->priv_dev, 0xf0, 0x48);
157 if (ret < 0)
158 return -EINVAL;
159
160 ret = dev->i2c_write(dev->priv_dev, 0xf1, 0x19);
161 if (ret < 0)
162 return -EINVAL;
163
164 ret = dev->i2c_write(dev->priv_dev, 0xf2, c_table[index*3]);
165 if (ret < 0)
166 return -EINVAL;
167
168 ret = dev->i2c_write(dev->priv_dev, 0xf3, c_table[index*3+1]);
169 if (ret < 0)
170 return -EINVAL;
171
172 ret = dev->i2c_write(dev->priv_dev, 0xf4, c_table[index*3+2]);
173 if (ret < 0)
174 return -EINVAL;
175
176 ret = dev->i2c_write(dev->priv_dev, 0xf5, 0xae);
177 if (ret < 0)
178 return -EINVAL;
179
180 ret = dev->i2c_write(dev->priv_dev, 0xf6, 0xb7);
181 if (ret < 0)
182 return -EINVAL;
183
184 ret = dev->i2c_write(dev->priv_dev, 0xf7, 0xba);
185 if (ret < 0)
186 return -EINVAL;
187
188 ret = dev->i2c_write(dev->priv_dev, 0xf8, 0xd7);
189 if (ret < 0)
190 return -EINVAL;
191
192 ret = dev->i2c_write(dev->priv_dev, 0x68, 0x0a);
193 if (ret < 0)
194 return -EINVAL;
195
196 ret = dev->i2c_write(dev->priv_dev, 0x69, 0x09);
197 if (ret < 0)
198 return -EINVAL;
199
200 dev->i2c_write(dev->priv_dev, 0x01, 0x40);
201 return 0;
202}
203
204static int s921_isdb_get_status(struct s921_isdb_t *dev, void *data) {
205 unsigned int *ret = (unsigned int*)data;
206 u8 ifagc_dt;
207 u8 rfagc_dt;
208
209 mdelay(10);
210 ifagc_dt = dev->i2c_read(dev->priv_dev, 0x81);
211 rfagc_dt = dev->i2c_read(dev->priv_dev, 0x82);
212 if (rfagc_dt == 0x40) {
213 *ret = 1;
214 }
215 return 0;
216}
diff --git a/drivers/media/dvb/frontends/s921_core.h b/drivers/media/dvb/frontends/s921_core.h
new file mode 100644
index 000000000000..de2f10a44e72
--- /dev/null
+++ b/drivers/media/dvb/frontends/s921_core.h
@@ -0,0 +1,114 @@
1#ifndef _S921_CORE_H
2#define _S921_CORE_H
3//#define u8 unsigned int
4//#define u32 unsigned int
5
6
7
8//#define EINVAL -1
9#define E_OK 0
10
11struct s921_isdb_t {
12 void *priv_dev;
13 int (*i2c_write)(void *dev, u8 reg, u8 val);
14 int (*i2c_read)(void *dev, u8 reg);
15};
16
17#define ISDB_T_CMD_INIT 0
18#define ISDB_T_CMD_SET_PARAM 1
19#define ISDB_T_CMD_TUNE 2
20#define ISDB_T_CMD_GET_STATUS 3
21
22struct s921_isdb_t_tune_params {
23 u32 frequency;
24};
25
26struct s921_isdb_t_status {
27};
28
29struct s921_isdb_t_transmission_mode_params {
30 u8 mode;
31 u8 layer_a_mode;
32#define ISDB_T_LA_MODE_1 0
33#define ISDB_T_LA_MODE_2 1
34#define ISDB_T_LA_MODE_3 2
35 u8 layer_a_carrier_modulation;
36#define ISDB_T_LA_CM_DQPSK 0
37#define ISDB_T_LA_CM_QPSK 1
38#define ISDB_T_LA_CM_16QAM 2
39#define ISDB_T_LA_CM_64QAM 3
40#define ISDB_T_LA_CM_NOLAYER 4
41 u8 layer_a_code_rate;
42#define ISDB_T_LA_CR_1_2 0
43#define ISDB_T_LA_CR_2_3 1
44#define ISDB_T_LA_CR_3_4 2
45#define ISDB_T_LA_CR_5_6 4
46#define ISDB_T_LA_CR_7_8 8
47#define ISDB_T_LA_CR_NOLAYER 16
48 u8 layer_a_time_interleave;
49#define ISDB_T_LA_TI_0 0
50#define ISDB_T_LA_TI_1 1
51#define ISDB_T_LA_TI_2 2
52#define ISDB_T_LA_TI_4 4
53#define ISDB_T_LA_TI_8 8
54#define ISDB_T_LA_TI_16 16
55#define ISDB_T_LA_TI_32 32
56 u8 layer_a_nseg;
57
58 u8 layer_b_mode;
59#define ISDB_T_LB_MODE_1 0
60#define ISDB_T_LB_MODE_2 1
61#define ISDB_T_LB_MODE_3 2
62 u8 layer_b_carrier_modulation;
63#define ISDB_T_LB_CM_DQPSK 0
64#define ISDB_T_LB_CM_QPSK 1
65#define ISDB_T_LB_CM_16QAM 2
66#define ISDB_T_LB_CM_64QAM 3
67#define ISDB_T_LB_CM_NOLAYER 4
68 u8 layer_b_code_rate;
69#define ISDB_T_LB_CR_1_2 0
70#define ISDB_T_LB_CR_2_3 1
71#define ISDB_T_LB_CR_3_4 2
72#define ISDB_T_LB_CR_5_6 4
73#define ISDB_T_LB_CR_7_8 8
74#define ISDB_T_LB_CR_NOLAYER 16
75 u8 layer_b_time_interleave;
76#define ISDB_T_LB_TI_0 0
77#define ISDB_T_LB_TI_1 1
78#define ISDB_T_LB_TI_2 2
79#define ISDB_T_LB_TI_4 4
80#define ISDB_T_LB_TI_8 8
81#define ISDB_T_LB_TI_16 16
82#define ISDB_T_LB_TI_32 32
83 u8 layer_b_nseg;
84
85 u8 layer_c_mode;
86#define ISDB_T_LC_MODE_1 0
87#define ISDB_T_LC_MODE_2 1
88#define ISDB_T_LC_MODE_3 2
89 u8 layer_c_carrier_modulation;
90#define ISDB_T_LC_CM_DQPSK 0
91#define ISDB_T_LC_CM_QPSK 1
92#define ISDB_T_LC_CM_16QAM 2
93#define ISDB_T_LC_CM_64QAM 3
94#define ISDB_T_LC_CM_NOLAYER 4
95 u8 layer_c_code_rate;
96#define ISDB_T_LC_CR_1_2 0
97#define ISDB_T_LC_CR_2_3 1
98#define ISDB_T_LC_CR_3_4 2
99#define ISDB_T_LC_CR_5_6 4
100#define ISDB_T_LC_CR_7_8 8
101#define ISDB_T_LC_CR_NOLAYER 16
102 u8 layer_c_time_interleave;
103#define ISDB_T_LC_TI_0 0
104#define ISDB_T_LC_TI_1 1
105#define ISDB_T_LC_TI_2 2
106#define ISDB_T_LC_TI_4 4
107#define ISDB_T_LC_TI_8 8
108#define ISDB_T_LC_TI_16 16
109#define ISDB_T_LC_TI_32 32
110 u8 layer_c_nseg;
111};
112
113int s921_isdb_cmd(struct s921_isdb_t *dev, u32 cmd, void *data);
114#endif
diff --git a/drivers/media/dvb/frontends/s921_module.c b/drivers/media/dvb/frontends/s921_module.c
new file mode 100644
index 000000000000..3cbb9cb2cf47
--- /dev/null
+++ b/drivers/media/dvb/frontends/s921_module.c
@@ -0,0 +1,190 @@
1/*
2 * Driver for Sharp s921 driver
3 *
4 * Copyright (C) 2008 Markus Rechberger <mrechberger@sundtek.de>
5 *
6 * All rights reserved.
7 *
8 */
9
10#include <linux/kernel.h>
11#include <linux/module.h>
12#include <linux/delay.h>
13#include "dvb_frontend.h"
14#include "s921_module.h"
15#include "s921_core.h"
16
17static unsigned int debug = 0;
18module_param(debug, int, 0644);
19MODULE_PARM_DESC(debug,"s921 debugging (default off)");
20
21#define dprintk(fmt, args...) if (debug) do {\
22 printk("s921 debug: " fmt, ##args); } while (0)
23
24struct s921_state
25{
26 struct dvb_frontend frontend;
27 fe_modulation_t current_modulation;
28 __u32 snr;
29 __u32 current_frequency;
30 __u8 addr;
31 struct s921_isdb_t dev;
32 struct i2c_adapter *i2c;
33};
34
35static int s921_set_parameters(struct dvb_frontend *fe, struct dvb_frontend_parameters *param) {
36 struct s921_state *state = (struct s921_state *)fe->demodulator_priv;
37 struct s921_isdb_t_transmission_mode_params params;
38 struct s921_isdb_t_tune_params tune_params;
39
40 tune_params.frequency = param->frequency;
41 s921_isdb_cmd(&state->dev, ISDB_T_CMD_SET_PARAM, &params);
42 s921_isdb_cmd(&state->dev, ISDB_T_CMD_TUNE, &tune_params);
43 mdelay(100);
44 return 0;
45}
46
47static int s921_init(struct dvb_frontend *fe) {
48 printk("s921 init\n");
49 return 0;
50}
51
52static int s921_sleep(struct dvb_frontend *fe) {
53 printk("s921 sleep\n");
54 return 0;
55}
56
57static int s921_read_status(struct dvb_frontend *fe, fe_status_t *status)
58{
59 struct s921_state *state = (struct s921_state *)fe->demodulator_priv;
60 unsigned int ret;
61 mdelay(5);
62 s921_isdb_cmd(&state->dev, ISDB_T_CMD_GET_STATUS, &ret);
63 *status = 0;
64
65 printk("status: %02x\n", ret);
66 if (ret == 1) {
67 *status |= FE_HAS_CARRIER;
68 *status |= FE_HAS_VITERBI;
69 *status |= FE_HAS_LOCK;
70 *status |= FE_HAS_SYNC;
71 *status |= FE_HAS_SIGNAL;
72 }
73
74 return 0;
75}
76
77static int s921_read_ber(struct dvb_frontend *fe, __u32 *ber)
78{
79 dprintk("read ber\n");
80 return 0;
81}
82
83static int s921_read_snr(struct dvb_frontend *fe, __u16 *snr)
84{
85 dprintk("read snr\n");
86 return 0;
87}
88
89static int s921_read_ucblocks(struct dvb_frontend *fe, __u32 *ucblocks)
90{
91 dprintk("read ucblocks\n");
92 return 0;
93}
94
95static void s921_release(struct dvb_frontend *fe)
96{
97 struct s921_state *state = (struct s921_state *)fe->demodulator_priv;
98 kfree(state);
99}
100
101static struct dvb_frontend_ops demod_s921={
102 .info = {
103 .name = "SHARP S921",
104 .type = FE_OFDM,
105 .frequency_min = 473143000,
106 .frequency_max = 767143000,
107 .frequency_stepsize = 6000000,
108 .frequency_tolerance = 0,
109 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 |
110 FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
111 FE_CAN_FEC_AUTO |
112 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
113 FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO |
114 FE_CAN_HIERARCHY_AUTO | FE_CAN_RECOVER |
115 FE_CAN_MUTE_TS
116 },
117 .init = s921_init,
118 .sleep = s921_sleep,
119 .set_frontend = s921_set_parameters,
120 .read_snr = s921_read_snr,
121 .read_ber = s921_read_ber,
122 .read_status = s921_read_status,
123 .read_ucblocks = s921_read_ucblocks,
124 .release = s921_release,
125};
126
127static int s921_write(void *dev, u8 reg, u8 val) {
128 struct s921_state *state = dev;
129 char buf[2]={reg,val};
130 int err;
131 struct i2c_msg i2cmsgs = {
132 .addr = state->addr,
133 .flags = 0,
134 .len = 2,
135 .buf = buf
136 };
137
138 if((err = i2c_transfer(state->i2c, &i2cmsgs, 1))<0) {
139 printk("%s i2c_transfer error %d\n", __FUNCTION__, err);
140 if (err < 0)
141 return err;
142 else
143 return -EREMOTEIO;
144 }
145
146 return 0;
147}
148
149static int s921_read(void *dev, u8 reg) {
150 struct s921_state *state = dev;
151 u8 b1;
152 int ret;
153 struct i2c_msg msg[2] = { { .addr = state->addr,
154 .flags = 0,
155 .buf = &reg, .len = 1 },
156 { .addr = state->addr,
157 .flags = I2C_M_RD,
158 .buf = &b1, .len = 1 } };
159
160 ret = i2c_transfer(state->i2c, msg, 2);
161 if (ret != 2)
162 return ret;
163 return b1;
164}
165
166struct dvb_frontend* s921_attach(const struct s921_config *config,
167 struct i2c_adapter *i2c)
168{
169
170 struct s921_state *state;
171 state = kzalloc(sizeof(struct s921_state), GFP_KERNEL);
172 memset(state, 0x0, sizeof(struct s921_state));
173
174 state->addr = config->i2c_address;
175 state->i2c = i2c;
176 state->dev.i2c_write = &s921_write;
177 state->dev.i2c_read = &s921_read;
178 state->dev.priv_dev = state;
179
180 s921_isdb_cmd(&state->dev, ISDB_T_CMD_INIT, NULL);
181
182 memcpy(&state->frontend.ops, &demod_s921, sizeof(struct dvb_frontend_ops));
183 state->frontend.demodulator_priv = state;
184 return &state->frontend;
185}
186
187EXPORT_SYMBOL_GPL(s921_attach);
188MODULE_AUTHOR("Markus Rechberger <mrechberger@empiatech.com>");
189MODULE_DESCRIPTION("Sharp S921 ISDB-T 1Seg");
190MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/s921_module.h b/drivers/media/dvb/frontends/s921_module.h
new file mode 100644
index 000000000000..78660424ba95
--- /dev/null
+++ b/drivers/media/dvb/frontends/s921_module.h
@@ -0,0 +1,49 @@
1/*
2 * Driver for DVB-T s921 demodulator
3 *
4 * Copyright (C) 2008 Markus Rechberger <mrechberger@sundtek.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 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 S921_MODULE_H
23#define S921_MODULE_H
24
25#include <linux/dvb/frontend.h>
26#include "s921_core.h"
27
28int s921_isdb_init(struct s921_isdb_t *dev);
29int s921_isdb_cmd(struct s921_isdb_t *dev, u32 cmd, void *data);
30
31struct s921_config
32{
33 /* demodulator's I2C address */
34 u8 i2c_address;
35};
36
37#if defined(CONFIG_DVB_S921) || (defined(CONFIG_DVB_S921_MODULE) && defined(MODULE))
38extern struct dvb_frontend* s921_attach(const struct s921_config *config,
39 struct i2c_adapter *i2c);
40#else
41static inline struct dvb_frontend* s921_attach(const struct s921_config *config,
42 struct i2c_adapter *i2c)
43{
44 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
45 return NULL;
46}
47#endif /* CONFIG_DVB_S921 */
48
49#endif /* S921_H */
diff --git a/drivers/media/dvb/frontends/si21xx.c b/drivers/media/dvb/frontends/si21xx.c
index 3ddbe69c45ce..0bd16af8a6cd 100644
--- a/drivers/media/dvb/frontends/si21xx.c
+++ b/drivers/media/dvb/frontends/si21xx.c
@@ -8,7 +8,6 @@
8* (at your option) any later version. 8* (at your option) any later version.
9* 9*
10*/ 10*/
11#include <linux/version.h>
12#include <linux/init.h> 11#include <linux/init.h>
13#include <linux/kernel.h> 12#include <linux/kernel.h>
14#include <linux/module.h> 13#include <linux/module.h>
diff --git a/drivers/media/dvb/frontends/stb0899_algo.c b/drivers/media/dvb/frontends/stb0899_algo.c
new file mode 100644
index 000000000000..ced9b7ae7d50
--- /dev/null
+++ b/drivers/media/dvb/frontends/stb0899_algo.c
@@ -0,0 +1,1519 @@
1/*
2 STB0899 Multistandard Frontend driver
3 Copyright (C) Manu Abraham (abraham.manu@gmail.com)
4
5 Copyright (C) ST Microelectronics
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 "stb0899_drv.h"
23#include "stb0899_priv.h"
24#include "stb0899_reg.h"
25
26inline u32 stb0899_do_div(u64 n, u32 d)
27{
28 /* wrap do_div() for ease of use */
29
30 do_div(n, d);
31 return n;
32}
33
34/*
35 * stb0899_calc_srate
36 * Compute symbol rate
37 */
38static u32 stb0899_calc_srate(u32 master_clk, u8 *sfr)
39{
40 u64 tmp;
41
42 /* srate = (SFR * master_clk) >> 20 */
43
44 /* sfr is of size 20 bit, stored with an offset of 4 bit */
45 tmp = (((u32)sfr[0]) << 16) | (((u32)sfr[1]) << 8) | sfr[2];
46 tmp &= ~0xf;
47 tmp *= master_clk;
48 tmp >>= 24;
49
50 return tmp;
51}
52
53/*
54 * stb0899_get_srate
55 * Get the current symbol rate
56 */
57u32 stb0899_get_srate(struct stb0899_state *state)
58{
59 struct stb0899_internal *internal = &state->internal;
60 u8 sfr[3];
61
62 stb0899_read_regs(state, STB0899_SFRH, sfr, 3);
63
64 return stb0899_calc_srate(internal->master_clk, sfr);
65}
66
67/*
68 * stb0899_set_srate
69 * Set symbol frequency
70 * MasterClock: master clock frequency (hz)
71 * SymbolRate: symbol rate (bauds)
72 * return symbol frequency
73 */
74static u32 stb0899_set_srate(struct stb0899_state *state, u32 master_clk, u32 srate)
75{
76 u32 tmp;
77 u8 sfr[3];
78
79 dprintk(state->verbose, FE_DEBUG, 1, "-->");
80 /*
81 * in order to have the maximum precision, the symbol rate entered into
82 * the chip is computed as the closest value of the "true value".
83 * In this purpose, the symbol rate value is rounded (1 is added on the bit
84 * below the LSB )
85 *
86 * srate = (SFR * master_clk) >> 20
87 * <=>
88 * SFR = srate << 20 / master_clk
89 *
90 * rounded:
91 * SFR = (srate << 21 + master_clk) / (2 * master_clk)
92 *
93 * stored as 20 bit number with an offset of 4 bit:
94 * sfr = SFR << 4;
95 */
96
97 tmp = stb0899_do_div((((u64)srate) << 21) + master_clk, 2 * master_clk);
98 tmp <<= 4;
99
100 sfr[0] = tmp >> 16;
101 sfr[1] = tmp >> 8;
102 sfr[2] = tmp;
103
104 stb0899_write_regs(state, STB0899_SFRH, sfr, 3);
105
106 return srate;
107}
108
109/*
110 * stb0899_calc_derot_time
111 * Compute the amount of time needed by the derotator to lock
112 * SymbolRate: Symbol rate
113 * return: derotator time constant (ms)
114 */
115static long stb0899_calc_derot_time(long srate)
116{
117 if (srate > 0)
118 return (100000 / (srate / 1000));
119 else
120 return 0;
121}
122
123/*
124 * stb0899_carr_width
125 * Compute the width of the carrier
126 * return: width of carrier (kHz or Mhz)
127 */
128long stb0899_carr_width(struct stb0899_state *state)
129{
130 struct stb0899_internal *internal = &state->internal;
131
132 return (internal->srate + (internal->srate * internal->rolloff) / 100);
133}
134
135/*
136 * stb0899_first_subrange
137 * Compute the first subrange of the search
138 */
139static void stb0899_first_subrange(struct stb0899_state *state)
140{
141 struct stb0899_internal *internal = &state->internal;
142 struct stb0899_params *params = &state->params;
143 struct stb0899_config *config = state->config;
144
145 int range = 0;
146 u32 bandwidth = 0;
147
148 if (config->tuner_get_bandwidth) {
149 stb0899_i2c_gate_ctrl(&state->frontend, 1);
150 config->tuner_get_bandwidth(&state->frontend, &bandwidth);
151 stb0899_i2c_gate_ctrl(&state->frontend, 0);
152 range = bandwidth - stb0899_carr_width(state) / 2;
153 }
154
155 if (range > 0)
156 internal->sub_range = MIN(internal->srch_range, range);
157 else
158 internal->sub_range = 0;
159
160 internal->freq = params->freq;
161 internal->tuner_offst = 0L;
162 internal->sub_dir = 1;
163}
164
165/*
166 * stb0899_check_tmg
167 * check for timing lock
168 * internal.Ttiming: time to wait for loop lock
169 */
170static enum stb0899_status stb0899_check_tmg(struct stb0899_state *state)
171{
172 struct stb0899_internal *internal = &state->internal;
173 int lock;
174 u8 reg;
175 s8 timing;
176
177 msleep(internal->t_derot);
178
179 stb0899_write_reg(state, STB0899_RTF, 0xf2);
180 reg = stb0899_read_reg(state, STB0899_TLIR);
181 lock = STB0899_GETFIELD(TLIR_TMG_LOCK_IND, reg);
182 timing = stb0899_read_reg(state, STB0899_RTF);
183
184 if (lock >= 42) {
185 if ((lock > 48) && (ABS(timing) >= 110)) {
186 internal->status = ANALOGCARRIER;
187 dprintk(state->verbose, FE_DEBUG, 1, "-->ANALOG Carrier !");
188 } else {
189 internal->status = TIMINGOK;
190 dprintk(state->verbose, FE_DEBUG, 1, "------->TIMING OK !");
191 }
192 } else {
193 internal->status = NOTIMING;
194 dprintk(state->verbose, FE_DEBUG, 1, "-->NO TIMING !");
195 }
196 return internal->status;
197}
198
199/*
200 * stb0899_search_tmg
201 * perform a fs/2 zig-zag to find timing
202 */
203static enum stb0899_status stb0899_search_tmg(struct stb0899_state *state)
204{
205 struct stb0899_internal *internal = &state->internal;
206 struct stb0899_params *params = &state->params;
207
208 short int derot_step, derot_freq = 0, derot_limit, next_loop = 3;
209 int index = 0;
210 u8 cfr[2];
211
212 internal->status = NOTIMING;
213
214 /* timing loop computation & symbol rate optimisation */
215 derot_limit = (internal->sub_range / 2L) / internal->mclk;
216 derot_step = (params->srate / 2L) / internal->mclk;
217
218 while ((stb0899_check_tmg(state) != TIMINGOK) && next_loop) {
219 index++;
220 derot_freq += index * internal->direction * derot_step; /* next derot zig zag position */
221
222 if (ABS(derot_freq) > derot_limit)
223 next_loop--;
224
225 if (next_loop) {
226 STB0899_SETFIELD_VAL(CFRM, cfr[0], MSB(state->config->inversion * derot_freq));
227 STB0899_SETFIELD_VAL(CFRL, cfr[1], LSB(state->config->inversion * derot_freq));
228 stb0899_write_regs(state, STB0899_CFRM, cfr, 2); /* derotator frequency */
229 }
230 internal->direction = -internal->direction; /* Change zigzag direction */
231 }
232
233 if (internal->status == TIMINGOK) {
234 stb0899_read_regs(state, STB0899_CFRM, cfr, 2); /* get derotator frequency */
235 internal->derot_freq = state->config->inversion * MAKEWORD16(cfr[0], cfr[1]);
236 dprintk(state->verbose, FE_DEBUG, 1, "------->TIMING OK ! Derot Freq = %d", internal->derot_freq);
237 }
238
239 return internal->status;
240}
241
242/*
243 * stb0899_check_carrier
244 * Check for carrier found
245 */
246static enum stb0899_status stb0899_check_carrier(struct stb0899_state *state)
247{
248 struct stb0899_internal *internal = &state->internal;
249 u8 reg;
250
251 msleep(internal->t_derot); /* wait for derotator ok */
252
253 reg = stb0899_read_reg(state, STB0899_CFD);
254 STB0899_SETFIELD_VAL(CFD_ON, reg, 1);
255 stb0899_write_reg(state, STB0899_CFD, reg);
256
257 reg = stb0899_read_reg(state, STB0899_DSTATUS);
258 dprintk(state->verbose, FE_DEBUG, 1, "--------------------> STB0899_DSTATUS=[0x%02x]", reg);
259 if (STB0899_GETFIELD(CARRIER_FOUND, reg)) {
260 internal->status = CARRIEROK;
261 dprintk(state->verbose, FE_DEBUG, 1, "-------------> CARRIEROK !");
262 } else {
263 internal->status = NOCARRIER;
264 dprintk(state->verbose, FE_DEBUG, 1, "-------------> NOCARRIER !");
265 }
266
267 return internal->status;
268}
269
270/*
271 * stb0899_search_carrier
272 * Search for a QPSK carrier with the derotator
273 */
274static enum stb0899_status stb0899_search_carrier(struct stb0899_state *state)
275{
276 struct stb0899_internal *internal = &state->internal;
277
278 short int derot_freq = 0, last_derot_freq = 0, derot_limit, next_loop = 3;
279 int index = 0;
280 u8 cfr[2];
281 u8 reg;
282
283 internal->status = NOCARRIER;
284 derot_limit = (internal->sub_range / 2L) / internal->mclk;
285 derot_freq = internal->derot_freq;
286
287 reg = stb0899_read_reg(state, STB0899_CFD);
288 STB0899_SETFIELD_VAL(CFD_ON, reg, 1);
289 stb0899_write_reg(state, STB0899_CFD, reg);
290
291 do {
292 dprintk(state->verbose, FE_DEBUG, 1, "Derot Freq=%d, mclk=%d", derot_freq, internal->mclk);
293 if (stb0899_check_carrier(state) == NOCARRIER) {
294 index++;
295 last_derot_freq = derot_freq;
296 derot_freq += index * internal->direction * internal->derot_step; /* next zig zag derotator position */
297
298 if(ABS(derot_freq) > derot_limit)
299 next_loop--;
300
301 if (next_loop) {
302 reg = stb0899_read_reg(state, STB0899_CFD);
303 STB0899_SETFIELD_VAL(CFD_ON, reg, 1);
304 stb0899_write_reg(state, STB0899_CFD, reg);
305
306 STB0899_SETFIELD_VAL(CFRM, cfr[0], MSB(state->config->inversion * derot_freq));
307 STB0899_SETFIELD_VAL(CFRL, cfr[1], LSB(state->config->inversion * derot_freq));
308 stb0899_write_regs(state, STB0899_CFRM, cfr, 2); /* derotator frequency */
309 }
310 }
311
312 internal->direction = -internal->direction; /* Change zigzag direction */
313 } while ((internal->status != CARRIEROK) && next_loop);
314
315 if (internal->status == CARRIEROK) {
316 stb0899_read_regs(state, STB0899_CFRM, cfr, 2); /* get derotator frequency */
317 internal->derot_freq = state->config->inversion * MAKEWORD16(cfr[0], cfr[1]);
318 dprintk(state->verbose, FE_DEBUG, 1, "----> CARRIER OK !, Derot Freq=%d", internal->derot_freq);
319 } else {
320 internal->derot_freq = last_derot_freq;
321 }
322
323 return internal->status;
324}
325
326/*
327 * stb0899_check_data
328 * Check for data found
329 */
330static enum stb0899_status stb0899_check_data(struct stb0899_state *state)
331{
332 struct stb0899_internal *internal = &state->internal;
333 struct stb0899_params *params = &state->params;
334
335 int lock = 0, index = 0, dataTime = 500, loop;
336 u8 reg;
337
338 internal->status = NODATA;
339
340 /* RESET FEC */
341 reg = stb0899_read_reg(state, STB0899_TSTRES);
342 STB0899_SETFIELD_VAL(FRESACS, reg, 1);
343 stb0899_write_reg(state, STB0899_TSTRES, reg);
344 msleep(1);
345 reg = stb0899_read_reg(state, STB0899_TSTRES);
346 STB0899_SETFIELD_VAL(FRESACS, reg, 0);
347 stb0899_write_reg(state, STB0899_TSTRES, reg);
348
349 if (params->srate <= 2000000)
350 dataTime = 2000;
351 else if (params->srate <= 5000000)
352 dataTime = 1500;
353 else if (params->srate <= 15000000)
354 dataTime = 1000;
355 else
356 dataTime = 500;
357
358 stb0899_write_reg(state, STB0899_DSTATUS2, 0x00); /* force search loop */
359 while (1) {
360 /* WARNING! VIT LOCKED has to be tested before VIT_END_LOOOP */
361 reg = stb0899_read_reg(state, STB0899_VSTATUS);
362 lock = STB0899_GETFIELD(VSTATUS_LOCKEDVIT, reg);
363 loop = STB0899_GETFIELD(VSTATUS_END_LOOPVIT, reg);
364
365 if (lock || loop || (index > dataTime))
366 break;
367 index++;
368 }
369
370 if (lock) { /* DATA LOCK indicator */
371 internal->status = DATAOK;
372 dprintk(state->verbose, FE_DEBUG, 1, "-----------------> DATA OK !");
373 }
374
375 return internal->status;
376}
377
378/*
379 * stb0899_search_data
380 * Search for a QPSK carrier with the derotator
381 */
382static enum stb0899_status stb0899_search_data(struct stb0899_state *state)
383{
384 short int derot_freq, derot_step, derot_limit, next_loop = 3;
385 u8 cfr[2];
386 u8 reg;
387 int index = 1;
388
389 struct stb0899_internal *internal = &state->internal;
390 struct stb0899_params *params = &state->params;
391
392 derot_step = (params->srate / 4L) / internal->mclk;
393 derot_limit = (internal->sub_range / 2L) / internal->mclk;
394 derot_freq = internal->derot_freq;
395
396 do {
397 if ((internal->status != CARRIEROK) || (stb0899_check_data(state) != DATAOK)) {
398
399 derot_freq += index * internal->direction * derot_step; /* next zig zag derotator position */
400 if (ABS(derot_freq) > derot_limit)
401 next_loop--;
402
403 if (next_loop) {
404 dprintk(state->verbose, FE_DEBUG, 1, "Derot freq=%d, mclk=%d", derot_freq, internal->mclk);
405 reg = stb0899_read_reg(state, STB0899_CFD);
406 STB0899_SETFIELD_VAL(CFD_ON, reg, 1);
407 stb0899_write_reg(state, STB0899_CFD, reg);
408
409 STB0899_SETFIELD_VAL(CFRM, cfr[0], MSB(state->config->inversion * derot_freq));
410 STB0899_SETFIELD_VAL(CFRL, cfr[1], LSB(state->config->inversion * derot_freq));
411 stb0899_write_regs(state, STB0899_CFRM, cfr, 2); /* derotator frequency */
412
413 stb0899_check_carrier(state);
414 index++;
415 }
416 }
417 internal->direction = -internal->direction; /* change zig zag direction */
418 } while ((internal->status != DATAOK) && next_loop);
419
420 if (internal->status == DATAOK) {
421 stb0899_read_regs(state, STB0899_CFRM, cfr, 2); /* get derotator frequency */
422 internal->derot_freq = state->config->inversion * MAKEWORD16(cfr[0], cfr[1]);
423 dprintk(state->verbose, FE_DEBUG, 1, "------> DATAOK ! Derot Freq=%d", internal->derot_freq);
424 }
425
426 return internal->status;
427}
428
429/*
430 * stb0899_check_range
431 * check if the found frequency is in the correct range
432 */
433static enum stb0899_status stb0899_check_range(struct stb0899_state *state)
434{
435 struct stb0899_internal *internal = &state->internal;
436 struct stb0899_params *params = &state->params;
437
438 int range_offst, tp_freq;
439
440 range_offst = internal->srch_range / 2000;
441 tp_freq = internal->freq + (internal->derot_freq * internal->mclk) / 1000;
442
443 if ((tp_freq >= params->freq - range_offst) && (tp_freq <= params->freq + range_offst)) {
444 internal->status = RANGEOK;
445 dprintk(state->verbose, FE_DEBUG, 1, "----> RANGEOK !");
446 } else {
447 internal->status = OUTOFRANGE;
448 dprintk(state->verbose, FE_DEBUG, 1, "----> OUT OF RANGE !");
449 }
450
451 return internal->status;
452}
453
454/*
455 * NextSubRange
456 * Compute the next subrange of the search
457 */
458static void next_sub_range(struct stb0899_state *state)
459{
460 struct stb0899_internal *internal = &state->internal;
461 struct stb0899_params *params = &state->params;
462
463 long old_sub_range;
464
465 if (internal->sub_dir > 0) {
466 old_sub_range = internal->sub_range;
467 internal->sub_range = MIN((internal->srch_range / 2) -
468 (internal->tuner_offst + internal->sub_range / 2),
469 internal->sub_range);
470
471 if (internal->sub_range < 0)
472 internal->sub_range = 0;
473
474 internal->tuner_offst += (old_sub_range + internal->sub_range) / 2;
475 }
476
477 internal->freq = params->freq + (internal->sub_dir * internal->tuner_offst) / 1000;
478 internal->sub_dir = -internal->sub_dir;
479}
480
481/*
482 * stb0899_dvbs_algo
483 * Search for a signal, timing, carrier and data for a
484 * given frequency in a given range
485 */
486enum stb0899_status stb0899_dvbs_algo(struct stb0899_state *state)
487{
488 struct stb0899_params *params = &state->params;
489 struct stb0899_internal *internal = &state->internal;
490 struct stb0899_config *config = state->config;
491
492 u8 bclc, reg;
493 u8 cfr[2];
494 u8 eq_const[10];
495 s32 clnI = 3;
496 u32 bandwidth = 0;
497
498 /* BETA values rated @ 99MHz */
499 s32 betaTab[5][4] = {
500 /* 5 10 20 30MBps */
501 { 37, 34, 32, 31 }, /* QPSK 1/2 */
502 { 37, 35, 33, 31 }, /* QPSK 2/3 */
503 { 37, 35, 33, 31 }, /* QPSK 3/4 */
504 { 37, 36, 33, 32 }, /* QPSK 5/6 */
505 { 37, 36, 33, 32 } /* QPSK 7/8 */
506 };
507
508 internal->direction = 1;
509
510 stb0899_set_srate(state, internal->master_clk, params->srate);
511 /* Carrier loop optimization versus symbol rate for acquisition*/
512 if (params->srate <= 5000000) {
513 stb0899_write_reg(state, STB0899_ACLC, 0x89);
514 bclc = stb0899_read_reg(state, STB0899_BCLC);
515 STB0899_SETFIELD_VAL(BETA, bclc, 0x1c);
516 stb0899_write_reg(state, STB0899_BCLC, bclc);
517 clnI = 0;
518 } else if (params->srate <= 15000000) {
519 stb0899_write_reg(state, STB0899_ACLC, 0xc9);
520 bclc = stb0899_read_reg(state, STB0899_BCLC);
521 STB0899_SETFIELD_VAL(BETA, bclc, 0x22);
522 stb0899_write_reg(state, STB0899_BCLC, bclc);
523 clnI = 1;
524 } else if(params->srate <= 25000000) {
525 stb0899_write_reg(state, STB0899_ACLC, 0x89);
526 bclc = stb0899_read_reg(state, STB0899_BCLC);
527 STB0899_SETFIELD_VAL(BETA, bclc, 0x27);
528 stb0899_write_reg(state, STB0899_BCLC, bclc);
529 clnI = 2;
530 } else {
531 stb0899_write_reg(state, STB0899_ACLC, 0xc8);
532 bclc = stb0899_read_reg(state, STB0899_BCLC);
533 STB0899_SETFIELD_VAL(BETA, bclc, 0x29);
534 stb0899_write_reg(state, STB0899_BCLC, bclc);
535 clnI = 3;
536 }
537
538 dprintk(state->verbose, FE_DEBUG, 1, "Set the timing loop to acquisition");
539 /* Set the timing loop to acquisition */
540 stb0899_write_reg(state, STB0899_RTC, 0x46);
541 stb0899_write_reg(state, STB0899_CFD, 0xee);
542
543 /* !! WARNING !!
544 * Do not read any status variables while acquisition,
545 * If any needed, read before the acquisition starts
546 * querying status while acquiring causes the
547 * acquisition to go bad and hence no locks.
548 */
549 dprintk(state->verbose, FE_DEBUG, 1, "Derot Percent=%d Srate=%d mclk=%d",
550 internal->derot_percent, params->srate, internal->mclk);
551
552 /* Initial calculations */
553 internal->derot_step = internal->derot_percent * (params->srate / 1000L) / internal->mclk; /* DerotStep/1000 * Fsymbol */
554 internal->t_derot = stb0899_calc_derot_time(params->srate);
555 internal->t_data = 500;
556
557 dprintk(state->verbose, FE_DEBUG, 1, "RESET stream merger");
558 /* RESET Stream merger */
559 reg = stb0899_read_reg(state, STB0899_TSTRES);
560 STB0899_SETFIELD_VAL(FRESRS, reg, 1);
561 stb0899_write_reg(state, STB0899_TSTRES, reg);
562
563 /*
564 * Set KDIVIDER to an intermediate value between
565 * 1/2 and 7/8 for acquisition
566 */
567 reg = stb0899_read_reg(state, STB0899_DEMAPVIT);
568 STB0899_SETFIELD_VAL(DEMAPVIT_KDIVIDER, reg, 60);
569 stb0899_write_reg(state, STB0899_DEMAPVIT, reg);
570
571 stb0899_write_reg(state, STB0899_EQON, 0x01); /* Equalizer OFF while acquiring */
572 stb0899_write_reg(state, STB0899_VITSYNC, 0x19);
573
574 stb0899_first_subrange(state);
575 do {
576 /* Initialisations */
577 cfr[0] = cfr[1] = 0;
578 stb0899_write_regs(state, STB0899_CFRM, cfr, 2); /* RESET derotator frequency */
579
580 stb0899_write_reg(state, STB0899_RTF, 0);
581 reg = stb0899_read_reg(state, STB0899_CFD);
582 STB0899_SETFIELD_VAL(CFD_ON, reg, 1);
583 stb0899_write_reg(state, STB0899_CFD, reg);
584
585 internal->derot_freq = 0;
586 internal->status = NOAGC1;
587
588 /* enable tuner I/O */
589 stb0899_i2c_gate_ctrl(&state->frontend, 1);
590
591 /* Move tuner to frequency */
592 dprintk(state->verbose, FE_DEBUG, 1, "Tuner set frequency");
593 if (state->config->tuner_set_frequency)
594 state->config->tuner_set_frequency(&state->frontend, internal->freq);
595
596 if (state->config->tuner_get_frequency)
597 state->config->tuner_get_frequency(&state->frontend, &internal->freq);
598
599 msleep(internal->t_agc1 + internal->t_agc2 + internal->t_derot); /* AGC1, AGC2 and timing loop */
600 dprintk(state->verbose, FE_DEBUG, 1, "current derot freq=%d", internal->derot_freq);
601 internal->status = AGC1OK;
602
603 /* There is signal in the band */
604 if (config->tuner_get_bandwidth)
605 config->tuner_get_bandwidth(&state->frontend, &bandwidth);
606
607 /* disable tuner I/O */
608 stb0899_i2c_gate_ctrl(&state->frontend, 0);
609
610 if (params->srate <= bandwidth / 2)
611 stb0899_search_tmg(state); /* For low rates (SCPC) */
612 else
613 stb0899_check_tmg(state); /* For high rates (MCPC) */
614
615 if (internal->status == TIMINGOK) {
616 dprintk(state->verbose, FE_DEBUG, 1,
617 "TIMING OK ! Derot freq=%d, mclk=%d",
618 internal->derot_freq, internal->mclk);
619
620 if (stb0899_search_carrier(state) == CARRIEROK) { /* Search for carrier */
621 dprintk(state->verbose, FE_DEBUG, 1,
622 "CARRIER OK ! Derot freq=%d, mclk=%d",
623 internal->derot_freq, internal->mclk);
624
625 if (stb0899_search_data(state) == DATAOK) { /* Check for data */
626 dprintk(state->verbose, FE_DEBUG, 1,
627 "DATA OK ! Derot freq=%d, mclk=%d",
628 internal->derot_freq, internal->mclk);
629
630 if (stb0899_check_range(state) == RANGEOK) {
631 dprintk(state->verbose, FE_DEBUG, 1,
632 "RANGE OK ! derot freq=%d, mclk=%d",
633 internal->derot_freq, internal->mclk);
634
635 internal->freq = params->freq + ((internal->derot_freq * internal->mclk) / 1000);
636 reg = stb0899_read_reg(state, STB0899_PLPARM);
637 internal->fecrate = STB0899_GETFIELD(VITCURPUN, reg);
638 dprintk(state->verbose, FE_DEBUG, 1,
639 "freq=%d, internal resultant freq=%d",
640 params->freq, internal->freq);
641
642 dprintk(state->verbose, FE_DEBUG, 1,
643 "internal puncture rate=%d",
644 internal->fecrate);
645 }
646 }
647 }
648 }
649 if (internal->status != RANGEOK)
650 next_sub_range(state);
651
652 } while (internal->sub_range && internal->status != RANGEOK);
653
654 /* Set the timing loop to tracking */
655 stb0899_write_reg(state, STB0899_RTC, 0x33);
656 stb0899_write_reg(state, STB0899_CFD, 0xf7);
657 /* if locked and range ok, set Kdiv */
658 if (internal->status == RANGEOK) {
659 dprintk(state->verbose, FE_DEBUG, 1, "Locked & Range OK !");
660 stb0899_write_reg(state, STB0899_EQON, 0x41); /* Equalizer OFF while acquiring */
661 stb0899_write_reg(state, STB0899_VITSYNC, 0x39); /* SN to b'11 for acquisition */
662
663 /*
664 * Carrier loop optimization versus
665 * symbol Rate/Puncture Rate for Tracking
666 */
667 reg = stb0899_read_reg(state, STB0899_BCLC);
668 switch (internal->fecrate) {
669 case STB0899_FEC_1_2: /* 13 */
670 stb0899_write_reg(state, STB0899_DEMAPVIT, 0x1a);
671 STB0899_SETFIELD_VAL(BETA, reg, betaTab[0][clnI]);
672 stb0899_write_reg(state, STB0899_BCLC, reg);
673 break;
674 case STB0899_FEC_2_3: /* 18 */
675 stb0899_write_reg(state, STB0899_DEMAPVIT, 44);
676 STB0899_SETFIELD_VAL(BETA, reg, betaTab[1][clnI]);
677 stb0899_write_reg(state, STB0899_BCLC, reg);
678 break;
679 case STB0899_FEC_3_4: /* 21 */
680 stb0899_write_reg(state, STB0899_DEMAPVIT, 60);
681 STB0899_SETFIELD_VAL(BETA, reg, betaTab[2][clnI]);
682 stb0899_write_reg(state, STB0899_BCLC, reg);
683 break;
684 case STB0899_FEC_5_6: /* 24 */
685 stb0899_write_reg(state, STB0899_DEMAPVIT, 75);
686 STB0899_SETFIELD_VAL(BETA, reg, betaTab[3][clnI]);
687 stb0899_write_reg(state, STB0899_BCLC, reg);
688 break;
689 case STB0899_FEC_6_7: /* 25 */
690 stb0899_write_reg(state, STB0899_DEMAPVIT, 88);
691 stb0899_write_reg(state, STB0899_ACLC, 0x88);
692 stb0899_write_reg(state, STB0899_BCLC, 0x9a);
693 break;
694 case STB0899_FEC_7_8: /* 26 */
695 stb0899_write_reg(state, STB0899_DEMAPVIT, 94);
696 STB0899_SETFIELD_VAL(BETA, reg, betaTab[4][clnI]);
697 stb0899_write_reg(state, STB0899_BCLC, reg);
698 break;
699 default:
700 dprintk(state->verbose, FE_DEBUG, 1, "Unsupported Puncture Rate");
701 break;
702 }
703 /* release stream merger RESET */
704 reg = stb0899_read_reg(state, STB0899_TSTRES);
705 STB0899_SETFIELD_VAL(FRESRS, reg, 0);
706 stb0899_write_reg(state, STB0899_TSTRES, reg);
707
708 /* disable carrier detector */
709 reg = stb0899_read_reg(state, STB0899_CFD);
710 STB0899_SETFIELD_VAL(CFD_ON, reg, 0);
711 stb0899_write_reg(state, STB0899_CFD, reg);
712
713 stb0899_read_regs(state, STB0899_EQUAI1, eq_const, 10);
714 }
715
716 return internal->status;
717}
718
719/*
720 * stb0899_dvbs2_config_uwp
721 * Configure UWP state machine
722 */
723static void stb0899_dvbs2_config_uwp(struct stb0899_state *state)
724{
725 struct stb0899_internal *internal = &state->internal;
726 struct stb0899_config *config = state->config;
727 u32 uwp1, uwp2, uwp3, reg;
728
729 uwp1 = STB0899_READ_S2REG(STB0899_S2DEMOD, UWP_CNTRL1);
730 uwp2 = STB0899_READ_S2REG(STB0899_S2DEMOD, UWP_CNTRL2);
731 uwp3 = STB0899_READ_S2REG(STB0899_S2DEMOD, UWP_CNTRL3);
732
733 STB0899_SETFIELD_VAL(UWP_ESN0_AVE, uwp1, config->esno_ave);
734 STB0899_SETFIELD_VAL(UWP_ESN0_QUANT, uwp1, config->esno_quant);
735 STB0899_SETFIELD_VAL(UWP_TH_SOF, uwp1, config->uwp_threshold_sof);
736
737 STB0899_SETFIELD_VAL(FE_COARSE_TRK, uwp2, internal->av_frame_coarse);
738 STB0899_SETFIELD_VAL(FE_FINE_TRK, uwp2, internal->av_frame_fine);
739 STB0899_SETFIELD_VAL(UWP_MISS_TH, uwp2, config->miss_threshold);
740
741 STB0899_SETFIELD_VAL(UWP_TH_ACQ, uwp3, config->uwp_threshold_acq);
742 STB0899_SETFIELD_VAL(UWP_TH_TRACK, uwp3, config->uwp_threshold_track);
743
744 stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_UWP_CNTRL1, STB0899_OFF0_UWP_CNTRL1, uwp1);
745 stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_UWP_CNTRL2, STB0899_OFF0_UWP_CNTRL2, uwp2);
746 stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_UWP_CNTRL3, STB0899_OFF0_UWP_CNTRL3, uwp3);
747
748 reg = STB0899_READ_S2REG(STB0899_S2DEMOD, SOF_SRCH_TO);
749 STB0899_SETFIELD_VAL(SOF_SEARCH_TIMEOUT, reg, config->sof_search_timeout);
750 stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_SOF_SRCH_TO, STB0899_OFF0_SOF_SRCH_TO, reg);
751}
752
753/*
754 * stb0899_dvbs2_config_csm_auto
755 * Set CSM to AUTO mode
756 */
757static void stb0899_dvbs2_config_csm_auto(struct stb0899_state *state)
758{
759 u32 reg;
760
761 reg = STB0899_READ_S2REG(STB0899_S2DEMOD, CSM_CNTRL1);
762 STB0899_SETFIELD_VAL(CSM_AUTO_PARAM, reg, 1);
763 stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CSM_CNTRL1, STB0899_OFF0_CSM_CNTRL1, reg);
764}
765
766long Log2Int(int number)
767{
768 int i;
769
770 i = 0;
771 while ((1 << i) <= ABS(number))
772 i++;
773
774 if (number == 0)
775 i = 1;
776
777 return i - 1;
778}
779
780/*
781 * stb0899_dvbs2_calc_srate
782 * compute BTR_NOM_FREQ for the symbol rate
783 */
784static u32 stb0899_dvbs2_calc_srate(struct stb0899_state *state)
785{
786 struct stb0899_internal *internal = &state->internal;
787 struct stb0899_config *config = state->config;
788
789 u32 dec_ratio, dec_rate, decim, remain, intval, btr_nom_freq;
790 u32 master_clk, srate;
791
792 dec_ratio = (internal->master_clk * 2) / (5 * internal->srate);
793 dec_ratio = (dec_ratio == 0) ? 1 : dec_ratio;
794 dec_rate = Log2Int(dec_ratio);
795 decim = 1 << dec_rate;
796 master_clk = internal->master_clk / 1000;
797 srate = internal->srate / 1000;
798
799 if (decim <= 4) {
800 intval = (decim * (1 << (config->btr_nco_bits - 1))) / master_clk;
801 remain = (decim * (1 << (config->btr_nco_bits - 1))) % master_clk;
802 } else {
803 intval = (1 << (config->btr_nco_bits - 1)) / (master_clk / 100) * decim / 100;
804 remain = (decim * (1 << (config->btr_nco_bits - 1))) % master_clk;
805 }
806 btr_nom_freq = (intval * srate) + ((remain * srate) / master_clk);
807
808 return btr_nom_freq;
809}
810
811/*
812 * stb0899_dvbs2_calc_dev
813 * compute the correction to be applied to symbol rate
814 */
815static u32 stb0899_dvbs2_calc_dev(struct stb0899_state *state)
816{
817 struct stb0899_internal *internal = &state->internal;
818 u32 dec_ratio, correction, master_clk, srate;
819
820 dec_ratio = (internal->master_clk * 2) / (5 * internal->srate);
821 dec_ratio = (dec_ratio == 0) ? 1 : dec_ratio;
822
823 master_clk = internal->master_clk / 1000; /* for integer Caculation*/
824 srate = internal->srate / 1000; /* for integer Caculation*/
825 correction = (512 * master_clk) / (2 * dec_ratio * srate);
826
827 return correction;
828}
829
830/*
831 * stb0899_dvbs2_set_srate
832 * Set DVBS2 symbol rate
833 */
834static void stb0899_dvbs2_set_srate(struct stb0899_state *state)
835{
836 struct stb0899_internal *internal = &state->internal;
837
838 u32 dec_ratio, dec_rate, win_sel, decim, f_sym, btr_nom_freq;
839 u32 correction, freq_adj, band_lim, decim_cntrl, reg;
840 u8 anti_alias;
841
842 /*set decimation to 1*/
843 dec_ratio = (internal->master_clk * 2) / (5 * internal->srate);
844 dec_ratio = (dec_ratio == 0) ? 1 : dec_ratio;
845 dec_rate = Log2Int(dec_ratio);
846
847 win_sel = 0;
848 if (dec_rate >= 5)
849 win_sel = dec_rate - 4;
850
851 decim = (1 << dec_rate);
852 /* (FSamp/Fsymbol *100) for integer Caculation */
853 f_sym = internal->master_clk / ((decim * internal->srate) / 1000);
854
855 if (f_sym <= 2250) /* don't band limit signal going into btr block*/
856 band_lim = 1;
857 else
858 band_lim = 0; /* band limit signal going into btr block*/
859
860 decim_cntrl = ((win_sel << 3) & 0x18) + ((band_lim << 5) & 0x20) + (dec_rate & 0x7);
861 stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_DECIM_CNTRL, STB0899_OFF0_DECIM_CNTRL, decim_cntrl);
862
863 if (f_sym <= 3450)
864 anti_alias = 0;
865 else if (f_sym <= 4250)
866 anti_alias = 1;
867 else
868 anti_alias = 2;
869
870 stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_ANTI_ALIAS_SEL, STB0899_OFF0_ANTI_ALIAS_SEL, anti_alias);
871 btr_nom_freq = stb0899_dvbs2_calc_srate(state);
872 stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_BTR_NOM_FREQ, STB0899_OFF0_BTR_NOM_FREQ, btr_nom_freq);
873
874 correction = stb0899_dvbs2_calc_dev(state);
875 reg = STB0899_READ_S2REG(STB0899_S2DEMOD, BTR_CNTRL);
876 STB0899_SETFIELD_VAL(BTR_FREQ_CORR, reg, correction);
877 stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_BTR_CNTRL, STB0899_OFF0_BTR_CNTRL, reg);
878
879 /* scale UWP+CSM frequency to sample rate*/
880 freq_adj = internal->srate / (internal->master_clk / 4096);
881 stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_FREQ_ADJ_SCALE, STB0899_OFF0_FREQ_ADJ_SCALE, freq_adj);
882}
883
884/*
885 * stb0899_dvbs2_set_btr_loopbw
886 * set bit timing loop bandwidth as a percentage of the symbol rate
887 */
888static void stb0899_dvbs2_set_btr_loopbw(struct stb0899_state *state)
889{
890 struct stb0899_internal *internal = &state->internal;
891 struct stb0899_config *config = state->config;
892
893 u32 sym_peak = 23, zeta = 707, loopbw_percent = 60;
894 s32 dec_ratio, dec_rate, k_btr1_rshft, k_btr1, k_btr0_rshft;
895 s32 k_btr0, k_btr2_rshft, k_direct_shift, k_indirect_shift;
896 u32 decim, K, wn, k_direct, k_indirect;
897 u32 reg;
898
899 dec_ratio = (internal->master_clk * 2) / (5 * internal->srate);
900 dec_ratio = (dec_ratio == 0) ? 1 : dec_ratio;
901 dec_rate = Log2Int(dec_ratio);
902 decim = (1 << dec_rate);
903
904 sym_peak *= 576000;
905 K = (1 << config->btr_nco_bits) / (internal->master_clk / 1000);
906 K *= (internal->srate / 1000000) * decim; /*k=k 10^-8*/
907
908 if (K != 0) {
909 K = sym_peak / K;
910 wn = (4 * zeta * zeta) + 1000000;
911 wn = (2 * (loopbw_percent * 1000) * 40 * zeta) /wn; /*wn =wn 10^-8*/
912
913 k_indirect = (wn * wn) / K;
914 k_indirect = k_indirect; /*kindirect = kindirect 10^-6*/
915 k_direct = (2 * wn * zeta) / K; /*kDirect = kDirect 10^-2*/
916 k_direct *= 100;
917
918 k_direct_shift = Log2Int(k_direct) - Log2Int(10000) - 2;
919 k_btr1_rshft = (-1 * k_direct_shift) + config->btr_gain_shift_offset;
920 k_btr1 = k_direct / (1 << k_direct_shift);
921 k_btr1 /= 10000;
922
923 k_indirect_shift = Log2Int(k_indirect + 15) - 20 /*- 2*/;
924 k_btr0_rshft = (-1 * k_indirect_shift) + config->btr_gain_shift_offset;
925 k_btr0 = k_indirect * (1 << (-k_indirect_shift));
926 k_btr0 /= 1000000;
927
928 k_btr2_rshft = 0;
929 if (k_btr0_rshft > 15) {
930 k_btr2_rshft = k_btr0_rshft - 15;
931 k_btr0_rshft = 15;
932 }
933 reg = STB0899_READ_S2REG(STB0899_S2DEMOD, BTR_LOOP_GAIN);
934 STB0899_SETFIELD_VAL(KBTR0_RSHFT, reg, k_btr0_rshft);
935 STB0899_SETFIELD_VAL(KBTR0, reg, k_btr0);
936 STB0899_SETFIELD_VAL(KBTR1_RSHFT, reg, k_btr1_rshft);
937 STB0899_SETFIELD_VAL(KBTR1, reg, k_btr1);
938 STB0899_SETFIELD_VAL(KBTR2_RSHFT, reg, k_btr2_rshft);
939 stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_BTR_LOOP_GAIN, STB0899_OFF0_BTR_LOOP_GAIN, reg);
940 } else
941 stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_BTR_LOOP_GAIN, STB0899_OFF0_BTR_LOOP_GAIN, 0xc4c4f);
942}
943
944/*
945 * stb0899_dvbs2_set_carr_freq
946 * set nominal frequency for carrier search
947 */
948static void stb0899_dvbs2_set_carr_freq(struct stb0899_state *state, s32 carr_freq, u32 master_clk)
949{
950 struct stb0899_config *config = state->config;
951 s32 crl_nom_freq;
952 u32 reg;
953
954 crl_nom_freq = (1 << config->crl_nco_bits) / master_clk;
955 crl_nom_freq *= carr_freq;
956 reg = STB0899_READ_S2REG(STB0899_S2DEMOD, CRL_NOM_FREQ);
957 STB0899_SETFIELD_VAL(CRL_NOM_FREQ, reg, crl_nom_freq);
958 stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CRL_NOM_FREQ, STB0899_OFF0_CRL_NOM_FREQ, reg);
959}
960
961/*
962 * stb0899_dvbs2_init_calc
963 * Initialize DVBS2 UWP, CSM, carrier and timing loops
964 */
965static void stb0899_dvbs2_init_calc(struct stb0899_state *state)
966{
967 struct stb0899_internal *internal = &state->internal;
968 s32 steps, step_size;
969 u32 range, reg;
970
971 /* config uwp and csm */
972 stb0899_dvbs2_config_uwp(state);
973 stb0899_dvbs2_config_csm_auto(state);
974
975 /* initialize BTR */
976 stb0899_dvbs2_set_srate(state);
977 stb0899_dvbs2_set_btr_loopbw(state);
978
979 if (internal->srate / 1000000 >= 15)
980 step_size = (1 << 17) / 5;
981 else if (internal->srate / 1000000 >= 10)
982 step_size = (1 << 17) / 7;
983 else if (internal->srate / 1000000 >= 5)
984 step_size = (1 << 17) / 10;
985 else
986 step_size = (1 << 17) / 4;
987
988 range = internal->srch_range / 1000000;
989 steps = (10 * range * (1 << 17)) / (step_size * (internal->srate / 1000000));
990 steps = (steps + 6) / 10;
991 steps = (steps == 0) ? 1 : steps;
992 if (steps % 2 == 0)
993 stb0899_dvbs2_set_carr_freq(state, internal->center_freq -
994 (internal->step_size * (internal->srate / 20000000)),
995 (internal->master_clk) / 1000000);
996 else
997 stb0899_dvbs2_set_carr_freq(state, internal->center_freq, (internal->master_clk) / 1000000);
998
999 /*Set Carrier Search params (zigzag, num steps and freq step size*/
1000 reg = STB0899_READ_S2REG(STB0899_S2DEMOD, ACQ_CNTRL2);
1001 STB0899_SETFIELD_VAL(ZIGZAG, reg, 1);
1002 STB0899_SETFIELD_VAL(NUM_STEPS, reg, steps);
1003 STB0899_SETFIELD_VAL(FREQ_STEPSIZE, reg, step_size);
1004 stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_ACQ_CNTRL2, STB0899_OFF0_ACQ_CNTRL2, reg);
1005}
1006
1007/*
1008 * stb0899_dvbs2_btr_init
1009 * initialize the timing loop
1010 */
1011static void stb0899_dvbs2_btr_init(struct stb0899_state *state)
1012{
1013 u32 reg;
1014
1015 /* set enable BTR loopback */
1016 reg = STB0899_READ_S2REG(STB0899_S2DEMOD, BTR_CNTRL);
1017 STB0899_SETFIELD_VAL(INTRP_PHS_SENSE, reg, 1);
1018 STB0899_SETFIELD_VAL(BTR_ERR_ENA, reg, 1);
1019 stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_BTR_CNTRL, STB0899_OFF0_BTR_CNTRL, reg);
1020
1021 /* fix btr freq accum at 0 */
1022 stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_BTR_FREQ_INIT, STB0899_OFF0_BTR_FREQ_INIT, 0x10000000);
1023 stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_BTR_FREQ_INIT, STB0899_OFF0_BTR_FREQ_INIT, 0x00000000);
1024
1025 /* fix btr freq accum at 0 */
1026 stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_BTR_PHS_INIT, STB0899_OFF0_BTR_PHS_INIT, 0x10000000);
1027 stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_BTR_PHS_INIT, STB0899_OFF0_BTR_PHS_INIT, 0x00000000);
1028}
1029
1030/*
1031 * stb0899_dvbs2_reacquire
1032 * trigger a DVB-S2 acquisition
1033 */
1034static void stb0899_dvbs2_reacquire(struct stb0899_state *state)
1035{
1036 u32 reg = 0;
1037
1038 /* demod soft reset */
1039 STB0899_SETFIELD_VAL(DVBS2_RESET, reg, 1);
1040 stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_RESET_CNTRL, STB0899_OFF0_RESET_CNTRL, reg);
1041
1042 /*Reset Timing Loop */
1043 stb0899_dvbs2_btr_init(state);
1044
1045 /* reset Carrier loop */
1046 stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CRL_FREQ_INIT, STB0899_OFF0_CRL_FREQ_INIT, (1 << 30));
1047 stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CRL_FREQ_INIT, STB0899_OFF0_CRL_FREQ_INIT, 0);
1048 stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CRL_LOOP_GAIN, STB0899_OFF0_CRL_LOOP_GAIN, 0);
1049 stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CRL_PHS_INIT, STB0899_OFF0_CRL_PHS_INIT, (1 << 30));
1050 stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CRL_PHS_INIT, STB0899_OFF0_CRL_PHS_INIT, 0);
1051
1052 /*release demod soft reset */
1053 reg = 0;
1054 STB0899_SETFIELD_VAL(DVBS2_RESET, reg, 0);
1055 stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_RESET_CNTRL, STB0899_OFF0_RESET_CNTRL, reg);
1056
1057 /* start acquisition process */
1058 stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_ACQUIRE_TRIG, STB0899_OFF0_ACQUIRE_TRIG, 1);
1059 stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_LOCK_LOST, STB0899_OFF0_LOCK_LOST, 0);
1060
1061 /* equalizer Init */
1062 stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_EQUALIZER_INIT, STB0899_OFF0_EQUALIZER_INIT, 1);
1063
1064 /*Start equilizer */
1065 stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_EQUALIZER_INIT, STB0899_OFF0_EQUALIZER_INIT, 0);
1066
1067 reg = STB0899_READ_S2REG(STB0899_S2DEMOD, EQ_CNTRL);
1068 STB0899_SETFIELD_VAL(EQ_SHIFT, reg, 0);
1069 STB0899_SETFIELD_VAL(EQ_DISABLE_UPDATE, reg, 0);
1070 STB0899_SETFIELD_VAL(EQ_DELAY, reg, 0x05);
1071 STB0899_SETFIELD_VAL(EQ_ADAPT_MODE, reg, 0x01);
1072 stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_EQ_CNTRL, STB0899_OFF0_EQ_CNTRL, reg);
1073
1074 /* RESET Packet delineator */
1075 stb0899_write_reg(state, STB0899_PDELCTRL, 0x4a);
1076}
1077
1078/*
1079 * stb0899_dvbs2_get_dmd_status
1080 * get DVB-S2 Demod LOCK status
1081 */
1082static enum stb0899_status stb0899_dvbs2_get_dmd_status(struct stb0899_state *state, int timeout)
1083{
1084 int time = -10, lock = 0, uwp, csm;
1085 u32 reg;
1086
1087 do {
1088 reg = STB0899_READ_S2REG(STB0899_S2DEMOD, DMD_STATUS);
1089 dprintk(state->verbose, FE_DEBUG, 1, "DMD_STATUS=[0x%02x]", reg);
1090 if (STB0899_GETFIELD(IF_AGC_LOCK, reg))
1091 dprintk(state->verbose, FE_DEBUG, 1, "------------->IF AGC LOCKED !");
1092 reg = STB0899_READ_S2REG(STB0899_S2DEMOD, DMD_STAT2);
1093 dprintk(state->verbose, FE_DEBUG, 1, "----------->DMD STAT2=[0x%02x]", reg);
1094 uwp = STB0899_GETFIELD(UWP_LOCK, reg);
1095 csm = STB0899_GETFIELD(CSM_LOCK, reg);
1096 if (uwp && csm)
1097 lock = 1;
1098
1099 time += 10;
1100 msleep(10);
1101
1102 } while ((!lock) && (time <= timeout));
1103
1104 if (lock) {
1105 dprintk(state->verbose, FE_DEBUG, 1, "----------------> DVB-S2 LOCK !");
1106 return DVBS2_DEMOD_LOCK;
1107 } else {
1108 return DVBS2_DEMOD_NOLOCK;
1109 }
1110}
1111
1112/*
1113 * stb0899_dvbs2_get_data_lock
1114 * get FEC status
1115 */
1116static int stb0899_dvbs2_get_data_lock(struct stb0899_state *state, int timeout)
1117{
1118 int time = 0, lock = 0;
1119 u8 reg;
1120
1121 while ((!lock) && (time < timeout)) {
1122 reg = stb0899_read_reg(state, STB0899_CFGPDELSTATUS1);
1123 dprintk(state->verbose, FE_DEBUG, 1, "---------> CFGPDELSTATUS=[0x%02x]", reg);
1124 lock = STB0899_GETFIELD(CFGPDELSTATUS_LOCK, reg);
1125 time++;
1126 }
1127
1128 return lock;
1129}
1130
1131/*
1132 * stb0899_dvbs2_get_fec_status
1133 * get DVB-S2 FEC LOCK status
1134 */
1135static enum stb0899_status stb0899_dvbs2_get_fec_status(struct stb0899_state *state, int timeout)
1136{
1137 int time = 0, Locked;
1138
1139 do {
1140 Locked = stb0899_dvbs2_get_data_lock(state, 1);
1141 time++;
1142 msleep(1);
1143
1144 } while ((!Locked) && (time < timeout));
1145
1146 if (Locked) {
1147 dprintk(state->verbose, FE_DEBUG, 1, "---------->DVB-S2 FEC LOCK !");
1148 return DVBS2_FEC_LOCK;
1149 } else {
1150 return DVBS2_FEC_NOLOCK;
1151 }
1152}
1153
1154
1155/*
1156 * stb0899_dvbs2_init_csm
1157 * set parameters for manual mode
1158 */
1159static void stb0899_dvbs2_init_csm(struct stb0899_state *state, int pilots, enum stb0899_modcod modcod)
1160{
1161 struct stb0899_internal *internal = &state->internal;
1162
1163 s32 dvt_tbl = 1, two_pass = 0, agc_gain = 6, agc_shift = 0, loop_shift = 0, phs_diff_thr = 0x80;
1164 s32 gamma_acq, gamma_rho_acq, gamma_trk, gamma_rho_trk, lock_count_thr;
1165 u32 csm1, csm2, csm3, csm4;
1166
1167 if (((internal->master_clk / internal->srate) <= 4) && (modcod <= 11) && (pilots == 1)) {
1168 switch (modcod) {
1169 case STB0899_QPSK_12:
1170 gamma_acq = 25;
1171 gamma_rho_acq = 2700;
1172 gamma_trk = 12;
1173 gamma_rho_trk = 180;
1174 lock_count_thr = 8;
1175 break;
1176 case STB0899_QPSK_35:
1177 gamma_acq = 38;
1178 gamma_rho_acq = 7182;
1179 gamma_trk = 14;
1180 gamma_rho_trk = 308;
1181 lock_count_thr = 8;
1182 break;
1183 case STB0899_QPSK_23:
1184 gamma_acq = 42;
1185 gamma_rho_acq = 9408;
1186 gamma_trk = 17;
1187 gamma_rho_trk = 476;
1188 lock_count_thr = 8;
1189 break;
1190 case STB0899_QPSK_34:
1191 gamma_acq = 53;
1192 gamma_rho_acq = 16642;
1193 gamma_trk = 19;
1194 gamma_rho_trk = 646;
1195 lock_count_thr = 8;
1196 break;
1197 case STB0899_QPSK_45:
1198 gamma_acq = 53;
1199 gamma_rho_acq = 17119;
1200 gamma_trk = 22;
1201 gamma_rho_trk = 880;
1202 lock_count_thr = 8;
1203 break;
1204 case STB0899_QPSK_56:
1205 gamma_acq = 55;
1206 gamma_rho_acq = 19250;
1207 gamma_trk = 23;
1208 gamma_rho_trk = 989;
1209 lock_count_thr = 8;
1210 break;
1211 case STB0899_QPSK_89:
1212 gamma_acq = 60;
1213 gamma_rho_acq = 24240;
1214 gamma_trk = 24;
1215 gamma_rho_trk = 1176;
1216 lock_count_thr = 8;
1217 break;
1218 case STB0899_QPSK_910:
1219 gamma_acq = 66;
1220 gamma_rho_acq = 29634;
1221 gamma_trk = 24;
1222 gamma_rho_trk = 1176;
1223 lock_count_thr = 8;
1224 break;
1225 default:
1226 gamma_acq = 66;
1227 gamma_rho_acq = 29634;
1228 gamma_trk = 24;
1229 gamma_rho_trk = 1176;
1230 lock_count_thr = 8;
1231 break;
1232 }
1233
1234 csm1 = STB0899_READ_S2REG(STB0899_S2DEMOD, CSM_CNTRL1);
1235 STB0899_SETFIELD_VAL(CSM_AUTO_PARAM, csm1, 0);
1236 stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CSM_CNTRL1, STB0899_OFF0_CSM_CNTRL1, csm1);
1237
1238 csm1 = STB0899_READ_S2REG(STB0899_S2DEMOD, CSM_CNTRL1);
1239 csm2 = STB0899_READ_S2REG(STB0899_S2DEMOD, CSM_CNTRL2);
1240 csm3 = STB0899_READ_S2REG(STB0899_S2DEMOD, CSM_CNTRL3);
1241 csm4 = STB0899_READ_S2REG(STB0899_S2DEMOD, CSM_CNTRL4);
1242
1243 STB0899_SETFIELD_VAL(CSM_DVT_TABLE, csm1, dvt_tbl);
1244 STB0899_SETFIELD_VAL(CSM_TWO_PASS, csm1, two_pass);
1245 STB0899_SETFIELD_VAL(CSM_AGC_GAIN, csm1, agc_gain);
1246 STB0899_SETFIELD_VAL(CSM_AGC_SHIFT, csm1, agc_shift);
1247 STB0899_SETFIELD_VAL(FE_LOOP_SHIFT, csm1, loop_shift);
1248 STB0899_SETFIELD_VAL(CSM_GAMMA_ACQ, csm2, gamma_acq);
1249 STB0899_SETFIELD_VAL(CSM_GAMMA_RHOACQ, csm2, gamma_rho_acq);
1250 STB0899_SETFIELD_VAL(CSM_GAMMA_TRACK, csm3, gamma_trk);
1251 STB0899_SETFIELD_VAL(CSM_GAMMA_RHOTRACK, csm3, gamma_rho_trk);
1252 STB0899_SETFIELD_VAL(CSM_LOCKCOUNT_THRESH, csm4, lock_count_thr);
1253 STB0899_SETFIELD_VAL(CSM_PHASEDIFF_THRESH, csm4, phs_diff_thr);
1254
1255 stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CSM_CNTRL1, STB0899_OFF0_CSM_CNTRL1, csm1);
1256 stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CSM_CNTRL2, STB0899_OFF0_CSM_CNTRL2, csm2);
1257 stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CSM_CNTRL3, STB0899_OFF0_CSM_CNTRL3, csm3);
1258 stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CSM_CNTRL4, STB0899_OFF0_CSM_CNTRL4, csm4);
1259 }
1260}
1261
1262/*
1263 * stb0899_dvbs2_get_srate
1264 * get DVB-S2 Symbol Rate
1265 */
1266static u32 stb0899_dvbs2_get_srate(struct stb0899_state *state)
1267{
1268 struct stb0899_internal *internal = &state->internal;
1269 struct stb0899_config *config = state->config;
1270
1271 u32 bTrNomFreq, srate, decimRate, intval1, intval2, reg;
1272 int div1, div2, rem1, rem2;
1273
1274 div1 = config->btr_nco_bits / 2;
1275 div2 = config->btr_nco_bits - div1 - 1;
1276
1277 bTrNomFreq = STB0899_READ_S2REG(STB0899_S2DEMOD, BTR_NOM_FREQ);
1278
1279 reg = STB0899_READ_S2REG(STB0899_S2DEMOD, DECIM_CNTRL);
1280 decimRate = STB0899_GETFIELD(DECIM_RATE, reg);
1281 decimRate = (1 << decimRate);
1282
1283 intval1 = internal->master_clk / (1 << div1);
1284 intval2 = bTrNomFreq / (1 << div2);
1285
1286 rem1 = internal->master_clk % (1 << div1);
1287 rem2 = bTrNomFreq % (1 << div2);
1288 /* only for integer calculation */
1289 srate = (intval1 * intval2) + ((intval1 * rem2) / (1 << div2)) + ((intval2 * rem1) / (1 << div1));
1290 srate /= decimRate; /*symbrate = (btrnomfreq_register_val*MasterClock)/2^(27+decim_rate_field) */
1291
1292 return srate;
1293}
1294
1295/*
1296 * stb0899_dvbs2_algo
1297 * Search for signal, timing, carrier and data for a given
1298 * frequency in a given range
1299 */
1300enum stb0899_status stb0899_dvbs2_algo(struct stb0899_state *state)
1301{
1302 struct stb0899_internal *internal = &state->internal;
1303 enum stb0899_modcod modcod;
1304
1305 s32 offsetfreq, searchTime, FecLockTime, pilots, iqSpectrum;
1306 int i = 0;
1307 u32 reg, csm1;
1308
1309 if (internal->srate <= 2000000) {
1310 searchTime = 5000; /* 5000 ms max time to lock UWP and CSM, SYMB <= 2Mbs */
1311 FecLockTime = 350; /* 350 ms max time to lock FEC, SYMB <= 2Mbs */
1312 } else if (internal->srate <= 5000000) {
1313 searchTime = 2500; /* 2500 ms max time to lock UWP and CSM, 2Mbs < SYMB <= 5Mbs */
1314 FecLockTime = 170; /* 170 ms max time to lock FEC, 2Mbs< SYMB <= 5Mbs */
1315 } else if (internal->srate <= 10000000) {
1316 searchTime = 1500; /* 1500 ms max time to lock UWP and CSM, 5Mbs <SYMB <= 10Mbs */
1317 FecLockTime = 80; /* 80 ms max time to lock FEC, 5Mbs< SYMB <= 10Mbs */
1318 } else if (internal->srate <= 15000000) {
1319 searchTime = 500; /* 500 ms max time to lock UWP and CSM, 10Mbs <SYMB <= 15Mbs */
1320 FecLockTime = 50; /* 50 ms max time to lock FEC, 10Mbs< SYMB <= 15Mbs */
1321 } else if (internal->srate <= 20000000) {
1322 searchTime = 300; /* 300 ms max time to lock UWP and CSM, 15Mbs < SYMB <= 20Mbs */
1323 FecLockTime = 30; /* 50 ms max time to lock FEC, 15Mbs< SYMB <= 20Mbs */
1324 } else if (internal->srate <= 25000000) {
1325 searchTime = 250; /* 250 ms max time to lock UWP and CSM, 20 Mbs < SYMB <= 25Mbs */
1326 FecLockTime = 25; /* 25 ms max time to lock FEC, 20Mbs< SYMB <= 25Mbs */
1327 } else {
1328 searchTime = 150; /* 150 ms max time to lock UWP and CSM, SYMB > 25Mbs */
1329 FecLockTime = 20; /* 20 ms max time to lock FEC, 20Mbs< SYMB <= 25Mbs */
1330 }
1331
1332 /* Maintain Stream Merger in reset during acquisition */
1333 reg = stb0899_read_reg(state, STB0899_TSTRES);
1334 STB0899_SETFIELD_VAL(FRESRS, reg, 1);
1335 stb0899_write_reg(state, STB0899_TSTRES, reg);
1336
1337 /* enable tuner I/O */
1338 stb0899_i2c_gate_ctrl(&state->frontend, 1);
1339
1340 /* Move tuner to frequency */
1341 if (state->config->tuner_set_frequency)
1342 state->config->tuner_set_frequency(&state->frontend, internal->freq);
1343 if (state->config->tuner_get_frequency)
1344 state->config->tuner_get_frequency(&state->frontend, &internal->freq);
1345
1346 /* disable tuner I/O */
1347 stb0899_i2c_gate_ctrl(&state->frontend, 0);
1348
1349 /* Set IF AGC to acquisition */
1350 reg = STB0899_READ_S2REG(STB0899_S2DEMOD, IF_AGC_CNTRL);
1351 STB0899_SETFIELD_VAL(IF_LOOP_GAIN, reg, 4);
1352 STB0899_SETFIELD_VAL(IF_AGC_REF, reg, 32);
1353 stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_IF_AGC_CNTRL, STB0899_OFF0_IF_AGC_CNTRL, reg);
1354
1355 reg = STB0899_READ_S2REG(STB0899_S2DEMOD, IF_AGC_CNTRL2);
1356 STB0899_SETFIELD_VAL(IF_AGC_DUMP_PER, reg, 0);
1357 stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_IF_AGC_CNTRL2, STB0899_OFF0_IF_AGC_CNTRL2, reg);
1358
1359 /* Initialisation */
1360 stb0899_dvbs2_init_calc(state);
1361
1362 reg = STB0899_READ_S2REG(STB0899_S2DEMOD, DMD_CNTRL2);
1363 switch (internal->inversion) {
1364 case IQ_SWAP_OFF:
1365 STB0899_SETFIELD_VAL(SPECTRUM_INVERT, reg, 0);
1366 break;
1367 case IQ_SWAP_ON:
1368 STB0899_SETFIELD_VAL(SPECTRUM_INVERT, reg, 1);
1369 break;
1370 case IQ_SWAP_AUTO: /* use last successful search first */
1371 STB0899_SETFIELD_VAL(SPECTRUM_INVERT, reg, 1);
1372 break;
1373 }
1374 stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_DMD_CNTRL2, STB0899_OFF0_DMD_CNTRL2, reg);
1375 stb0899_dvbs2_reacquire(state);
1376
1377 /* Wait for demod lock (UWP and CSM) */
1378 internal->status = stb0899_dvbs2_get_dmd_status(state, searchTime);
1379
1380 if (internal->status == DVBS2_DEMOD_LOCK) {
1381 dprintk(state->verbose, FE_DEBUG, 1, "------------> DVB-S2 DEMOD LOCK !");
1382 i = 0;
1383 /* Demod Locked, check FEC status */
1384 internal->status = stb0899_dvbs2_get_fec_status(state, FecLockTime);
1385
1386 /*If false lock (UWP and CSM Locked but no FEC) try 3 time max*/
1387 while ((internal->status != DVBS2_FEC_LOCK) && (i < 3)) {
1388 /* Read the frequency offset*/
1389 offsetfreq = STB0899_READ_S2REG(STB0899_S2DEMOD, CRL_FREQ);
1390
1391 /* Set the Nominal frequency to the found frequency offset for the next reacquire*/
1392 reg = STB0899_READ_S2REG(STB0899_S2DEMOD, CRL_NOM_FREQ);
1393 STB0899_SETFIELD_VAL(CRL_NOM_FREQ, reg, offsetfreq);
1394 stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CRL_NOM_FREQ, STB0899_OFF0_CRL_NOM_FREQ, reg);
1395 stb0899_dvbs2_reacquire(state);
1396 internal->status = stb0899_dvbs2_get_fec_status(state, searchTime);
1397 i++;
1398 }
1399 }
1400
1401 if (internal->status != DVBS2_FEC_LOCK) {
1402 if (internal->inversion == IQ_SWAP_AUTO) {
1403 reg = STB0899_READ_S2REG(STB0899_S2DEMOD, DMD_CNTRL2);
1404 iqSpectrum = STB0899_GETFIELD(SPECTRUM_INVERT, reg);
1405 /* IQ Spectrum Inversion */
1406 STB0899_SETFIELD_VAL(SPECTRUM_INVERT, reg, !iqSpectrum);
1407 stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_DMD_CNTRL2, STB0899_OFF0_DMD_CNTRL2, reg);
1408 /* start acquistion process */
1409 stb0899_dvbs2_reacquire(state);
1410
1411 /* Wait for demod lock (UWP and CSM) */
1412 internal->status = stb0899_dvbs2_get_dmd_status(state, searchTime);
1413 if (internal->status == DVBS2_DEMOD_LOCK) {
1414 i = 0;
1415 /* Demod Locked, check FEC */
1416 internal->status = stb0899_dvbs2_get_fec_status(state, FecLockTime);
1417 /*try thrice for false locks, (UWP and CSM Locked but no FEC) */
1418 while ((internal->status != DVBS2_FEC_LOCK) && (i < 3)) {
1419 /* Read the frequency offset*/
1420 offsetfreq = STB0899_READ_S2REG(STB0899_S2DEMOD, CRL_FREQ);
1421
1422 /* Set the Nominal frequency to the found frequency offset for the next reacquire*/
1423 reg = STB0899_READ_S2REG(STB0899_S2DEMOD, CRL_NOM_FREQ);
1424 STB0899_SETFIELD_VAL(CRL_NOM_FREQ, reg, offsetfreq);
1425 stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CRL_NOM_FREQ, STB0899_OFF0_CRL_NOM_FREQ, reg);
1426
1427 stb0899_dvbs2_reacquire(state);
1428 internal->status = stb0899_dvbs2_get_fec_status(state, searchTime);
1429 i++;
1430 }
1431 }
1432/*
1433 if (pParams->DVBS2State == FE_DVBS2_FEC_LOCKED)
1434 pParams->IQLocked = !iqSpectrum;
1435*/
1436 }
1437 }
1438 if (internal->status == DVBS2_FEC_LOCK) {
1439 dprintk(state->verbose, FE_DEBUG, 1, "----------------> DVB-S2 FEC Lock !");
1440 reg = STB0899_READ_S2REG(STB0899_S2DEMOD, UWP_STAT2);
1441 modcod = STB0899_GETFIELD(UWP_DECODE_MOD, reg) >> 2;
1442 pilots = STB0899_GETFIELD(UWP_DECODE_MOD, reg) & 0x01;
1443
1444 if ((((10 * internal->master_clk) / (internal->srate / 10)) <= 410) &&
1445 (INRANGE(STB0899_QPSK_23, modcod, STB0899_QPSK_910)) &&
1446 (pilots == 1)) {
1447
1448 stb0899_dvbs2_init_csm(state, pilots, modcod);
1449 /* Wait for UWP,CSM and data LOCK 20ms max */
1450 internal->status = stb0899_dvbs2_get_fec_status(state, FecLockTime);
1451
1452 i = 0;
1453 while ((internal->status != DVBS2_FEC_LOCK) && (i < 3)) {
1454 csm1 = STB0899_READ_S2REG(STB0899_S2DEMOD, CSM_CNTRL1);
1455 STB0899_SETFIELD_VAL(CSM_TWO_PASS, csm1, 1);
1456 stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CSM_CNTRL1, STB0899_OFF0_CSM_CNTRL1, csm1);
1457 csm1 = STB0899_READ_S2REG(STB0899_S2DEMOD, CSM_CNTRL1);
1458 STB0899_SETFIELD_VAL(CSM_TWO_PASS, csm1, 0);
1459 stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CSM_CNTRL1, STB0899_OFF0_CSM_CNTRL1, csm1);
1460
1461 internal->status = stb0899_dvbs2_get_fec_status(state, FecLockTime);
1462 i++;
1463 }
1464 }
1465
1466 if ((((10 * internal->master_clk) / (internal->srate / 10)) <= 410) &&
1467 (INRANGE(STB0899_QPSK_12, modcod, STB0899_QPSK_35)) &&
1468 (pilots == 1)) {
1469
1470 /* Equalizer Disable update */
1471 reg = STB0899_READ_S2REG(STB0899_S2DEMOD, EQ_CNTRL);
1472 STB0899_SETFIELD_VAL(EQ_DISABLE_UPDATE, reg, 1);
1473 stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_EQ_CNTRL, STB0899_OFF0_EQ_CNTRL, reg);
1474 }
1475
1476 /* slow down the Equalizer once locked */
1477 reg = STB0899_READ_S2REG(STB0899_S2DEMOD, EQ_CNTRL);
1478 STB0899_SETFIELD_VAL(EQ_SHIFT, reg, 0x02);
1479 stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_EQ_CNTRL, STB0899_OFF0_EQ_CNTRL, reg);
1480
1481 /* Store signal parameters */
1482 offsetfreq = STB0899_READ_S2REG(STB0899_S2DEMOD, CRL_FREQ);
1483
1484 offsetfreq = offsetfreq / ((1 << 30) / 1000);
1485 offsetfreq *= (internal->master_clk / 1000000);
1486 reg = STB0899_READ_S2REG(STB0899_S2DEMOD, DMD_CNTRL2);
1487 if (STB0899_GETFIELD(SPECTRUM_INVERT, reg))
1488 offsetfreq *= -1;
1489
1490 internal->freq = internal->freq - offsetfreq;
1491 internal->srate = stb0899_dvbs2_get_srate(state);
1492
1493 reg = STB0899_READ_S2REG(STB0899_S2DEMOD, UWP_STAT2);
1494 internal->modcod = STB0899_GETFIELD(UWP_DECODE_MOD, reg) >> 2;
1495 internal->pilots = STB0899_GETFIELD(UWP_DECODE_MOD, reg) & 0x01;
1496 internal->frame_length = (STB0899_GETFIELD(UWP_DECODE_MOD, reg) >> 1) & 0x01;
1497
1498 /* Set IF AGC to tracking */
1499 reg = STB0899_READ_S2REG(STB0899_S2DEMOD, IF_AGC_CNTRL);
1500 STB0899_SETFIELD_VAL(IF_LOOP_GAIN, reg, 3);
1501
1502 /* if QPSK 1/2,QPSK 3/5 or QPSK 2/3 set IF AGC reference to 16 otherwise 32*/
1503 if (INRANGE(STB0899_QPSK_12, internal->modcod, STB0899_QPSK_23))
1504 STB0899_SETFIELD_VAL(IF_AGC_REF, reg, 16);
1505
1506 stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_IF_AGC_CNTRL, STB0899_OFF0_IF_AGC_CNTRL, reg);
1507
1508 reg = STB0899_READ_S2REG(STB0899_S2DEMOD, IF_AGC_CNTRL2);
1509 STB0899_SETFIELD_VAL(IF_AGC_DUMP_PER, reg, 7);
1510 stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_IF_AGC_CNTRL2, STB0899_OFF0_IF_AGC_CNTRL2, reg);
1511 }
1512
1513 /* Release Stream Merger Reset */
1514 reg = stb0899_read_reg(state, STB0899_TSTRES);
1515 STB0899_SETFIELD_VAL(FRESRS, reg, 0);
1516 stb0899_write_reg(state, STB0899_TSTRES, reg);
1517
1518 return internal->status;
1519}
diff --git a/drivers/media/dvb/frontends/stb0899_cfg.h b/drivers/media/dvb/frontends/stb0899_cfg.h
new file mode 100644
index 000000000000..0867906d3ff3
--- /dev/null
+++ b/drivers/media/dvb/frontends/stb0899_cfg.h
@@ -0,0 +1,287 @@
1/*
2 STB0899 Multistandard Frontend driver
3 Copyright (C) Manu Abraham (abraham.manu@gmail.com)
4
5 Copyright (C) ST Microelectronics
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 __STB0899_CFG_H
23#define __STB0899_CFG_H
24
25static const struct stb0899_s2_reg stb0899_s2_init_2[] = {
26
27 { STB0899_OFF0_DMD_STATUS , STB0899_BASE_DMD_STATUS , 0x00000103 }, /* DMDSTATUS */
28 { STB0899_OFF0_CRL_FREQ , STB0899_BASE_CRL_FREQ , 0x3ed1da56 }, /* CRLFREQ */
29 { STB0899_OFF0_BTR_FREQ , STB0899_BASE_BTR_FREQ , 0x00004000 }, /* BTRFREQ */
30 { STB0899_OFF0_IF_AGC_GAIN , STB0899_BASE_IF_AGC_GAIN , 0x00002ade }, /* IFAGCGAIN */
31 { STB0899_OFF0_BB_AGC_GAIN , STB0899_BASE_BB_AGC_GAIN , 0x000001bc }, /* BBAGCGAIN */
32 { STB0899_OFF0_DC_OFFSET , STB0899_BASE_DC_OFFSET , 0x00000200 }, /* DCOFFSET */
33 { STB0899_OFF0_DMD_CNTRL , STB0899_BASE_DMD_CNTRL , 0x0000000f }, /* DMDCNTRL */
34
35 { STB0899_OFF0_IF_AGC_CNTRL , STB0899_BASE_IF_AGC_CNTRL , 0x03fb4a20 }, /* IFAGCCNTRL */
36 { STB0899_OFF0_BB_AGC_CNTRL , STB0899_BASE_BB_AGC_CNTRL , 0x00200c97 }, /* BBAGCCNTRL */
37
38 { STB0899_OFF0_CRL_CNTRL , STB0899_BASE_CRL_CNTRL , 0x00000016 }, /* CRLCNTRL */
39 { STB0899_OFF0_CRL_PHS_INIT , STB0899_BASE_CRL_PHS_INIT , 0x00000000 }, /* CRLPHSINIT */
40 { STB0899_OFF0_CRL_FREQ_INIT , STB0899_BASE_CRL_FREQ_INIT , 0x00000000 }, /* CRLFREQINIT */
41 { STB0899_OFF0_CRL_LOOP_GAIN , STB0899_BASE_CRL_LOOP_GAIN , 0x00000000 }, /* CRLLOOPGAIN */
42 { STB0899_OFF0_CRL_NOM_FREQ , STB0899_BASE_CRL_NOM_FREQ , 0x3ed097b6 }, /* CRLNOMFREQ */
43 { STB0899_OFF0_CRL_SWP_RATE , STB0899_BASE_CRL_SWP_RATE , 0x00000000 }, /* CRLSWPRATE */
44 { STB0899_OFF0_CRL_MAX_SWP , STB0899_BASE_CRL_MAX_SWP , 0x00000000 }, /* CRLMAXSWP */
45 { STB0899_OFF0_CRL_LK_CNTRL , STB0899_BASE_CRL_LK_CNTRL , 0x0f6cdc01 }, /* CRLLKCNTRL */
46 { STB0899_OFF0_DECIM_CNTRL , STB0899_BASE_DECIM_CNTRL , 0x00000000 }, /* DECIMCNTRL */
47 { STB0899_OFF0_BTR_CNTRL , STB0899_BASE_BTR_CNTRL , 0x00003993 }, /* BTRCNTRL */
48 { STB0899_OFF0_BTR_LOOP_GAIN , STB0899_BASE_BTR_LOOP_GAIN , 0x000d3c6f }, /* BTRLOOPGAIN */
49 { STB0899_OFF0_BTR_PHS_INIT , STB0899_BASE_BTR_PHS_INIT , 0x00000000 }, /* BTRPHSINIT */
50 { STB0899_OFF0_BTR_FREQ_INIT , STB0899_BASE_BTR_FREQ_INIT , 0x00000000 }, /* BTRFREQINIT */
51 { STB0899_OFF0_BTR_NOM_FREQ , STB0899_BASE_BTR_NOM_FREQ , 0x0238e38e }, /* BTRNOMFREQ */
52 { STB0899_OFF0_BTR_LK_CNTRL , STB0899_BASE_BTR_LK_CNTRL , 0x00000000 }, /* BTRLKCNTRL */
53 { STB0899_OFF0_DECN_CNTRL , STB0899_BASE_DECN_CNTRL , 0x00000000 }, /* DECNCNTRL */
54 { STB0899_OFF0_TP_CNTRL , STB0899_BASE_TP_CNTRL , 0x00000000 }, /* TPCNTRL */
55 { STB0899_OFF0_TP_BUF_STATUS , STB0899_BASE_TP_BUF_STATUS , 0x00000000 }, /* TPBUFSTATUS */
56 { STB0899_OFF0_DC_ESTIM , STB0899_BASE_DC_ESTIM , 0x00000000 }, /* DCESTIM */
57 { STB0899_OFF0_FLL_CNTRL , STB0899_BASE_FLL_CNTRL , 0x00000000 }, /* FLLCNTRL */
58 { STB0899_OFF0_FLL_FREQ_WD , STB0899_BASE_FLL_FREQ_WD , 0x40070000 }, /* FLLFREQWD */
59 { STB0899_OFF0_ANTI_ALIAS_SEL , STB0899_BASE_ANTI_ALIAS_SEL , 0x00000001 }, /* ANTIALIASSEL */
60 { STB0899_OFF0_RRC_ALPHA , STB0899_BASE_RRC_ALPHA , 0x00000002 }, /* RRCALPHA */
61 { STB0899_OFF0_DC_ADAPT_LSHFT , STB0899_BASE_DC_ADAPT_LSHFT , 0x00000000 }, /* DCADAPTISHFT */
62 { STB0899_OFF0_IMB_OFFSET , STB0899_BASE_IMB_OFFSET , 0x0000fe01 }, /* IMBOFFSET */
63 { STB0899_OFF0_IMB_ESTIMATE , STB0899_BASE_IMB_ESTIMATE , 0x00000000 }, /* IMBESTIMATE */
64 { STB0899_OFF0_IMB_CNTRL , STB0899_BASE_IMB_CNTRL , 0x00000001 }, /* IMBCNTRL */
65 { STB0899_OFF0_IF_AGC_CNTRL2 , STB0899_BASE_IF_AGC_CNTRL2 , 0x00005007 }, /* IFAGCCNTRL2 */
66 { STB0899_OFF0_DMD_CNTRL2 , STB0899_BASE_DMD_CNTRL2 , 0x00000002 }, /* DMDCNTRL2 */
67 { STB0899_OFF0_TP_BUFFER , STB0899_BASE_TP_BUFFER , 0x00000000 }, /* TPBUFFER */
68 { STB0899_OFF0_TP_BUFFER1 , STB0899_BASE_TP_BUFFER1 , 0x00000000 }, /* TPBUFFER1 */
69 { STB0899_OFF0_TP_BUFFER2 , STB0899_BASE_TP_BUFFER2 , 0x00000000 }, /* TPBUFFER2 */
70 { STB0899_OFF0_TP_BUFFER3 , STB0899_BASE_TP_BUFFER3 , 0x00000000 }, /* TPBUFFER3 */
71 { STB0899_OFF0_TP_BUFFER4 , STB0899_BASE_TP_BUFFER4 , 0x00000000 }, /* TPBUFFER4 */
72 { STB0899_OFF0_TP_BUFFER5 , STB0899_BASE_TP_BUFFER5 , 0x00000000 }, /* TPBUFFER5 */
73 { STB0899_OFF0_TP_BUFFER6 , STB0899_BASE_TP_BUFFER6 , 0x00000000 }, /* TPBUFFER6 */
74 { STB0899_OFF0_TP_BUFFER7 , STB0899_BASE_TP_BUFFER7 , 0x00000000 }, /* TPBUFFER7 */
75 { STB0899_OFF0_TP_BUFFER8 , STB0899_BASE_TP_BUFFER8 , 0x00000000 }, /* TPBUFFER8 */
76 { STB0899_OFF0_TP_BUFFER9 , STB0899_BASE_TP_BUFFER9 , 0x00000000 }, /* TPBUFFER9 */
77 { STB0899_OFF0_TP_BUFFER10 , STB0899_BASE_TP_BUFFER10 , 0x00000000 }, /* TPBUFFER10 */
78 { STB0899_OFF0_TP_BUFFER11 , STB0899_BASE_TP_BUFFER11 , 0x00000000 }, /* TPBUFFER11 */
79 { STB0899_OFF0_TP_BUFFER12 , STB0899_BASE_TP_BUFFER12 , 0x00000000 }, /* TPBUFFER12 */
80 { STB0899_OFF0_TP_BUFFER13 , STB0899_BASE_TP_BUFFER13 , 0x00000000 }, /* TPBUFFER13 */
81 { STB0899_OFF0_TP_BUFFER14 , STB0899_BASE_TP_BUFFER14 , 0x00000000 }, /* TPBUFFER14 */
82 { STB0899_OFF0_TP_BUFFER15 , STB0899_BASE_TP_BUFFER15 , 0x00000000 }, /* TPBUFFER15 */
83 { STB0899_OFF0_TP_BUFFER16 , STB0899_BASE_TP_BUFFER16 , 0x0000ff00 }, /* TPBUFFER16 */
84 { STB0899_OFF0_TP_BUFFER17 , STB0899_BASE_TP_BUFFER17 , 0x00000100 }, /* TPBUFFER17 */
85 { STB0899_OFF0_TP_BUFFER18 , STB0899_BASE_TP_BUFFER18 , 0x0000fe01 }, /* TPBUFFER18 */
86 { STB0899_OFF0_TP_BUFFER19 , STB0899_BASE_TP_BUFFER19 , 0x000004fe }, /* TPBUFFER19 */
87 { STB0899_OFF0_TP_BUFFER20 , STB0899_BASE_TP_BUFFER20 , 0x0000cfe7 }, /* TPBUFFER20 */
88 { STB0899_OFF0_TP_BUFFER21 , STB0899_BASE_TP_BUFFER21 , 0x0000bec6 }, /* TPBUFFER21 */
89 { STB0899_OFF0_TP_BUFFER22 , STB0899_BASE_TP_BUFFER22 , 0x0000c2bf }, /* TPBUFFER22 */
90 { STB0899_OFF0_TP_BUFFER23 , STB0899_BASE_TP_BUFFER23 , 0x0000c1c1 }, /* TPBUFFER23 */
91 { STB0899_OFF0_TP_BUFFER24 , STB0899_BASE_TP_BUFFER24 , 0x0000c1c1 }, /* TPBUFFER24 */
92 { STB0899_OFF0_TP_BUFFER25 , STB0899_BASE_TP_BUFFER25 , 0x0000c1c1 }, /* TPBUFFER25 */
93 { STB0899_OFF0_TP_BUFFER26 , STB0899_BASE_TP_BUFFER26 , 0x0000c1c1 }, /* TPBUFFER26 */
94 { STB0899_OFF0_TP_BUFFER27 , STB0899_BASE_TP_BUFFER27 , 0x0000c1c0 }, /* TPBUFFER27 */
95 { STB0899_OFF0_TP_BUFFER28 , STB0899_BASE_TP_BUFFER28 , 0x0000c0c0 }, /* TPBUFFER28 */
96 { STB0899_OFF0_TP_BUFFER29 , STB0899_BASE_TP_BUFFER29 , 0x0000c1c1 }, /* TPBUFFER29 */
97 { STB0899_OFF0_TP_BUFFER30 , STB0899_BASE_TP_BUFFER30 , 0x0000c1c1 }, /* TPBUFFER30 */
98 { STB0899_OFF0_TP_BUFFER31 , STB0899_BASE_TP_BUFFER31 , 0x0000c0c1 }, /* TPBUFFER31 */
99 { STB0899_OFF0_TP_BUFFER32 , STB0899_BASE_TP_BUFFER32 , 0x0000c0c1 }, /* TPBUFFER32 */
100 { STB0899_OFF0_TP_BUFFER33 , STB0899_BASE_TP_BUFFER33 , 0x0000c1c1 }, /* TPBUFFER33 */
101 { STB0899_OFF0_TP_BUFFER34 , STB0899_BASE_TP_BUFFER34 , 0x0000c1c1 }, /* TPBUFFER34 */
102 { STB0899_OFF0_TP_BUFFER35 , STB0899_BASE_TP_BUFFER35 , 0x0000c0c1 }, /* TPBUFFER35 */
103 { STB0899_OFF0_TP_BUFFER36 , STB0899_BASE_TP_BUFFER36 , 0x0000c1c1 }, /* TPBUFFER36 */
104 { STB0899_OFF0_TP_BUFFER37 , STB0899_BASE_TP_BUFFER37 , 0x0000c0c1 }, /* TPBUFFER37 */
105 { STB0899_OFF0_TP_BUFFER38 , STB0899_BASE_TP_BUFFER38 , 0x0000c1c1 }, /* TPBUFFER38 */
106 { STB0899_OFF0_TP_BUFFER39 , STB0899_BASE_TP_BUFFER39 , 0x0000c0c0 }, /* TPBUFFER39 */
107 { STB0899_OFF0_TP_BUFFER40 , STB0899_BASE_TP_BUFFER40 , 0x0000c1c0 }, /* TPBUFFER40 */
108 { STB0899_OFF0_TP_BUFFER41 , STB0899_BASE_TP_BUFFER41 , 0x0000c1c1 }, /* TPBUFFER41 */
109 { STB0899_OFF0_TP_BUFFER42 , STB0899_BASE_TP_BUFFER42 , 0x0000c0c0 }, /* TPBUFFER42 */
110 { STB0899_OFF0_TP_BUFFER43 , STB0899_BASE_TP_BUFFER43 , 0x0000c1c0 }, /* TPBUFFER43 */
111 { STB0899_OFF0_TP_BUFFER44 , STB0899_BASE_TP_BUFFER44 , 0x0000c0c1 }, /* TPBUFFER44 */
112 { STB0899_OFF0_TP_BUFFER45 , STB0899_BASE_TP_BUFFER45 , 0x0000c1be }, /* TPBUFFER45 */
113 { STB0899_OFF0_TP_BUFFER46 , STB0899_BASE_TP_BUFFER46 , 0x0000c1c9 }, /* TPBUFFER46 */
114 { STB0899_OFF0_TP_BUFFER47 , STB0899_BASE_TP_BUFFER47 , 0x0000c0da }, /* TPBUFFER47 */
115 { STB0899_OFF0_TP_BUFFER48 , STB0899_BASE_TP_BUFFER48 , 0x0000c0ba }, /* TPBUFFER48 */
116 { STB0899_OFF0_TP_BUFFER49 , STB0899_BASE_TP_BUFFER49 , 0x0000c1c4 }, /* TPBUFFER49 */
117 { STB0899_OFF0_TP_BUFFER50 , STB0899_BASE_TP_BUFFER50 , 0x0000c1bf }, /* TPBUFFER50 */
118 { STB0899_OFF0_TP_BUFFER51 , STB0899_BASE_TP_BUFFER51 , 0x0000c0c1 }, /* TPBUFFER51 */
119 { STB0899_OFF0_TP_BUFFER52 , STB0899_BASE_TP_BUFFER52 , 0x0000c1c0 }, /* TPBUFFER52 */
120 { STB0899_OFF0_TP_BUFFER53 , STB0899_BASE_TP_BUFFER53 , 0x0000c0c1 }, /* TPBUFFER53 */
121 { STB0899_OFF0_TP_BUFFER54 , STB0899_BASE_TP_BUFFER54 , 0x0000c1c1 }, /* TPBUFFER54 */
122 { STB0899_OFF0_TP_BUFFER55 , STB0899_BASE_TP_BUFFER55 , 0x0000c1c1 }, /* TPBUFFER55 */
123 { STB0899_OFF0_TP_BUFFER56 , STB0899_BASE_TP_BUFFER56 , 0x0000c1c1 }, /* TPBUFFER56 */
124 { STB0899_OFF0_TP_BUFFER57 , STB0899_BASE_TP_BUFFER57 , 0x0000c1c1 }, /* TPBUFFER57 */
125 { STB0899_OFF0_TP_BUFFER58 , STB0899_BASE_TP_BUFFER58 , 0x0000c1c1 }, /* TPBUFFER58 */
126 { STB0899_OFF0_TP_BUFFER59 , STB0899_BASE_TP_BUFFER59 , 0x0000c1c1 }, /* TPBUFFER59 */
127 { STB0899_OFF0_TP_BUFFER60 , STB0899_BASE_TP_BUFFER60 , 0x0000c1c1 }, /* TPBUFFER60 */
128 { STB0899_OFF0_TP_BUFFER61 , STB0899_BASE_TP_BUFFER61 , 0x0000c1c1 }, /* TPBUFFER61 */
129 { STB0899_OFF0_TP_BUFFER62 , STB0899_BASE_TP_BUFFER62 , 0x0000c1c1 }, /* TPBUFFER62 */
130 { STB0899_OFF0_TP_BUFFER63 , STB0899_BASE_TP_BUFFER63 , 0x0000c1c0 }, /* TPBUFFER63 */
131 { STB0899_OFF0_RESET_CNTRL , STB0899_BASE_RESET_CNTRL , 0x00000001 }, /* RESETCNTRL */
132 { STB0899_OFF0_ACM_ENABLE , STB0899_BASE_ACM_ENABLE , 0x00005654 }, /* ACMENABLE */
133 { STB0899_OFF0_DESCR_CNTRL , STB0899_BASE_DESCR_CNTRL , 0x00000000 }, /* DESCRCNTRL */
134 { STB0899_OFF0_CSM_CNTRL1 , STB0899_BASE_CSM_CNTRL1 , 0x00020019 }, /* CSMCNTRL1 */
135 { STB0899_OFF0_CSM_CNTRL2 , STB0899_BASE_CSM_CNTRL2 , 0x004b3237 }, /* CSMCNTRL2 */
136 { STB0899_OFF0_CSM_CNTRL3 , STB0899_BASE_CSM_CNTRL3 , 0x0003dd17 }, /* CSMCNTRL3 */
137 { STB0899_OFF0_CSM_CNTRL4 , STB0899_BASE_CSM_CNTRL4 , 0x00008008 }, /* CSMCNTRL4 */
138 { STB0899_OFF0_UWP_CNTRL1 , STB0899_BASE_UWP_CNTRL1 , 0x002a3106 }, /* UWPCNTRL1 */
139 { STB0899_OFF0_UWP_CNTRL2 , STB0899_BASE_UWP_CNTRL2 , 0x0006140a }, /* UWPCNTRL2 */
140 { STB0899_OFF0_UWP_STAT1 , STB0899_BASE_UWP_STAT1 , 0x00008000 }, /* UWPSTAT1 */
141 { STB0899_OFF0_UWP_STAT2 , STB0899_BASE_UWP_STAT2 , 0x00000000 }, /* UWPSTAT2 */
142 { STB0899_OFF0_DMD_STAT2 , STB0899_BASE_DMD_STAT2 , 0x00000000 }, /* DMDSTAT2 */
143 { STB0899_OFF0_FREQ_ADJ_SCALE , STB0899_BASE_FREQ_ADJ_SCALE , 0x00000471 }, /* FREQADJSCALE */
144 { STB0899_OFF0_UWP_CNTRL3 , STB0899_BASE_UWP_CNTRL3 , 0x017b0465 }, /* UWPCNTRL3 */
145 { STB0899_OFF0_SYM_CLK_SEL , STB0899_BASE_SYM_CLK_SEL , 0x00000002 }, /* SYMCLKSEL */
146 { STB0899_OFF0_SOF_SRCH_TO , STB0899_BASE_SOF_SRCH_TO , 0x00196464 }, /* SOFSRCHTO */
147 { STB0899_OFF0_ACQ_CNTRL1 , STB0899_BASE_ACQ_CNTRL1 , 0x00000603 }, /* ACQCNTRL1 */
148 { STB0899_OFF0_ACQ_CNTRL2 , STB0899_BASE_ACQ_CNTRL2 , 0x02046666 }, /* ACQCNTRL2 */
149 { STB0899_OFF0_ACQ_CNTRL3 , STB0899_BASE_ACQ_CNTRL3 , 0x10046583 }, /* ACQCNTRL3 */
150 { STB0899_OFF0_FE_SETTLE , STB0899_BASE_FE_SETTLE , 0x00010404 }, /* FESETTLE */
151 { STB0899_OFF0_AC_DWELL , STB0899_BASE_AC_DWELL , 0x0002aa8a }, /* ACDWELL */
152 { STB0899_OFF0_ACQUIRE_TRIG , STB0899_BASE_ACQUIRE_TRIG , 0x00000000 }, /* ACQUIRETRIG */
153 { STB0899_OFF0_LOCK_LOST , STB0899_BASE_LOCK_LOST , 0x00000001 }, /* LOCKLOST */
154 { STB0899_OFF0_ACQ_STAT1 , STB0899_BASE_ACQ_STAT1 , 0x00000500 }, /* ACQSTAT1 */
155 { STB0899_OFF0_ACQ_TIMEOUT , STB0899_BASE_ACQ_TIMEOUT , 0x0028a0a0 }, /* ACQTIMEOUT */
156 { STB0899_OFF0_ACQ_TIME , STB0899_BASE_ACQ_TIME , 0x00000000 }, /* ACQTIME */
157 { STB0899_OFF0_FINAL_AGC_CNTRL , STB0899_BASE_FINAL_AGC_CNTRL , 0x00800c17 }, /* FINALAGCCNTRL*/
158 { STB0899_OFF0_FINAL_AGC_GAIN , STB0899_BASE_FINAL_AGC_GAIN , 0x00000000 }, /* FINALAGCCGAIN*/
159 { STB0899_OFF0_EQUALIZER_INIT , STB0899_BASE_EQUALIZER_INIT , 0x00000000 }, /* EQUILIZERINIT*/
160 { STB0899_OFF0_EQ_CNTRL , STB0899_BASE_EQ_CNTRL , 0x00054802 }, /* EQCNTL */
161 { STB0899_OFF0_EQ_I_INIT_COEFF_0, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF0 */
162 { STB0899_OFF1_EQ_I_INIT_COEFF_1, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF1 */
163 { STB0899_OFF2_EQ_I_INIT_COEFF_2, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF2 */
164 { STB0899_OFF3_EQ_I_INIT_COEFF_3, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF3 */
165 { STB0899_OFF4_EQ_I_INIT_COEFF_4, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF4 */
166 { STB0899_OFF5_EQ_I_INIT_COEFF_5, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000400 }, /* EQIINITCOEFF5 */
167 { STB0899_OFF6_EQ_I_INIT_COEFF_6, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF6 */
168 { STB0899_OFF7_EQ_I_INIT_COEFF_7, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF7 */
169 { STB0899_OFF8_EQ_I_INIT_COEFF_8, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF8 */
170 { STB0899_OFF9_EQ_I_INIT_COEFF_9, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF9 */
171 { STB0899_OFFa_EQ_I_INIT_COEFF_10,STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF10*/
172 { STB0899_OFF0_EQ_Q_INIT_COEFF_0, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF0 */
173 { STB0899_OFF1_EQ_Q_INIT_COEFF_1, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF1 */
174 { STB0899_OFF2_EQ_Q_INIT_COEFF_2, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF2 */
175 { STB0899_OFF3_EQ_Q_INIT_COEFF_3, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF3 */
176 { STB0899_OFF4_EQ_Q_INIT_COEFF_4, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF4 */
177 { STB0899_OFF5_EQ_Q_INIT_COEFF_5, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF5 */
178 { STB0899_OFF6_EQ_Q_INIT_COEFF_6, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF6 */
179 { STB0899_OFF7_EQ_Q_INIT_COEFF_7, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF7 */
180 { STB0899_OFF8_EQ_Q_INIT_COEFF_8, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF8 */
181 { STB0899_OFF9_EQ_Q_INIT_COEFF_9, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF9 */
182 { STB0899_OFFa_EQ_Q_INIT_COEFF_10,STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF10*/
183 { STB0899_OFF0_EQ_I_OUT_COEFF_0 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT0 */
184 { STB0899_OFF1_EQ_I_OUT_COEFF_1 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT1 */
185 { STB0899_OFF2_EQ_I_OUT_COEFF_2 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT2 */
186 { STB0899_OFF3_EQ_I_OUT_COEFF_3 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT3 */
187 { STB0899_OFF4_EQ_I_OUT_COEFF_4 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT4 */
188 { STB0899_OFF5_EQ_I_OUT_COEFF_5 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT5 */
189 { STB0899_OFF6_EQ_I_OUT_COEFF_6 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT6 */
190 { STB0899_OFF7_EQ_I_OUT_COEFF_7 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT7 */
191 { STB0899_OFF8_EQ_I_OUT_COEFF_8 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT8 */
192 { STB0899_OFF9_EQ_I_OUT_COEFF_9 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT9 */
193 { STB0899_OFFa_EQ_I_OUT_COEFF_10,STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT10*/
194 { STB0899_OFF0_EQ_Q_OUT_COEFF_0 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT0 */
195 { STB0899_OFF1_EQ_Q_OUT_COEFF_1 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT1 */
196 { STB0899_OFF2_EQ_Q_OUT_COEFF_2 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT2 */
197 { STB0899_OFF3_EQ_Q_OUT_COEFF_3 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT3 */
198 { STB0899_OFF4_EQ_Q_OUT_COEFF_4 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT4 */
199 { STB0899_OFF5_EQ_Q_OUT_COEFF_5 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT5 */
200 { STB0899_OFF6_EQ_Q_OUT_COEFF_6 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT6 */
201 { STB0899_OFF7_EQ_Q_OUT_COEFF_7 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT7 */
202 { STB0899_OFF8_EQ_Q_OUT_COEFF_8 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT8 */
203 { STB0899_OFF9_EQ_Q_OUT_COEFF_9 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT9 */
204 { STB0899_OFFa_EQ_Q_OUT_COEFF_10, STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT10*/
205 { 0xffff , 0xffffffff , 0xffffffff },
206};
207static const struct stb0899_s2_reg stb0899_s2_init_4[] = {
208 { STB0899_OFF0_BLOCK_LNGTH , STB0899_BASE_BLOCK_LNGTH , 0x00000008 }, /* BLOCKLNGTH */
209 { STB0899_OFF0_ROW_STR , STB0899_BASE_ROW_STR , 0x000000b4 }, /* ROWSTR */
210 { STB0899_OFF0_BN_END_ADDR , STB0899_BASE_BN_END_ADDR , 0x000004b5 }, /* BNANDADDR */
211 { STB0899_OFF0_CN_END_ADDR , STB0899_BASE_CN_END_ADDR , 0x00000b4b }, /* CNANDADDR */
212 { STB0899_OFF0_INFO_LENGTH , STB0899_BASE_INFO_LENGTH , 0x00000078 }, /* INFOLENGTH */
213 { STB0899_OFF0_BOT_ADDR , STB0899_BASE_BOT_ADDR , 0x000001e0 }, /* BOT_ADDR */
214 { STB0899_OFF0_BCH_BLK_LN , STB0899_BASE_BCH_BLK_LN , 0x0000a8c0 }, /* BCHBLKLN */
215 { STB0899_OFF0_BCH_T , STB0899_BASE_BCH_T , 0x0000000c }, /* BCHT */
216 { STB0899_OFF0_CNFG_MODE , STB0899_BASE_CNFG_MODE , 0x00000001 }, /* CNFGMODE */
217 { STB0899_OFF0_LDPC_STAT , STB0899_BASE_LDPC_STAT , 0x0000000d }, /* LDPCSTAT */
218 { STB0899_OFF0_ITER_SCALE , STB0899_BASE_ITER_SCALE , 0x00000040 }, /* ITERSCALE */
219 { STB0899_OFF0_INPUT_MODE , STB0899_BASE_INPUT_MODE , 0x00000000 }, /* INPUTMODE */
220 { STB0899_OFF0_LDPCDECRST , STB0899_BASE_LDPCDECRST , 0x00000000 }, /* LDPCDECRST */
221 { STB0899_OFF0_CLK_PER_BYTE_RW , STB0899_BASE_CLK_PER_BYTE_RW , 0x00000008 }, /* CLKPERBYTE */
222 { STB0899_OFF0_BCH_ERRORS , STB0899_BASE_BCH_ERRORS , 0x00000000 }, /* BCHERRORS */
223 { STB0899_OFF0_LDPC_ERRORS , STB0899_BASE_LDPC_ERRORS , 0x00000000 }, /* LDPCERRORS */
224 { STB0899_OFF0_BCH_MODE , STB0899_BASE_BCH_MODE , 0x00000000 }, /* BCHMODE */
225 { STB0899_OFF0_ERR_ACC_PER , STB0899_BASE_ERR_ACC_PER , 0x00000008 }, /* ERRACCPER */
226 { STB0899_OFF0_BCH_ERR_ACC , STB0899_BASE_BCH_ERR_ACC , 0x00000000 }, /* BCHERRACC */
227 { STB0899_OFF0_FEC_TP_SEL , STB0899_BASE_FEC_TP_SEL , 0x00000000 }, /* FECTPSEL */
228 { 0xffff , 0xffffffff , 0xffffffff },
229};
230
231static const struct stb0899_s1_reg stb0899_s1_init_5[] = {
232 { STB0899_TSTCK , 0x00 },
233 { STB0899_TSTRES , 0x00 },
234 { STB0899_TSTOUT , 0x00 },
235 { STB0899_TSTIN , 0x00 },
236 { STB0899_TSTSYS , 0x00 },
237 { STB0899_TSTCHIP , 0x00 },
238 { STB0899_TSTFREE , 0x00 },
239 { STB0899_TSTI2C , 0x00 },
240 { STB0899_BITSPEEDM , 0x00 },
241 { STB0899_BITSPEEDL , 0x00 },
242 { STB0899_TBUSBIT , 0x00 },
243 { STB0899_TSTDIS , 0x00 },
244 { STB0899_TSTDISRX , 0x00 },
245 { STB0899_TSTJETON , 0x00 },
246 { STB0899_TSTDCADJ , 0x00 },
247 { STB0899_TSTAGC1 , 0x00 },
248 { STB0899_TSTAGC1N , 0x00 },
249 { STB0899_TSTPOLYPH , 0x00 },
250 { STB0899_TSTR , 0x00 },
251 { STB0899_TSTAGC2 , 0x00 },
252 { STB0899_TSTCTL1 , 0x00 },
253 { STB0899_TSTCTL2 , 0x00 },
254 { STB0899_TSTCTL3 , 0x00 },
255 { STB0899_TSTDEMAP , 0x00 },
256 { STB0899_TSTDEMAP2 , 0x00 },
257 { STB0899_TSTDEMMON , 0x00 },
258 { STB0899_TSTRATE , 0x00 },
259 { STB0899_TSTSELOUT , 0x00 },
260 { STB0899_TSYNC , 0x00 },
261 { STB0899_TSTERR , 0x00 },
262 { STB0899_TSTRAM1 , 0x00 },
263 { STB0899_TSTVSELOUT , 0x00 },
264 { STB0899_TSTFORCEIN , 0x00 },
265 { STB0899_TSTRS1 , 0x00 },
266 { STB0899_TSTRS2 , 0x00 },
267 { STB0899_TSTRS3 , 0x00 },
268 { STB0899_GHOSTREG , 0x81 },
269 { 0xffff , 0xff },
270};
271
272#define STB0899_DVBS2_ESNO_AVE 3
273#define STB0899_DVBS2_ESNO_QUANT 32
274#define STB0899_DVBS2_AVFRAMES_COARSE 10
275#define STB0899_DVBS2_AVFRAMES_FINE 20
276#define STB0899_DVBS2_MISS_THRESHOLD 6
277#define STB0899_DVBS2_UWP_THRESHOLD_ACQ 1125
278#define STB0899_DVBS2_UWP_THRESHOLD_TRACK 758
279#define STB0899_DVBS2_UWP_THRESHOLD_SOF 1350
280#define STB0899_DVBS2_SOF_SEARCH_TIMEOUT 1664100
281
282#define STB0899_DVBS2_BTR_NCO_BITS 28
283#define STB0899_DVBS2_BTR_GAIN_SHIFT_OFFSET 15
284#define STB0899_DVBS2_CRL_NCO_BITS 30
285#define STB0899_DVBS2_LDPC_MAX_ITER 70
286
287#endif //__STB0899_CFG_H
diff --git a/drivers/media/dvb/frontends/stb0899_drv.c b/drivers/media/dvb/frontends/stb0899_drv.c
new file mode 100644
index 000000000000..528820170228
--- /dev/null
+++ b/drivers/media/dvb/frontends/stb0899_drv.c
@@ -0,0 +1,1684 @@
1/*
2 STB0899 Multistandard Frontend driver
3 Copyright (C) Manu Abraham (abraham.manu@gmail.com)
4
5 Copyright (C) ST Microelectronics
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/init.h>
23#include <linux/kernel.h>
24#include <linux/module.h>
25#include <linux/string.h>
26
27#include <linux/dvb/frontend.h>
28#include "dvb_frontend.h"
29
30#include "stb0899_drv.h"
31#include "stb0899_priv.h"
32#include "stb0899_reg.h"
33
34static unsigned int verbose = 0;//1;
35module_param(verbose, int, 0644);
36
37/* C/N in dB/10, NIRM/NIRL */
38static const struct stb0899_tab stb0899_cn_tab[] = {
39 { 200, 2600 },
40 { 190, 2700 },
41 { 180, 2860 },
42 { 170, 3020 },
43 { 160, 3210 },
44 { 150, 3440 },
45 { 140, 3710 },
46 { 130, 4010 },
47 { 120, 4360 },
48 { 110, 4740 },
49 { 100, 5190 },
50 { 90, 5670 },
51 { 80, 6200 },
52 { 70, 6770 },
53 { 60, 7360 },
54 { 50, 7970 },
55 { 40, 8250 },
56 { 30, 9000 },
57 { 20, 9450 },
58 { 15, 9600 },
59};
60
61/* DVB-S AGCIQ_VALUE vs. signal level in dBm/10.
62 * As measured, connected to a modulator.
63 * -8.0 to -50.0 dBm directly connected,
64 * -52.0 to -74.8 with extra attenuation.
65 * Cut-off to AGCIQ_VALUE = 0x80 below -74.8dBm.
66 * Crude linear extrapolation below -84.8dBm and above -8.0dBm.
67 */
68static const struct stb0899_tab stb0899_dvbsrf_tab[] = {
69 { -950, -128 },
70 { -748, -94 },
71 { -745, -92 },
72 { -735, -90 },
73 { -720, -87 },
74 { -670, -77 },
75 { -640, -70 },
76 { -610, -62 },
77 { -600, -60 },
78 { -590, -56 },
79 { -560, -41 },
80 { -540, -25 },
81 { -530, -17 },
82 { -520, -11 },
83 { -500, 1 },
84 { -490, 6 },
85 { -480, 10 },
86 { -440, 22 },
87 { -420, 27 },
88 { -400, 31 },
89 { -380, 34 },
90 { -340, 40 },
91 { -320, 43 },
92 { -280, 48 },
93 { -250, 52 },
94 { -230, 55 },
95 { -180, 61 },
96 { -140, 66 },
97 { -90, 73 },
98 { -80, 74 },
99 { 500, 127 }
100};
101
102/* DVB-S2 IF_AGC_GAIN vs. signal level in dBm/10.
103 * As measured, connected to a modulator.
104 * -8.0 to -50.1 dBm directly connected,
105 * -53.0 to -76.6 with extra attenuation.
106 * Cut-off to IF_AGC_GAIN = 0x3fff below -76.6dBm.
107 * Crude linear extrapolation below -76.6dBm and above -8.0dBm.
108 */
109static const struct stb0899_tab stb0899_dvbs2rf_tab[] = {
110 { 700, 0 },
111 { -80, 3217 },
112 { -150, 3893 },
113 { -190, 4217 },
114 { -240, 4621 },
115 { -280, 4945 },
116 { -320, 5273 },
117 { -350, 5545 },
118 { -370, 5741 },
119 { -410, 6147 },
120 { -450, 6671 },
121 { -490, 7413 },
122 { -501, 7665 },
123 { -530, 8767 },
124 { -560, 10219 },
125 { -580, 10939 },
126 { -590, 11518 },
127 { -600, 11723 },
128 { -650, 12659 },
129 { -690, 13219 },
130 { -730, 13645 },
131 { -750, 13909 },
132 { -766, 14153 },
133 { -999, 16383 }
134};
135
136/* DVB-S2 Es/N0 quant in dB/100 vs read value * 100*/
137struct stb0899_tab stb0899_quant_tab[] = {
138 { 0, 0 },
139 { 0, 100 },
140 { 600, 200 },
141 { 950, 299 },
142 { 1200, 398 },
143 { 1400, 501 },
144 { 1560, 603 },
145 { 1690, 700 },
146 { 1810, 804 },
147 { 1910, 902 },
148 { 2000, 1000 },
149 { 2080, 1096 },
150 { 2160, 1202 },
151 { 2230, 1303 },
152 { 2350, 1496 },
153 { 2410, 1603 },
154 { 2460, 1698 },
155 { 2510, 1799 },
156 { 2600, 1995 },
157 { 2650, 2113 },
158 { 2690, 2213 },
159 { 2720, 2291 },
160 { 2760, 2399 },
161 { 2800, 2512 },
162 { 2860, 2692 },
163 { 2930, 2917 },
164 { 2960, 3020 },
165 { 3010, 3199 },
166 { 3040, 3311 },
167 { 3060, 3388 },
168 { 3120, 3631 },
169 { 3190, 3936 },
170 { 3400, 5012 },
171 { 3610, 6383 },
172 { 3800, 7943 },
173 { 4210, 12735 },
174 { 4500, 17783 },
175 { 4690, 22131 },
176 { 4810, 25410 }
177};
178
179/* DVB-S2 Es/N0 estimate in dB/100 vs read value */
180struct stb0899_tab stb0899_est_tab[] = {
181 { 0, 0 },
182 { 0, 1 },
183 { 301, 2 },
184 { 1204, 16 },
185 { 1806, 64 },
186 { 2408, 256 },
187 { 2709, 512 },
188 { 3010, 1023 },
189 { 3311, 2046 },
190 { 3612, 4093 },
191 { 3823, 6653 },
192 { 3913, 8185 },
193 { 4010, 10233 },
194 { 4107, 12794 },
195 { 4214, 16368 },
196 { 4266, 18450 },
197 { 4311, 20464 },
198 { 4353, 22542 },
199 { 4391, 24604 },
200 { 4425, 26607 },
201 { 4457, 28642 },
202 { 4487, 30690 },
203 { 4515, 32734 },
204 { 4612, 40926 },
205 { 4692, 49204 },
206 { 4816, 65464 },
207 { 4913, 81846 },
208 { 4993, 98401 },
209 { 5060, 114815 },
210 { 5118, 131220 },
211 { 5200, 158489 },
212 { 5300, 199526 },
213 { 5400, 251189 },
214 { 5500, 316228 },
215 { 5600, 398107 },
216 { 5720, 524807 },
217 { 5721, 526017 },
218};
219
220int _stb0899_read_reg(struct stb0899_state *state, unsigned int reg)
221{
222 int ret;
223
224 u8 b0[] = { reg >> 8, reg & 0xff };
225 u8 buf;
226
227 struct i2c_msg msg[] = {
228 {
229 .addr = state->config->demod_address,
230 .flags = 0,
231 .buf = b0,
232 .len = 2
233 },{
234 .addr = state->config->demod_address,
235 .flags = I2C_M_RD,
236 .buf = &buf,
237 .len = 1
238 }
239 };
240
241 ret = i2c_transfer(state->i2c, msg, 2);
242 if (ret != 2) {
243 if (ret != -ERESTARTSYS)
244 dprintk(state->verbose, FE_ERROR, 1,
245 "Read error, Reg=[0x%02x], Status=%d",
246 reg, ret);
247
248 return ret < 0 ? ret : -EREMOTEIO;
249 }
250 if (unlikely(*state->verbose >= FE_DEBUGREG))
251 dprintk(state->verbose, FE_ERROR, 1, "Reg=[0x%02x], data=%02x",
252 reg, buf);
253
254 return (unsigned int)buf;
255}
256
257int stb0899_read_reg(struct stb0899_state *state, unsigned int reg)
258{
259 int result;
260
261 result = _stb0899_read_reg(state, reg);
262 /*
263 * Bug ID 9:
264 * access to 0xf2xx/0xf6xx
265 * must be followed by read from 0xf2ff/0xf6ff.
266 */
267 if ((reg != 0xf2ff) && (reg != 0xf6ff) &&
268 (((reg & 0xff00) == 0xf200) || ((reg & 0xff00) == 0xf600)))
269 _stb0899_read_reg(state, (reg | 0x00ff));
270
271 return result;
272}
273
274u32 _stb0899_read_s2reg(struct stb0899_state *state,
275 u32 stb0899_i2cdev,
276 u32 stb0899_base_addr,
277 u16 stb0899_reg_offset)
278{
279 int status;
280 u32 data;
281 u8 buf[7] = { 0 };
282 u16 tmpaddr;
283
284 u8 buf_0[] = {
285 GETBYTE(stb0899_i2cdev, BYTE1), /* 0xf3 S2 Base Address (MSB) */
286 GETBYTE(stb0899_i2cdev, BYTE0), /* 0xfc S2 Base Address (LSB) */
287 GETBYTE(stb0899_base_addr, BYTE0), /* 0x00 Base Address (LSB) */
288 GETBYTE(stb0899_base_addr, BYTE1), /* 0x04 Base Address (LSB) */
289 GETBYTE(stb0899_base_addr, BYTE2), /* 0x00 Base Address (MSB) */
290 GETBYTE(stb0899_base_addr, BYTE3), /* 0x00 Base Address (MSB) */
291 };
292 u8 buf_1[] = {
293 0x00, /* 0xf3 Reg Offset */
294 0x00, /* 0x44 Reg Offset */
295 };
296
297 struct i2c_msg msg_0 = {
298 .addr = state->config->demod_address,
299 .flags = 0,
300 .buf = buf_0,
301 .len = 6
302 };
303
304 struct i2c_msg msg_1 = {
305 .addr = state->config->demod_address,
306 .flags = 0,
307 .buf = buf_1,
308 .len = 2
309 };
310
311 struct i2c_msg msg_r = {
312 .addr = state->config->demod_address,
313 .flags = I2C_M_RD,
314 .buf = buf,
315 .len = 4
316 };
317
318 tmpaddr = stb0899_reg_offset & 0xff00;
319 if (!(stb0899_reg_offset & 0x8))
320 tmpaddr = stb0899_reg_offset | 0x20;
321
322 buf_1[0] = GETBYTE(tmpaddr, BYTE1);
323 buf_1[1] = GETBYTE(tmpaddr, BYTE0);
324
325 status = i2c_transfer(state->i2c, &msg_0, 1);
326 if (status < 1) {
327 if (status != -ERESTARTSYS)
328 printk(KERN_ERR "%s ERR(1), Device=[0x%04x], Base address=[0x%08x], Offset=[0x%04x], Status=%d\n",
329 __func__, stb0899_i2cdev, stb0899_base_addr, stb0899_reg_offset, status);
330
331 goto err;
332 }
333
334 /* Dummy */
335 status = i2c_transfer(state->i2c, &msg_1, 1);
336 if (status < 1)
337 goto err;
338
339 status = i2c_transfer(state->i2c, &msg_r, 1);
340 if (status < 1)
341 goto err;
342
343 buf_1[0] = GETBYTE(stb0899_reg_offset, BYTE1);
344 buf_1[1] = GETBYTE(stb0899_reg_offset, BYTE0);
345
346 /* Actual */
347 status = i2c_transfer(state->i2c, &msg_1, 1);
348 if (status < 1) {
349 if (status != -ERESTARTSYS)
350 printk(KERN_ERR "%s ERR(2), Device=[0x%04x], Base address=[0x%08x], Offset=[0x%04x], Status=%d\n",
351 __func__, stb0899_i2cdev, stb0899_base_addr, stb0899_reg_offset, status);
352 goto err;
353 }
354
355 status = i2c_transfer(state->i2c, &msg_r, 1);
356 if (status < 1) {
357 if (status != -ERESTARTSYS)
358 printk(KERN_ERR "%s ERR(3), Device=[0x%04x], Base address=[0x%08x], Offset=[0x%04x], Status=%d\n",
359 __func__, stb0899_i2cdev, stb0899_base_addr, stb0899_reg_offset, status);
360 return status < 0 ? status : -EREMOTEIO;
361 }
362
363 data = MAKEWORD32(buf[3], buf[2], buf[1], buf[0]);
364 if (unlikely(*state->verbose >= FE_DEBUGREG))
365 printk(KERN_DEBUG "%s Device=[0x%04x], Base address=[0x%08x], Offset=[0x%04x], Data=[0x%08x]\n",
366 __func__, stb0899_i2cdev, stb0899_base_addr, stb0899_reg_offset, data);
367
368 return data;
369
370err:
371 return status < 0 ? status : -EREMOTEIO;
372}
373
374int stb0899_write_s2reg(struct stb0899_state *state,
375 u32 stb0899_i2cdev,
376 u32 stb0899_base_addr,
377 u16 stb0899_reg_offset,
378 u32 stb0899_data)
379{
380 int status;
381
382 /* Base Address Setup */
383 u8 buf_0[] = {
384 GETBYTE(stb0899_i2cdev, BYTE1), /* 0xf3 S2 Base Address (MSB) */
385 GETBYTE(stb0899_i2cdev, BYTE0), /* 0xfc S2 Base Address (LSB) */
386 GETBYTE(stb0899_base_addr, BYTE0), /* 0x00 Base Address (LSB) */
387 GETBYTE(stb0899_base_addr, BYTE1), /* 0x04 Base Address (LSB) */
388 GETBYTE(stb0899_base_addr, BYTE2), /* 0x00 Base Address (MSB) */
389 GETBYTE(stb0899_base_addr, BYTE3), /* 0x00 Base Address (MSB) */
390 };
391 u8 buf_1[] = {
392 0x00, /* 0xf3 Reg Offset */
393 0x00, /* 0x44 Reg Offset */
394 0x00, /* data */
395 0x00, /* data */
396 0x00, /* data */
397 0x00, /* data */
398 };
399
400 struct i2c_msg msg_0 = {
401 .addr = state->config->demod_address,
402 .flags = 0,
403 .buf = buf_0,
404 .len = 6
405 };
406
407 struct i2c_msg msg_1 = {
408 .addr = state->config->demod_address,
409 .flags = 0,
410 .buf = buf_1,
411 .len = 6
412 };
413
414 buf_1[0] = GETBYTE(stb0899_reg_offset, BYTE1);
415 buf_1[1] = GETBYTE(stb0899_reg_offset, BYTE0);
416 buf_1[2] = GETBYTE(stb0899_data, BYTE0);
417 buf_1[3] = GETBYTE(stb0899_data, BYTE1);
418 buf_1[4] = GETBYTE(stb0899_data, BYTE2);
419 buf_1[5] = GETBYTE(stb0899_data, BYTE3);
420
421 if (unlikely(*state->verbose >= FE_DEBUGREG))
422 printk(KERN_DEBUG "%s Device=[0x%04x], Base Address=[0x%08x], Offset=[0x%04x], Data=[0x%08x]\n",
423 __func__, stb0899_i2cdev, stb0899_base_addr, stb0899_reg_offset, stb0899_data);
424
425 status = i2c_transfer(state->i2c, &msg_0, 1);
426 if (unlikely(status < 1)) {
427 if (status != -ERESTARTSYS)
428 printk(KERN_ERR "%s ERR (1), Device=[0x%04x], Base Address=[0x%08x], Offset=[0x%04x], Data=[0x%08x], status=%d\n",
429 __func__, stb0899_i2cdev, stb0899_base_addr, stb0899_reg_offset, stb0899_data, status);
430 goto err;
431 }
432 status = i2c_transfer(state->i2c, &msg_1, 1);
433 if (unlikely(status < 1)) {
434 if (status != -ERESTARTSYS)
435 printk(KERN_ERR "%s ERR (2), Device=[0x%04x], Base Address=[0x%08x], Offset=[0x%04x], Data=[0x%08x], status=%d\n",
436 __func__, stb0899_i2cdev, stb0899_base_addr, stb0899_reg_offset, stb0899_data, status);
437
438 return status < 0 ? status : -EREMOTEIO;
439 }
440
441 return 0;
442
443err:
444 return status < 0 ? status : -EREMOTEIO;
445}
446
447int stb0899_read_regs(struct stb0899_state *state, unsigned int reg, u8 *buf, u32 count)
448{
449 int status;
450
451 u8 b0[] = { reg >> 8, reg & 0xff };
452
453 struct i2c_msg msg[] = {
454 {
455 .addr = state->config->demod_address,
456 .flags = 0,
457 .buf = b0,
458 .len = 2
459 },{
460 .addr = state->config->demod_address,
461 .flags = I2C_M_RD,
462 .buf = buf,
463 .len = count
464 }
465 };
466
467 status = i2c_transfer(state->i2c, msg, 2);
468 if (status != 2) {
469 if (status != -ERESTARTSYS)
470 printk(KERN_ERR "%s Read error, Reg=[0x%04x], Count=%u, Status=%d\n",
471 __func__, reg, count, status);
472 goto err;
473 }
474 /*
475 * Bug ID 9:
476 * access to 0xf2xx/0xf6xx
477 * must be followed by read from 0xf2ff/0xf6ff.
478 */
479 if ((reg != 0xf2ff) && (reg != 0xf6ff) &&
480 (((reg & 0xff00) == 0xf200) || ((reg & 0xff00) == 0xf600)))
481 _stb0899_read_reg(state, (reg | 0x00ff));
482
483 if (unlikely(*state->verbose >= FE_DEBUGREG)) {
484 int i;
485
486 printk(KERN_DEBUG "%s [0x%04x]:", __func__, reg);
487 for (i = 0; i < count; i++) {
488 printk(" %02x", buf[i]);
489 }
490 printk("\n");
491 }
492
493 return 0;
494err:
495 return status < 0 ? status : -EREMOTEIO;
496}
497
498int stb0899_write_regs(struct stb0899_state *state, unsigned int reg, u8 *data, u32 count)
499{
500 int ret;
501 u8 buf[2 + count];
502 struct i2c_msg i2c_msg = {
503 .addr = state->config->demod_address,
504 .flags = 0,
505 .buf = buf,
506 .len = 2 + count
507 };
508
509 buf[0] = reg >> 8;
510 buf[1] = reg & 0xff;
511 memcpy(&buf[2], data, count);
512
513 if (unlikely(*state->verbose >= FE_DEBUGREG)) {
514 int i;
515
516 printk(KERN_DEBUG "%s [0x%04x]:", __func__, reg);
517 for (i = 0; i < count; i++)
518 printk(" %02x", data[i]);
519 printk("\n");
520 }
521 ret = i2c_transfer(state->i2c, &i2c_msg, 1);
522
523 /*
524 * Bug ID 9:
525 * access to 0xf2xx/0xf6xx
526 * must be followed by read from 0xf2ff/0xf6ff.
527 */
528 if ((((reg & 0xff00) == 0xf200) || ((reg & 0xff00) == 0xf600)))
529 stb0899_read_reg(state, (reg | 0x00ff));
530
531 if (ret != 1) {
532 if (ret != -ERESTARTSYS)
533 dprintk(state->verbose, FE_ERROR, 1, "Reg=[0x%04x], Data=[0x%02x ...], Count=%u, Status=%d",
534 reg, data[0], count, ret);
535 return ret < 0 ? ret : -EREMOTEIO;
536 }
537
538 return 0;
539}
540
541int stb0899_write_reg(struct stb0899_state *state, unsigned int reg, u8 data)
542{
543 return stb0899_write_regs(state, reg, &data, 1);
544}
545
546/*
547 * stb0899_get_mclk
548 * Get STB0899 master clock frequency
549 * ExtClk: external clock frequency (Hz)
550 */
551static u32 stb0899_get_mclk(struct stb0899_state *state)
552{
553 u32 mclk = 0, div = 0;
554
555 div = stb0899_read_reg(state, STB0899_NCOARSE);
556 mclk = (div + 1) * state->config->xtal_freq / 6;
557 dprintk(state->verbose, FE_DEBUG, 1, "div=%d, mclk=%d", div, mclk);
558
559 return mclk;
560}
561
562/*
563 * stb0899_set_mclk
564 * Set STB0899 master Clock frequency
565 * Mclk: demodulator master clock
566 * ExtClk: external clock frequency (Hz)
567 */
568static void stb0899_set_mclk(struct stb0899_state *state, u32 Mclk)
569{
570 struct stb0899_internal *internal = &state->internal;
571 u8 mdiv = 0;
572
573 dprintk(state->verbose, FE_DEBUG, 1, "state->config=%p", state->config);
574 mdiv = ((6 * Mclk) / state->config->xtal_freq) - 1;
575 dprintk(state->verbose, FE_DEBUG, 1, "mdiv=%d", mdiv);
576
577 stb0899_write_reg(state, STB0899_NCOARSE, mdiv);
578 internal->master_clk = stb0899_get_mclk(state);
579
580 dprintk(state->verbose, FE_DEBUG, 1, "MasterCLOCK=%d", internal->master_clk);
581}
582
583static int stb0899_postproc(struct stb0899_state *state, u8 ctl, int enable)
584{
585 struct stb0899_config *config = state->config;
586 const struct stb0899_postproc *postproc = config->postproc;
587
588 /* post process event */
589 if (postproc) {
590 if (enable) {
591 if (postproc[ctl].level == STB0899_GPIOPULLUP)
592 stb0899_write_reg(state, postproc[ctl].gpio, 0x02);
593 else
594 stb0899_write_reg(state, postproc[ctl].gpio, 0x82);
595 } else {
596 if (postproc[ctl].level == STB0899_GPIOPULLUP)
597 stb0899_write_reg(state, postproc[ctl].gpio, 0x82);
598 else
599 stb0899_write_reg(state, postproc[ctl].gpio, 0x02);
600 }
601 }
602 return 0;
603}
604
605static void stb0899_release(struct dvb_frontend *fe)
606{
607 struct stb0899_state *state = fe->demodulator_priv;
608
609 dprintk(state->verbose, FE_DEBUG, 1, "Release Frontend");
610 /* post process event */
611 stb0899_postproc(state, STB0899_POSTPROC_GPIO_POWER, 0);
612 kfree(state);
613}
614
615/*
616 * stb0899_get_alpha
617 * return: rolloff
618 */
619static int stb0899_get_alpha(struct stb0899_state *state)
620{
621 u8 mode_coeff;
622
623 mode_coeff = stb0899_read_reg(state, STB0899_DEMOD);
624
625 if (STB0899_GETFIELD(MODECOEFF, mode_coeff) == 1)
626 return 20;
627 else
628 return 35;
629}
630
631/*
632 * stb0899_init_calc
633 */
634static void stb0899_init_calc(struct stb0899_state *state)
635{
636 struct stb0899_internal *internal = &state->internal;
637 int master_clk;
638 u8 agc[2];
639 u8 agc1cn;
640 u32 reg;
641
642 /* Read registers (in burst mode) */
643 agc1cn = stb0899_read_reg(state, STB0899_AGC1CN);
644 stb0899_read_regs(state, STB0899_AGC1REF, agc, 2); /* AGC1R and AGC2O */
645
646 /* Initial calculations */
647 master_clk = stb0899_get_mclk(state);
648 internal->t_agc1 = 0;
649 internal->t_agc2 = 0;
650 internal->master_clk = master_clk;
651 internal->mclk = master_clk / 65536L;
652 internal->rolloff = stb0899_get_alpha(state);
653
654 /* DVBS2 Initial calculations */
655 /* Set AGC value to the middle */
656 internal->agc_gain = 8154;
657 reg = STB0899_READ_S2REG(STB0899_S2DEMOD, IF_AGC_CNTRL);
658 STB0899_SETFIELD_VAL(IF_GAIN_INIT, reg, internal->agc_gain);
659 stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_IF_AGC_CNTRL, STB0899_OFF0_IF_AGC_CNTRL, reg);
660
661 reg = STB0899_READ_S2REG(STB0899_S2DEMOD, RRC_ALPHA);
662 internal->rrc_alpha = STB0899_GETFIELD(RRC_ALPHA, reg);
663
664 internal->center_freq = 0;
665 internal->av_frame_coarse = 10;
666 internal->av_frame_fine = 20;
667 internal->step_size = 2;
668/*
669 if ((pParams->SpectralInv == FE_IQ_NORMAL) || (pParams->SpectralInv == FE_IQ_AUTO))
670 pParams->IQLocked = 0;
671 else
672 pParams->IQLocked = 1;
673*/
674}
675
676static int stb0899_wait_diseqc_fifo_empty(struct stb0899_state *state, int timeout)
677{
678 u8 reg = 0;
679 unsigned long start = jiffies;
680
681 while (1) {
682 reg = stb0899_read_reg(state, STB0899_DISSTATUS);
683 if (!STB0899_GETFIELD(FIFOFULL, reg))
684 break;
685 if ((jiffies - start) > timeout) {
686 dprintk(state->verbose, FE_ERROR, 1, "timed out !!");
687 return -ETIMEDOUT;
688 }
689 }
690
691 return 0;
692}
693
694static int stb0899_send_diseqc_msg(struct dvb_frontend *fe, struct dvb_diseqc_master_cmd *cmd)
695{
696 struct stb0899_state *state = fe->demodulator_priv;
697 u8 reg, i;
698
699 if (cmd->msg_len > 8)
700 return -EINVAL;
701
702 /* enable FIFO precharge */
703 reg = stb0899_read_reg(state, STB0899_DISCNTRL1);
704 STB0899_SETFIELD_VAL(DISPRECHARGE, reg, 1);
705 stb0899_write_reg(state, STB0899_DISCNTRL1, reg);
706 for (i = 0; i < cmd->msg_len; i++) {
707 /* wait for FIFO empty */
708 if (stb0899_wait_diseqc_fifo_empty(state, 10) < 0)
709 return -ETIMEDOUT;
710
711 stb0899_write_reg(state, STB0899_DISFIFO, cmd->msg[i]);
712 }
713 reg = stb0899_read_reg(state, STB0899_DISCNTRL1);
714 STB0899_SETFIELD_VAL(DISPRECHARGE, reg, 0);
715 stb0899_write_reg(state, STB0899_DISCNTRL1, reg);
716
717 return 0;
718}
719
720static int stb0899_wait_diseqc_rxidle(struct stb0899_state *state, int timeout)
721{
722 u8 reg = 0;
723 unsigned long start = jiffies;
724
725 while (!STB0899_GETFIELD(RXEND, reg)) {
726 reg = stb0899_read_reg(state, STB0899_DISRX_ST0);
727 if (jiffies - start > timeout) {
728 dprintk(state->verbose, FE_ERROR, 1, "timed out!!");
729 return -ETIMEDOUT;
730 }
731 msleep(10);
732 }
733
734 return 0;
735}
736
737static int stb0899_recv_slave_reply(struct dvb_frontend *fe, struct dvb_diseqc_slave_reply *reply)
738{
739 struct stb0899_state *state = fe->demodulator_priv;
740 u8 reg, length = 0, i;
741 int result;
742
743 if (stb0899_wait_diseqc_rxidle(state, 100) < 0)
744 return -ETIMEDOUT;
745
746 reg = stb0899_read_reg(state, STB0899_DISRX_ST0);
747 if (STB0899_GETFIELD(RXEND, reg)) {
748
749 reg = stb0899_read_reg(state, STB0899_DISRX_ST1);
750 length = STB0899_GETFIELD(FIFOBYTENBR, reg);
751
752 if (length > sizeof (reply->msg)) {
753 result = -EOVERFLOW;
754 goto exit;
755 }
756 reply->msg_len = length;
757
758 /* extract data */
759 for (i = 0; i < length; i++)
760 reply->msg[i] = stb0899_read_reg(state, STB0899_DISFIFO);
761 }
762
763 return 0;
764exit:
765
766 return result;
767}
768
769static int stb0899_wait_diseqc_txidle(struct stb0899_state *state, int timeout)
770{
771 u8 reg = 0;
772 unsigned long start = jiffies;
773
774 while (!STB0899_GETFIELD(TXIDLE, reg)) {
775 reg = stb0899_read_reg(state, STB0899_DISSTATUS);
776 if (jiffies - start > timeout) {
777 dprintk(state->verbose, FE_ERROR, 1, "timed out!!");
778 return -ETIMEDOUT;
779 }
780 msleep(10);
781 }
782 return 0;
783}
784
785static int stb0899_send_diseqc_burst(struct dvb_frontend *fe, fe_sec_mini_cmd_t burst)
786{
787 struct stb0899_state *state = fe->demodulator_priv;
788 u8 reg, old_state;
789
790 /* wait for diseqc idle */
791 if (stb0899_wait_diseqc_txidle(state, 100) < 0)
792 return -ETIMEDOUT;
793
794 reg = stb0899_read_reg(state, STB0899_DISCNTRL1);
795 old_state = reg;
796 /* set to burst mode */
797 STB0899_SETFIELD_VAL(DISEQCMODE, reg, 0x02);
798 STB0899_SETFIELD_VAL(DISPRECHARGE, reg, 0x01);
799 stb0899_write_reg(state, STB0899_DISCNTRL1, reg);
800 switch (burst) {
801 case SEC_MINI_A:
802 /* unmodulated */
803 stb0899_write_reg(state, STB0899_DISFIFO, 0x00);
804 break;
805 case SEC_MINI_B:
806 /* modulated */
807 stb0899_write_reg(state, STB0899_DISFIFO, 0xff);
808 break;
809 }
810 reg = stb0899_read_reg(state, STB0899_DISCNTRL1);
811 STB0899_SETFIELD_VAL(DISPRECHARGE, reg, 0x00);
812 stb0899_write_reg(state, STB0899_DISCNTRL1, reg);
813 /* wait for diseqc idle */
814 if (stb0899_wait_diseqc_txidle(state, 100) < 0)
815 return -ETIMEDOUT;
816
817 /* restore state */
818 stb0899_write_reg(state, STB0899_DISCNTRL1, old_state);
819
820 return 0;
821}
822
823static int stb0899_diseqc_init(struct stb0899_state *state)
824{
825 struct dvb_diseqc_master_cmd tx_data;
826/*
827 struct dvb_diseqc_slave_reply rx_data;
828*/
829 u8 f22_tx, f22_rx, reg;
830
831 u32 mclk, tx_freq = 22000;/* count = 0, i; */
832 tx_data.msg[0] = 0xe2;
833 tx_data.msg_len = 3;
834 reg = stb0899_read_reg(state, STB0899_DISCNTRL2);
835 STB0899_SETFIELD_VAL(ONECHIP_TRX, reg, 0);
836 stb0899_write_reg(state, STB0899_DISCNTRL2, reg);
837
838 /* disable Tx spy */
839 reg = stb0899_read_reg(state, STB0899_DISCNTRL1);
840 STB0899_SETFIELD_VAL(DISEQCRESET, reg, 1);
841 stb0899_write_reg(state, STB0899_DISCNTRL1, reg);
842
843 reg = stb0899_read_reg(state, STB0899_DISCNTRL1);
844 STB0899_SETFIELD_VAL(DISEQCRESET, reg, 0);
845 stb0899_write_reg(state, STB0899_DISCNTRL1, reg);
846
847 mclk = stb0899_get_mclk(state);
848 f22_tx = mclk / (tx_freq * 32);
849 stb0899_write_reg(state, STB0899_DISF22, f22_tx); /* DiSEqC Tx freq */
850 state->rx_freq = 20000;
851 f22_rx = mclk / (state->rx_freq * 32);
852
853 return 0;
854}
855
856static int stb0899_sleep(struct dvb_frontend *fe)
857{
858 struct stb0899_state *state = fe->demodulator_priv;
859/*
860 u8 reg;
861*/
862 dprintk(state->verbose, FE_DEBUG, 1, "Going to Sleep .. (Really tired .. :-))");
863 /* post process event */
864 stb0899_postproc(state, STB0899_POSTPROC_GPIO_POWER, 0);
865
866 return 0;
867}
868
869static int stb0899_wakeup(struct dvb_frontend *fe)
870{
871 int rc;
872 struct stb0899_state *state = fe->demodulator_priv;
873
874 if ((rc = stb0899_write_reg(state, STB0899_SYNTCTRL, STB0899_SELOSCI)))
875 return rc;
876 /* Activate all clocks; DVB-S2 registers are inaccessible otherwise. */
877 if ((rc = stb0899_write_reg(state, STB0899_STOPCLK1, 0x00)))
878 return rc;
879 if ((rc = stb0899_write_reg(state, STB0899_STOPCLK2, 0x00)))
880 return rc;
881
882 /* post process event */
883 stb0899_postproc(state, STB0899_POSTPROC_GPIO_POWER, 1);
884
885 return 0;
886}
887
888static int stb0899_init(struct dvb_frontend *fe)
889{
890 int i;
891 struct stb0899_state *state = fe->demodulator_priv;
892 struct stb0899_config *config = state->config;
893
894 dprintk(state->verbose, FE_DEBUG, 1, "Initializing STB0899 ... ");
895
896 /* init device */
897 dprintk(state->verbose, FE_DEBUG, 1, "init device");
898 for (i = 0; config->init_dev[i].address != 0xffff; i++)
899 stb0899_write_reg(state, config->init_dev[i].address, config->init_dev[i].data);
900
901 dprintk(state->verbose, FE_DEBUG, 1, "init S2 demod");
902 /* init S2 demod */
903 for (i = 0; config->init_s2_demod[i].offset != 0xffff; i++)
904 stb0899_write_s2reg(state, STB0899_S2DEMOD,
905 config->init_s2_demod[i].base_address,
906 config->init_s2_demod[i].offset,
907 config->init_s2_demod[i].data);
908
909 dprintk(state->verbose, FE_DEBUG, 1, "init S1 demod");
910 /* init S1 demod */
911 for (i = 0; config->init_s1_demod[i].address != 0xffff; i++)
912 stb0899_write_reg(state, config->init_s1_demod[i].address, config->init_s1_demod[i].data);
913
914 dprintk(state->verbose, FE_DEBUG, 1, "init S2 FEC");
915 /* init S2 fec */
916 for (i = 0; config->init_s2_fec[i].offset != 0xffff; i++)
917 stb0899_write_s2reg(state, STB0899_S2FEC,
918 config->init_s2_fec[i].base_address,
919 config->init_s2_fec[i].offset,
920 config->init_s2_fec[i].data);
921
922 dprintk(state->verbose, FE_DEBUG, 1, "init TST");
923 /* init test */
924 for (i = 0; config->init_tst[i].address != 0xffff; i++)
925 stb0899_write_reg(state, config->init_tst[i].address, config->init_tst[i].data);
926
927 stb0899_init_calc(state);
928 stb0899_diseqc_init(state);
929
930 return 0;
931}
932
933static int stb0899_table_lookup(const struct stb0899_tab *tab, int max, int val)
934{
935 int res = 0;
936 int min = 0, med;
937
938 if (val < tab[min].read)
939 res = tab[min].real;
940 else if (val >= tab[max].read)
941 res = tab[max].real;
942 else {
943 while ((max - min) > 1) {
944 med = (max + min) / 2;
945 if (val >= tab[min].read && val < tab[med].read)
946 max = med;
947 else
948 min = med;
949 }
950 res = ((val - tab[min].read) *
951 (tab[max].real - tab[min].real) /
952 (tab[max].read - tab[min].read)) +
953 tab[min].real;
954 }
955
956 return res;
957}
958
959static int stb0899_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
960{
961 struct stb0899_state *state = fe->demodulator_priv;
962 struct stb0899_internal *internal = &state->internal;
963
964 int val;
965 u32 reg;
966 switch (state->delsys) {
967 case SYS_DVBS:
968 case SYS_DSS:
969 if (internal->lock) {
970 reg = stb0899_read_reg(state, STB0899_VSTATUS);
971 if (STB0899_GETFIELD(VSTATUS_LOCKEDVIT, reg)) {
972
973 reg = stb0899_read_reg(state, STB0899_AGCIQIN);
974 val = (s32)(s8)STB0899_GETFIELD(AGCIQVALUE, reg);
975
976 *strength = stb0899_table_lookup(stb0899_dvbsrf_tab, ARRAY_SIZE(stb0899_dvbsrf_tab) - 1, val);
977 *strength += 750;
978 dprintk(state->verbose, FE_DEBUG, 1, "AGCIQVALUE = 0x%02x, C = %d * 0.1 dBm",
979 val & 0xff, *strength);
980 }
981 }
982 break;
983 case SYS_DVBS2:
984 if (internal->lock) {
985 reg = STB0899_READ_S2REG(STB0899_DEMOD, IF_AGC_GAIN);
986 val = STB0899_GETFIELD(IF_AGC_GAIN, reg);
987
988 *strength = stb0899_table_lookup(stb0899_dvbs2rf_tab, ARRAY_SIZE(stb0899_dvbs2rf_tab) - 1, val);
989 *strength += 750;
990 dprintk(state->verbose, FE_DEBUG, 1, "IF_AGC_GAIN = 0x%04x, C = %d * 0.1 dBm",
991 val & 0x3fff, *strength);
992 }
993 break;
994 default:
995 dprintk(state->verbose, FE_DEBUG, 1, "Unsupported delivery system");
996 return -EINVAL;
997 }
998
999 return 0;
1000}
1001
1002static int stb0899_read_snr(struct dvb_frontend *fe, u16 *snr)
1003{
1004 struct stb0899_state *state = fe->demodulator_priv;
1005 struct stb0899_internal *internal = &state->internal;
1006
1007 unsigned int val, quant, quantn = -1, est, estn = -1;
1008 u8 buf[2];
1009 u32 reg;
1010
1011 reg = stb0899_read_reg(state, STB0899_VSTATUS);
1012 switch (state->delsys) {
1013 case SYS_DVBS:
1014 case SYS_DSS:
1015 if (internal->lock) {
1016 if (STB0899_GETFIELD(VSTATUS_LOCKEDVIT, reg)) {
1017
1018 stb0899_read_regs(state, STB0899_NIRM, buf, 2);
1019 val = MAKEWORD16(buf[0], buf[1]);
1020
1021 *snr = stb0899_table_lookup(stb0899_cn_tab, ARRAY_SIZE(stb0899_cn_tab) - 1, val);
1022 dprintk(state->verbose, FE_DEBUG, 1, "NIR = 0x%02x%02x = %u, C/N = %d * 0.1 dBm\n",
1023 buf[0], buf[1], val, *snr);
1024 }
1025 }
1026 break;
1027 case SYS_DVBS2:
1028 if (internal->lock) {
1029 reg = STB0899_READ_S2REG(STB0899_S2DEMOD, UWP_CNTRL1);
1030 quant = STB0899_GETFIELD(UWP_ESN0_QUANT, reg);
1031 reg = STB0899_READ_S2REG(STB0899_S2DEMOD, UWP_STAT2);
1032 est = STB0899_GETFIELD(ESN0_EST, reg);
1033 if (est == 1)
1034 val = 301; /* C/N = 30.1 dB */
1035 else if (est == 2)
1036 val = 270; /* C/N = 27.0 dB */
1037 else {
1038 /* quantn = 100 * log(quant^2) */
1039 quantn = stb0899_table_lookup(stb0899_quant_tab, ARRAY_SIZE(stb0899_quant_tab) - 1, quant * 100);
1040 /* estn = 100 * log(est) */
1041 estn = stb0899_table_lookup(stb0899_est_tab, ARRAY_SIZE(stb0899_est_tab) - 1, est);
1042 /* snr(dBm/10) = -10*(log(est)-log(quant^2)) => snr(dBm/10) = (100*log(quant^2)-100*log(est))/10 */
1043 val = (quantn - estn) / 10;
1044 }
1045 *snr = val;
1046 dprintk(state->verbose, FE_DEBUG, 1, "Es/N0 quant = %d (%d) estimate = %u (%d), C/N = %d * 0.1 dBm",
1047 quant, quantn, est, estn, val);
1048 }
1049 break;
1050 default:
1051 dprintk(state->verbose, FE_DEBUG, 1, "Unsupported delivery system");
1052 return -EINVAL;
1053 }
1054
1055 return 0;
1056}
1057
1058static int stb0899_read_status(struct dvb_frontend *fe, enum fe_status *status)
1059{
1060 struct stb0899_state *state = fe->demodulator_priv;
1061 struct stb0899_internal *internal = &state->internal;
1062 u8 reg;
1063 *status = 0;
1064
1065 switch (state->delsys) {
1066 case SYS_DVBS:
1067 case SYS_DSS:
1068 dprintk(state->verbose, FE_DEBUG, 1, "Delivery system DVB-S/DSS");
1069 if (internal->lock) {
1070 reg = stb0899_read_reg(state, STB0899_VSTATUS);
1071 if (STB0899_GETFIELD(VSTATUS_LOCKEDVIT, reg)) {
1072 dprintk(state->verbose, FE_DEBUG, 1, "--------> FE_HAS_CARRIER | FE_HAS_LOCK");
1073 *status |= FE_HAS_CARRIER | FE_HAS_LOCK;
1074
1075 reg = stb0899_read_reg(state, STB0899_PLPARM);
1076 if (STB0899_GETFIELD(VITCURPUN, reg)) {
1077 dprintk(state->verbose, FE_DEBUG, 1, "--------> FE_HAS_VITERBI | FE_HAS_SYNC");
1078 *status |= FE_HAS_VITERBI | FE_HAS_SYNC;
1079 /* post process event */
1080 stb0899_postproc(state, STB0899_POSTPROC_GPIO_LOCK, 1);
1081 }
1082 }
1083 }
1084 break;
1085 case SYS_DVBS2:
1086 dprintk(state->verbose, FE_DEBUG, 1, "Delivery system DVB-S2");
1087 if (internal->lock) {
1088 reg = STB0899_READ_S2REG(STB0899_S2DEMOD, DMD_STAT2);
1089 if (STB0899_GETFIELD(UWP_LOCK, reg) && STB0899_GETFIELD(CSM_LOCK, reg)) {
1090 *status |= FE_HAS_CARRIER;
1091 dprintk(state->verbose, FE_DEBUG, 1,
1092 "UWP & CSM Lock ! ---> DVB-S2 FE_HAS_CARRIER");
1093
1094 reg = stb0899_read_reg(state, STB0899_CFGPDELSTATUS1);
1095 if (STB0899_GETFIELD(CFGPDELSTATUS_LOCK, reg)) {
1096 *status |= FE_HAS_LOCK;
1097 dprintk(state->verbose, FE_DEBUG, 1,
1098 "Packet Delineator Locked ! -----> DVB-S2 FE_HAS_LOCK");
1099
1100 }
1101 if (STB0899_GETFIELD(CONTINUOUS_STREAM, reg)) {
1102 *status |= FE_HAS_VITERBI;
1103 dprintk(state->verbose, FE_DEBUG, 1,
1104 "Packet Delineator found VITERBI ! -----> DVB-S2 FE_HAS_VITERBI");
1105 }
1106 if (STB0899_GETFIELD(ACCEPTED_STREAM, reg)) {
1107 *status |= FE_HAS_SYNC;
1108 dprintk(state->verbose, FE_DEBUG, 1,
1109 "Packet Delineator found SYNC ! -----> DVB-S2 FE_HAS_SYNC");
1110 /* post process event */
1111 stb0899_postproc(state, STB0899_POSTPROC_GPIO_LOCK, 1);
1112 }
1113 }
1114 }
1115 break;
1116 default:
1117 dprintk(state->verbose, FE_DEBUG, 1, "Unsupported delivery system");
1118 return -EINVAL;
1119 }
1120 return 0;
1121}
1122
1123/*
1124 * stb0899_get_error
1125 * viterbi error for DVB-S/DSS
1126 * packet error for DVB-S2
1127 * Bit Error Rate or Packet Error Rate * 10 ^ 7
1128 */
1129static int stb0899_read_ber(struct dvb_frontend *fe, u32 *ber)
1130{
1131 struct stb0899_state *state = fe->demodulator_priv;
1132 struct stb0899_internal *internal = &state->internal;
1133
1134 u8 lsb, msb;
1135 u32 i;
1136
1137 *ber = 0;
1138
1139 switch (state->delsys) {
1140 case SYS_DVBS:
1141 case SYS_DSS:
1142 if (internal->lock) {
1143 /* average 5 BER values */
1144 for (i = 0; i < 5; i++) {
1145 msleep(100);
1146 lsb = stb0899_read_reg(state, STB0899_ECNT1L);
1147 msb = stb0899_read_reg(state, STB0899_ECNT1M);
1148 *ber += MAKEWORD16(msb, lsb);
1149 }
1150 *ber /= 5;
1151 /* Viterbi Check */
1152 if (STB0899_GETFIELD(VSTATUS_PRFVIT, internal->v_status)) {
1153 /* Error Rate */
1154 *ber *= 9766;
1155 /* ber = ber * 10 ^ 7 */
1156 *ber /= (-1 + (1 << (2 * STB0899_GETFIELD(NOE, internal->err_ctrl))));
1157 *ber /= 8;
1158 }
1159 }
1160 break;
1161 case SYS_DVBS2:
1162 if (internal->lock) {
1163 /* Average 5 PER values */
1164 for (i = 0; i < 5; i++) {
1165 msleep(100);
1166 lsb = stb0899_read_reg(state, STB0899_ECNT1L);
1167 msb = stb0899_read_reg(state, STB0899_ECNT1M);
1168 *ber += MAKEWORD16(msb, lsb);
1169 }
1170 /* ber = ber * 10 ^ 7 */
1171 *ber *= 10000000;
1172 *ber /= (-1 + (1 << (4 + 2 * STB0899_GETFIELD(NOE, internal->err_ctrl))));
1173 }
1174 break;
1175 default:
1176 dprintk(state->verbose, FE_DEBUG, 1, "Unsupported delivery system");
1177 return -EINVAL;
1178 }
1179
1180 return 0;
1181}
1182
1183static int stb0899_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
1184{
1185 struct stb0899_state *state = fe->demodulator_priv;
1186
1187 switch (voltage) {
1188 case SEC_VOLTAGE_13:
1189 stb0899_write_reg(state, STB0899_GPIO00CFG, 0x82);
1190 stb0899_write_reg(state, STB0899_GPIO01CFG, 0x02);
1191 stb0899_write_reg(state, STB0899_GPIO02CFG, 0x00);
1192 break;
1193 case SEC_VOLTAGE_18:
1194 stb0899_write_reg(state, STB0899_GPIO00CFG, 0x02);
1195 stb0899_write_reg(state, STB0899_GPIO01CFG, 0x02);
1196 stb0899_write_reg(state, STB0899_GPIO02CFG, 0x82);
1197 break;
1198 case SEC_VOLTAGE_OFF:
1199 stb0899_write_reg(state, STB0899_GPIO00CFG, 0x82);
1200 stb0899_write_reg(state, STB0899_GPIO01CFG, 0x82);
1201 stb0899_write_reg(state, STB0899_GPIO02CFG, 0x82);
1202 break;
1203 default:
1204 return -EINVAL;
1205 }
1206
1207 return 0;
1208}
1209
1210static int stb0899_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
1211{
1212 struct stb0899_state *state = fe->demodulator_priv;
1213 struct stb0899_internal *internal = &state->internal;
1214
1215 u8 div, reg;
1216
1217 /* wait for diseqc idle */
1218 if (stb0899_wait_diseqc_txidle(state, 100) < 0)
1219 return -ETIMEDOUT;
1220
1221 switch (tone) {
1222 case SEC_TONE_ON:
1223 div = (internal->master_clk / 100) / 5632;
1224 div = (div + 5) / 10;
1225 stb0899_write_reg(state, STB0899_DISEQCOCFG, 0x66);
1226 reg = stb0899_read_reg(state, STB0899_ACRPRESC);
1227 STB0899_SETFIELD_VAL(ACRPRESC, reg, 0x03);
1228 stb0899_write_reg(state, STB0899_ACRPRESC, reg);
1229 stb0899_write_reg(state, STB0899_ACRDIV1, div);
1230 break;
1231 case SEC_TONE_OFF:
1232 stb0899_write_reg(state, STB0899_DISEQCOCFG, 0x20);
1233 break;
1234 default:
1235 return -EINVAL;
1236 }
1237 return 0;
1238}
1239
1240int stb0899_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
1241{
1242 int i2c_stat;
1243 struct stb0899_state *state = fe->demodulator_priv;
1244
1245 i2c_stat = stb0899_read_reg(state, STB0899_I2CRPT);
1246 if (i2c_stat < 0)
1247 goto err;
1248
1249 if (enable) {
1250 dprintk(state->verbose, FE_DEBUG, 1, "Enabling I2C Repeater ...");
1251 i2c_stat |= STB0899_I2CTON;
1252 if (stb0899_write_reg(state, STB0899_I2CRPT, i2c_stat) < 0)
1253 goto err;
1254 } else {
1255 dprintk(state->verbose, FE_DEBUG, 1, "Disabling I2C Repeater ...");
1256 i2c_stat &= ~STB0899_I2CTON;
1257 if (stb0899_write_reg(state, STB0899_I2CRPT, i2c_stat) < 0)
1258 goto err;
1259 }
1260 return 0;
1261err:
1262 dprintk(state->verbose, FE_ERROR, 1, "I2C Repeater control failed");
1263 return -EREMOTEIO;
1264}
1265
1266
1267static inline void CONVERT32(u32 x, char *str)
1268{
1269 *str++ = (x >> 24) & 0xff;
1270 *str++ = (x >> 16) & 0xff;
1271 *str++ = (x >> 8) & 0xff;
1272 *str++ = (x >> 0) & 0xff;
1273 *str = '\0';
1274}
1275
1276int stb0899_get_dev_id(struct stb0899_state *state)
1277{
1278 u8 chip_id, release;
1279 u16 id;
1280 u32 demod_ver = 0, fec_ver = 0;
1281 char demod_str[5] = { 0 };
1282 char fec_str[5] = { 0 };
1283
1284 id = stb0899_read_reg(state, STB0899_DEV_ID);
1285 dprintk(state->verbose, FE_DEBUG, 1, "ID reg=[0x%02x]", id);
1286 chip_id = STB0899_GETFIELD(CHIP_ID, id);
1287 release = STB0899_GETFIELD(CHIP_REL, id);
1288
1289 dprintk(state->verbose, FE_ERROR, 1, "Device ID=[%d], Release=[%d]",
1290 chip_id, release);
1291
1292 CONVERT32(STB0899_READ_S2REG(STB0899_S2DEMOD, DMD_CORE_ID), (char *)&demod_str);
1293
1294 demod_ver = STB0899_READ_S2REG(STB0899_S2DEMOD, DMD_VERSION_ID);
1295 dprintk(state->verbose, FE_ERROR, 1, "Demodulator Core ID=[%s], Version=[%d]", (char *) &demod_str, demod_ver);
1296 CONVERT32(STB0899_READ_S2REG(STB0899_S2FEC, FEC_CORE_ID_REG), (char *)&fec_str);
1297 fec_ver = STB0899_READ_S2REG(STB0899_S2FEC, FEC_VER_ID_REG);
1298 if (! (chip_id > 0)) {
1299 dprintk(state->verbose, FE_ERROR, 1, "couldn't find a STB 0899");
1300
1301 return -ENODEV;
1302 }
1303 dprintk(state->verbose, FE_ERROR, 1, "FEC Core ID=[%s], Version=[%d]", (char*) &fec_str, fec_ver);
1304
1305 return 0;
1306}
1307
1308static void stb0899_set_delivery(struct stb0899_state *state)
1309{
1310 u8 reg;
1311 u8 stop_clk[2];
1312
1313 stop_clk[0] = stb0899_read_reg(state, STB0899_STOPCLK1);
1314 stop_clk[1] = stb0899_read_reg(state, STB0899_STOPCLK2);
1315
1316 switch (state->delsys) {
1317 case SYS_DVBS:
1318 dprintk(state->verbose, FE_DEBUG, 1, "Delivery System -- DVB-S");
1319 /* FECM/Viterbi ON */
1320 reg = stb0899_read_reg(state, STB0899_FECM);
1321 STB0899_SETFIELD_VAL(FECM_RSVD0, reg, 0);
1322 STB0899_SETFIELD_VAL(FECM_VITERBI_ON, reg, 1);
1323 stb0899_write_reg(state, STB0899_FECM, reg);
1324
1325 stb0899_write_reg(state, STB0899_RSULC, 0xb1);
1326 stb0899_write_reg(state, STB0899_TSULC, 0x40);
1327 stb0899_write_reg(state, STB0899_RSLLC, 0x42);
1328 stb0899_write_reg(state, STB0899_TSLPL, 0x12);
1329
1330 reg = stb0899_read_reg(state, STB0899_TSTRES);
1331 STB0899_SETFIELD_VAL(FRESLDPC, reg, 1);
1332 stb0899_write_reg(state, STB0899_TSTRES, reg);
1333
1334 STB0899_SETFIELD_VAL(STOP_CHK8PSK, stop_clk[0], 1);
1335 STB0899_SETFIELD_VAL(STOP_CKFEC108, stop_clk[0], 1);
1336 STB0899_SETFIELD_VAL(STOP_CKFEC216, stop_clk[0], 1);
1337
1338 STB0899_SETFIELD_VAL(STOP_CKPKDLIN108, stop_clk[1], 1);
1339 STB0899_SETFIELD_VAL(STOP_CKPKDLIN216, stop_clk[1], 1);
1340
1341 STB0899_SETFIELD_VAL(STOP_CKINTBUF216, stop_clk[0], 1);
1342 STB0899_SETFIELD_VAL(STOP_CKCORE216, stop_clk[0], 0);
1343
1344 STB0899_SETFIELD_VAL(STOP_CKS2DMD108, stop_clk[1], 1);
1345 break;
1346 case SYS_DVBS2:
1347 /* FECM/Viterbi OFF */
1348 reg = stb0899_read_reg(state, STB0899_FECM);
1349 STB0899_SETFIELD_VAL(FECM_RSVD0, reg, 0);
1350 STB0899_SETFIELD_VAL(FECM_VITERBI_ON, reg, 0);
1351 stb0899_write_reg(state, STB0899_FECM, reg);
1352
1353 stb0899_write_reg(state, STB0899_RSULC, 0xb1);
1354 stb0899_write_reg(state, STB0899_TSULC, 0x42);
1355 stb0899_write_reg(state, STB0899_RSLLC, 0x40);
1356 stb0899_write_reg(state, STB0899_TSLPL, 0x02);
1357
1358 reg = stb0899_read_reg(state, STB0899_TSTRES);
1359 STB0899_SETFIELD_VAL(FRESLDPC, reg, 0);
1360 stb0899_write_reg(state, STB0899_TSTRES, reg);
1361
1362 STB0899_SETFIELD_VAL(STOP_CHK8PSK, stop_clk[0], 1);
1363 STB0899_SETFIELD_VAL(STOP_CKFEC108, stop_clk[0], 0);
1364 STB0899_SETFIELD_VAL(STOP_CKFEC216, stop_clk[0], 0);
1365
1366 STB0899_SETFIELD_VAL(STOP_CKPKDLIN108, stop_clk[1], 0);
1367 STB0899_SETFIELD_VAL(STOP_CKPKDLIN216, stop_clk[1], 0);
1368
1369 STB0899_SETFIELD_VAL(STOP_CKINTBUF216, stop_clk[0], 0);
1370 STB0899_SETFIELD_VAL(STOP_CKCORE216, stop_clk[0], 0);
1371
1372 STB0899_SETFIELD_VAL(STOP_CKS2DMD108, stop_clk[1], 0);
1373 break;
1374 case SYS_DSS:
1375 /* FECM/Viterbi ON */
1376 reg = stb0899_read_reg(state, STB0899_FECM);
1377 STB0899_SETFIELD_VAL(FECM_RSVD0, reg, 1);
1378 STB0899_SETFIELD_VAL(FECM_VITERBI_ON, reg, 1);
1379 stb0899_write_reg(state, STB0899_FECM, reg);
1380
1381 stb0899_write_reg(state, STB0899_RSULC, 0xa1);
1382 stb0899_write_reg(state, STB0899_TSULC, 0x61);
1383 stb0899_write_reg(state, STB0899_RSLLC, 0x42);
1384
1385 reg = stb0899_read_reg(state, STB0899_TSTRES);
1386 STB0899_SETFIELD_VAL(FRESLDPC, reg, 1);
1387 stb0899_write_reg(state, STB0899_TSTRES, reg);
1388
1389 STB0899_SETFIELD_VAL(STOP_CHK8PSK, stop_clk[0], 1);
1390 STB0899_SETFIELD_VAL(STOP_CKFEC108, stop_clk[0], 1);
1391 STB0899_SETFIELD_VAL(STOP_CKFEC216, stop_clk[0], 1);
1392
1393 STB0899_SETFIELD_VAL(STOP_CKPKDLIN108, stop_clk[1], 1);
1394 STB0899_SETFIELD_VAL(STOP_CKPKDLIN216, stop_clk[1], 1);
1395
1396 STB0899_SETFIELD_VAL(STOP_CKCORE216, stop_clk[0], 0);
1397
1398 STB0899_SETFIELD_VAL(STOP_CKS2DMD108, stop_clk[1], 1);
1399 break;
1400 default:
1401 dprintk(state->verbose, FE_ERROR, 1, "Unsupported delivery system");
1402 break;
1403 }
1404 STB0899_SETFIELD_VAL(STOP_CKADCI108, stop_clk[0], 0);
1405 stb0899_write_regs(state, STB0899_STOPCLK1, stop_clk, 2);
1406}
1407
1408/*
1409 * stb0899_set_iterations
1410 * set the LDPC iteration scale function
1411 */
1412static void stb0899_set_iterations(struct stb0899_state *state)
1413{
1414 struct stb0899_internal *internal = &state->internal;
1415 struct stb0899_config *config = state->config;
1416
1417 s32 iter_scale;
1418 u32 reg;
1419
1420 iter_scale = 17 * (internal->master_clk / 1000);
1421 iter_scale += 410000;
1422 iter_scale /= (internal->srate / 1000000);
1423 iter_scale /= 1000;
1424
1425 if (iter_scale > config->ldpc_max_iter)
1426 iter_scale = config->ldpc_max_iter;
1427
1428 reg = STB0899_READ_S2REG(STB0899_S2DEMOD, MAX_ITER);
1429 STB0899_SETFIELD_VAL(MAX_ITERATIONS, reg, iter_scale);
1430 stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_MAX_ITER, STB0899_OFF0_MAX_ITER, reg);
1431}
1432
1433static enum dvbfe_search stb0899_search(struct dvb_frontend *fe, struct dvb_frontend_parameters *p)
1434{
1435 struct stb0899_state *state = fe->demodulator_priv;
1436 struct stb0899_params *i_params = &state->params;
1437 struct stb0899_internal *internal = &state->internal;
1438 struct stb0899_config *config = state->config;
1439 struct dtv_frontend_properties *props = &fe->dtv_property_cache;
1440
1441 u32 SearchRange, gain;
1442
1443 i_params->freq = p->frequency;
1444 i_params->srate = p->u.qpsk.symbol_rate;
1445 state->delsys = props->delivery_system;
1446 dprintk(state->verbose, FE_DEBUG, 1, "delivery system=%d", state->delsys);
1447
1448 SearchRange = 10000000;
1449 dprintk(state->verbose, FE_DEBUG, 1, "Frequency=%d, Srate=%d", i_params->freq, i_params->srate);
1450 /* checking Search Range is meaningless for a fixed 3 Mhz */
1451 if (INRANGE(i_params->srate, 1000000, 45000000)) {
1452 dprintk(state->verbose, FE_DEBUG, 1, "Parameters IN RANGE");
1453 stb0899_set_delivery(state);
1454
1455 if (state->config->tuner_set_rfsiggain) {
1456 if (internal->srate > 15000000)
1457 gain = 8; /* 15Mb < srate < 45Mb, gain = 8dB */
1458 else if (internal->srate > 5000000)
1459 gain = 12; /* 5Mb < srate < 15Mb, gain = 12dB */
1460 else
1461 gain = 14; /* 1Mb < srate < 5Mb, gain = 14db */
1462 state->config->tuner_set_rfsiggain(fe, gain);
1463 }
1464
1465 if (i_params->srate <= 5000000)
1466 stb0899_set_mclk(state, config->lo_clk);
1467 else
1468 stb0899_set_mclk(state, config->hi_clk);
1469
1470 switch (state->delsys) {
1471 case SYS_DVBS:
1472 case SYS_DSS:
1473 dprintk(state->verbose, FE_DEBUG, 1, "DVB-S delivery system");
1474 internal->freq = i_params->freq;
1475 internal->srate = i_params->srate;
1476 /*
1477 * search = user search range +
1478 * 500Khz +
1479 * 2 * Tuner_step_size +
1480 * 10% of the symbol rate
1481 */
1482 internal->srch_range = SearchRange + 1500000 + (i_params->srate / 5);
1483 internal->derot_percent = 30;
1484
1485 /* What to do for tuners having no bandwidth setup ? */
1486 /* enable tuner I/O */
1487 stb0899_i2c_gate_ctrl(&state->frontend, 1);
1488
1489 if (state->config->tuner_set_bandwidth)
1490 state->config->tuner_set_bandwidth(fe, (13 * (stb0899_carr_width(state) + SearchRange)) / 10);
1491 if (state->config->tuner_get_bandwidth)
1492 state->config->tuner_get_bandwidth(fe, &internal->tuner_bw);
1493
1494 /* disable tuner I/O */
1495 stb0899_i2c_gate_ctrl(&state->frontend, 0);
1496
1497 /* Set DVB-S1 AGC */
1498 stb0899_write_reg(state, STB0899_AGCRFCFG, 0x11);
1499
1500 /* Run the search algorithm */
1501 dprintk(state->verbose, FE_DEBUG, 1, "running DVB-S search algo ..");
1502 if (stb0899_dvbs_algo(state) == RANGEOK) {
1503 internal->lock = 1;
1504 dprintk(state->verbose, FE_DEBUG, 1,
1505 "-------------------------------------> DVB-S LOCK !");
1506
1507// stb0899_write_reg(state, STB0899_ERRCTRL1, 0x3d); /* Viterbi Errors */
1508// internal->v_status = stb0899_read_reg(state, STB0899_VSTATUS);
1509// internal->err_ctrl = stb0899_read_reg(state, STB0899_ERRCTRL1);
1510// dprintk(state->verbose, FE_DEBUG, 1, "VSTATUS=0x%02x", internal->v_status);
1511// dprintk(state->verbose, FE_DEBUG, 1, "ERR_CTRL=0x%02x", internal->err_ctrl);
1512
1513 return DVBFE_ALGO_SEARCH_SUCCESS;
1514 } else {
1515 internal->lock = 0;
1516
1517 return DVBFE_ALGO_SEARCH_FAILED;
1518 }
1519 break;
1520 case SYS_DVBS2:
1521 internal->freq = i_params->freq;
1522 internal->srate = i_params->srate;
1523 internal->srch_range = SearchRange;
1524
1525 /* enable tuner I/O */
1526 stb0899_i2c_gate_ctrl(&state->frontend, 1);
1527
1528 if (state->config->tuner_set_bandwidth)
1529 state->config->tuner_set_bandwidth(fe, (stb0899_carr_width(state) + SearchRange));
1530 if (state->config->tuner_get_bandwidth)
1531 state->config->tuner_get_bandwidth(fe, &internal->tuner_bw);
1532
1533 /* disable tuner I/O */
1534 stb0899_i2c_gate_ctrl(&state->frontend, 0);
1535
1536// pParams->SpectralInv = pSearch->IQ_Inversion;
1537
1538 /* Set DVB-S2 AGC */
1539 stb0899_write_reg(state, STB0899_AGCRFCFG, 0x1c);
1540
1541 /* Set IterScale =f(MCLK,SYMB) */
1542 stb0899_set_iterations(state);
1543
1544 /* Run the search algorithm */
1545 dprintk(state->verbose, FE_DEBUG, 1, "running DVB-S2 search algo ..");
1546 if (stb0899_dvbs2_algo(state) == DVBS2_FEC_LOCK) {
1547 internal->lock = 1;
1548 dprintk(state->verbose, FE_DEBUG, 1,
1549 "-------------------------------------> DVB-S2 LOCK !");
1550
1551// stb0899_write_reg(state, STB0899_ERRCTRL1, 0xb6); /* Packet Errors */
1552// internal->v_status = stb0899_read_reg(state, STB0899_VSTATUS);
1553// internal->err_ctrl = stb0899_read_reg(state, STB0899_ERRCTRL1);
1554
1555 return DVBFE_ALGO_SEARCH_SUCCESS;
1556 } else {
1557 internal->lock = 0;
1558
1559 return DVBFE_ALGO_SEARCH_FAILED;
1560 }
1561 break;
1562 default:
1563 dprintk(state->verbose, FE_ERROR, 1, "Unsupported delivery system");
1564 return DVBFE_ALGO_SEARCH_INVALID;
1565 }
1566 }
1567
1568 return DVBFE_ALGO_SEARCH_ERROR;
1569}
1570/*
1571 * stb0899_track
1572 * periodically check the signal level against a specified
1573 * threshold level and perform derotator centering.
1574 * called once we have a lock from a succesful search
1575 * event.
1576 *
1577 * Will be called periodically called to maintain the
1578 * lock.
1579 *
1580 * Will be used to get parameters as well as info from
1581 * the decoded baseband header
1582 *
1583 * Once a new lock has established, the internal state
1584 * frequency (internal->freq) is updated
1585 */
1586static int stb0899_track(struct dvb_frontend *fe, struct dvb_frontend_parameters *p)
1587{
1588 return 0;
1589}
1590
1591static int stb0899_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *p)
1592{
1593 struct stb0899_state *state = fe->demodulator_priv;
1594 struct stb0899_internal *internal = &state->internal;
1595
1596 dprintk(state->verbose, FE_DEBUG, 1, "Get params");
1597 p->u.qpsk.symbol_rate = internal->srate;
1598
1599 return 0;
1600}
1601
1602static enum dvbfe_algo stb0899_frontend_algo(struct dvb_frontend *fe)
1603{
1604 return DVBFE_ALGO_CUSTOM;
1605}
1606
1607static struct dvb_frontend_ops stb0899_ops = {
1608
1609 .info = {
1610 .name = "STB0899 Multistandard",
1611 .type = FE_QPSK,
1612 .frequency_min = 950000,
1613 .frequency_max = 2150000,
1614 .frequency_stepsize = 0,
1615 .frequency_tolerance = 0,
1616 .symbol_rate_min = 5000000,
1617 .symbol_rate_max = 45000000,
1618
1619 .caps = FE_CAN_INVERSION_AUTO |
1620 FE_CAN_FEC_AUTO |
1621 FE_CAN_QPSK
1622 },
1623
1624 .release = stb0899_release,
1625 .init = stb0899_init,
1626 .sleep = stb0899_sleep,
1627// .wakeup = stb0899_wakeup,
1628
1629 .i2c_gate_ctrl = stb0899_i2c_gate_ctrl,
1630
1631 .get_frontend_algo = stb0899_frontend_algo,
1632 .search = stb0899_search,
1633 .track = stb0899_track,
1634 .get_frontend = stb0899_get_frontend,
1635
1636
1637 .read_status = stb0899_read_status,
1638 .read_snr = stb0899_read_snr,
1639 .read_signal_strength = stb0899_read_signal_strength,
1640 .read_ber = stb0899_read_ber,
1641
1642 .set_voltage = stb0899_set_voltage,
1643 .set_tone = stb0899_set_tone,
1644
1645 .diseqc_send_master_cmd = stb0899_send_diseqc_msg,
1646 .diseqc_recv_slave_reply = stb0899_recv_slave_reply,
1647 .diseqc_send_burst = stb0899_send_diseqc_burst,
1648};
1649
1650struct dvb_frontend *stb0899_attach(struct stb0899_config *config, struct i2c_adapter *i2c)
1651{
1652 struct stb0899_state *state = NULL;
1653 enum stb0899_inversion inversion;
1654
1655 state = kzalloc(sizeof (struct stb0899_state), GFP_KERNEL);
1656 if (state == NULL)
1657 goto error;
1658
1659 inversion = config->inversion;
1660 state->verbose = &verbose;
1661 state->config = config;
1662 state->i2c = i2c;
1663 state->frontend.ops = stb0899_ops;
1664 state->frontend.demodulator_priv = state;
1665 state->internal.inversion = inversion;
1666
1667 stb0899_wakeup(&state->frontend);
1668 if (stb0899_get_dev_id(state) == -ENODEV) {
1669 printk("%s: Exiting .. !\n", __func__);
1670 goto error;
1671 }
1672
1673 printk("%s: Attaching STB0899 \n", __func__);
1674 return &state->frontend;
1675
1676error:
1677 kfree(state);
1678 return NULL;
1679}
1680EXPORT_SYMBOL(stb0899_attach);
1681MODULE_PARM_DESC(verbose, "Set Verbosity level");
1682MODULE_AUTHOR("Manu Abraham");
1683MODULE_DESCRIPTION("STB0899 Multi-Std frontend");
1684MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/stb0899_drv.h b/drivers/media/dvb/frontends/stb0899_drv.h
new file mode 100644
index 000000000000..98b200ce0c34
--- /dev/null
+++ b/drivers/media/dvb/frontends/stb0899_drv.h
@@ -0,0 +1,162 @@
1/*
2 STB0899 Multistandard Frontend driver
3 Copyright (C) Manu Abraham (abraham.manu@gmail.com)
4
5 Copyright (C) ST Microelectronics
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 __STB0899_DRV_H
23#define __STB0899_DRV_H
24
25#include <linux/kernel.h>
26#include <linux/module.h>
27
28#include "dvb_frontend.h"
29
30#define STB0899_TSMODE_SERIAL 1
31#define STB0899_CLKPOL_FALLING 2
32#define STB0899_CLKNULL_PARITY 3
33#define STB0899_SYNC_FORCED 4
34#define STB0899_FECMODE_DSS 5
35
36struct stb0899_s1_reg {
37 u16 address;
38 u8 data;
39};
40
41struct stb0899_s2_reg {
42 u16 offset;
43 u32 base_address;
44 u32 data;
45};
46
47enum stb0899_inversion {
48 IQ_SWAP_OFF = 0,
49 IQ_SWAP_ON,
50 IQ_SWAP_AUTO
51};
52
53#define STB0899_GPIO00 0xf140
54#define STB0899_GPIO01 0xf141
55#define STB0899_GPIO02 0xf142
56#define STB0899_GPIO03 0xf143
57#define STB0899_GPIO04 0xf144
58#define STB0899_GPIO05 0xf145
59#define STB0899_GPIO06 0xf146
60#define STB0899_GPIO07 0xf147
61#define STB0899_GPIO08 0xf148
62#define STB0899_GPIO09 0xf149
63#define STB0899_GPIO10 0xf14a
64#define STB0899_GPIO11 0xf14b
65#define STB0899_GPIO12 0xf14c
66#define STB0899_GPIO13 0xf14d
67#define STB0899_GPIO14 0xf14e
68#define STB0899_GPIO15 0xf14f
69#define STB0899_GPIO16 0xf150
70#define STB0899_GPIO17 0xf151
71#define STB0899_GPIO18 0xf152
72#define STB0899_GPIO19 0xf153
73#define STB0899_GPIO20 0xf154
74
75#define STB0899_GPIOPULLUP 0x01 /* Output device is connected to Vdd */
76#define STB0899_GPIOPULLDN 0x00 /* Output device is connected to Vss */
77
78#define STB0899_POSTPROC_GPIO_POWER 0x00
79#define STB0899_POSTPROC_GPIO_LOCK 0x01
80
81/*
82 * Post process output configuration control
83 * 1. POWER ON/OFF (index 0)
84 * 2. FE_HAS_LOCK/LOCK_LOSS (index 1)
85 *
86 * @gpio = one of the above listed GPIO's
87 * @level = output state: pulled up or low
88 */
89struct stb0899_postproc {
90 u16 gpio;
91 u8 level;
92};
93
94struct stb0899_config {
95 const struct stb0899_s1_reg *init_dev;
96 const struct stb0899_s2_reg *init_s2_demod;
97 const struct stb0899_s1_reg *init_s1_demod;
98 const struct stb0899_s2_reg *init_s2_fec;
99 const struct stb0899_s1_reg *init_tst;
100
101 const struct stb0899_postproc *postproc;
102
103 enum stb0899_inversion inversion;
104
105 u32 xtal_freq;
106
107 u8 demod_address;
108 u8 ts_output_mode;
109 u8 block_sync_mode;
110 u8 ts_pfbit_toggle;
111
112 u8 clock_polarity;
113 u8 data_clk_parity;
114 u8 fec_mode;
115 u8 data_output_ctl;
116 u8 data_fifo_mode;
117 u8 out_rate_comp;
118 u8 i2c_repeater;
119// int inversion;
120 int lo_clk;
121 int hi_clk;
122
123 u32 esno_ave;
124 u32 esno_quant;
125 u32 avframes_coarse;
126 u32 avframes_fine;
127 u32 miss_threshold;
128 u32 uwp_threshold_acq;
129 u32 uwp_threshold_track;
130 u32 uwp_threshold_sof;
131 u32 sof_search_timeout;
132
133 u32 btr_nco_bits;
134 u32 btr_gain_shift_offset;
135 u32 crl_nco_bits;
136 u32 ldpc_max_iter;
137
138 int (*tuner_set_frequency)(struct dvb_frontend *fe, u32 frequency);
139 int (*tuner_get_frequency)(struct dvb_frontend *fe, u32 *frequency);
140 int (*tuner_set_bandwidth)(struct dvb_frontend *fe, u32 bandwidth);
141 int (*tuner_get_bandwidth)(struct dvb_frontend *fe, u32 *bandwidth);
142 int (*tuner_set_rfsiggain)(struct dvb_frontend *fe, u32 rf_gain);
143};
144
145#if defined(CONFIG_DVB_STB0899) || (defined(CONFIG_DVB_STB0899_MODULE) && defined(MODULE))
146
147extern struct dvb_frontend *stb0899_attach(struct stb0899_config *config,
148 struct i2c_adapter *i2c);
149
150#else
151
152static inline struct dvb_frontend *stb0899_attach(struct stb0899_config *config,
153 struct i2c_adapter *i2c)
154{
155 printk(KERN_WARNING "%s: Driver disabled by Kconfig\n", __func__);
156 return NULL;
157}
158
159#endif //CONFIG_DVB_STB0899
160
161
162#endif
diff --git a/drivers/media/dvb/frontends/stb0899_priv.h b/drivers/media/dvb/frontends/stb0899_priv.h
new file mode 100644
index 000000000000..24619e3689db
--- /dev/null
+++ b/drivers/media/dvb/frontends/stb0899_priv.h
@@ -0,0 +1,267 @@
1/*
2 STB0899 Multistandard Frontend driver
3 Copyright (C) Manu Abraham (abraham.manu@gmail.com)
4
5 Copyright (C) ST Microelectronics
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 __STB0899_PRIV_H
23#define __STB0899_PRIV_H
24
25#include "dvb_frontend.h"
26#include "stb0899_drv.h"
27
28#define FE_ERROR 0
29#define FE_NOTICE 1
30#define FE_INFO 2
31#define FE_DEBUG 3
32#define FE_DEBUGREG 4
33
34#define dprintk(x, y, z, format, arg...) do { \
35 if (z) { \
36 if ((*x > FE_ERROR) && (*x > y)) \
37 printk(KERN_ERR "%s: " format "\n", __func__ , ##arg); \
38 else if ((*x > FE_NOTICE) && (*x > y)) \
39 printk(KERN_NOTICE "%s: " format "\n", __func__ , ##arg); \
40 else if ((*x > FE_INFO) && (*x > y)) \
41 printk(KERN_INFO "%s: " format "\n", __func__ , ##arg); \
42 else if ((*x > FE_DEBUG) && (*x > y)) \
43 printk(KERN_DEBUG "%s: " format "\n", __func__ , ##arg); \
44 } else { \
45 if (*x > y) \
46 printk(format, ##arg); \
47 } \
48} while(0)
49
50#define INRANGE(val, x, y) (((x <= val) && (val <= y)) || \
51 ((y <= val) && (val <= x)) ? 1 : 0)
52
53#define BYTE0 0
54#define BYTE1 8
55#define BYTE2 16
56#define BYTE3 24
57
58#define GETBYTE(x, y) (((x) >> (y)) & 0xff)
59#define MAKEWORD32(a, b, c, d) (((a) << 24) | ((b) << 16) | ((c) << 8) | (d))
60#define MAKEWORD16(a, b) (((a) << 8) | (b))
61
62#define MIN(x, y) ((x) <= (y) ? (x) : (y))
63#define MAX(x, y) ((x) >= (y) ? (x) : (y))
64#define ABS(x) ((x) >= 0 ? (x) : -(x))
65
66#define LSB(x) ((x & 0xff))
67#define MSB(y) ((y >> 8) & 0xff)
68
69
70#define STB0899_GETFIELD(bitf, val) ((val >> STB0899_OFFST_##bitf) & ((1 << STB0899_WIDTH_##bitf) - 1))
71
72
73#define STB0899_SETFIELD(mask, val, width, offset) (mask & (~(((1 << width) - 1) << \
74 offset))) | ((val & \
75 ((1 << width) - 1)) << offset)
76
77#define STB0899_SETFIELD_VAL(bitf, mask, val) (mask = (mask & (~(((1 << STB0899_WIDTH_##bitf) - 1) <<\
78 STB0899_OFFST_##bitf))) | \
79 (val << STB0899_OFFST_##bitf))
80
81
82enum stb0899_status {
83 NOAGC1 = 0,
84 AGC1OK,
85 NOTIMING,
86 ANALOGCARRIER,
87 TIMINGOK,
88 NOAGC2,
89 AGC2OK,
90 NOCARRIER,
91 CARRIEROK,
92 NODATA,
93 FALSELOCK,
94 DATAOK,
95 OUTOFRANGE,
96 RANGEOK,
97 DVBS2_DEMOD_LOCK,
98 DVBS2_DEMOD_NOLOCK,
99 DVBS2_FEC_LOCK,
100 DVBS2_FEC_NOLOCK
101};
102
103enum stb0899_modcod {
104 STB0899_DUMMY_PLF,
105 STB0899_QPSK_14,
106 STB0899_QPSK_13,
107 STB0899_QPSK_25,
108 STB0899_QPSK_12,
109 STB0899_QPSK_35,
110 STB0899_QPSK_23,
111 STB0899_QPSK_34,
112 STB0899_QPSK_45,
113 STB0899_QPSK_56,
114 STB0899_QPSK_89,
115 STB0899_QPSK_910,
116 STB0899_8PSK_35,
117 STB0899_8PSK_23,
118 STB0899_8PSK_34,
119 STB0899_8PSK_56,
120 STB0899_8PSK_89,
121 STB0899_8PSK_910,
122 STB0899_16APSK_23,
123 STB0899_16APSK_34,
124 STB0899_16APSK_45,
125 STB0899_16APSK_56,
126 STB0899_16APSK_89,
127 STB0899_16APSK_910,
128 STB0899_32APSK_34,
129 STB0899_32APSK_45,
130 STB0899_32APSK_56,
131 STB0899_32APSK_89,
132 STB0899_32APSK_910
133};
134
135enum stb0899_frame {
136 STB0899_LONG_FRAME,
137 STB0899_SHORT_FRAME
138};
139
140enum stb0899_alpha {
141 RRC_20,
142 RRC_25,
143 RRC_35
144};
145
146struct stb0899_tab {
147 s32 real;
148 s32 read;
149};
150
151enum stb0899_fec {
152 STB0899_FEC_1_2 = 13,
153 STB0899_FEC_2_3 = 18,
154 STB0899_FEC_3_4 = 21,
155 STB0899_FEC_5_6 = 24,
156 STB0899_FEC_6_7 = 25,
157 STB0899_FEC_7_8 = 26
158};
159
160struct stb0899_params {
161 u32 freq; /* Frequency */
162 u32 srate; /* Symbol rate */
163 enum fe_code_rate fecrate;
164};
165
166struct stb0899_internal {
167 u32 master_clk;
168 u32 freq; /* Demod internal Frequency */
169 u32 srate; /* Demod internal Symbol rate */
170 enum stb0899_fec fecrate; /* Demod internal FEC rate */
171 u32 srch_range; /* Demod internal Search Range */
172 u32 sub_range; /* Demod current sub range (Hz) */
173 u32 tuner_step; /* Tuner step (Hz) */
174 u32 tuner_offst; /* Relative offset to carrier (Hz) */
175 u32 tuner_bw; /* Current bandwidth of the tuner (Hz) */
176
177 s32 mclk; /* Masterclock Divider factor (binary) */
178 s32 rolloff; /* Current RollOff of the filter (x100) */
179
180 s16 derot_freq; /* Current derotator frequency (Hz) */
181 s16 derot_percent;
182
183 s16 direction; /* Current derotator search direction */
184 s16 derot_step; /* Derotator step (binary value) */
185 s16 t_derot; /* Derotator time constant (ms) */
186 s16 t_data; /* Data recovery time constant (ms) */
187 s16 sub_dir; /* Direction of the next sub range */
188
189 s16 t_agc1; /* Agc1 time constant (ms) */
190 s16 t_agc2; /* Agc2 time constant (ms) */
191
192 u32 lock; /* Demod internal lock state */
193 enum stb0899_status status; /* Demod internal status */
194
195 /* DVB-S2 */
196 s32 agc_gain; /* RF AGC Gain */
197 s32 center_freq; /* Nominal carrier frequency */
198 s32 av_frame_coarse; /* Coarse carrier freq search frames */
199 s32 av_frame_fine; /* Fine carrier freq search frames */
200
201 s16 step_size; /* Carrier frequency search step size */
202
203 enum stb0899_alpha rrc_alpha;
204 enum stb0899_inversion inversion;
205 enum stb0899_modcod modcod;
206 u8 pilots; /* Pilots found */
207
208 enum stb0899_frame frame_length;
209 u8 v_status; /* VSTATUS */
210 u8 err_ctrl; /* ERRCTRLn */
211};
212
213struct stb0899_state {
214 struct i2c_adapter *i2c;
215 struct stb0899_config *config;
216 struct dvb_frontend frontend;
217
218 u32 *verbose; /* Cached module verbosity level */
219
220 struct stb0899_internal internal; /* Device internal parameters */
221
222 /* cached params from API */
223 enum fe_delivery_system delsys;
224 struct stb0899_params params;
225
226 u32 rx_freq; /* DiSEqC 2.0 receiver freq */
227 struct mutex search_lock;
228};
229/* stb0899.c */
230extern int stb0899_read_reg(struct stb0899_state *state,
231 unsigned int reg);
232
233extern u32 _stb0899_read_s2reg(struct stb0899_state *state,
234 u32 stb0899_i2cdev,
235 u32 stb0899_base_addr,
236 u16 stb0899_reg_offset);
237
238extern int stb0899_read_regs(struct stb0899_state *state,
239 unsigned int reg, u8 *buf,
240 u32 count);
241
242extern int stb0899_write_regs(struct stb0899_state *state,
243 unsigned int reg, u8 *data,
244 u32 count);
245
246extern int stb0899_write_reg(struct stb0899_state *state,
247 unsigned int reg,
248 u8 data);
249
250extern int stb0899_write_s2reg(struct stb0899_state *state,
251 u32 stb0899_i2cdev,
252 u32 stb0899_base_addr,
253 u16 stb0899_reg_offset,
254 u32 stb0899_data);
255
256extern int stb0899_i2c_gate_ctrl(struct dvb_frontend *fe, int enable);
257
258
259#define STB0899_READ_S2REG(DEVICE, REG) (_stb0899_read_s2reg(state, DEVICE, STB0899_BASE_##REG, STB0899_OFF0_##REG))
260//#define STB0899_WRITE_S2REG(DEVICE, REG, DATA) (_stb0899_write_s2reg(state, DEVICE, STB0899_BASE_##REG, STB0899_OFF0_##REG, DATA))
261
262/* stb0899_algo.c */
263extern enum stb0899_status stb0899_dvbs_algo(struct stb0899_state *state);
264extern enum stb0899_status stb0899_dvbs2_algo(struct stb0899_state *state);
265extern long stb0899_carr_width(struct stb0899_state *state);
266
267#endif //__STB0899_PRIV_H
diff --git a/drivers/media/dvb/frontends/stb0899_reg.h b/drivers/media/dvb/frontends/stb0899_reg.h
new file mode 100644
index 000000000000..ba1ed56304a0
--- /dev/null
+++ b/drivers/media/dvb/frontends/stb0899_reg.h
@@ -0,0 +1,2027 @@
1/*
2 STB0899 Multistandard Frontend driver
3 Copyright (C) Manu Abraham (abraham.manu@gmail.com)
4
5 Copyright (C) ST Microelectronics
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 __STB0899_REG_H
23#define __STB0899_REG_H
24
25/* S1 */
26#define STB0899_DEV_ID 0xf000
27#define STB0899_CHIP_ID (0x0f << 4)
28#define STB0899_OFFST_CHIP_ID 4
29#define STB0899_WIDTH_CHIP_ID 4
30#define STB0899_CHIP_REL (0x0f << 0)
31#define STB0899_OFFST_CHIP_REL 0
32#define STB0899_WIDTH_CHIP_REL 4
33
34#define STB0899_DEMOD 0xf40e
35#define STB0899_MODECOEFF (0x01 << 0)
36#define STB0899_OFFST_MODECOEFF 0
37#define STB0899_WIDTH_MODECOEFF 1
38
39#define STB0899_RCOMPC 0xf410
40#define STB0899_AGC1CN 0xf412
41#define STB0899_AGC1REF 0xf413
42#define STB0899_RTC 0xf417
43#define STB0899_TMGCFG 0xf418
44#define STB0899_AGC2REF 0xf419
45#define STB0899_TLSR 0xf41a
46
47#define STB0899_CFD 0xf41b
48#define STB0899_CFD_ON (0x01 << 7)
49#define STB0899_OFFST_CFD_ON 7
50#define STB0899_WIDTH_CFD_ON 1
51
52#define STB0899_ACLC 0xf41c
53
54#define STB0899_BCLC 0xf41d
55#define STB0899_OFFST_ALGO 6
56#define STB0899_WIDTH_ALGO_QPSK2 2
57#define STB0899_ALGO_QPSK2 (2 << 6)
58#define STB0899_ALGO_QPSK1 (1 << 6)
59#define STB0899_ALGO_BPSK (0 << 6)
60#define STB0899_OFFST_BETA 0
61#define STB0899_WIDTH_BETA 6
62
63#define STB0899_EQON 0xf41e
64#define STB0899_LDT 0xf41f
65#define STB0899_LDT2 0xf420
66#define STB0899_EQUALREF 0xf425
67#define STB0899_TMGRAMP 0xf426
68#define STB0899_TMGTHD 0xf427
69#define STB0899_IDCCOMP 0xf428
70#define STB0899_QDCCOMP 0xf429
71#define STB0899_POWERI 0xf42a
72#define STB0899_POWERQ 0xf42b
73#define STB0899_RCOMP 0xf42c
74
75#define STB0899_AGCIQIN 0xf42e
76#define STB0899_AGCIQVALUE (0xff << 0)
77#define STB0899_OFFST_AGCIQVALUE 0
78#define STB0899_WIDTH_AGCIQVALUE 8
79
80#define STB0899_AGC2I1 0xf436
81#define STB0899_AGC2I2 0xf437
82
83#define STB0899_TLIR 0xf438
84#define STB0899_TLIR_TMG_LOCK_IND (0xff << 0)
85#define STB0899_OFFST_TLIR_TMG_LOCK_IND 0
86#define STB0899_WIDTH_TLIR_TMG_LOCK_IND 8
87
88#define STB0899_RTF 0xf439
89#define STB0899_RTF_TIMING_LOOP_FREQ (0xff << 0)
90#define STB0899_OFFST_RTF_TIMING_LOOP_FREQ 0
91#define STB0899_WIDTH_RTF_TIMING_LOOP_FREQ 8
92
93#define STB0899_DSTATUS 0xf43a
94#define STB0899_CARRIER_FOUND (0x01 << 7)
95#define STB0899_OFFST_CARRIER_FOUND 7
96#define STB0899_WIDTH_CARRIER_FOUND 1
97#define STB0899_TMG_LOCK (0x01 << 6)
98#define STB0899_OFFST_TMG_LOCK 6
99#define STB0899_WIDTH_TMG_LOCK 1
100#define STB0899_DEMOD_LOCK (0x01 << 5)
101#define STB0899_OFFST_DEMOD_LOCK 5
102#define STB0899_WIDTH_DEMOD_LOCK 1
103#define STB0899_TMG_AUTO (0x01 << 4)
104#define STB0899_OFFST_TMG_AUTO 4
105#define STB0899_WIDTH_TMG_AUTO 1
106#define STB0899_END_MAIN (0x01 << 3)
107#define STB0899_OFFST_END_MAIN 3
108#define STB0899_WIDTH_END_MAIN 1
109
110#define STB0899_LDI 0xf43b
111#define STB0899_OFFST_LDI 0
112#define STB0899_WIDTH_LDI 8
113
114#define STB0899_CFRM 0xf43e
115#define STB0899_OFFST_CFRM 0
116#define STB0899_WIDTH_CFRM 8
117
118#define STB0899_CFRL 0xf43f
119#define STB0899_OFFST_CFRL 0
120#define STB0899_WIDTH_CFRL 8
121
122#define STB0899_NIRM 0xf440
123#define STB0899_OFFST_NIRM 0
124#define STB0899_WIDTH_NIRM 8
125
126#define STB0899_NIRL 0xf441
127#define STB0899_OFFST_NIRL 0
128#define STB0899_WIDTH_NIRL 8
129
130#define STB0899_ISYMB 0xf444
131#define STB0899_QSYMB 0xf445
132
133#define STB0899_SFRH 0xf446
134#define STB0899_OFFST_SFRH 0
135#define STB0899_WIDTH_SFRH 8
136
137#define STB0899_SFRM 0xf447
138#define STB0899_OFFST_SFRM 0
139#define STB0899_WIDTH_SFRM 8
140
141#define STB0899_SFRL 0xf448
142#define STB0899_OFFST_SFRL 4
143#define STB0899_WIDTH_SFRL 4
144
145#define STB0899_SFRUPH 0xf44c
146#define STB0899_SFRUPM 0xf44d
147#define STB0899_SFRUPL 0xf44e
148
149#define STB0899_EQUAI1 0xf4e0
150#define STB0899_EQUAQ1 0xf4e1
151#define STB0899_EQUAI2 0xf4e2
152#define STB0899_EQUAQ2 0xf4e3
153#define STB0899_EQUAI3 0xf4e4
154#define STB0899_EQUAQ3 0xf4e5
155#define STB0899_EQUAI4 0xf4e6
156#define STB0899_EQUAQ4 0xf4e7
157#define STB0899_EQUAI5 0xf4e8
158#define STB0899_EQUAQ5 0xf4e9
159
160#define STB0899_DSTATUS2 0xf50c
161#define STB0899_DS2_TMG_AUTOSRCH (0x01 << 7)
162#define STB8999_OFFST_DS2_TMG_AUTOSRCH 7
163#define STB0899_WIDTH_DS2_TMG_AUTOSRCH 1
164#define STB0899_DS2_END_MAINLOOP (0x01 << 6)
165#define STB0899_OFFST_DS2_END_MAINLOOP 6
166#define STB0899_WIDTH_DS2_END_MAINLOOP 1
167#define STB0899_DS2_CFSYNC (0x01 << 5)
168#define STB0899_OFFST_DS2_CFSYNC 5
169#define STB0899_WIDTH_DS2_CFSYNC 1
170#define STB0899_DS2_TMGLOCK (0x01 << 4)
171#define STB0899_OFFST_DS2_TMGLOCK 4
172#define STB0899_WIDTH_DS2_TMGLOCK 1
173#define STB0899_DS2_DEMODWAIT (0x01 << 3)
174#define STB0899_OFFST_DS2_DEMODWAIT 3
175#define STB0899_WIDTH_DS2_DEMODWAIT 1
176#define STB0899_DS2_FECON (0x01 << 1)
177#define STB0899_OFFST_DS2_FECON 1
178#define STB0899_WIDTH_DS2_FECON 1
179
180/* S1 FEC */
181#define STB0899_VSTATUS 0xf50d
182#define STB0899_VSTATUS_VITERBI_ON (0x01 << 7)
183#define STB0899_OFFST_VSTATUS_VITERBI_ON 7
184#define STB0899_WIDTH_VSTATUS_VITERBI_ON 1
185#define STB0899_VSTATUS_END_LOOPVIT (0x01 << 6)
186#define STB0899_OFFST_VSTATUS_END_LOOPVIT 6
187#define STB0899_WIDTH_VSTATUS_END_LOOPVIT 1
188#define STB0899_VSTATUS_PRFVIT (0x01 << 4)
189#define STB0899_OFFST_VSTATUS_PRFVIT 4
190#define STB0899_WIDTH_VSTATUS_PRFVIT 1
191#define STB0899_VSTATUS_LOCKEDVIT (0x01 << 3)
192#define STB0899_OFFST_VSTATUS_LOCKEDVIT 3
193#define STB0899_WIDTH_VSTATUS_LOCKEDVIT 1
194
195#define STB0899_VERROR 0xf50f
196
197#define STB0899_IQSWAP 0xf523
198#define STB0899_SYM (0x01 << 3)
199#define STB0899_OFFST_SYM 3
200#define STB0899_WIDTH_SYM 1
201
202#define STB0899_FECAUTO1 0xf530
203#define STB0899_DSSSRCH (0x01 << 3)
204#define STB0899_OFFST_DSSSRCH 3
205#define STB0899_WIDTH_DSSSRCH 1
206#define STB0899_SYMSRCH (0x01 << 2)
207#define STB0899_OFFST_SYMSRCH 2
208#define STB0899_WIDTH_SYMSRCH 1
209#define STB0899_QPSKSRCH (0x01 << 1)
210#define STB0899_OFFST_QPSKSRCH 1
211#define STB0899_WIDTH_QPSKSRCH 1
212#define STB0899_BPSKSRCH (0x01 << 0)
213#define STB0899_OFFST_BPSKSRCH 0
214#define STB0899_WIDTH_BPSKSRCH 1
215
216#define STB0899_FECM 0xf533
217#define STB0899_FECM_NOT_DVB (0x01 << 7)
218#define STB0899_OFFST_FECM_NOT_DVB 7
219#define STB0899_WIDTH_FECM_NOT_DVB 1
220#define STB0899_FECM_RSVD1 (0x07 << 4)
221#define STB0899_OFFST_FECM_RSVD1 4
222#define STB0899_WIDTH_FECM_RSVD1 3
223#define STB0899_FECM_VITERBI_ON (0x01 << 3)
224#define STB0899_OFFST_FECM_VITERBI_ON 3
225#define STB0899_WIDTH_FECM_VITERBI_ON 1
226#define STB0899_FECM_RSVD0 (0x01 << 2)
227#define STB0899_OFFST_FECM_RSVD0 2
228#define STB0899_WIDTH_FECM_RSVD0 1
229#define STB0899_FECM_SYNCDIS (0x01 << 1)
230#define STB0899_OFFST_FECM_SYNCDIS 1
231#define STB0899_WIDTH_FECM_SYNCDIS 1
232#define STB0899_FECM_SYMI (0x01 << 0)
233#define STB0899_OFFST_FECM_SYMI 0
234#define STB0899_WIDTH_FECM_SYMI 1
235
236#define STB0899_VTH12 0xf534
237#define STB0899_VTH23 0xf535
238#define STB0899_VTH34 0xf536
239#define STB0899_VTH56 0xf537
240#define STB0899_VTH67 0xf538
241#define STB0899_VTH78 0xf539
242
243#define STB0899_PRVIT 0xf53c
244#define STB0899_PR_7_8 (0x01 << 5)
245#define STB0899_OFFST_PR_7_8 5
246#define STB0899_WIDTH_PR_7_8 1
247#define STB0899_PR_6_7 (0x01 << 4)
248#define STB0899_OFFST_PR_6_7 4
249#define STB0899_WIDTH_PR_6_7 1
250#define STB0899_PR_5_6 (0x01 << 3)
251#define STB0899_OFFST_PR_5_6 3
252#define STB0899_WIDTH_PR_5_6 1
253#define STB0899_PR_3_4 (0x01 << 2)
254#define STB0899_OFFST_PR_3_4 2
255#define STB0899_WIDTH_PR_3_4 1
256#define STB0899_PR_2_3 (0x01 << 1)
257#define STB0899_OFFST_PR_2_3 1
258#define STB0899_WIDTH_PR_2_3 1
259#define STB0899_PR_1_2 (0x01 << 0)
260#define STB0899_OFFST_PR_1_2 0
261#define STB0899_WIDTH_PR_1_2 1
262
263#define STB0899_VITSYNC 0xf53d
264#define STB0899_AM (0x01 << 7)
265#define STB0899_OFFST_AM 7
266#define STB0899_WIDTH_AM 1
267#define STB0899_FREEZE (0x01 << 6)
268#define STB0899_OFFST_FREEZE 6
269#define STB0899_WIDTH_FREEZE 1
270#define STB0899_SN_65536 (0x03 << 4)
271#define STB0899_OFFST_SN_65536 4
272#define STB0899_WIDTH_SN_65536 2
273#define STB0899_SN_16384 (0x01 << 5)
274#define STB0899_OFFST_SN_16384 5
275#define STB0899_WIDTH_SN_16384 1
276#define STB0899_SN_4096 (0x01 << 4)
277#define STB0899_OFFST_SN_4096 4
278#define STB0899_WIDTH_SN_4096 1
279#define STB0899_SN_1024 (0x00 << 4)
280#define STB0899_OFFST_SN_1024 4
281#define STB0899_WIDTH_SN_1024 0
282#define STB0899_TO_128 (0x03 << 2)
283#define STB0899_OFFST_TO_128 2
284#define STB0899_WIDTH_TO_128 2
285#define STB0899_TO_64 (0x01 << 3)
286#define STB0899_OFFST_TO_64 3
287#define STB0899_WIDTH_TO_64 1
288#define STB0899_TO_32 (0x01 << 2)
289#define STB0899_OFFST_TO_32 2
290#define STB0899_WIDTH_TO_32 1
291#define STB0899_TO_16 (0x00 << 2)
292#define STB0899_OFFST_TO_16 2
293#define STB0899_WIDTH_TO_16 0
294#define STB0899_HYST_128 (0x03 << 1)
295#define STB0899_OFFST_HYST_128 1
296#define STB0899_WIDTH_HYST_128 2
297#define STB0899_HYST_64 (0x01 << 1)
298#define STB0899_OFFST_HYST_64 1
299#define STB0899_WIDTH_HYST_64 1
300#define STB0899_HYST_32 (0x01 << 0)
301#define STB0899_OFFST_HYST_32 0
302#define STB0899_WIDTH_HYST_32 1
303#define STB0899_HYST_16 (0x00 << 0)
304#define STB0899_OFFST_HYST_16 0
305#define STB0899_WIDTH_HYST_16 0
306
307#define STB0899_RSULC 0xf548
308#define STB0899_ULDIL_ON (0x01 << 7)
309#define STB0899_OFFST_ULDIL_ON 7
310#define STB0899_WIDTH_ULDIL_ON 1
311#define STB0899_ULAUTO_ON (0x01 << 6)
312#define STB0899_OFFST_ULAUTO_ON 6
313#define STB0899_WIDTH_ULAUTO_ON 1
314#define STB0899_ULRS_ON (0x01 << 5)
315#define STB0899_OFFST_ULRS_ON 5
316#define STB0899_WIDTH_ULRS_ON 1
317#define STB0899_ULDESCRAM_ON (0x01 << 4)
318#define STB0899_OFFST_ULDESCRAM_ON 4
319#define STB0899_WIDTH_ULDESCRAM_ON 1
320#define STB0899_UL_DISABLE (0x01 << 2)
321#define STB0899_OFFST_UL_DISABLE 2
322#define STB0899_WIDTH_UL_DISABLE 1
323#define STB0899_NOFTHRESHOLD (0x01 << 0)
324#define STB0899_OFFST_NOFTHRESHOLD 0
325#define STB0899_WIDTH_NOFTHRESHOLD 1
326
327#define STB0899_RSLLC 0xf54a
328#define STB0899_DEMAPVIT 0xf583
329#define STB0899_DEMAPVIT_RSVD (0x01 << 7)
330#define STB0899_OFFST_DEMAPVIT_RSVD 7
331#define STB0899_WIDTH_DEMAPVIT_RSVD 1
332#define STB0899_DEMAPVIT_KDIVIDER (0x7f << 0)
333#define STB0899_OFFST_DEMAPVIT_KDIVIDER 0
334#define STB0899_WIDTH_DEMAPVIT_KDIVIDER 7
335
336#define STB0899_PLPARM 0xf58c
337#define STB0899_VITMAPPING (0x07 << 5)
338#define STB0899_OFFST_VITMAPPING 5
339#define STB0899_WIDTH_VITMAPPING 3
340#define STB0899_VITMAPPING_BPSK (0x01 << 5)
341#define STB0899_OFFST_VITMAPPING_BPSK 5
342#define STB0899_WIDTH_VITMAPPING_BPSK 1
343#define STB0899_VITMAPPING_QPSK (0x00 << 5)
344#define STB0899_OFFST_VITMAPPING_QPSK 5
345#define STB0899_WIDTH_VITMAPPING_QPSK 0
346#define STB0899_VITCURPUN (0x1f << 0)
347#define STB0899_OFFST_VITCURPUN 0
348#define STB0899_WIDTH_VITCURPUN 5
349#define STB0899_VITCURPUN_1_2 (0x0d << 0)
350#define STB0899_VITCURPUN_2_3 (0x12 << 0)
351#define STB0899_VITCURPUN_3_4 (0x15 << 0)
352#define STB0899_VITCURPUN_5_6 (0x18 << 0)
353#define STB0899_VITCURPUN_6_7 (0x19 << 0)
354#define STB0899_VITCURPUN_7_8 (0x1a << 0)
355
356/* S2 DEMOD */
357#define STB0899_OFF0_DMD_STATUS 0xf300
358#define STB0899_BASE_DMD_STATUS 0x00000000
359#define STB0899_IF_AGC_LOCK (0x01 << 8)
360#define STB0899_OFFST_IF_AGC_LOCK 0
361#define STB0899_WIDTH_IF_AGC_LOCK 1
362
363#define STB0899_OFF0_CRL_FREQ 0xf304
364#define STB0899_BASE_CRL_FREQ 0x00000000
365#define STB0899_CARR_FREQ (0x3fffffff << 0)
366#define STB0899_OFFST_CARR_FREQ 0
367#define STB0899_WIDTH_CARR_FREQ 30
368
369#define STB0899_OFF0_BTR_FREQ 0xf308
370#define STB0899_BASE_BTR_FREQ 0x00000000
371#define STB0899_BTR_FREQ (0xfffffff << 0)
372#define STB0899_OFFST_BTR_FREQ 0
373#define STB0899_WIDTH_BTR_FREQ 28
374
375#define STB0899_OFF0_IF_AGC_GAIN 0xf30c
376#define STB0899_BASE_IF_AGC_GAIN 0x00000000
377#define STB0899_IF_AGC_GAIN (0x3fff < 0)
378#define STB0899_OFFST_IF_AGC_GAIN 0
379#define STB0899_WIDTH_IF_AGC_GAIN 14
380
381#define STB0899_OFF0_BB_AGC_GAIN 0xf310
382#define STB0899_BASE_BB_AGC_GAIN 0x00000000
383#define STB0899_BB_AGC_GAIN (0x3fff < 0)
384#define STB0899_OFFST_BB_AGC_GAIN 0
385#define STB0899_WIDTH_BB_AGC_GAIN 14
386
387#define STB0899_OFF0_DC_OFFSET 0xf314
388#define STB0899_BASE_DC_OFFSET 0x00000000
389#define STB0899_I (0xff < 8)
390#define STB0899_OFFST_I 8
391#define STB0899_WIDTH_I 8
392#define STB0899_Q (0xff < 0)
393#define STB0899_OFFST_Q 8
394#define STB0899_WIDTH_Q 8
395
396#define STB0899_OFF0_DMD_CNTRL 0xf31c
397#define STB0899_BASE_DMD_CNTRL 0x00000000
398#define STB0899_ADC0_PINS1IN (0x01 << 6)
399#define STB0899_OFFST_ADC0_PINS1IN 6
400#define STB0899_WIDTH_ADC0_PINS1IN 1
401#define STB0899_IN2COMP1_OFFBIN0 (0x01 << 3)
402#define STB0899_OFFST_IN2COMP1_OFFBIN0 3
403#define STB0899_WIDTH_IN2COMP1_OFFBIN0 1
404#define STB0899_DC_COMP (0x01 << 2)
405#define STB0899_OFFST_DC_COMP 2
406#define STB0899_WIDTH_DC_COMP 1
407#define STB0899_MODMODE (0x03 << 0)
408#define STB0899_OFFST_MODMODE 0
409#define STB0899_WIDTH_MODMODE 2
410
411#define STB0899_OFF0_IF_AGC_CNTRL 0xf320
412#define STB0899_BASE_IF_AGC_CNTRL 0x00000000
413#define STB0899_IF_GAIN_INIT (0x3fff << 13)
414#define STB0899_OFFST_IF_GAIN_INIT 13
415#define STB0899_WIDTH_IF_GAIN_INIT 14
416#define STB0899_IF_GAIN_SENSE (0x01 << 12)
417#define STB0899_OFFST_IF_GAIN_SENSE 12
418#define STB0899_WIDTH_IF_GAIN_SENSE 1
419#define STB0899_IF_LOOP_GAIN (0x0f << 8)
420#define STB0899_OFFST_IF_LOOP_GAIN 8
421#define STB0899_WIDTH_IF_LOOP_GAIN 4
422#define STB0899_IF_LD_GAIN_INIT (0x01 << 7)
423#define STB0899_OFFST_IF_LD_GAIN_INIT 7
424#define STB0899_WIDTH_IF_LD_GAIN_INIT 1
425#define STB0899_IF_AGC_REF (0x7f << 0)
426#define STB0899_OFFST_IF_AGC_REF 0
427#define STB0899_WIDTH_IF_AGC_REF 7
428
429#define STB0899_OFF0_BB_AGC_CNTRL 0xf324
430#define STB0899_BASE_BB_AGC_CNTRL 0x00000000
431#define STB0899_BB_GAIN_INIT (0x3fff << 12)
432#define STB0899_OFFST_BB_GAIN_INIT 12
433#define STB0899_WIDTH_BB_GAIN_INIT 14
434#define STB0899_BB_LOOP_GAIN (0x0f << 8)
435#define STB0899_OFFST_BB_LOOP_GAIN 8
436#define STB0899_WIDTH_BB_LOOP_GAIN 4
437#define STB0899_BB_LD_GAIN_INIT (0x01 << 7)
438#define STB0899_OFFST_BB_LD_GAIN_INIT 7
439#define STB0899_WIDTH_BB_LD_GAIN_INIT 1
440#define STB0899_BB_AGC_REF (0x7f << 0)
441#define STB0899_OFFST_BB_AGC_REF 0
442#define STB0899_WIDTH_BB_AGC_REF 7
443
444#define STB0899_OFF0_CRL_CNTRL 0xf328
445#define STB0899_BASE_CRL_CNTRL 0x00000000
446#define STB0899_CRL_LOCK_CLEAR (0x01 << 5)
447#define STB0899_OFFST_CRL_LOCK_CLEAR 5
448#define STB0899_WIDTH_CRL_LOCK_CLEAR 1
449#define STB0899_CRL_SWPR_CLEAR (0x01 << 4)
450#define STB0899_OFFST_CRL_SWPR_CLEAR 4
451#define STB0899_WIDTH_CRL_SWPR_CLEAR 1
452#define STB0899_CRL_SWP_ENA (0x01 << 3)
453#define STB0899_OFFST_CRL_SWP_ENA 3
454#define STB0899_WIDTH_CRL_SWP_ENA 1
455#define STB0899_CRL_DET_SEL (0x01 << 2)
456#define STB0899_OFFST_CRL_DET_SEL 2
457#define STB0899_WIDTH_CRL_DET_SEL 1
458#define STB0899_CRL_SENSE (0x01 << 1)
459#define STB0899_OFFST_CRL_SENSE 1
460#define STB0899_WIDTH_CRL_SENSE 1
461#define STB0899_CRL_PHSERR_CLEAR (0x01 << 0)
462#define STB0899_OFFST_CRL_PHSERR_CLEAR 0
463#define STB0899_WIDTH_CRL_PHSERR_CLEAR 1
464
465#define STB0899_OFF0_CRL_PHS_INIT 0xf32c
466#define STB0899_BASE_CRL_PHS_INIT 0x00000000
467#define STB0899_CRL_PHS_INIT_31 (0x1 << 30)
468#define STB0899_OFFST_CRL_PHS_INIT_31 30
469#define STB0899_WIDTH_CRL_PHS_INIT_31 1
470#define STB0899_CRL_LD_INIT_PHASE (0x1 << 24)
471#define STB0899_OFFST_CRL_LD_INIT_PHASE 24
472#define STB0899_WIDTH_CRL_LD_INIT_PHASE 1
473#define STB0899_CRL_INIT_PHASE (0xffffff << 0)
474#define STB0899_OFFST_CRL_INIT_PHASE 0
475#define STB0899_WIDTH_CRL_INIT_PHASE 24
476
477#define STB0899_OFF0_CRL_FREQ_INIT 0xf330
478#define STB0899_BASE_CRL_FREQ_INIT 0x00000000
479#define STB0899_CRL_FREQ_INIT_31 (0x1 << 30)
480#define STB0899_OFFST_CRL_FREQ_INIT_31 30
481#define STB0899_WIDTH_CRL_FREQ_INIT_31 1
482#define STB0899_CRL_LD_FREQ_INIT (0x1 << 24)
483#define STB0899_OFFST_CRL_LD_FREQ_INIT 24
484#define STB0899_WIDTH_CRL_LD_FREQ_INIT 1
485#define STB0899_CRL_FREQ_INIT (0xffffff << 0)
486#define STB0899_OFFST_CRL_FREQ_INIT 0
487#define STB0899_WIDTH_CRL_FREQ_INIT 24
488
489#define STB0899_OFF0_CRL_LOOP_GAIN 0xf334
490#define STB0899_BASE_CRL_LOOP_GAIN 0x00000000
491#define STB0899_KCRL2_RSHFT (0xf << 16)
492#define STB0899_OFFST_KCRL2_RSHFT 16
493#define STB0899_WIDTH_KCRL2_RSHFT 4
494#define STB0899_KCRL1 (0xf << 12)
495#define STB0899_OFFST_KCRL1 12
496#define STB0899_WIDTH_KCRL1 4
497#define STB0899_KCRL1_RSHFT (0xf << 8)
498#define STB0899_OFFST_KCRL1_RSHFT 8
499#define STB0899_WIDTH_KCRL1_RSHFT 4
500#define STB0899_KCRL0 (0xf << 4)
501#define STB0899_OFFST_KCRL0 4
502#define STB0899_WIDTH_KCRL0 4
503#define STB0899_KCRL0_RSHFT (0xf << 0)
504#define STB0899_OFFST_KCRL0_RSHFT 0
505#define STB0899_WIDTH_KCRL0_RSHFT 4
506
507#define STB0899_OFF0_CRL_NOM_FREQ 0xf338
508#define STB0899_BASE_CRL_NOM_FREQ 0x00000000
509#define STB0899_CRL_NOM_FREQ (0x3fffffff << 0)
510#define STB0899_OFFST_CRL_NOM_FREQ 0
511#define STB0899_WIDTH_CRL_NOM_FREQ 30
512
513#define STB0899_OFF0_CRL_SWP_RATE 0xf33c
514#define STB0899_BASE_CRL_SWP_RATE 0x00000000
515#define STB0899_CRL_SWP_RATE (0x3fffffff << 0)
516#define STB0899_OFFST_CRL_SWP_RATE 0
517#define STB0899_WIDTH_CRL_SWP_RATE 30
518
519#define STB0899_OFF0_CRL_MAX_SWP 0xf340
520#define STB0899_BASE_CRL_MAX_SWP 0x00000000
521#define STB0899_CRL_MAX_SWP (0x3fffffff << 0)
522#define STB0899_OFFST_CRL_MAX_SWP 0
523#define STB0899_WIDTH_CRL_MAX_SWP 30
524
525#define STB0899_OFF0_CRL_LK_CNTRL 0xf344
526#define STB0899_BASE_CRL_LK_CNTRL 0x00000000
527
528#define STB0899_OFF0_DECIM_CNTRL 0xf348
529#define STB0899_BASE_DECIM_CNTRL 0x00000000
530#define STB0899_BAND_LIMIT_B (0x01 << 5)
531#define STB0899_OFFST_BAND_LIMIT_B 5
532#define STB0899_WIDTH_BAND_LIMIT_B 1
533#define STB0899_WIN_SEL (0x03 << 3)
534#define STB0899_OFFST_WIN_SEL 3
535#define STB0899_WIDTH_WIN_SEL 2
536#define STB0899_DECIM_RATE (0x07 << 0)
537#define STB0899_OFFST_DECIM_RATE 0
538#define STB0899_WIDTH_DECIM_RATE 3
539
540#define STB0899_OFF0_BTR_CNTRL 0xf34c
541#define STB0899_BASE_BTR_CNTRL 0x00000000
542#define STB0899_BTR_FREQ_CORR (0x7ff << 4)
543#define STB0899_OFFST_BTR_FREQ_CORR 4
544#define STB0899_WIDTH_BTR_FREQ_CORR 11
545#define STB0899_BTR_CLR_LOCK (0x01 << 3)
546#define STB0899_OFFST_BTR_CLR_LOCK 3
547#define STB0899_WIDTH_BTR_CLR_LOCK 1
548#define STB0899_BTR_SENSE (0x01 << 2)
549#define STB0899_OFFST_BTR_SENSE 2
550#define STB0899_WIDTH_BTR_SENSE 1
551#define STB0899_BTR_ERR_ENA (0x01 << 1)
552#define STB0899_OFFST_BTR_ERR_ENA 1
553#define STB0899_WIDTH_BTR_ERR_ENA 1
554#define STB0899_INTRP_PHS_SENSE (0x01 << 0)
555#define STB0899_OFFST_INTRP_PHS_SENSE 0
556#define STB0899_WIDTH_INTRP_PHS_SENSE 1
557
558#define STB0899_OFF0_BTR_LOOP_GAIN 0xf350
559#define STB0899_BASE_BTR_LOOP_GAIN 0x00000000
560#define STB0899_KBTR2_RSHFT (0x0f << 16)
561#define STB0899_OFFST_KBTR2_RSHFT 16
562#define STB0899_WIDTH_KBTR2_RSHFT 4
563#define STB0899_KBTR1 (0x0f << 12)
564#define STB0899_OFFST_KBTR1 12
565#define STB0899_WIDTH_KBTR1 4
566#define STB0899_KBTR1_RSHFT (0x0f << 8)
567#define STB0899_OFFST_KBTR1_RSHFT 8
568#define STB0899_WIDTH_KBTR1_RSHFT 4
569#define STB0899_KBTR0 (0x0f << 4)
570#define STB0899_OFFST_KBTR0 4
571#define STB0899_WIDTH_KBTR0 4
572#define STB0899_KBTR0_RSHFT (0x0f << 0)
573#define STB0899_OFFST_KBTR0_RSHFT 0
574#define STB0899_WIDTH_KBTR0_RSHFT 4
575
576#define STB0899_OFF0_BTR_PHS_INIT 0xf354
577#define STB0899_BASE_BTR_PHS_INIT 0x00000000
578#define STB0899_BTR_LD_PHASE_INIT (0x01 << 28)
579#define STB0899_OFFST_BTR_LD_PHASE_INIT 28
580#define STB0899_WIDTH_BTR_LD_PHASE_INIT 1
581#define STB0899_BTR_INIT_PHASE (0xfffffff << 0)
582#define STB0899_OFFST_BTR_INIT_PHASE 0
583#define STB0899_WIDTH_BTR_INIT_PHASE 28
584
585#define STB0899_OFF0_BTR_FREQ_INIT 0xf358
586#define STB0899_BASE_BTR_FREQ_INIT 0x00000000
587#define STB0899_BTR_LD_FREQ_INIT (1 << 28)
588#define STB0899_OFFST_BTR_LD_FREQ_INIT 28
589#define STB0899_WIDTH_BTR_LD_FREQ_INIT 1
590#define STB0899_BTR_FREQ_INIT (0xfffffff << 0)
591#define STB0899_OFFST_BTR_FREQ_INIT 0
592#define STB0899_WIDTH_BTR_FREQ_INIT 28
593
594#define STB0899_OFF0_BTR_NOM_FREQ 0xf35c
595#define STB0899_BASE_BTR_NOM_FREQ 0x00000000
596#define STB0899_BTR_NOM_FREQ (0xfffffff << 0)
597#define STB0899_OFFST_BTR_NOM_FREQ 0
598#define STB0899_WIDTH_BTR_NOM_FREQ 28
599
600#define STB0899_OFF0_BTR_LK_CNTRL 0xf360
601#define STB0899_BASE_BTR_LK_CNTRL 0x00000000
602#define STB0899_BTR_MIN_ENERGY (0x0f << 24)
603#define STB0899_OFFST_BTR_MIN_ENERGY 24
604#define STB0899_WIDTH_BTR_MIN_ENERGY 4
605#define STB0899_BTR_LOCK_TH_LO (0xff << 16)
606#define STB0899_OFFST_BTR_LOCK_TH_LO 16
607#define STB0899_WIDTH_BTR_LOCK_TH_LO 8
608#define STB0899_BTR_LOCK_TH_HI (0xff << 8)
609#define STB0899_OFFST_BTR_LOCK_TH_HI 8
610#define STB0899_WIDTH_BTR_LOCK_TH_HI 8
611#define STB0899_BTR_LOCK_GAIN (0x03 << 6)
612#define STB0899_OFFST_BTR_LOCK_GAIN 6
613#define STB0899_WIDTH_BTR_LOCK_GAIN 2
614#define STB0899_BTR_LOCK_LEAK (0x3f << 0)
615#define STB0899_OFFST_BTR_LOCK_LEAK 0
616#define STB0899_WIDTH_BTR_LOCK_LEAK 6
617
618#define STB0899_OFF0_DECN_CNTRL 0xf364
619#define STB0899_BASE_DECN_CNTRL 0x00000000
620
621#define STB0899_OFF0_TP_CNTRL 0xf368
622#define STB0899_BASE_TP_CNTRL 0x00000000
623
624#define STB0899_OFF0_TP_BUF_STATUS 0xf36c
625#define STB0899_BASE_TP_BUF_STATUS 0x00000000
626#define STB0899_TP_BUFFER_FULL (1 << 0)
627
628#define STB0899_OFF0_DC_ESTIM 0xf37c
629#define STB0899_BASE_DC_ESTIM 0x0000
630#define STB0899_I_DC_ESTIMATE (0xff << 8)
631#define STB0899_OFFST_I_DC_ESTIMATE 8
632#define STB0899_WIDTH_I_DC_ESTIMATE 8
633#define STB0899_Q_DC_ESTIMATE (0xff << 0)
634#define STB0899_OFFST_Q_DC_ESTIMATE 0
635#define STB0899_WIDTH_Q_DC_ESTIMATE 8
636
637#define STB0899_OFF0_FLL_CNTRL 0xf310
638#define STB0899_BASE_FLL_CNTRL 0x00000020
639#define STB0899_CRL_FLL_ACC (0x01 << 4)
640#define STB0899_OFFST_CRL_FLL_ACC 4
641#define STB0899_WIDTH_CRL_FLL_ACC 1
642#define STB0899_FLL_AVG_PERIOD (0x0f << 0)
643#define STB0899_OFFST_FLL_AVG_PERIOD 0
644#define STB0899_WIDTH_FLL_AVG_PERIOD 4
645
646#define STB0899_OFF0_FLL_FREQ_WD 0xf314
647#define STB0899_BASE_FLL_FREQ_WD 0x00000020
648#define STB0899_FLL_FREQ_WD (0xffffffff << 0)
649#define STB0899_OFFST_FLL_FREQ_WD 0
650#define STB0899_WIDTH_FLL_FREQ_WD 32
651
652#define STB0899_OFF0_ANTI_ALIAS_SEL 0xf358
653#define STB0899_BASE_ANTI_ALIAS_SEL 0x00000020
654#define STB0899_ANTI_ALIAS_SELB (0x03 << 0)
655#define STB0899_OFFST_ANTI_ALIAS_SELB 0
656#define STB0899_WIDTH_ANTI_ALIAS_SELB 2
657
658#define STB0899_OFF0_RRC_ALPHA 0xf35c
659#define STB0899_BASE_RRC_ALPHA 0x00000020
660#define STB0899_RRC_ALPHA (0x03 << 0)
661#define STB0899_OFFST_RRC_ALPHA 0
662#define STB0899_WIDTH_RRC_ALPHA 2
663
664#define STB0899_OFF0_DC_ADAPT_LSHFT 0xf360
665#define STB0899_BASE_DC_ADAPT_LSHFT 0x00000020
666#define STB0899_DC_ADAPT_LSHFT (0x077 << 0)
667#define STB0899_OFFST_DC_ADAPT_LSHFT 0
668#define STB0899_WIDTH_DC_ADAPT_LSHFT 3
669
670#define STB0899_OFF0_IMB_OFFSET 0xf364
671#define STB0899_BASE_IMB_OFFSET 0x00000020
672#define STB0899_PHS_IMB_COMP (0xff << 8)
673#define STB0899_OFFST_PHS_IMB_COMP 8
674#define STB0899_WIDTH_PHS_IMB_COMP 8
675#define STB0899_AMPL_IMB_COMP (0xff << 0)
676#define STB0899_OFFST_AMPL_IMB_COMP 0
677#define STB0899_WIDTH_AMPL_IMB_COMP 8
678
679#define STB0899_OFF0_IMB_ESTIMATE 0xf368
680#define STB0899_BASE_IMB_ESTIMATE 0x00000020
681#define STB0899_PHS_IMB_ESTIMATE (0xff << 8)
682#define STB0899_OFFST_PHS_IMB_ESTIMATE 8
683#define STB0899_WIDTH_PHS_IMB_ESTIMATE 8
684#define STB0899_AMPL_IMB_ESTIMATE (0xff << 0)
685#define STB0899_OFFST_AMPL_IMB_ESTIMATE 0
686#define STB0899_WIDTH_AMPL_IMB_ESTIMATE 8
687
688#define STB0899_OFF0_IMB_CNTRL 0xf36c
689#define STB0899_BASE_IMB_CNTRL 0x00000020
690#define STB0899_PHS_ADAPT_LSHFT (0x07 << 4)
691#define STB0899_OFFST_PHS_ADAPT_LSHFT 4
692#define STB0899_WIDTH_PHS_ADAPT_LSHFT 3
693#define STB0899_AMPL_ADAPT_LSHFT (0x07 << 1)
694#define STB0899_OFFST_AMPL_ADAPT_LSHFT 1
695#define STB0899_WIDTH_AMPL_ADAPT_LSHFT 3
696#define STB0899_IMB_COMP (0x01 << 0)
697#define STB0899_OFFST_IMB_COMP 0
698#define STB0899_WIDTH_IMB_COMP 1
699
700#define STB0899_OFF0_IF_AGC_CNTRL2 0xf374
701#define STB0899_BASE_IF_AGC_CNTRL2 0x00000020
702#define STB0899_IF_AGC_LOCK_TH (0xff << 11)
703#define STB0899_OFFST_IF_AGC_LOCK_TH 11
704#define STB0899_WIDTH_IF_AGC_LOCK_TH 8
705#define STB0899_IF_AGC_SD_DIV (0xff << 3)
706#define STB0899_OFFST_IF_AGC_SD_DIV 3
707#define STB0899_WIDTH_IF_AGC_SD_DIV 8
708#define STB0899_IF_AGC_DUMP_PER (0x07 << 0)
709#define STB0899_OFFST_IF_AGC_DUMP_PER 0
710#define STB0899_WIDTH_IF_AGC_DUMP_PER 3
711
712#define STB0899_OFF0_DMD_CNTRL2 0xf378
713#define STB0899_BASE_DMD_CNTRL2 0x00000020
714#define STB0899_SPECTRUM_INVERT (0x01 << 2)
715#define STB0899_OFFST_SPECTRUM_INVERT 2
716#define STB0899_WIDTH_SPECTRUM_INVERT 1
717#define STB0899_AGC_MODE (0x01 << 1)
718#define STB0899_OFFST_AGC_MODE 1
719#define STB0899_WIDTH_AGC_MODE 1
720#define STB0899_CRL_FREQ_ADJ (0x01 << 0)
721#define STB0899_OFFST_CRL_FREQ_ADJ 0
722#define STB0899_WIDTH_CRL_FREQ_ADJ 1
723
724#define STB0899_OFF0_TP_BUFFER 0xf300
725#define STB0899_BASE_TP_BUFFER 0x00000040
726#define STB0899_TP_BUFFER_IN (0xffff << 0)
727#define STB0899_OFFST_TP_BUFFER_IN 0
728#define STB0899_WIDTH_TP_BUFFER_IN 16
729
730#define STB0899_OFF0_TP_BUFFER1 0xf304
731#define STB0899_BASE_TP_BUFFER1 0x00000040
732#define STB0899_OFF0_TP_BUFFER2 0xf308
733#define STB0899_BASE_TP_BUFFER2 0x00000040
734#define STB0899_OFF0_TP_BUFFER3 0xf30c
735#define STB0899_BASE_TP_BUFFER3 0x00000040
736#define STB0899_OFF0_TP_BUFFER4 0xf310
737#define STB0899_BASE_TP_BUFFER4 0x00000040
738#define STB0899_OFF0_TP_BUFFER5 0xf314
739#define STB0899_BASE_TP_BUFFER5 0x00000040
740#define STB0899_OFF0_TP_BUFFER6 0xf318
741#define STB0899_BASE_TP_BUFFER6 0x00000040
742#define STB0899_OFF0_TP_BUFFER7 0xf31c
743#define STB0899_BASE_TP_BUFFER7 0x00000040
744#define STB0899_OFF0_TP_BUFFER8 0xf320
745#define STB0899_BASE_TP_BUFFER8 0x00000040
746#define STB0899_OFF0_TP_BUFFER9 0xf324
747#define STB0899_BASE_TP_BUFFER9 0x00000040
748#define STB0899_OFF0_TP_BUFFER10 0xf328
749#define STB0899_BASE_TP_BUFFER10 0x00000040
750#define STB0899_OFF0_TP_BUFFER11 0xf32c
751#define STB0899_BASE_TP_BUFFER11 0x00000040
752#define STB0899_OFF0_TP_BUFFER12 0xf330
753#define STB0899_BASE_TP_BUFFER12 0x00000040
754#define STB0899_OFF0_TP_BUFFER13 0xf334
755#define STB0899_BASE_TP_BUFFER13 0x00000040
756#define STB0899_OFF0_TP_BUFFER14 0xf338
757#define STB0899_BASE_TP_BUFFER14 0x00000040
758#define STB0899_OFF0_TP_BUFFER15 0xf33c
759#define STB0899_BASE_TP_BUFFER15 0x00000040
760#define STB0899_OFF0_TP_BUFFER16 0xf340
761#define STB0899_BASE_TP_BUFFER16 0x00000040
762#define STB0899_OFF0_TP_BUFFER17 0xf344
763#define STB0899_BASE_TP_BUFFER17 0x00000040
764#define STB0899_OFF0_TP_BUFFER18 0xf348
765#define STB0899_BASE_TP_BUFFER18 0x00000040
766#define STB0899_OFF0_TP_BUFFER19 0xf34c
767#define STB0899_BASE_TP_BUFFER19 0x00000040
768#define STB0899_OFF0_TP_BUFFER20 0xf350
769#define STB0899_BASE_TP_BUFFER20 0x00000040
770#define STB0899_OFF0_TP_BUFFER21 0xf354
771#define STB0899_BASE_TP_BUFFER21 0x00000040
772#define STB0899_OFF0_TP_BUFFER22 0xf358
773#define STB0899_BASE_TP_BUFFER22 0x00000040
774#define STB0899_OFF0_TP_BUFFER23 0xf35c
775#define STB0899_BASE_TP_BUFFER23 0x00000040
776#define STB0899_OFF0_TP_BUFFER24 0xf360
777#define STB0899_BASE_TP_BUFFER24 0x00000040
778#define STB0899_OFF0_TP_BUFFER25 0xf364
779#define STB0899_BASE_TP_BUFFER25 0x00000040
780#define STB0899_OFF0_TP_BUFFER26 0xf368
781#define STB0899_BASE_TP_BUFFER26 0x00000040
782#define STB0899_OFF0_TP_BUFFER27 0xf36c
783#define STB0899_BASE_TP_BUFFER27 0x00000040
784#define STB0899_OFF0_TP_BUFFER28 0xf370
785#define STB0899_BASE_TP_BUFFER28 0x00000040
786#define STB0899_OFF0_TP_BUFFER29 0xf374
787#define STB0899_BASE_TP_BUFFER29 0x00000040
788#define STB0899_OFF0_TP_BUFFER30 0xf378
789#define STB0899_BASE_TP_BUFFER30 0x00000040
790#define STB0899_OFF0_TP_BUFFER31 0xf37c
791#define STB0899_BASE_TP_BUFFER31 0x00000040
792#define STB0899_OFF0_TP_BUFFER32 0xf300
793#define STB0899_BASE_TP_BUFFER32 0x00000060
794#define STB0899_OFF0_TP_BUFFER33 0xf304
795#define STB0899_BASE_TP_BUFFER33 0x00000060
796#define STB0899_OFF0_TP_BUFFER34 0xf308
797#define STB0899_BASE_TP_BUFFER34 0x00000060
798#define STB0899_OFF0_TP_BUFFER35 0xf30c
799#define STB0899_BASE_TP_BUFFER35 0x00000060
800#define STB0899_OFF0_TP_BUFFER36 0xf310
801#define STB0899_BASE_TP_BUFFER36 0x00000060
802#define STB0899_OFF0_TP_BUFFER37 0xf314
803#define STB0899_BASE_TP_BUFFER37 0x00000060
804#define STB0899_OFF0_TP_BUFFER38 0xf318
805#define STB0899_BASE_TP_BUFFER38 0x00000060
806#define STB0899_OFF0_TP_BUFFER39 0xf31c
807#define STB0899_BASE_TP_BUFFER39 0x00000060
808#define STB0899_OFF0_TP_BUFFER40 0xf320
809#define STB0899_BASE_TP_BUFFER40 0x00000060
810#define STB0899_OFF0_TP_BUFFER41 0xf324
811#define STB0899_BASE_TP_BUFFER41 0x00000060
812#define STB0899_OFF0_TP_BUFFER42 0xf328
813#define STB0899_BASE_TP_BUFFER42 0x00000060
814#define STB0899_OFF0_TP_BUFFER43 0xf32c
815#define STB0899_BASE_TP_BUFFER43 0x00000060
816#define STB0899_OFF0_TP_BUFFER44 0xf330
817#define STB0899_BASE_TP_BUFFER44 0x00000060
818#define STB0899_OFF0_TP_BUFFER45 0xf334
819#define STB0899_BASE_TP_BUFFER45 0x00000060
820#define STB0899_OFF0_TP_BUFFER46 0xf338
821#define STB0899_BASE_TP_BUFFER46 0x00000060
822#define STB0899_OFF0_TP_BUFFER47 0xf33c
823#define STB0899_BASE_TP_BUFFER47 0x00000060
824#define STB0899_OFF0_TP_BUFFER48 0xf340
825#define STB0899_BASE_TP_BUFFER48 0x00000060
826#define STB0899_OFF0_TP_BUFFER49 0xf344
827#define STB0899_BASE_TP_BUFFER49 0x00000060
828#define STB0899_OFF0_TP_BUFFER50 0xf348
829#define STB0899_BASE_TP_BUFFER50 0x00000060
830#define STB0899_OFF0_TP_BUFFER51 0xf34c
831#define STB0899_BASE_TP_BUFFER51 0x00000060
832#define STB0899_OFF0_TP_BUFFER52 0xf350
833#define STB0899_BASE_TP_BUFFER52 0x00000060
834#define STB0899_OFF0_TP_BUFFER53 0xf354
835#define STB0899_BASE_TP_BUFFER53 0x00000060
836#define STB0899_OFF0_TP_BUFFER54 0xf358
837#define STB0899_BASE_TP_BUFFER54 0x00000060
838#define STB0899_OFF0_TP_BUFFER55 0xf35c
839#define STB0899_BASE_TP_BUFFER55 0x00000060
840#define STB0899_OFF0_TP_BUFFER56 0xf360
841#define STB0899_BASE_TP_BUFFER56 0x00000060
842#define STB0899_OFF0_TP_BUFFER57 0xf364
843#define STB0899_BASE_TP_BUFFER57 0x00000060
844#define STB0899_OFF0_TP_BUFFER58 0xf368
845#define STB0899_BASE_TP_BUFFER58 0x00000060
846#define STB0899_OFF0_TP_BUFFER59 0xf36c
847#define STB0899_BASE_TP_BUFFER59 0x00000060
848#define STB0899_OFF0_TP_BUFFER60 0xf370
849#define STB0899_BASE_TP_BUFFER60 0x00000060
850#define STB0899_OFF0_TP_BUFFER61 0xf374
851#define STB0899_BASE_TP_BUFFER61 0x00000060
852#define STB0899_OFF0_TP_BUFFER62 0xf378
853#define STB0899_BASE_TP_BUFFER62 0x00000060
854#define STB0899_OFF0_TP_BUFFER63 0xf37c
855#define STB0899_BASE_TP_BUFFER63 0x00000060
856
857#define STB0899_OFF0_RESET_CNTRL 0xf300
858#define STB0899_BASE_RESET_CNTRL 0x00000400
859#define STB0899_DVBS2_RESET (0x01 << 0)
860#define STB0899_OFFST_DVBS2_RESET 0
861#define STB0899_WIDTH_DVBS2_RESET 1
862
863#define STB0899_OFF0_ACM_ENABLE 0xf304
864#define STB0899_BASE_ACM_ENABLE 0x00000400
865#define STB0899_ACM_ENABLE 1
866
867#define STB0899_OFF0_DESCR_CNTRL 0xf30c
868#define STB0899_BASE_DESCR_CNTRL 0x00000400
869#define STB0899_OFFST_DESCR_CNTRL 0
870#define STB0899_WIDTH_DESCR_CNTRL 16
871
872#define STB0899_OFF0_UWP_CNTRL1 0xf320
873#define STB0899_BASE_UWP_CNTRL1 0x00000400
874#define STB0899_UWP_TH_SOF (0x7fff << 11)
875#define STB0899_OFFST_UWP_TH_SOF 11
876#define STB0899_WIDTH_UWP_TH_SOF 15
877#define STB0899_UWP_ESN0_QUANT (0xff << 3)
878#define STB0899_OFFST_UWP_ESN0_QUANT 3
879#define STB0899_WIDTH_UWP_ESN0_QUANT 8
880#define STB0899_UWP_ESN0_AVE (0x03 << 1)
881#define STB0899_OFFST_UWP_ESN0_AVE 1
882#define STB0899_WIDTH_UWP_ESN0_AVE 2
883#define STB0899_UWP_START (0x01 << 0)
884#define STB0899_OFFST_UWP_START 0
885#define STB0899_WIDTH_UWP_START 1
886
887#define STB0899_OFF0_UWP_CNTRL2 0xf324
888#define STB0899_BASE_UWP_CNTRL2 0x00000400
889#define STB0899_UWP_MISS_TH (0xff << 16)
890#define STB0899_OFFST_UWP_MISS_TH 16
891#define STB0899_WIDTH_UWP_MISS_TH 8
892#define STB0899_FE_FINE_TRK (0xff << 8)
893#define STB0899_OFFST_FE_FINE_TRK 8
894#define STB0899_WIDTH_FE_FINE_TRK 8
895#define STB0899_FE_COARSE_TRK (0xff << 0)
896#define STB0899_OFFST_FE_COARSE_TRK 0
897#define STB0899_WIDTH_FE_COARSE_TRK 8
898
899#define STB0899_OFF0_UWP_STAT1 0xf328
900#define STB0899_BASE_UWP_STAT1 0x00000400
901#define STB0899_UWP_STATE (0x03ff << 15)
902#define STB0899_OFFST_UWP_STATE 15
903#define STB0899_WIDTH_UWP_STATE 10
904#define STB0899_UW_MAX_PEAK (0x7fff << 0)
905#define STB0899_OFFST_UW_MAX_PEAK 0
906#define STB0899_WIDTH_UW_MAX_PEAK 15
907
908#define STB0899_OFF0_UWP_STAT2 0xf32c
909#define STB0899_BASE_UWP_STAT2 0x00000400
910#define STB0899_ESNO_EST (0x07ffff << 7)
911#define STB0899_OFFST_ESN0_EST 7
912#define STB0899_WIDTH_ESN0_EST 19
913#define STB0899_UWP_DECODE_MOD (0x7f << 0)
914#define STB0899_OFFST_UWP_DECODE_MOD 0
915#define STB0899_WIDTH_UWP_DECODE_MOD 7
916
917#define STB0899_OFF0_DMD_CORE_ID 0xf334
918#define STB0899_BASE_DMD_CORE_ID 0x00000400
919#define STB0899_CORE_ID (0xffffffff << 0)
920#define STB0899_OFFST_CORE_ID 0
921#define STB0899_WIDTH_CORE_ID 32
922
923#define STB0899_OFF0_DMD_VERSION_ID 0xf33c
924#define STB0899_BASE_DMD_VERSION_ID 0x00000400
925#define STB0899_VERSION_ID (0xff << 0)
926#define STB0899_OFFST_VERSION_ID 0
927#define STB0899_WIDTH_VERSION_ID 8
928
929#define STB0899_OFF0_DMD_STAT2 0xf340
930#define STB0899_BASE_DMD_STAT2 0x00000400
931#define STB0899_CSM_LOCK (0x01 << 1)
932#define STB0899_OFFST_CSM_LOCK 1
933#define STB0899_WIDTH_CSM_LOCK 1
934#define STB0899_UWP_LOCK (0x01 << 0)
935#define STB0899_OFFST_UWP_LOCK 0
936#define STB0899_WIDTH_UWP_LOCK 1
937
938#define STB0899_OFF0_FREQ_ADJ_SCALE 0xf344
939#define STB0899_BASE_FREQ_ADJ_SCALE 0x00000400
940#define STB0899_FREQ_ADJ_SCALE (0x0fff << 0)
941#define STB0899_OFFST_FREQ_ADJ_SCALE 0
942#define STB0899_WIDTH_FREQ_ADJ_SCALE 12
943
944#define STB0899_OFF0_UWP_CNTRL3 0xf34c
945#define STB0899_BASE_UWP_CNTRL3 0x00000400
946#define STB0899_UWP_TH_TRACK (0x7fff << 15)
947#define STB0899_OFFST_UWP_TH_TRACK 15
948#define STB0899_WIDTH_UWP_TH_TRACK 15
949#define STB0899_UWP_TH_ACQ (0x7fff << 0)
950#define STB0899_OFFST_UWP_TH_ACQ 0
951#define STB0899_WIDTH_UWP_TH_ACQ 15
952
953#define STB0899_OFF0_SYM_CLK_SEL 0xf350
954#define STB0899_BASE_SYM_CLK_SEL 0x00000400
955#define STB0899_SYM_CLK_SEL (0x03 << 0)
956#define STB0899_OFFST_SYM_CLK_SEL 0
957#define STB0899_WIDTH_SYM_CLK_SEL 2
958
959#define STB0899_OFF0_SOF_SRCH_TO 0xf354
960#define STB0899_BASE_SOF_SRCH_TO 0x00000400
961#define STB0899_SOF_SEARCH_TIMEOUT (0x3fffff << 0)
962#define STB0899_OFFST_SOF_SEARCH_TIMEOUT 0
963#define STB0899_WIDTH_SOF_SEARCH_TIMEOUT 22
964
965#define STB0899_OFF0_ACQ_CNTRL1 0xf358
966#define STB0899_BASE_ACQ_CNTRL1 0x00000400
967#define STB0899_FE_FINE_ACQ (0xff << 8)
968#define STB0899_OFFST_FE_FINE_ACQ 8
969#define STB0899_WIDTH_FE_FINE_ACQ 8
970#define STB0899_FE_COARSE_ACQ (0xff << 0)
971#define STB0899_OFFST_FE_COARSE_ACQ 0
972#define STB0899_WIDTH_FE_COARSE_ACQ 8
973
974#define STB0899_OFF0_ACQ_CNTRL2 0xf35c
975#define STB0899_BASE_ACQ_CNTRL2 0x00000400
976#define STB0899_ZIGZAG (0x01 << 25)
977#define STB0899_OFFST_ZIGZAG 25
978#define STB0899_WIDTH_ZIGZAG 1
979#define STB0899_NUM_STEPS (0xff << 17)
980#define STB0899_OFFST_NUM_STEPS 17
981#define STB0899_WIDTH_NUM_STEPS 8
982#define STB0899_FREQ_STEPSIZE (0x1ffff << 0)
983#define STB0899_OFFST_FREQ_STEPSIZE 0
984#define STB0899_WIDTH_FREQ_STEPSIZE 17
985
986#define STB0899_OFF0_ACQ_CNTRL3 0xf360
987#define STB0899_BASE_ACQ_CNTRL3 0x00000400
988#define STB0899_THRESHOLD_SCL (0x3f << 23)
989#define STB0899_OFFST_THRESHOLD_SCL 23
990#define STB0899_WIDTH_THRESHOLD_SCL 6
991#define STB0899_UWP_TH_SRCH (0x7fff << 8)
992#define STB0899_OFFST_UWP_TH_SRCH 8
993#define STB0899_WIDTH_UWP_TH_SRCH 15
994#define STB0899_AUTO_REACQUIRE (0x01 << 7)
995#define STB0899_OFFST_AUTO_REACQUIRE 7
996#define STB0899_WIDTH_AUTO_REACQUIRE 1
997#define STB0899_TRACK_LOCK_SEL (0x01 << 6)
998#define STB0899_OFFST_TRACK_LOCK_SEL 6
999#define STB0899_WIDTH_TRACK_LOCK_SEL 1
1000#define STB0899_ACQ_SEARCH_MODE (0x03 << 4)
1001#define STB0899_OFFST_ACQ_SEARCH_MODE 4
1002#define STB0899_WIDTH_ACQ_SEARCH_MODE 2
1003#define STB0899_CONFIRM_FRAMES (0x0f << 0)
1004#define STB0899_OFFST_CONFIRM_FRAMES 0
1005#define STB0899_WIDTH_CONFIRM_FRAMES 4
1006
1007#define STB0899_OFF0_FE_SETTLE 0xf364
1008#define STB0899_BASE_FE_SETTLE 0x00000400
1009#define STB0899_SETTLING_TIME (0x3fffff << 0)
1010#define STB0899_OFFST_SETTLING_TIME 0
1011#define STB0899_WIDTH_SETTLING_TIME 22
1012
1013#define STB0899_OFF0_AC_DWELL 0xf368
1014#define STB0899_BASE_AC_DWELL 0x00000400
1015#define STB0899_DWELL_TIME (0x3fffff << 0)
1016#define STB0899_OFFST_DWELL_TIME 0
1017#define STB0899_WIDTH_DWELL_TIME 22
1018
1019#define STB0899_OFF0_ACQUIRE_TRIG 0xf36c
1020#define STB0899_BASE_ACQUIRE_TRIG 0x00000400
1021#define STB0899_ACQUIRE (0x01 << 0)
1022#define STB0899_OFFST_ACQUIRE 0
1023#define STB0899_WIDTH_ACQUIRE 1
1024
1025#define STB0899_OFF0_LOCK_LOST 0xf370
1026#define STB0899_BASE_LOCK_LOST 0x00000400
1027#define STB0899_LOCK_LOST (0x01 << 0)
1028#define STB0899_OFFST_LOCK_LOST 0
1029#define STB0899_WIDTH_LOCK_LOST 1
1030
1031#define STB0899_OFF0_ACQ_STAT1 0xf374
1032#define STB0899_BASE_ACQ_STAT1 0x00000400
1033#define STB0899_STEP_FREQ (0x1fffff << 11)
1034#define STB0899_OFFST_STEP_FREQ 11
1035#define STB0899_WIDTH_STEP_FREQ 21
1036#define STB0899_ACQ_STATE (0x07 << 8)
1037#define STB0899_OFFST_ACQ_STATE 8
1038#define STB0899_WIDTH_ACQ_STATE 3
1039#define STB0899_UW_DETECT_COUNT (0xff << 0)
1040#define STB0899_OFFST_UW_DETECT_COUNT 0
1041#define STB0899_WIDTH_UW_DETECT_COUNT 8
1042
1043#define STB0899_OFF0_ACQ_TIMEOUT 0xf378
1044#define STB0899_BASE_ACQ_TIMEOUT 0x00000400
1045#define STB0899_ACQ_TIMEOUT (0x3fffff << 0)
1046#define STB0899_OFFST_ACQ_TIMEOUT 0
1047#define STB0899_WIDTH_ACQ_TIMEOUT 22
1048
1049#define STB0899_OFF0_ACQ_TIME 0xf37c
1050#define STB0899_BASE_ACQ_TIME 0x00000400
1051#define STB0899_ACQ_TIME_SYM (0xffffff << 0)
1052#define STB0899_OFFST_ACQ_TIME_SYM 0
1053#define STB0899_WIDTH_ACQ_TIME_SYM 24
1054
1055#define STB0899_OFF0_FINAL_AGC_CNTRL 0xf308
1056#define STB0899_BASE_FINAL_AGC_CNTRL 0x00000440
1057#define STB0899_FINAL_GAIN_INIT (0x3fff << 12)
1058#define STB0899_OFFST_FINAL_GAIN_INIT 12
1059#define STB0899_WIDTH_FINAL_GAIN_INIT 14
1060#define STB0899_FINAL_LOOP_GAIN (0x0f << 8)
1061#define STB0899_OFFST_FINAL_LOOP_GAIN 8
1062#define STB0899_WIDTH_FINAL_LOOP_GAIN 4
1063#define STB0899_FINAL_LD_GAIN_INIT (0x01 << 7)
1064#define STB0899_OFFST_FINAL_LD_GAIN_INIT 7
1065#define STB0899_WIDTH_FINAL_LD_GAIN_INIT 1
1066#define STB0899_FINAL_AGC_REF (0x7f << 0)
1067#define STB0899_OFFST_FINAL_AGC_REF 0
1068#define STB0899_WIDTH_FINAL_AGC_REF 7
1069
1070#define STB0899_OFF0_FINAL_AGC_GAIN 0xf30c
1071#define STB0899_BASE_FINAL_AGC_GAIN 0x00000440
1072#define STB0899_FINAL_AGC_GAIN (0x3fff << 0)
1073#define STB0899_OFFST_FINAL_AGC_GAIN 0
1074#define STB0899_WIDTH_FINAL_AGC_GAIN 14
1075
1076#define STB0899_OFF0_EQUALIZER_INIT 0xf310
1077#define STB0899_BASE_EQUALIZER_INIT 0x00000440
1078#define STB0899_EQ_SRST (0x01 << 1)
1079#define STB0899_OFFST_EQ_SRST 1
1080#define STB0899_WIDTH_EQ_SRST 1
1081#define STB0899_EQ_INIT (0x01 << 0)
1082#define STB0899_OFFST_EQ_INIT 0
1083#define STB0899_WIDTH_EQ_INIT 1
1084
1085#define STB0899_OFF0_EQ_CNTRL 0xf314
1086#define STB0899_BASE_EQ_CNTRL 0x00000440
1087#define STB0899_EQ_ADAPT_MODE (0x01 << 18)
1088#define STB0899_OFFST_EQ_ADAPT_MODE 18
1089#define STB0899_WIDTH_EQ_ADAPT_MODE 1
1090#define STB0899_EQ_DELAY (0x0f << 14)
1091#define STB0899_OFFST_EQ_DELAY 14
1092#define STB0899_WIDTH_EQ_DELAY 4
1093#define STB0899_EQ_QUANT_LEVEL (0xff << 6)
1094#define STB0899_OFFST_EQ_QUANT_LEVEL 6
1095#define STB0899_WIDTH_EQ_QUANT_LEVEL 8
1096#define STB0899_EQ_DISABLE_UPDATE (0x01 << 5)
1097#define STB0899_OFFST_EQ_DISABLE_UPDATE 5
1098#define STB0899_WIDTH_EQ_DISABLE_UPDATE 1
1099#define STB0899_EQ_BYPASS (0x01 << 4)
1100#define STB0899_OFFST_EQ_BYPASS 4
1101#define STB0899_WIDTH_EQ_BYPASS 1
1102#define STB0899_EQ_SHIFT (0x0f << 0)
1103#define STB0899_OFFST_EQ_SHIFT 0
1104#define STB0899_WIDTH_EQ_SHIFT 4
1105
1106#define STB0899_OFF0_EQ_I_INIT_COEFF_0 0xf320
1107#define STB0899_OFF1_EQ_I_INIT_COEFF_1 0xf324
1108#define STB0899_OFF2_EQ_I_INIT_COEFF_2 0xf328
1109#define STB0899_OFF3_EQ_I_INIT_COEFF_3 0xf32c
1110#define STB0899_OFF4_EQ_I_INIT_COEFF_4 0xf330
1111#define STB0899_OFF5_EQ_I_INIT_COEFF_5 0xf334
1112#define STB0899_OFF6_EQ_I_INIT_COEFF_6 0xf338
1113#define STB0899_OFF7_EQ_I_INIT_COEFF_7 0xf33c
1114#define STB0899_OFF8_EQ_I_INIT_COEFF_8 0xf340
1115#define STB0899_OFF9_EQ_I_INIT_COEFF_9 0xf344
1116#define STB0899_OFFa_EQ_I_INIT_COEFF_10 0xf348
1117#define STB0899_BASE_EQ_I_INIT_COEFF_N 0x00000440
1118#define STB0899_EQ_I_INIT_COEFF_N (0x0fff << 0)
1119#define STB0899_OFFST_EQ_I_INIT_COEFF_N 0
1120#define STB0899_WIDTH_EQ_I_INIT_COEFF_N 12
1121
1122#define STB0899_OFF0_EQ_Q_INIT_COEFF_0 0xf350
1123#define STB0899_OFF1_EQ_Q_INIT_COEFF_1 0xf354
1124#define STB0899_OFF2_EQ_Q_INIT_COEFF_2 0xf358
1125#define STB0899_OFF3_EQ_Q_INIT_COEFF_3 0xf35c
1126#define STB0899_OFF4_EQ_Q_INIT_COEFF_4 0xf360
1127#define STB0899_OFF5_EQ_Q_INIT_COEFF_5 0xf364
1128#define STB0899_OFF6_EQ_Q_INIT_COEFF_6 0xf368
1129#define STB0899_OFF7_EQ_Q_INIT_COEFF_7 0xf36c
1130#define STB0899_OFF8_EQ_Q_INIT_COEFF_8 0xf370
1131#define STB0899_OFF9_EQ_Q_INIT_COEFF_9 0xf374
1132#define STB0899_OFFa_EQ_Q_INIT_COEFF_10 0xf378
1133#define STB0899_BASE_EQ_Q_INIT_COEFF_N 0x00000440
1134#define STB0899_EQ_Q_INIT_COEFF_N (0x0fff << 0)
1135#define STB0899_OFFST_EQ_Q_INIT_COEFF_N 0
1136#define STB0899_WIDTH_EQ_Q_INIT_COEFF_N 12
1137
1138#define STB0899_OFF0_EQ_I_OUT_COEFF_0 0xf300
1139#define STB0899_OFF1_EQ_I_OUT_COEFF_1 0xf304
1140#define STB0899_OFF2_EQ_I_OUT_COEFF_2 0xf308
1141#define STB0899_OFF3_EQ_I_OUT_COEFF_3 0xf30c
1142#define STB0899_OFF4_EQ_I_OUT_COEFF_4 0xf310
1143#define STB0899_OFF5_EQ_I_OUT_COEFF_5 0xf314
1144#define STB0899_OFF6_EQ_I_OUT_COEFF_6 0xf318
1145#define STB0899_OFF7_EQ_I_OUT_COEFF_7 0xf31c
1146#define STB0899_OFF8_EQ_I_OUT_COEFF_8 0xf320
1147#define STB0899_OFF9_EQ_I_OUT_COEFF_9 0xf324
1148#define STB0899_OFFa_EQ_I_OUT_COEFF_10 0xf328
1149#define STB0899_BASE_EQ_I_OUT_COEFF_N 0x00000460
1150#define STB0899_EQ_I_OUT_COEFF_N (0x0fff << 0)
1151#define STB0899_OFFST_EQ_I_OUT_COEFF_N 0
1152#define STB0899_WIDTH_EQ_I_OUT_COEFF_N 12
1153
1154#define STB0899_OFF0_EQ_Q_OUT_COEFF_0 0xf330
1155#define STB0899_OFF1_EQ_Q_OUT_COEFF_1 0xf334
1156#define STB0899_OFF2_EQ_Q_OUT_COEFF_2 0xf338
1157#define STB0899_OFF3_EQ_Q_OUT_COEFF_3 0xf33c
1158#define STB0899_OFF4_EQ_Q_OUT_COEFF_4 0xf340
1159#define STB0899_OFF5_EQ_Q_OUT_COEFF_5 0xf344
1160#define STB0899_OFF6_EQ_Q_OUT_COEFF_6 0xf348
1161#define STB0899_OFF7_EQ_Q_OUT_COEFF_7 0xf34c
1162#define STB0899_OFF8_EQ_Q_OUT_COEFF_8 0xf350
1163#define STB0899_OFF9_EQ_Q_OUT_COEFF_9 0xf354
1164#define STB0899_OFFa_EQ_Q_OUT_COEFF_10 0xf358
1165#define STB0899_BASE_EQ_Q_OUT_COEFF_N 0x00000460
1166#define STB0899_EQ_Q_OUT_COEFF_N (0x0fff << 0)
1167#define STB0899_OFFST_EQ_Q_OUT_COEFF_N 0
1168#define STB0899_WIDTH_EQ_Q_OUT_COEFF_N 12
1169
1170/* S2 FEC */
1171#define STB0899_OFF0_BLOCK_LNGTH 0xfa04
1172#define STB0899_BASE_BLOCK_LNGTH 0x00000000
1173#define STB0899_BLOCK_LENGTH (0xff << 0)
1174#define STB0899_OFFST_BLOCK_LENGTH 0
1175#define STB0899_WIDTH_BLOCK_LENGTH 8
1176
1177#define STB0899_OFF0_ROW_STR 0xfa08
1178#define STB0899_BASE_ROW_STR 0x00000000
1179#define STB0899_ROW_STRIDE (0xff << 0)
1180#define STB0899_OFFST_ROW_STRIDE 0
1181#define STB0899_WIDTH_ROW_STRIDE 8
1182
1183#define STB0899_OFF0_MAX_ITER 0xfa0c
1184#define STB0899_BASE_MAX_ITER 0x00000000
1185#define STB0899_MAX_ITERATIONS (0xff << 0)
1186#define STB0899_OFFST_MAX_ITERATIONS 0
1187#define STB0899_WIDTH_MAX_ITERATIONS 8
1188
1189#define STB0899_OFF0_BN_END_ADDR 0xfa10
1190#define STB0899_BASE_BN_END_ADDR 0x00000000
1191#define STB0899_BN_END_ADDR (0x0fff << 0)
1192#define STB0899_OFFST_BN_END_ADDR 0
1193#define STB0899_WIDTH_BN_END_ADDR 12
1194
1195#define STB0899_OFF0_CN_END_ADDR 0xfa14
1196#define STB0899_BASE_CN_END_ADDR 0x00000000
1197#define STB0899_CN_END_ADDR (0x0fff << 0)
1198#define STB0899_OFFST_CN_END_ADDR 0
1199#define STB0899_WIDTH_CN_END_ADDR 12
1200
1201#define STB0899_OFF0_INFO_LENGTH 0xfa1c
1202#define STB0899_BASE_INFO_LENGTH 0x00000000
1203#define STB0899_INFO_LENGTH (0xff << 0)
1204#define STB0899_OFFST_INFO_LENGTH 0
1205#define STB0899_WIDTH_INFO_LENGTH 8
1206
1207#define STB0899_OFF0_BOT_ADDR 0xfa20
1208#define STB0899_BASE_BOT_ADDR 0x00000000
1209#define STB0899_BOTTOM_BASE_ADDR (0x03ff << 0)
1210#define STB0899_OFFST_BOTTOM_BASE_ADDR 0
1211#define STB0899_WIDTH_BOTTOM_BASE_ADDR 10
1212
1213#define STB0899_OFF0_BCH_BLK_LN 0xfa24
1214#define STB0899_BASE_BCH_BLK_LN 0x00000000
1215#define STB0899_BCH_BLOCK_LENGTH (0xffff << 0)
1216#define STB0899_OFFST_BCH_BLOCK_LENGTH 0
1217#define STB0899_WIDTH_BCH_BLOCK_LENGTH 16
1218
1219#define STB0899_OFF0_BCH_T 0xfa28
1220#define STB0899_BASE_BCH_T 0x00000000
1221#define STB0899_BCH_T (0x0f << 0)
1222#define STB0899_OFFST_BCH_T 0
1223#define STB0899_WIDTH_BCH_T 4
1224
1225#define STB0899_OFF0_CNFG_MODE 0xfa00
1226#define STB0899_BASE_CNFG_MODE 0x00000800
1227#define STB0899_MODCOD (0x1f << 2)
1228#define STB0899_OFFST_MODCOD 2
1229#define STB0899_WIDTH_MODCOD 5
1230#define STB0899_MODCOD_SEL (0x01 << 1)
1231#define STB0899_OFFST_MODCOD_SEL 1
1232#define STB0899_WIDTH_MODCOD_SEL 1
1233#define STB0899_CONFIG_MODE (0x01 << 0)
1234#define STB0899_OFFST_CONFIG_MODE 0
1235#define STB0899_WIDTH_CONFIG_MODE 1
1236
1237#define STB0899_OFF0_LDPC_STAT 0xfa04
1238#define STB0899_BASE_LDPC_STAT 0x00000800
1239#define STB0899_ITERATION (0xff << 3)
1240#define STB0899_OFFST_ITERATION 3
1241#define STB0899_WIDTH_ITERATION 8
1242#define STB0899_LDPC_DEC_STATE (0x07 << 0)
1243#define STB0899_OFFST_LDPC_DEC_STATE 0
1244#define STB0899_WIDTH_LDPC_DEC_STATE 3
1245
1246#define STB0899_OFF0_ITER_SCALE 0xfa08
1247#define STB0899_BASE_ITER_SCALE 0x00000800
1248#define STB0899_ITERATION_SCALE (0xff << 0)
1249#define STB0899_OFFST_ITERATION_SCALE 0
1250#define STB0899_WIDTH_ITERATION_SCALE 8
1251
1252#define STB0899_OFF0_INPUT_MODE 0xfa0c
1253#define STB0899_BASE_INPUT_MODE 0x00000800
1254#define STB0899_SD_BLOCK1_STREAM0 (0x01 << 0)
1255#define STB0899_OFFST_SD_BLOCK1_STREAM0 0
1256#define STB0899_WIDTH_SD_BLOCK1_STREAM0 1
1257
1258#define STB0899_OFF0_LDPCDECRST 0xfa10
1259#define STB0899_BASE_LDPCDECRST 0x00000800
1260#define STB0899_LDPC_DEC_RST (0x01 << 0)
1261#define STB0899_OFFST_LDPC_DEC_RST 0
1262#define STB0899_WIDTH_LDPC_DEC_RST 1
1263
1264#define STB0899_OFF0_CLK_PER_BYTE_RW 0xfa14
1265#define STB0899_BASE_CLK_PER_BYTE_RW 0x00000800
1266#define STB0899_CLKS_PER_BYTE (0x0f << 0)
1267#define STB0899_OFFST_CLKS_PER_BYTE 0
1268#define STB0899_WIDTH_CLKS_PER_BYTE 5
1269
1270#define STB0899_OFF0_BCH_ERRORS 0xfa18
1271#define STB0899_BASE_BCH_ERRORS 0x00000800
1272#define STB0899_BCH_ERRORS (0x0f << 0)
1273#define STB0899_OFFST_BCH_ERRORS 0
1274#define STB0899_WIDTH_BCH_ERRORS 4
1275
1276#define STB0899_OFF0_LDPC_ERRORS 0xfa1c
1277#define STB0899_BASE_LDPC_ERRORS 0x00000800
1278#define STB0899_LDPC_ERRORS (0xffff << 0)
1279#define STB0899_OFFST_LDPC_ERRORS 0
1280#define STB0899_WIDTH_LDPC_ERRORS 16
1281
1282#define STB0899_OFF0_BCH_MODE 0xfa20
1283#define STB0899_BASE_BCH_MODE 0x00000800
1284#define STB0899_BCH_CORRECT_N (0x01 << 1)
1285#define STB0899_OFFST_BCH_CORRECT_N 1
1286#define STB0899_WIDTH_BCH_CORRECT_N 1
1287#define STB0899_FULL_BYPASS (0x01 << 0)
1288#define STB0899_OFFST_FULL_BYPASS 0
1289#define STB0899_WIDTH_FULL_BYPASS 1
1290
1291#define STB0899_OFF0_ERR_ACC_PER 0xfa24
1292#define STB0899_BASE_ERR_ACC_PER 0x00000800
1293#define STB0899_BCH_ERR_ACC_PERIOD (0x0f << 0)
1294#define STB0899_OFFST_BCH_ERR_ACC_PERIOD 0
1295#define STB0899_WIDTH_BCH_ERR_ACC_PERIOD 4
1296
1297#define STB0899_OFF0_BCH_ERR_ACC 0xfa28
1298#define STB0899_BASE_BCH_ERR_ACC 0x00000800
1299#define STB0899_BCH_ERR_ACCUM (0xff << 0)
1300#define STB0899_OFFST_BCH_ERR_ACCUM 0
1301#define STB0899_WIDTH_BCH_ERR_ACCUM 8
1302
1303#define STB0899_OFF0_FEC_CORE_ID_REG 0xfa2c
1304#define STB0899_BASE_FEC_CORE_ID_REG 0x00000800
1305#define STB0899_FEC_CORE_ID (0xffffffff << 0)
1306#define STB0899_OFFST_FEC_CORE_ID 0
1307#define STB0899_WIDTH_FEC_CORE_ID 32
1308
1309#define STB0899_OFF0_FEC_VER_ID_REG 0xfa34
1310#define STB0899_BASE_FEC_VER_ID_REG 0x00000800
1311#define STB0899_FEC_VER_ID (0xff << 0)
1312#define STB0899_OFFST_FEC_VER_ID 0
1313#define STB0899_WIDTH_FEC_VER_ID 8
1314
1315#define STB0899_OFF0_FEC_TP_SEL 0xfa38
1316#define STB0899_BASE_FEC_TP_SEL 0x00000800
1317
1318#define STB0899_OFF0_CSM_CNTRL1 0xf310
1319#define STB0899_BASE_CSM_CNTRL1 0x00000400
1320#define STB0899_CSM_FORCE_FREQLOCK (0x01 << 19)
1321#define STB0899_OFFST_CSM_FORCE_FREQLOCK 19
1322#define STB0899_WIDTH_CSM_FORCE_FREQLOCK 1
1323#define STB0899_CSM_FREQ_LOCKSTATE (0x01 << 18)
1324#define STB0899_OFFST_CSM_FREQ_LOCKSTATE 18
1325#define STB0899_WIDTH_CSM_FREQ_LOCKSTATE 1
1326#define STB0899_CSM_AUTO_PARAM (0x01 << 17)
1327#define STB0899_OFFST_CSM_AUTO_PARAM 17
1328#define STB0899_WIDTH_CSM_AUTO_PARAM 1
1329#define STB0899_FE_LOOP_SHIFT (0x07 << 14)
1330#define STB0899_OFFST_FE_LOOP_SHIFT 14
1331#define STB0899_WIDTH_FE_LOOP_SHIFT 3
1332#define STB0899_CSM_AGC_SHIFT (0x07 << 11)
1333#define STB0899_OFFST_CSM_AGC_SHIFT 11
1334#define STB0899_WIDTH_CSM_AGC_SHIFT 3
1335#define STB0899_CSM_AGC_GAIN (0x1ff << 2)
1336#define STB0899_OFFST_CSM_AGC_GAIN 2
1337#define STB0899_WIDTH_CSM_AGC_GAIN 9
1338#define STB0899_CSM_TWO_PASS (0x01 << 1)
1339#define STB0899_OFFST_CSM_TWO_PASS 1
1340#define STB0899_WIDTH_CSM_TWO_PASS 1
1341#define STB0899_CSM_DVT_TABLE (0x01 << 0)
1342#define STB0899_OFFST_CSM_DVT_TABLE 0
1343#define STB0899_WIDTH_CSM_DVT_TABLE 1
1344
1345#define STB0899_OFF0_CSM_CNTRL2 0xf314
1346#define STB0899_BASE_CSM_CNTRL2 0x00000400
1347#define STB0899_CSM_GAMMA_RHO_ACQ (0x1ff << 9)
1348#define STB0899_OFFST_CSM_GAMMA_RHOACQ 9
1349#define STB0899_WIDTH_CSM_GAMMA_RHOACQ 9
1350#define STB0899_CSM_GAMMA_ACQ (0x1ff << 0)
1351#define STB0899_OFFST_CSM_GAMMA_ACQ 0
1352#define STB0899_WIDTH_CSM_GAMMA_ACQ 9
1353
1354#define STB0899_OFF0_CSM_CNTRL3 0xf318
1355#define STB0899_BASE_CSM_CNTRL3 0x00000400
1356#define STB0899_CSM_GAMMA_RHO_TRACK (0x1ff << 9)
1357#define STB0899_OFFST_CSM_GAMMA_RHOTRACK 9
1358#define STB0899_WIDTH_CSM_GAMMA_RHOTRACK 9
1359#define STB0899_CSM_GAMMA_TRACK (0x1ff << 0)
1360#define STB0899_OFFST_CSM_GAMMA_TRACK 0
1361#define STB0899_WIDTH_CSM_GAMMA_TRACK 9
1362
1363#define STB0899_OFF0_CSM_CNTRL4 0xf31c
1364#define STB0899_BASE_CSM_CNTRL4 0x00000400
1365#define STB0899_CSM_PHASEDIFF_THRESH (0x0f << 8)
1366#define STB0899_OFFST_CSM_PHASEDIFF_THRESH 8
1367#define STB0899_WIDTH_CSM_PHASEDIFF_THRESH 4
1368#define STB0899_CSM_LOCKCOUNT_THRESH (0xff << 0)
1369#define STB0899_OFFST_CSM_LOCKCOUNT_THRESH 0
1370#define STB0899_WIDTH_CSM_LOCKCOUNT_THRESH 8
1371
1372/* Check on chapter 8 page 42 */
1373#define STB0899_ERRCTRL1 0xf574
1374#define STB0899_ERRCTRL2 0xf575
1375#define STB0899_ERRCTRL3 0xf576
1376#define STB0899_ERR_SRC_S1 (0x1f << 3)
1377#define STB0899_OFFST_ERR_SRC_S1 3
1378#define STB0899_WIDTH_ERR_SRC_S1 5
1379#define STB0899_ERR_SRC_S2 (0x0f << 0)
1380#define STB0899_OFFST_ERR_SRC_S2 0
1381#define STB0899_WIDTH_ERR_SRC_S2 4
1382#define STB0899_NOE (0x07 << 0)
1383#define STB0899_OFFST_NOE 0
1384#define STB0899_WIDTH_NOE 3
1385
1386#define STB0899_ECNT1M 0xf524
1387#define STB0899_ECNT1L 0xf525
1388#define STB0899_ECNT2M 0xf526
1389#define STB0899_ECNT2L 0xf527
1390#define STB0899_ECNT3M 0xf528
1391#define STB0899_ECNT3L 0xf529
1392
1393#define STB0899_DMONMSK1 0xf57b
1394#define STB0899_DMONMSK1_WAIT_1STEP (1 << 7)
1395#define STB0899_DMONMSK1_FREE_14 (1 << 6)
1396#define STB0899_DMONMSK1_AVRGVIT_CALC (1 << 5)
1397#define STB0899_DMONMSK1_FREE_12 (1 << 4)
1398#define STB0899_DMONMSK1_FREE_11 (1 << 3)
1399#define STB0899_DMONMSK1_B0DIV_CALC (1 << 2)
1400#define STB0899_DMONMSK1_KDIVB1_CALC (1 << 1)
1401#define STB0899_DMONMSK1_KDIVB2_CALC (1 << 0)
1402
1403#define STB0899_DMONMSK0 0xf57c
1404#define STB0899_DMONMSK0_SMOTTH_CALC (1 << 7)
1405#define STB0899_DMONMSK0_FREE_6 (1 << 6)
1406#define STB0899_DMONMSK0_SIGPOWER_CALC (1 << 5)
1407#define STB0899_DMONMSK0_QSEUIL_CALC (1 << 4)
1408#define STB0899_DMONMSK0_FREE_3 (1 << 3)
1409#define STB0899_DMONMSK0_FREE_2 (1 << 2)
1410#define STB0899_DMONMSK0_KVDIVB1_CALC (1 << 1)
1411#define STB0899_DMONMSK0_KVDIVB2_CALC (1 << 0)
1412
1413#define STB0899_TSULC 0xf549
1414#define STB0899_ULNOSYNCBYTES (0x01 << 7)
1415#define STB0899_OFFST_ULNOSYNCBYTES 7
1416#define STB0899_WIDTH_ULNOSYNCBYTES 1
1417#define STB0899_ULPARITY_ON (0x01 << 6)
1418#define STB0899_OFFST_ULPARITY_ON 6
1419#define STB0899_WIDTH_ULPARITY_ON 1
1420#define STB0899_ULSYNCOUTRS (0x01 << 5)
1421#define STB0899_OFFST_ULSYNCOUTRS 5
1422#define STB0899_WIDTH_ULSYNCOUTRS 1
1423#define STB0899_ULDSS_PACKETS (0x01 << 0)
1424#define STB0899_OFFST_ULDSS_PACKETS 0
1425#define STB0899_WIDTH_ULDSS_PACKETS 1
1426
1427#define STB0899_TSLPL 0xf54b
1428#define STB0899_LLDVBS2_MODE (0x01 << 4)
1429#define STB0899_OFFST_LLDVBS2_MODE 4
1430#define STB0899_WIDTH_LLDVBS2_MODE 1
1431#define STB0899_LLISSYI_ON (0x01 << 3)
1432#define STB0899_OFFST_LLISSYI_ON 3
1433#define STB0899_WIDTH_LLISSYI_ON 1
1434#define STB0899_LLNPD_ON (0x01 << 2)
1435#define STB0899_OFFST_LLNPD_ON 2
1436#define STB0899_WIDTH_LLNPD_ON 1
1437#define STB0899_LLCRC8_ON (0x01 << 1)
1438#define STB0899_OFFST_LLCRC8_ON 1
1439#define STB0899_WIDTH_LLCRC8_ON 1
1440
1441#define STB0899_TSCFGH 0xf54c
1442#define STB0899_OUTRS_PS (0x01 << 6)
1443#define STB0899_OFFST_OUTRS_PS 6
1444#define STB0899_WIDTH_OUTRS_PS 1
1445#define STB0899_SYNCBYTE (0x01 << 5)
1446#define STB0899_OFFST_SYNCBYTE 5
1447#define STB0899_WIDTH_SYNCBYTE 1
1448#define STB0899_PFBIT (0x01 << 4)
1449#define STB0899_OFFST_PFBIT 4
1450#define STB0899_WIDTH_PFBIT 1
1451#define STB0899_ERR_BIT (0x01 << 3)
1452#define STB0899_OFFST_ERR_BIT 3
1453#define STB0899_WIDTH_ERR_BIT 1
1454#define STB0899_MPEG (0x01 << 2)
1455#define STB0899_OFFST_MPEG 2
1456#define STB0899_WIDTH_MPEG 1
1457#define STB0899_CLK_POL (0x01 << 1)
1458#define STB0899_OFFST_CLK_POL 1
1459#define STB0899_WIDTH_CLK_POL 1
1460#define STB0899_FORCE0 (0x01 << 0)
1461#define STB0899_OFFST_FORCE0 0
1462#define STB0899_WIDTH_FORCE0 1
1463
1464#define STB0899_TSCFGM 0xf54d
1465#define STB0899_LLPRIORITY (0x01 << 3)
1466#define STB0899_OFFST_LLPRIORIY 3
1467#define STB0899_WIDTH_LLPRIORITY 1
1468#define STB0899_EN188 (0x01 << 2)
1469#define STB0899_OFFST_EN188 2
1470#define STB0899_WIDTH_EN188 1
1471
1472#define STB0899_TSCFGL 0xf54e
1473#define STB0899_DEL_ERRPCK (0x01 << 7)
1474#define STB0899_OFFST_DEL_ERRPCK 7
1475#define STB0899_WIDTH_DEL_ERRPCK 1
1476#define STB0899_ERRFLAGSTD (0x01 << 5)
1477#define STB0899_OFFST_ERRFLAGSTD 5
1478#define STB0899_WIDTH_ERRFLAGSTD 1
1479#define STB0899_MPEGERR (0x01 << 4)
1480#define STB0899_OFFST_MPEGERR 4
1481#define STB0899_WIDTH_MPEGERR 1
1482#define STB0899_BCH_CHK (0x01 << 3)
1483#define STB0899_OFFST_BCH_CHK 5
1484#define STB0899_WIDTH_BCH_CHK 1
1485#define STB0899_CRC8CHK (0x01 << 2)
1486#define STB0899_OFFST_CRC8CHK 2
1487#define STB0899_WIDTH_CRC8CHK 1
1488#define STB0899_SPEC_INFO (0x01 << 1)
1489#define STB0899_OFFST_SPEC_INFO 1
1490#define STB0899_WIDTH_SPEC_INFO 1
1491#define STB0899_LOW_PRIO_CLK (0x01 << 0)
1492#define STB0899_OFFST_LOW_PRIO_CLK 0
1493#define STB0899_WIDTH_LOW_PRIO_CLK 1
1494#define STB0899_ERROR_NORM (0x00 << 0)
1495#define STB0899_OFFST_ERROR_NORM 0
1496#define STB0899_WIDTH_ERROR_NORM 0
1497
1498#define STB0899_TSOUT 0xf54f
1499#define STB0899_RSSYNCDEL 0xf550
1500#define STB0899_TSINHDELH 0xf551
1501#define STB0899_TSINHDELM 0xf552
1502#define STB0899_TSINHDELL 0xf553
1503#define STB0899_TSLLSTKM 0xf55a
1504#define STB0899_TSLLSTKL 0xf55b
1505#define STB0899_TSULSTKM 0xf55c
1506#define STB0899_TSULSTKL 0xf55d
1507#define STB0899_TSSTATUS 0xf561
1508
1509#define STB0899_PDELCTRL 0xf600
1510#define STB0899_INVERT_RES (0x01 << 7)
1511#define STB0899_OFFST_INVERT_RES 7
1512#define STB0899_WIDTH_INVERT_RES 1
1513#define STB0899_FORCE_ACCEPTED (0x01 << 6)
1514#define STB0899_OFFST_FORCE_ACCEPTED 6
1515#define STB0899_WIDTH_FORCE_ACCEPTED 1
1516#define STB0899_FILTER_EN (0x01 << 5)
1517#define STB0899_OFFST_FILTER_EN 5
1518#define STB0899_WIDTH_FILTER_EN 1
1519#define STB0899_LOCKFALL_THRESH (0x01 << 4)
1520#define STB0899_OFFST_LOCKFALL_THRESH 4
1521#define STB0899_WIDTH_LOCKFALL_THRESH 1
1522#define STB0899_HYST_EN (0x01 << 3)
1523#define STB0899_OFFST_HYST_EN 3
1524#define STB0899_WIDTH_HYST_EN 1
1525#define STB0899_HYST_SWRST (0x01 << 2)
1526#define STB0899_OFFST_HYST_SWRST 2
1527#define STB0899_WIDTH_HYST_SWRST 1
1528#define STB0899_ALGO_EN (0x01 << 1)
1529#define STB0899_OFFST_ALGO_EN 1
1530#define STB0899_WIDTH_ALGO_EN 1
1531#define STB0899_ALGO_SWRST (0x01 << 0)
1532#define STB0899_OFFST_ALGO_SWRST 0
1533#define STB0899_WIDTH_ALGO_SWRST 1
1534
1535#define STB0899_PDELCTRL2 0xf601
1536#define STB0899_BBHCTRL1 0xf602
1537#define STB0899_BBHCTRL2 0xf603
1538#define STB0899_HYSTTHRESH 0xf604
1539
1540#define STB0899_MATCSTM 0xf605
1541#define STB0899_MATCSTL 0xf606
1542#define STB0899_UPLCSTM 0xf607
1543#define STB0899_UPLCSTL 0xf608
1544#define STB0899_DFLCSTM 0xf609
1545#define STB0899_DFLCSTL 0xf60a
1546#define STB0899_SYNCCST 0xf60b
1547#define STB0899_SYNCDCSTM 0xf60c
1548#define STB0899_SYNCDCSTL 0xf60d
1549#define STB0899_ISI_ENTRY 0xf60e
1550#define STB0899_ISI_BIT_EN 0xf60f
1551#define STB0899_MATSTRM 0xf610
1552#define STB0899_MATSTRL 0xf611
1553#define STB0899_UPLSTRM 0xf612
1554#define STB0899_UPLSTRL 0xf613
1555#define STB0899_DFLSTRM 0xf614
1556#define STB0899_DFLSTRL 0xf615
1557#define STB0899_SYNCSTR 0xf616
1558#define STB0899_SYNCDSTRM 0xf617
1559#define STB0899_SYNCDSTRL 0xf618
1560
1561#define STB0899_CFGPDELSTATUS1 0xf619
1562#define STB0899_BADDFL (0x01 << 6)
1563#define STB0899_OFFST_BADDFL 6
1564#define STB0899_WIDTH_BADDFL 1
1565#define STB0899_CONTINUOUS_STREAM (0x01 << 5)
1566#define STB0899_OFFST_CONTINUOUS_STREAM 5
1567#define STB0899_WIDTH_CONTINUOUS_STREAM 1
1568#define STB0899_ACCEPTED_STREAM (0x01 << 4)
1569#define STB0899_OFFST_ACCEPTED_STREAM 4
1570#define STB0899_WIDTH_ACCEPTED_STREAM 1
1571#define STB0899_BCH_ERRFLAG (0x01 << 3)
1572#define STB0899_OFFST_BCH_ERRFLAG 3
1573#define STB0899_WIDTH_BCH_ERRFLAG 1
1574#define STB0899_CRCRES (0x01 << 2)
1575#define STB0899_OFFST_CRCRES 2
1576#define STB0899_WIDTH_CRCRES 1
1577#define STB0899_CFGPDELSTATUS_LOCK (0x01 << 1)
1578#define STB0899_OFFST_CFGPDELSTATUS_LOCK 1
1579#define STB0899_WIDTH_CFGPDELSTATUS_LOCK 1
1580#define STB0899_1STLOCK (0x01 << 0)
1581#define STB0899_OFFST_1STLOCK 0
1582#define STB0899_WIDTH_1STLOCK 1
1583
1584#define STB0899_CFGPDELSTATUS2 0xf61a
1585#define STB0899_BBFERRORM 0xf61b
1586#define STB0899_BBFERRORL 0xf61c
1587#define STB0899_UPKTERRORM 0xf61d
1588#define STB0899_UPKTERRORL 0xf61e
1589
1590#define STB0899_TSTCK 0xff10
1591
1592#define STB0899_TSTRES 0xff11
1593#define STB0899_FRESLDPC (0x01 << 7)
1594#define STB0899_OFFST_FRESLDPC 7
1595#define STB0899_WIDTH_FRESLDPC 1
1596#define STB0899_FRESRS (0x01 << 6)
1597#define STB0899_OFFST_FRESRS 6
1598#define STB0899_WIDTH_FRESRS 1
1599#define STB0899_FRESVIT (0x01 << 5)
1600#define STB0899_OFFST_FRESVIT 5
1601#define STB0899_WIDTH_FRESVIT 1
1602#define STB0899_FRESMAS1_2 (0x01 << 4)
1603#define STB0899_OFFST_FRESMAS1_2 4
1604#define STB0899_WIDTH_FRESMAS1_2 1
1605#define STB0899_FRESACS (0x01 << 3)
1606#define STB0899_OFFST_FRESACS 3
1607#define STB0899_WIDTH_FRESACS 1
1608#define STB0899_FRESSYM (0x01 << 2)
1609#define STB0899_OFFST_FRESSYM 2
1610#define STB0899_WIDTH_FRESSYM 1
1611#define STB0899_FRESMAS (0x01 << 1)
1612#define STB0899_OFFST_FRESMAS 1
1613#define STB0899_WIDTH_FRESMAS 1
1614#define STB0899_FRESINT (0x01 << 0)
1615#define STB0899_OFFST_FRESINIT 0
1616#define STB0899_WIDTH_FRESINIT 1
1617
1618#define STB0899_TSTOUT 0xff12
1619#define STB0899_EN_SIGNATURE (0x01 << 7)
1620#define STB0899_OFFST_EN_SIGNATURE 7
1621#define STB0899_WIDTH_EN_SIGNATURE 1
1622#define STB0899_BCLK_CLK (0x01 << 6)
1623#define STB0899_OFFST_BCLK_CLK 6
1624#define STB0899_WIDTH_BCLK_CLK 1
1625#define STB0899_SGNL_OUT (0x01 << 5)
1626#define STB0899_OFFST_SGNL_OUT 5
1627#define STB0899_WIDTH_SGNL_OUT 1
1628#define STB0899_TS (0x01 << 4)
1629#define STB0899_OFFST_TS 4
1630#define STB0899_WIDTH_TS 1
1631#define STB0899_CTEST (0x01 << 0)
1632#define STB0899_OFFST_CTEST 0
1633#define STB0899_WIDTH_CTEST 1
1634
1635#define STB0899_TSTIN 0xff13
1636#define STB0899_TEST_IN (0x01 << 7)
1637#define STB0899_OFFST_TEST_IN 7
1638#define STB0899_WIDTH_TEST_IN 1
1639#define STB0899_EN_ADC (0x01 << 6)
1640#define STB0899_OFFST_EN_ADC 6
1641#define STB0899_WIDTH_ENADC 1
1642#define STB0899_SGN_ADC (0x01 << 5)
1643#define STB0899_OFFST_SGN_ADC 5
1644#define STB0899_WIDTH_SGN_ADC 1
1645#define STB0899_BCLK_IN (0x01 << 4)
1646#define STB0899_OFFST_BCLK_IN 4
1647#define STB0899_WIDTH_BCLK_IN 1
1648#define STB0899_JETONIN_MODE (0x01 << 3)
1649#define STB0899_OFFST_JETONIN_MODE 3
1650#define STB0899_WIDTH_JETONIN_MODE 1
1651#define STB0899_BCLK_VALUE (0x01 << 2)
1652#define STB0899_OFFST_BCLK_VALUE 2
1653#define STB0899_WIDTH_BCLK_VALUE 1
1654#define STB0899_SGNRST_T12 (0x01 << 1)
1655#define STB0899_OFFST_SGNRST_T12 1
1656#define STB0899_WIDTH_SGNRST_T12 1
1657#define STB0899_LOWSP_ENAX (0x01 << 0)
1658#define STB0899_OFFST_LOWSP_ENAX 0
1659#define STB0899_WIDTH_LOWSP_ENAX 1
1660
1661#define STB0899_TSTSYS 0xff14
1662#define STB0899_TSTCHIP 0xff15
1663#define STB0899_TSTFREE 0xff16
1664#define STB0899_TSTI2C 0xff17
1665#define STB0899_BITSPEEDM 0xff1c
1666#define STB0899_BITSPEEDL 0xff1d
1667#define STB0899_TBUSBIT 0xff1e
1668#define STB0899_TSTDIS 0xff24
1669#define STB0899_TSTDISRX 0xff25
1670#define STB0899_TSTJETON 0xff28
1671#define STB0899_TSTDCADJ 0xff40
1672#define STB0899_TSTAGC1 0xff41
1673#define STB0899_TSTAGC1N 0xff42
1674#define STB0899_TSTPOLYPH 0xff48
1675#define STB0899_TSTR 0xff49
1676#define STB0899_TSTAGC2 0xff4a
1677#define STB0899_TSTCTL1 0xff4b
1678#define STB0899_TSTCTL2 0xff4c
1679#define STB0899_TSTCTL3 0xff4d
1680#define STB0899_TSTDEMAP 0xff50
1681#define STB0899_TSTDEMAP2 0xff51
1682#define STB0899_TSTDEMMON 0xff52
1683#define STB0899_TSTRATE 0xff53
1684#define STB0899_TSTSELOUT 0xff54
1685#define STB0899_TSYNC 0xff55
1686#define STB0899_TSTERR 0xff56
1687#define STB0899_TSTRAM1 0xff58
1688#define STB0899_TSTVSELOUT 0xff59
1689#define STB0899_TSTFORCEIN 0xff5a
1690#define STB0899_TSTRS1 0xff5c
1691#define STB0899_TSTRS2 0xff5d
1692#define STB0899_TSTRS3 0xff53
1693
1694#define STB0899_INTBUFSTATUS 0xf200
1695#define STB0899_INTBUFCTRL 0xf201
1696#define STB0899_PCKLENUL 0xf55e
1697#define STB0899_PCKLENLL 0xf55f
1698#define STB0899_RSPCKLEN 0xf560
1699
1700/* 2 registers */
1701#define STB0899_SYNCDCST 0xf60c
1702
1703/* DiSEqC */
1704#define STB0899_DISCNTRL1 0xf0a0
1705#define STB0899_TIMOFF (0x01 << 7)
1706#define STB0899_OFFST_TIMOFF 7
1707#define STB0899_WIDTH_TIMOFF 1
1708#define STB0899_DISEQCRESET (0x01 << 6)
1709#define STB0899_OFFST_DISEQCRESET 6
1710#define STB0899_WIDTH_DISEQCRESET 1
1711#define STB0899_TIMCMD (0x03 << 4)
1712#define STB0899_OFFST_TIMCMD 4
1713#define STB0899_WIDTH_TIMCMD 2
1714#define STB0899_DISPRECHARGE (0x01 << 2)
1715#define STB0899_OFFST_DISPRECHARGE 2
1716#define STB0899_WIDTH_DISPRECHARGE 1
1717#define STB0899_DISEQCMODE (0x03 << 0)
1718#define STB0899_OFFST_DISEQCMODE 0
1719#define STB0899_WIDTH_DISEQCMODE 2
1720
1721#define STB0899_DISCNTRL2 0xf0a1
1722#define STB0899_RECEIVER_ON (0x01 << 7)
1723#define STB0899_OFFST_RECEIVER_ON 7
1724#define STB0899_WIDTH_RECEIVER_ON 1
1725#define STB0899_IGNO_SHORT_22K (0x01 << 6)
1726#define STB0899_OFFST_IGNO_SHORT_22K 6
1727#define STB0899_WIDTH_IGNO_SHORT_22K 1
1728#define STB0899_ONECHIP_TRX (0x01 << 5)
1729#define STB0899_OFFST_ONECHIP_TRX 5
1730#define STB0899_WIDTH_ONECHIP_TRX 1
1731#define STB0899_EXT_ENVELOP (0x01 << 4)
1732#define STB0899_OFFST_EXT_ENVELOP 4
1733#define STB0899_WIDTH_EXT_ENVELOP 1
1734#define STB0899_PIN_SELECT (0x03 << 2)
1735#define STB0899_OFFST_PIN_SELCT 2
1736#define STB0899_WIDTH_PIN_SELCT 2
1737#define STB0899_IRQ_RXEND (0x01 << 1)
1738#define STB0899_OFFST_IRQ_RXEND 1
1739#define STB0899_WIDTH_IRQ_RXEND 1
1740#define STB0899_IRQ_4NBYTES (0x01 << 0)
1741#define STB0899_OFFST_IRQ_4NBYTES 0
1742#define STB0899_WIDTH_IRQ_4NBYTES 1
1743
1744#define STB0899_DISRX_ST0 0xf0a4
1745#define STB0899_RXEND (0x01 << 7)
1746#define STB0899_OFFST_RXEND 7
1747#define STB0899_WIDTH_RXEND 1
1748#define STB0899_RXACTIVE (0x01 << 6)
1749#define STB0899_OFFST_RXACTIVE 6
1750#define STB0899_WIDTH_RXACTIVE 1
1751#define STB0899_SHORT22K (0x01 << 5)
1752#define STB0899_OFFST_SHORT22K 5
1753#define STB0899_WIDTH_SHORT22K 1
1754#define STB0899_CONTTONE (0x01 << 4)
1755#define STB0899_OFFST_CONTTONE 4
1756#define STB0899_WIDTH_CONTONE 1
1757#define STB0899_4BFIFOREDY (0x01 << 3)
1758#define STB0899_OFFST_4BFIFOREDY 3
1759#define STB0899_WIDTH_4BFIFOREDY 1
1760#define STB0899_FIFOEMPTY (0x01 << 2)
1761#define STB0899_OFFST_FIFOEMPTY 2
1762#define STB0899_WIDTH_FIFOEMPTY 1
1763#define STB0899_ABORTTRX (0x01 << 0)
1764#define STB0899_OFFST_ABORTTRX 0
1765#define STB0899_WIDTH_ABORTTRX 1
1766
1767#define STB0899_DISRX_ST1 0xf0a5
1768#define STB0899_RXFAIL (0x01 << 7)
1769#define STB0899_OFFST_RXFAIL 7
1770#define STB0899_WIDTH_RXFAIL 1
1771#define STB0899_FIFOPFAIL (0x01 << 6)
1772#define STB0899_OFFST_FIFOPFAIL 6
1773#define STB0899_WIDTH_FIFOPFAIL 1
1774#define STB0899_RXNONBYTES (0x01 << 5)
1775#define STB0899_OFFST_RXNONBYTES 5
1776#define STB0899_WIDTH_RXNONBYTES 1
1777#define STB0899_FIFOOVF (0x01 << 4)
1778#define STB0899_OFFST_FIFOOVF 4
1779#define STB0899_WIDTH_FIFOOVF 1
1780#define STB0899_FIFOBYTENBR (0x0f << 0)
1781#define STB0899_OFFST_FIFOBYTENBR 0
1782#define STB0899_WIDTH_FIFOBYTENBR 4
1783
1784#define STB0899_DISPARITY 0xf0a6
1785
1786#define STB0899_DISFIFO 0xf0a7
1787
1788#define STB0899_DISSTATUS 0xf0a8
1789#define STB0899_FIFOFULL (0x01 << 6)
1790#define STB0899_OFFST_FIFOFULL 6
1791#define STB0899_WIDTH_FIFOFULL 1
1792#define STB0899_TXIDLE (0x01 << 5)
1793#define STB0899_OFFST_TXIDLE 5
1794#define STB0899_WIDTH_TXIDLE 1
1795#define STB0899_GAPBURST (0x01 << 4)
1796#define STB0899_OFFST_GAPBURST 4
1797#define STB0899_WIDTH_GAPBURST 1
1798#define STB0899_TXFIFOBYTES (0x0f << 0)
1799#define STB0899_OFFST_TXFIFOBYTES 0
1800#define STB0899_WIDTH_TXFIFOBYTES 4
1801#define STB0899_DISF22 0xf0a9
1802
1803#define STB0899_DISF22RX 0xf0aa
1804
1805/* General Purpose */
1806#define STB0899_SYSREG 0xf101
1807#define STB0899_ACRPRESC 0xf110
1808#define STB0899_OFFST_RSVD2 7
1809#define STB0899_WIDTH_RSVD2 1
1810#define STB0899_OFFST_ACRPRESC 4
1811#define STB0899_WIDTH_ACRPRESC 3
1812#define STB0899_OFFST_RSVD1 3
1813#define STB0899_WIDTH_RSVD1 1
1814#define STB0899_OFFST_ACRPRESC2 0
1815#define STB0899_WIDTH_ACRPRESC2 3
1816
1817#define STB0899_ACRDIV1 0xf111
1818#define STB0899_ACRDIV2 0xf112
1819#define STB0899_DACR1 0xf113
1820#define STB0899_DACR2 0xf114
1821#define STB0899_OUTCFG 0xf11c
1822#define STB0899_MODECFG 0xf11d
1823#define STB0899_NCOARSE 0xf1b3
1824
1825#define STB0899_SYNTCTRL 0xf1b6
1826#define STB0899_STANDBY (0x01 << 7)
1827#define STB0899_OFFST_STANDBY 7
1828#define STB0899_WIDTH_STANDBY 1
1829#define STB0899_BYPASSPLL (0x01 << 6)
1830#define STB0899_OFFST_BYPASSPLL 6
1831#define STB0899_WIDTH_BYPASSPLL 1
1832#define STB0899_SEL1XRATIO (0x01 << 5)
1833#define STB0899_OFFST_SEL1XRATIO 5
1834#define STB0899_WIDTH_SEL1XRATIO 1
1835#define STB0899_SELOSCI (0x01 << 1)
1836#define STB0899_OFFST_SELOSCI 1
1837#define STB0899_WIDTH_SELOSCI 1
1838
1839#define STB0899_FILTCTRL 0xf1b7
1840#define STB0899_SYSCTRL 0xf1b8
1841
1842#define STB0899_STOPCLK1 0xf1c2
1843#define STB0899_STOP_CKINTBUF108 (0x01 << 7)
1844#define STB0899_OFFST_STOP_CKINTBUF108 7
1845#define STB0899_WIDTH_STOP_CKINTBUF108 1
1846#define STB0899_STOP_CKINTBUF216 (0x01 << 6)
1847#define STB0899_OFFST_STOP_CKINTBUF216 6
1848#define STB0899_WIDTH_STOP_CKINTBUF216 1
1849#define STB0899_STOP_CHK8PSK (0x01 << 5)
1850#define STB0899_OFFST_STOP_CHK8PSK 5
1851#define STB0899_WIDTH_STOP_CHK8PSK 1
1852#define STB0899_STOP_CKFEC108 (0x01 << 4)
1853#define STB0899_OFFST_STOP_CKFEC108 4
1854#define STB0899_WIDTH_STOP_CKFEC108 1
1855#define STB0899_STOP_CKFEC216 (0x01 << 3)
1856#define STB0899_OFFST_STOP_CKFEC216 3
1857#define STB0899_WIDTH_STOP_CKFEC216 1
1858#define STB0899_STOP_CKCORE216 (0x01 << 2)
1859#define STB0899_OFFST_STOP_CKCORE216 2
1860#define STB0899_WIDTH_STOP_CKCORE216 1
1861#define STB0899_STOP_CKADCI108 (0x01 << 1)
1862#define STB0899_OFFST_STOP_CKADCI108 1
1863#define STB0899_WIDTH_STOP_CKADCI108 1
1864#define STB0899_STOP_INVCKADCI108 (0x01 << 0)
1865#define STB0899_OFFST_STOP_INVCKADCI108 0
1866#define STB0899_WIDTH_STOP_INVCKADCI108 1
1867
1868#define STB0899_STOPCLK2 0xf1c3
1869#define STB0899_STOP_CKS2DMD108 (0x01 << 2)
1870#define STB0899_OFFST_STOP_CKS2DMD108 2
1871#define STB0899_WIDTH_STOP_CKS2DMD108 1
1872#define STB0899_STOP_CKPKDLIN108 (0x01 << 1)
1873#define STB0899_OFFST_STOP_CKPKDLIN108 1
1874#define STB0899_WIDTH_STOP_CKPKDLIN108 1
1875#define STB0899_STOP_CKPKDLIN216 (0x01 << 0)
1876#define STB0899_OFFST_STOP_CKPKDLIN216 0
1877#define STB0899_WIDTH_STOP_CKPKDLIN216 1
1878
1879#define STB0899_TSTTNR1 0xf1e0
1880#define STB0899_BYPASS_ADC (0x01 << 7)
1881#define STB0899_OFFST_BYPASS_ADC 7
1882#define STB0899_WIDTH_BYPASS_ADC 1
1883#define STB0899_INVADCICKOUT (0x01 << 6)
1884#define STB0899_OFFST_INVADCICKOUT 6
1885#define STB0899_WIDTH_INVADCICKOUT 1
1886#define STB0899_ADCTEST_VOLTAGE (0x03 << 4)
1887#define STB0899_OFFST_ADCTEST_VOLTAGE 4
1888#define STB0899_WIDTH_ADCTEST_VOLTAGE 1
1889#define STB0899_ADC_RESET (0x01 << 3)
1890#define STB0899_OFFST_ADC_RESET 3
1891#define STB0899_WIDTH_ADC_RESET 1
1892#define STB0899_TSTTNR1_2 (0x01 << 2)
1893#define STB0899_OFFST_TSTTNR1_2 2
1894#define STB0899_WIDTH_TSTTNR1_2 1
1895#define STB0899_ADCPON (0x01 << 1)
1896#define STB0899_OFFST_ADCPON 1
1897#define STB0899_WIDTH_ADCPON 1
1898#define STB0899_ADCIN_MODE (0x01 << 0)
1899#define STB0899_OFFST_ADCIN_MODE 0
1900#define STB0899_WIDTH_ADCIN_MODE 1
1901
1902#define STB0899_TSTTNR2 0xf1e1
1903#define STB0899_TSTTNR2_7 (0x01 << 7)
1904#define STB0899_OFFST_TSTTNR2_7 7
1905#define STB0899_WIDTH_TSTTNR2_7 1
1906#define STB0899_NOT_DISRX_WIRED (0x01 << 6)
1907#define STB0899_OFFST_NOT_DISRX_WIRED 6
1908#define STB0899_WIDTH_NOT_DISRX_WIRED 1
1909#define STB0899_DISEQC_DCURRENT (0x01 << 5)
1910#define STB0899_OFFST_DISEQC_DCURRENT 5
1911#define STB0899_WIDTH_DISEQC_DCURRENT 1
1912#define STB0899_DISEQC_ZCURRENT (0x01 << 4)
1913#define STB0899_OFFST_DISEQC_ZCURRENT 4
1914#define STB0899_WIDTH_DISEQC_ZCURRENT 1
1915#define STB0899_DISEQC_SINC_SOURCE (0x03 << 2)
1916#define STB0899_OFFST_DISEQC_SINC_SOURCE 2
1917#define STB0899_WIDTH_DISEQC_SINC_SOURCE 2
1918#define STB0899_SELIQSRC (0x03 << 0)
1919#define STB0899_OFFST_SELIQSRC 0
1920#define STB0899_WIDTH_SELIQSRC 2
1921
1922#define STB0899_TSTTNR3 0xf1e2
1923
1924#define STB0899_I2CCFG 0xf129
1925#define STB0899_I2CCFGRSVD (0x0f << 4)
1926#define STB0899_OFFST_I2CCFGRSVD 4
1927#define STB0899_WIDTH_I2CCFGRSVD 4
1928#define STB0899_I2CFASTMODE (0x01 << 3)
1929#define STB0899_OFFST_I2CFASTMODE 3
1930#define STB0899_WIDTH_I2CFASTMODE 1
1931#define STB0899_STATUSWR (0x01 << 2)
1932#define STB0899_OFFST_STATUSWR 2
1933#define STB0899_WIDTH_STATUSWR 1
1934#define STB0899_I2CADDRINC (0x03 << 0)
1935#define STB0899_OFFST_I2CADDRINC 0
1936#define STB0899_WIDTH_I2CADDRINC 2
1937
1938#define STB0899_I2CRPT 0xf12a
1939#define STB0899_I2CTON (0x01 << 7)
1940#define STB0899_OFFST_I2CTON 7
1941#define STB0899_WIDTH_I2CTON 1
1942#define STB0899_ENARPTLEVEL (0x01 << 6)
1943#define STB0899_OFFST_ENARPTLEVEL 6
1944#define STB0899_WIDTH_ENARPTLEVEL 2
1945#define STB0899_SCLTDELAY (0x01 << 3)
1946#define STB0899_OFFST_SCLTDELAY 3
1947#define STB0899_WIDTH_SCLTDELAY 1
1948#define STB0899_STOPENA (0x01 << 2)
1949#define STB0899_OFFST_STOPENA 2
1950#define STB0899_WIDTH_STOPENA 1
1951#define STB0899_STOPSDAT2SDA (0x01 << 1)
1952#define STB0899_OFFST_STOPSDAT2SDA 1
1953#define STB0899_WIDTH_STOPSDAT2SDA 1
1954
1955#define STB0899_IOPVALUE8 0xf136
1956#define STB0899_IOPVALUE7 0xf137
1957#define STB0899_IOPVALUE6 0xf138
1958#define STB0899_IOPVALUE5 0xf139
1959#define STB0899_IOPVALUE4 0xf13a
1960#define STB0899_IOPVALUE3 0xf13b
1961#define STB0899_IOPVALUE2 0xf13c
1962#define STB0899_IOPVALUE1 0xf13d
1963#define STB0899_IOPVALUE0 0xf13e
1964
1965#define STB0899_GPIO00CFG 0xf140
1966
1967#define STB0899_GPIO01CFG 0xf141
1968#define STB0899_GPIO02CFG 0xf142
1969#define STB0899_GPIO03CFG 0xf143
1970#define STB0899_GPIO04CFG 0xf144
1971#define STB0899_GPIO05CFG 0xf145
1972#define STB0899_GPIO06CFG 0xf146
1973#define STB0899_GPIO07CFG 0xf147
1974#define STB0899_GPIO08CFG 0xf148
1975#define STB0899_GPIO09CFG 0xf149
1976#define STB0899_GPIO10CFG 0xf14a
1977#define STB0899_GPIO11CFG 0xf14b
1978#define STB0899_GPIO12CFG 0xf14c
1979#define STB0899_GPIO13CFG 0xf14d
1980#define STB0899_GPIO14CFG 0xf14e
1981#define STB0899_GPIO15CFG 0xf14f
1982#define STB0899_GPIO16CFG 0xf150
1983#define STB0899_GPIO17CFG 0xf151
1984#define STB0899_GPIO18CFG 0xf152
1985#define STB0899_GPIO19CFG 0xf153
1986#define STB0899_GPIO20CFG 0xf154
1987
1988#define STB0899_SDATCFG 0xf155
1989#define STB0899_SCLTCFG 0xf156
1990#define STB0899_AGCRFCFG 0xf157
1991#define STB0899_GPIO22 0xf158 /* AGCBB2CFG */
1992#define STB0899_GPIO21 0xf159 /* AGCBB1CFG */
1993#define STB0899_DIRCLKCFG 0xf15a
1994#define STB0899_CLKOUT27CFG 0xf15b
1995#define STB0899_STDBYCFG 0xf15c
1996#define STB0899_CS0CFG 0xf15d
1997#define STB0899_CS1CFG 0xf15e
1998#define STB0899_DISEQCOCFG 0xf15f
1999
2000#define STB0899_GPIO32CFG 0xf160
2001#define STB0899_GPIO33CFG 0xf161
2002#define STB0899_GPIO34CFG 0xf162
2003#define STB0899_GPIO35CFG 0xf163
2004#define STB0899_GPIO36CFG 0xf164
2005#define STB0899_GPIO37CFG 0xf165
2006#define STB0899_GPIO38CFG 0xf166
2007#define STB0899_GPIO39CFG 0xf167
2008
2009#define STB0899_IRQSTATUS_3 0xf120
2010#define STB0899_IRQSTATUS_2 0xf121
2011#define STB0899_IRQSTATUS_1 0xf122
2012#define STB0899_IRQSTATUS_0 0xf123
2013
2014#define STB0899_IRQMSK_3 0xf124
2015#define STB0899_IRQMSK_2 0xf125
2016#define STB0899_IRQMSK_1 0xf126
2017#define STB0899_IRQMSK_0 0xf127
2018
2019#define STB0899_IRQCFG 0xf128
2020
2021#define STB0899_GHOSTREG 0xf000
2022
2023#define STB0899_S2DEMOD 0xf3fc
2024#define STB0899_S2FEC 0xfafc
2025
2026
2027#endif
diff --git a/drivers/media/dvb/frontends/stb6100.c b/drivers/media/dvb/frontends/stb6100.c
new file mode 100644
index 000000000000..ff39275ab49c
--- /dev/null
+++ b/drivers/media/dvb/frontends/stb6100.c
@@ -0,0 +1,545 @@
1/*
2 STB6100 Silicon Tuner
3 Copyright (C) Manu Abraham (abraham.manu@gmail.com)
4
5 Copyright (C) ST Microelectronics
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/init.h>
23#include <linux/kernel.h>
24#include <linux/module.h>
25#include <linux/string.h>
26
27#include "dvb_frontend.h"
28#include "stb6100.h"
29
30static unsigned int verbose;
31module_param(verbose, int, 0644);
32
33
34#define FE_ERROR 0
35#define FE_NOTICE 1
36#define FE_INFO 2
37#define FE_DEBUG 3
38
39#define dprintk(x, y, z, format, arg...) do { \
40 if (z) { \
41 if ((x > FE_ERROR) && (x > y)) \
42 printk(KERN_ERR "%s: " format "\n", __func__ , ##arg); \
43 else if ((x > FE_NOTICE) && (x > y)) \
44 printk(KERN_NOTICE "%s: " format "\n", __func__ , ##arg); \
45 else if ((x > FE_INFO) && (x > y)) \
46 printk(KERN_INFO "%s: " format "\n", __func__ , ##arg); \
47 else if ((x > FE_DEBUG) && (x > y)) \
48 printk(KERN_DEBUG "%s: " format "\n", __func__ , ##arg); \
49 } else { \
50 if (x > y) \
51 printk(format, ##arg); \
52 } \
53} while(0)
54
55struct stb6100_lkup {
56 u32 val_low;
57 u32 val_high;
58 u8 reg;
59};
60
61static int stb6100_release(struct dvb_frontend *fe);
62
63static const struct stb6100_lkup lkup[] = {
64 { 0, 950000, 0x0a },
65 { 950000, 1000000, 0x0a },
66 { 1000000, 1075000, 0x0c },
67 { 1075000, 1200000, 0x00 },
68 { 1200000, 1300000, 0x01 },
69 { 1300000, 1370000, 0x02 },
70 { 1370000, 1470000, 0x04 },
71 { 1470000, 1530000, 0x05 },
72 { 1530000, 1650000, 0x06 },
73 { 1650000, 1800000, 0x08 },
74 { 1800000, 1950000, 0x0a },
75 { 1950000, 2150000, 0x0c },
76 { 2150000, 9999999, 0x0c },
77 { 0, 0, 0x00 }
78};
79
80/* Register names for easy debugging. */
81static const char *stb6100_regnames[] = {
82 [STB6100_LD] = "LD",
83 [STB6100_VCO] = "VCO",
84 [STB6100_NI] = "NI",
85 [STB6100_NF_LSB] = "NF",
86 [STB6100_K] = "K",
87 [STB6100_G] = "G",
88 [STB6100_F] = "F",
89 [STB6100_DLB] = "DLB",
90 [STB6100_TEST1] = "TEST1",
91 [STB6100_FCCK] = "FCCK",
92 [STB6100_LPEN] = "LPEN",
93 [STB6100_TEST3] = "TEST3",
94};
95
96/* Template for normalisation, i.e. setting unused or undocumented
97 * bits as required according to the documentation.
98 */
99struct stb6100_regmask {
100 u8 mask;
101 u8 set;
102};
103
104static const struct stb6100_regmask stb6100_template[] = {
105 [STB6100_LD] = { 0xff, 0x00 },
106 [STB6100_VCO] = { 0xff, 0x00 },
107 [STB6100_NI] = { 0xff, 0x00 },
108 [STB6100_NF_LSB] = { 0xff, 0x00 },
109 [STB6100_K] = { 0xc7, 0x38 },
110 [STB6100_G] = { 0xef, 0x10 },
111 [STB6100_F] = { 0x1f, 0xc0 },
112 [STB6100_DLB] = { 0x38, 0xc4 },
113 [STB6100_TEST1] = { 0x00, 0x8f },
114 [STB6100_FCCK] = { 0x40, 0x0d },
115 [STB6100_LPEN] = { 0xf0, 0x0b },
116 [STB6100_TEST3] = { 0x00, 0xde },
117};
118
119static void stb6100_normalise_regs(u8 regs[])
120{
121 int i;
122
123 for (i = 0; i < STB6100_NUMREGS; i++)
124 regs[i] = (regs[i] & stb6100_template[i].mask) | stb6100_template[i].set;
125}
126
127static int stb6100_read_regs(struct stb6100_state *state, u8 regs[])
128{
129 int rc;
130 struct i2c_msg msg = {
131 .addr = state->config->tuner_address,
132 .flags = I2C_M_RD,
133 .buf = regs,
134 .len = STB6100_NUMREGS
135 };
136
137 rc = i2c_transfer(state->i2c, &msg, 1);
138 if (unlikely(rc != 1)) {
139 dprintk(verbose, FE_ERROR, 1, "Read (0x%x) err, rc=[%d]",
140 state->config->tuner_address, rc);
141
142 return -EREMOTEIO;
143 }
144 if (unlikely(verbose > FE_DEBUG)) {
145 int i;
146
147 dprintk(verbose, FE_DEBUG, 1, " Read from 0x%02x", state->config->tuner_address);
148 for (i = 0; i < STB6100_NUMREGS; i++)
149 dprintk(verbose, FE_DEBUG, 1, " %s: 0x%02x", stb6100_regnames[i], regs[i]);
150 }
151 return 0;
152}
153
154static int stb6100_read_reg(struct stb6100_state *state, u8 reg)
155{
156 u8 regs[STB6100_NUMREGS];
157 int rc;
158
159 if (unlikely(reg >= STB6100_NUMREGS)) {
160 dprintk(verbose, FE_ERROR, 1, "Invalid register offset 0x%x", reg);
161 return -EINVAL;
162 }
163 if ((rc = stb6100_read_regs(state, regs)) < 0)
164 return rc;
165 return (unsigned int)regs[reg];
166}
167
168static int stb6100_write_reg_range(struct stb6100_state *state, u8 buf[], int start, int len)
169{
170 int rc;
171 u8 cmdbuf[len + 1];
172 struct i2c_msg msg = {
173 .addr = state->config->tuner_address,
174 .flags = 0,
175 .buf = cmdbuf,
176 .len = len + 1
177 };
178
179 if (unlikely(start < 1 || start + len > STB6100_NUMREGS)) {
180 dprintk(verbose, FE_ERROR, 1, "Invalid register range %d:%d",
181 start, len);
182 return -EINVAL;
183 }
184 memcpy(&cmdbuf[1], buf, len);
185 cmdbuf[0] = start;
186
187 if (unlikely(verbose > FE_DEBUG)) {
188 int i;
189
190 dprintk(verbose, FE_DEBUG, 1, " Write @ 0x%02x: [%d:%d]", state->config->tuner_address, start, len);
191 for (i = 0; i < len; i++)
192 dprintk(verbose, FE_DEBUG, 1, " %s: 0x%02x", stb6100_regnames[start + i], buf[i]);
193 }
194 rc = i2c_transfer(state->i2c, &msg, 1);
195 if (unlikely(rc != 1)) {
196 dprintk(verbose, FE_ERROR, 1, "(0x%x) write err [%d:%d], rc=[%d]",
197 (unsigned int)state->config->tuner_address, start, len, rc);
198 return -EREMOTEIO;
199 }
200 return 0;
201}
202
203static int stb6100_write_reg(struct stb6100_state *state, u8 reg, u8 data)
204{
205 if (unlikely(reg >= STB6100_NUMREGS)) {
206 dprintk(verbose, FE_ERROR, 1, "Invalid register offset 0x%x", reg);
207 return -EREMOTEIO;
208 }
209 data = (data & stb6100_template[reg].mask) | stb6100_template[reg].set;
210 return stb6100_write_reg_range(state, &data, reg, 1);
211}
212
213static int stb6100_write_regs(struct stb6100_state *state, u8 regs[])
214{
215 stb6100_normalise_regs(regs);
216 return stb6100_write_reg_range(state, &regs[1], 1, STB6100_NUMREGS - 1);
217}
218
219static int stb6100_get_status(struct dvb_frontend *fe, u32 *status)
220{
221 int rc;
222 struct stb6100_state *state = fe->tuner_priv;
223
224 if ((rc = stb6100_read_reg(state, STB6100_LD)) < 0)
225 return rc;
226
227 return (rc & STB6100_LD_LOCK) ? TUNER_STATUS_LOCKED : 0;
228}
229
230static int stb6100_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
231{
232 int rc;
233 u8 f;
234 struct stb6100_state *state = fe->tuner_priv;
235
236 if ((rc = stb6100_read_reg(state, STB6100_F)) < 0)
237 return rc;
238 f = rc & STB6100_F_F;
239
240 state->status.bandwidth = (f + 5) * 2000; /* x2 for ZIF */
241
242 *bandwidth = state->bandwidth = state->status.bandwidth * 1000;
243 dprintk(verbose, FE_DEBUG, 1, "bandwidth = %u Hz", state->bandwidth);
244 return 0;
245}
246
247static int stb6100_set_bandwidth(struct dvb_frontend *fe, u32 bandwidth)
248{
249 u32 tmp;
250 int rc;
251 struct stb6100_state *state = fe->tuner_priv;
252
253 dprintk(verbose, FE_DEBUG, 1, "set bandwidth to %u Hz", bandwidth);
254
255 bandwidth /= 2; /* ZIF */
256
257 if (bandwidth >= 36000000) /* F[4:0] BW/2 max =31+5=36 mhz for F=31 */
258 tmp = 31;
259 else if (bandwidth <= 5000000) /* bw/2 min = 5Mhz for F=0 */
260 tmp = 0;
261 else /* if 5 < bw/2 < 36 */
262 tmp = (bandwidth + 500000) / 1000000 - 5;
263
264 /* Turn on LPF bandwidth setting clock control,
265 * set bandwidth, wait 10ms, turn off.
266 */
267 if ((rc = stb6100_write_reg(state, STB6100_FCCK, 0x0d | STB6100_FCCK_FCCK)) < 0)
268 return rc;
269 if ((rc = stb6100_write_reg(state, STB6100_F, 0xc0 | tmp)) < 0)
270 return rc;
271 msleep(1);
272 if ((rc = stb6100_write_reg(state, STB6100_FCCK, 0x0d)) < 0)
273 return rc;
274
275 return 0;
276}
277
278static int stb6100_get_frequency(struct dvb_frontend *fe, u32 *frequency)
279{
280 int rc;
281 u32 nint, nfrac, fvco;
282 int psd2, odiv;
283 struct stb6100_state *state = fe->tuner_priv;
284 u8 regs[STB6100_NUMREGS];
285
286 if ((rc = stb6100_read_regs(state, regs)) < 0)
287 return rc;
288
289 odiv = (regs[STB6100_VCO] & STB6100_VCO_ODIV) >> STB6100_VCO_ODIV_SHIFT;
290 psd2 = (regs[STB6100_K] & STB6100_K_PSD2) >> STB6100_K_PSD2_SHIFT;
291 nint = regs[STB6100_NI];
292 nfrac = ((regs[STB6100_K] & STB6100_K_NF_MSB) << 8) | regs[STB6100_NF_LSB];
293 fvco = (nfrac * state->reference >> (9 - psd2)) + (nint * state->reference << psd2);
294 *frequency = state->frequency = fvco >> (odiv + 1);
295
296 dprintk(verbose, FE_DEBUG, 1,
297 "frequency = %u kHz, odiv = %u, psd2 = %u, fxtal = %u kHz, fvco = %u kHz, N(I) = %u, N(F) = %u",
298 state->frequency, odiv, psd2, state->reference, fvco, nint, nfrac);
299 return 0;
300}
301
302
303static int stb6100_set_frequency(struct dvb_frontend *fe, u32 frequency)
304{
305 int rc;
306 const struct stb6100_lkup *ptr;
307 struct stb6100_state *state = fe->tuner_priv;
308 struct dvb_frontend_parameters p;
309
310 u32 srate = 0, fvco, nint, nfrac;
311 u8 regs[STB6100_NUMREGS];
312 u8 g, psd2, odiv;
313
314 if ((rc = stb6100_read_regs(state, regs)) < 0)
315 return rc;
316
317 if (fe->ops.get_frontend) {
318 dprintk(verbose, FE_DEBUG, 1, "Get frontend parameters");
319 fe->ops.get_frontend(fe, &p);
320 }
321 srate = p.u.qpsk.symbol_rate;
322
323 regs[STB6100_DLB] = 0xdc;
324 /* Disable LPEN */
325 regs[STB6100_LPEN] &= ~STB6100_LPEN_LPEN; /* PLL Loop disabled */
326
327 if ((rc = stb6100_write_regs(state, regs)) < 0)
328 return rc;
329
330 /* Baseband gain. */
331 if (srate >= 15000000)
332 g = 9; // +4 dB
333 else if (srate >= 5000000)
334 g = 11; // +8 dB
335 else
336 g = 14; // +14 dB
337
338 regs[STB6100_G] = (regs[STB6100_G] & ~STB6100_G_G) | g;
339 regs[STB6100_G] &= ~STB6100_G_GCT; /* mask GCT */
340 regs[STB6100_G] |= (1 << 5); /* 2Vp-p Mode */
341
342 /* VCO divide ratio (LO divide ratio, VCO prescaler enable). */
343 if (frequency <= 1075000)
344 odiv = 1;
345 else
346 odiv = 0;
347 regs[STB6100_VCO] = (regs[STB6100_VCO] & ~STB6100_VCO_ODIV) | (odiv << STB6100_VCO_ODIV_SHIFT);
348
349 if ((frequency > 1075000) && (frequency <= 1325000))
350 psd2 = 0;
351 else
352 psd2 = 1;
353 regs[STB6100_K] = (regs[STB6100_K] & ~STB6100_K_PSD2) | (psd2 << STB6100_K_PSD2_SHIFT);
354
355 /* OSM */
356 for (ptr = lkup;
357 (ptr->val_high != 0) && !CHKRANGE(frequency, ptr->val_low, ptr->val_high);
358 ptr++);
359 if (ptr->val_high == 0) {
360 printk(KERN_ERR "%s: frequency out of range: %u kHz\n", __func__, frequency);
361 return -EINVAL;
362 }
363 regs[STB6100_VCO] = (regs[STB6100_VCO] & ~STB6100_VCO_OSM) | ptr->reg;
364
365 /* F(VCO) = F(LO) * (ODIV == 0 ? 2 : 4) */
366 fvco = frequency << (1 + odiv);
367 /* N(I) = floor(f(VCO) / (f(XTAL) * (PSD2 ? 2 : 1))) */
368 nint = fvco / (state->reference << psd2);
369 /* N(F) = round(f(VCO) / f(XTAL) * (PSD2 ? 2 : 1) - N(I)) * 2 ^ 9 */
370 nfrac = (((fvco - (nint * state->reference << psd2)) << (9 - psd2)) + state->reference / 2) / state->reference;
371 dprintk(verbose, FE_DEBUG, 1,
372 "frequency = %u, srate = %u, g = %u, odiv = %u, psd2 = %u, fxtal = %u, osm = %u, fvco = %u, N(I) = %u, N(F) = %u",
373 frequency, srate, (unsigned int)g, (unsigned int)odiv,
374 (unsigned int)psd2, state->reference,
375 ptr->reg, fvco, nint, nfrac);
376 regs[STB6100_NI] = nint;
377 regs[STB6100_NF_LSB] = nfrac;
378 regs[STB6100_K] = (regs[STB6100_K] & ~STB6100_K_NF_MSB) | ((nfrac >> 8) & STB6100_K_NF_MSB);
379 regs[STB6100_VCO] |= STB6100_VCO_OSCH; /* VCO search enabled */
380 regs[STB6100_VCO] |= STB6100_VCO_OCK; /* VCO search clock off */
381 regs[STB6100_FCCK] |= STB6100_FCCK_FCCK; /* LPF BW setting clock enabled */
382 regs[STB6100_LPEN] &= ~STB6100_LPEN_LPEN; /* PLL loop disabled */
383 /* Power up. */
384 regs[STB6100_LPEN] |= STB6100_LPEN_SYNP | STB6100_LPEN_OSCP | STB6100_LPEN_BEN;
385
386 msleep(2);
387 if ((rc = stb6100_write_regs(state, regs)) < 0)
388 return rc;
389
390 msleep(2);
391 regs[STB6100_LPEN] |= STB6100_LPEN_LPEN; /* PLL loop enabled */
392 if ((rc = stb6100_write_reg(state, STB6100_LPEN, regs[STB6100_LPEN])) < 0)
393 return rc;
394
395 regs[STB6100_VCO] &= ~STB6100_VCO_OCK; /* VCO fast search */
396 if ((rc = stb6100_write_reg(state, STB6100_VCO, regs[STB6100_VCO])) < 0)
397 return rc;
398
399 msleep(10); /* wait for LO to lock */
400 regs[STB6100_VCO] &= ~STB6100_VCO_OSCH; /* vco search disabled */
401 regs[STB6100_VCO] |= STB6100_VCO_OCK; /* search clock off */
402 if ((rc = stb6100_write_reg(state, STB6100_VCO, regs[STB6100_VCO])) < 0)
403 return rc;
404 regs[STB6100_FCCK] &= ~STB6100_FCCK_FCCK; /* LPF BW clock disabled */
405 stb6100_normalise_regs(regs);
406 if ((rc = stb6100_write_reg_range(state, &regs[1], 1, STB6100_NUMREGS - 3)) < 0)
407 return rc;
408
409 msleep(100);
410
411 return 0;
412}
413
414static int stb6100_sleep(struct dvb_frontend *fe)
415{
416 /* TODO: power down */
417 return 0;
418}
419
420static int stb6100_init(struct dvb_frontend *fe)
421{
422 struct stb6100_state *state = fe->tuner_priv;
423 struct tuner_state *status = &state->status;
424
425 status->tunerstep = 125000;
426 status->ifreq = 0;
427 status->refclock = 27000000; /* Hz */
428 status->iqsense = 1;
429 status->bandwidth = 36000; /* kHz */
430 state->bandwidth = status->bandwidth * 1000; /* MHz */
431 state->reference = status->refclock / 1000; /* kHz */
432
433 /* Set default bandwidth. */
434 return stb6100_set_bandwidth(fe, status->bandwidth);
435}
436
437static int stb6100_get_state(struct dvb_frontend *fe,
438 enum tuner_param param,
439 struct tuner_state *state)
440{
441 switch (param) {
442 case DVBFE_TUNER_FREQUENCY:
443 stb6100_get_frequency(fe, &state->frequency);
444 break;
445 case DVBFE_TUNER_TUNERSTEP:
446 break;
447 case DVBFE_TUNER_IFFREQ:
448 break;
449 case DVBFE_TUNER_BANDWIDTH:
450 stb6100_get_bandwidth(fe, &state->bandwidth);
451 break;
452 case DVBFE_TUNER_REFCLOCK:
453 break;
454 default:
455 break;
456 }
457
458 return 0;
459}
460
461static int stb6100_set_state(struct dvb_frontend *fe,
462 enum tuner_param param,
463 struct tuner_state *state)
464{
465 struct stb6100_state *tstate = fe->tuner_priv;
466
467 switch (param) {
468 case DVBFE_TUNER_FREQUENCY:
469 stb6100_set_frequency(fe, state->frequency);
470 tstate->frequency = state->frequency;
471 break;
472 case DVBFE_TUNER_TUNERSTEP:
473 break;
474 case DVBFE_TUNER_IFFREQ:
475 break;
476 case DVBFE_TUNER_BANDWIDTH:
477 stb6100_set_bandwidth(fe, state->bandwidth);
478 tstate->bandwidth = state->bandwidth;
479 break;
480 case DVBFE_TUNER_REFCLOCK:
481 break;
482 default:
483 break;
484 }
485
486 return 0;
487}
488
489static struct dvb_tuner_ops stb6100_ops = {
490 .info = {
491 .name = "STB6100 Silicon Tuner",
492 .frequency_min = 950000,
493 .frequency_max = 2150000,
494 .frequency_step = 0,
495 },
496
497 .init = stb6100_init,
498 .sleep = stb6100_sleep,
499 .get_status = stb6100_get_status,
500 .get_state = stb6100_get_state,
501 .set_state = stb6100_set_state,
502 .release = stb6100_release
503};
504
505struct dvb_frontend *stb6100_attach(struct dvb_frontend *fe,
506 struct stb6100_config *config,
507 struct i2c_adapter *i2c)
508{
509 struct stb6100_state *state = NULL;
510
511 state = kzalloc(sizeof (struct stb6100_state), GFP_KERNEL);
512 if (state == NULL)
513 goto error;
514
515 state->config = config;
516 state->i2c = i2c;
517 state->frontend = fe;
518 state->reference = config->refclock / 1000; /* kHz */
519 fe->tuner_priv = state;
520 fe->ops.tuner_ops = stb6100_ops;
521
522 printk("%s: Attaching STB6100 \n", __func__);
523 return fe;
524
525error:
526 kfree(state);
527 return NULL;
528}
529
530static int stb6100_release(struct dvb_frontend *fe)
531{
532 struct stb6100_state *state = fe->tuner_priv;
533
534 fe->tuner_priv = NULL;
535 kfree(state);
536
537 return 0;
538}
539
540EXPORT_SYMBOL(stb6100_attach);
541MODULE_PARM_DESC(verbose, "Set Verbosity level");
542
543MODULE_AUTHOR("Manu Abraham");
544MODULE_DESCRIPTION("STB6100 Silicon tuner");
545MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/stb6100.h b/drivers/media/dvb/frontends/stb6100.h
new file mode 100644
index 000000000000..395d056599a6
--- /dev/null
+++ b/drivers/media/dvb/frontends/stb6100.h
@@ -0,0 +1,115 @@
1/*
2 STB6100 Silicon Tuner
3 Copyright (C) Manu Abraham (abraham.manu@gmail.com)
4
5 Copyright (C) ST Microelectronics
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 __STB_6100_REG_H
23#define __STB_6100_REG_H
24
25#include <linux/dvb/frontend.h>
26#include "dvb_frontend.h"
27
28#define STB6100_LD 0x00
29#define STB6100_LD_LOCK (1 << 0)
30
31#define STB6100_VCO 0x01
32#define STB6100_VCO_OSCH (0x01 << 7)
33#define STB6100_VCO_OSCH_SHIFT 7
34#define STB6100_VCO_OCK (0x03 << 5)
35#define STB6100_VCO_OCK_SHIFT 5
36#define STB6100_VCO_ODIV (0x01 << 4)
37#define STB6100_VCO_ODIV_SHIFT 4
38#define STB6100_VCO_OSM (0x0f << 0)
39
40#define STB6100_NI 0x02
41#define STB6100_NF_LSB 0x03
42
43#define STB6100_K 0x04
44#define STB6100_K_PSD2 (0x01 << 2)
45#define STB6100_K_PSD2_SHIFT 2
46#define STB6100_K_NF_MSB (0x03 << 0)
47
48#define STB6100_G 0x05
49#define STB6100_G_G (0x0f << 0)
50#define STB6100_G_GCT (0x07 << 5)
51
52#define STB6100_F 0x06
53#define STB6100_F_F (0x1f << 0)
54
55#define STB6100_DLB 0x07
56
57#define STB6100_TEST1 0x08
58
59#define STB6100_FCCK 0x09
60#define STB6100_FCCK_FCCK (0x01 << 6)
61
62#define STB6100_LPEN 0x0a
63#define STB6100_LPEN_LPEN (0x01 << 4)
64#define STB6100_LPEN_SYNP (0x01 << 5)
65#define STB6100_LPEN_OSCP (0x01 << 6)
66#define STB6100_LPEN_BEN (0x01 << 7)
67
68#define STB6100_TEST3 0x0b
69
70#define STB6100_NUMREGS 0x0c
71
72
73#define INRANGE(val, x, y) (((x <= val) && (val <= y)) || \
74 ((y <= val) && (val <= x)) ? 1 : 0)
75
76#define CHKRANGE(val, x, y) (((val >= x) && (val < y)) ? 1 : 0)
77
78struct stb6100_config {
79 u8 tuner_address;
80 u32 refclock;
81};
82
83struct stb6100_state {
84 struct i2c_adapter *i2c;
85
86 const struct stb6100_config *config;
87 struct dvb_tuner_ops ops;
88 struct dvb_frontend *frontend;
89 struct tuner_state status;
90
91 u32 frequency;
92 u32 srate;
93 u32 bandwidth;
94 u32 reference;
95};
96
97#if defined(CONFIG_DVB_STB6100) || (defined(CONFIG_DVB_STB6100_MODULE) && defined(MODULE))
98
99extern struct dvb_frontend *stb6100_attach(struct dvb_frontend *fe,
100 struct stb6100_config *config,
101 struct i2c_adapter *i2c);
102
103#else
104
105static inline struct dvb_frontend *stb6100_attach(struct dvb_frontend *fe,
106 struct stb6100_config *config,
107 struct i2c_adapter *i2c)
108{
109 printk(KERN_WARNING "%s: Driver disabled by Kconfig\n", __func__);
110 return NULL;
111}
112
113#endif //CONFIG_DVB_STB6100
114
115#endif
diff --git a/drivers/media/dvb/frontends/stb6100_cfg.h b/drivers/media/dvb/frontends/stb6100_cfg.h
new file mode 100644
index 000000000000..d3133405dc03
--- /dev/null
+++ b/drivers/media/dvb/frontends/stb6100_cfg.h
@@ -0,0 +1,108 @@
1/*
2 STB6100 Silicon Tuner
3 Copyright (C) Manu Abraham (abraham.manu@gmail.com)
4
5 Copyright (C) ST Microelectronics
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
22static int stb6100_get_frequency(struct dvb_frontend *fe, u32 *frequency)
23{
24 struct dvb_frontend_ops *frontend_ops = NULL;
25 struct dvb_tuner_ops *tuner_ops = NULL;
26 struct tuner_state t_state;
27 int err = 0;
28
29 if (&fe->ops)
30 frontend_ops = &fe->ops;
31 if (&frontend_ops->tuner_ops)
32 tuner_ops = &frontend_ops->tuner_ops;
33 if (tuner_ops->get_state) {
34 if ((err = tuner_ops->get_state(fe, DVBFE_TUNER_FREQUENCY, &t_state)) < 0) {
35 printk("%s: Invalid parameter\n", __func__);
36 return err;
37 }
38 *frequency = t_state.frequency;
39 printk("%s: Frequency=%d\n", __func__, t_state.frequency);
40 }
41 return 0;
42}
43
44static int stb6100_set_frequency(struct dvb_frontend *fe, u32 frequency)
45{
46 struct dvb_frontend_ops *frontend_ops = NULL;
47 struct dvb_tuner_ops *tuner_ops = NULL;
48 struct tuner_state t_state;
49 int err = 0;
50
51 t_state.frequency = frequency;
52 if (&fe->ops)
53 frontend_ops = &fe->ops;
54 if (&frontend_ops->tuner_ops)
55 tuner_ops = &frontend_ops->tuner_ops;
56 if (tuner_ops->set_state) {
57 if ((err = tuner_ops->set_state(fe, DVBFE_TUNER_FREQUENCY, &t_state)) < 0) {
58 printk("%s: Invalid parameter\n", __func__);
59 return err;
60 }
61 }
62 printk("%s: Frequency=%d\n", __func__, t_state.frequency);
63 return 0;
64}
65
66static int stb6100_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
67{
68 struct dvb_frontend_ops *frontend_ops = &fe->ops;
69 struct dvb_tuner_ops *tuner_ops = &frontend_ops->tuner_ops;
70 struct tuner_state t_state;
71 int err = 0;
72
73 if (&fe->ops)
74 frontend_ops = &fe->ops;
75 if (&frontend_ops->tuner_ops)
76 tuner_ops = &frontend_ops->tuner_ops;
77 if (tuner_ops->get_state) {
78 if ((err = tuner_ops->get_state(fe, DVBFE_TUNER_BANDWIDTH, &t_state)) < 0) {
79 printk("%s: Invalid parameter\n", __func__);
80 return err;
81 }
82 *bandwidth = t_state.bandwidth;
83 }
84 printk("%s: Bandwidth=%d\n", __func__, t_state.bandwidth);
85 return 0;
86}
87
88static int stb6100_set_bandwidth(struct dvb_frontend *fe, u32 bandwidth)
89{
90 struct dvb_frontend_ops *frontend_ops = NULL;
91 struct dvb_tuner_ops *tuner_ops = NULL;
92 struct tuner_state t_state;
93 int err = 0;
94
95 t_state.bandwidth = bandwidth;
96 if (&fe->ops)
97 frontend_ops = &fe->ops;
98 if (&frontend_ops->tuner_ops)
99 tuner_ops = &frontend_ops->tuner_ops;
100 if (tuner_ops->set_state) {
101 if ((err = tuner_ops->set_state(fe, DVBFE_TUNER_BANDWIDTH, &t_state)) < 0) {
102 printk("%s: Invalid parameter\n", __func__);
103 return err;
104 }
105 }
106 printk("%s: Bandwidth=%d\n", __func__, t_state.bandwidth);
107 return 0;
108}
diff --git a/drivers/media/dvb/frontends/tda8261.c b/drivers/media/dvb/frontends/tda8261.c
new file mode 100644
index 000000000000..b6d177799104
--- /dev/null
+++ b/drivers/media/dvb/frontends/tda8261.c
@@ -0,0 +1,230 @@
1/*
2 TDA8261 8PSK/QPSK tuner driver
3 Copyright (C) Manu Abraham (abraham.manu@gmail.com)
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18*/
19
20
21#include <linux/init.h>
22#include <linux/kernel.h>
23#include <linux/module.h>
24
25#include "dvb_frontend.h"
26#include "tda8261.h"
27
28struct tda8261_state {
29 struct dvb_frontend *fe;
30 struct i2c_adapter *i2c;
31 const struct tda8261_config *config;
32
33 /* state cache */
34 u32 frequency;
35 u32 bandwidth;
36};
37
38static int tda8261_read(struct tda8261_state *state, u8 *buf)
39{
40 const struct tda8261_config *config = state->config;
41 int err = 0;
42 struct i2c_msg msg = { .addr = config->addr, .flags = I2C_M_RD,.buf = buf, .len = 2 };
43
44 if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1)
45 printk("%s: read error, err=%d\n", __func__, err);
46
47 return err;
48}
49
50static int tda8261_write(struct tda8261_state *state, u8 *buf)
51{
52 const struct tda8261_config *config = state->config;
53 int err = 0;
54 struct i2c_msg msg = { .addr = config->addr, .flags = 0, .buf = buf, .len = 4 };
55
56 if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1)
57 printk("%s: write error, err=%d\n", __func__, err);
58
59 return err;
60}
61
62static int tda8261_get_status(struct dvb_frontend *fe, u32 *status)
63{
64 struct tda8261_state *state = fe->tuner_priv;
65 u8 result = 0;
66 int err = 0;
67
68 *status = 0;
69
70 if ((err = tda8261_read(state, &result)) < 0) {
71 printk("%s: I/O Error\n", __func__);
72 return err;
73 }
74 if ((result >> 6) & 0x01) {
75 printk("%s: Tuner Phase Locked\n", __func__);
76 *status = 1;
77 }
78
79 return err;
80}
81
82static const u32 div_tab[] = { 2000, 1000, 500, 250, 125 }; /* kHz */
83static const u8 ref_div[] = { 0x00, 0x01, 0x02, 0x05, 0x07 };
84
85static int tda8261_get_state(struct dvb_frontend *fe,
86 enum tuner_param param,
87 struct tuner_state *tstate)
88{
89 struct tda8261_state *state = fe->tuner_priv;
90 int err = 0;
91
92 switch (param) {
93 case DVBFE_TUNER_FREQUENCY:
94 tstate->frequency = state->frequency;
95 break;
96 case DVBFE_TUNER_BANDWIDTH:
97 tstate->bandwidth = 40000000; /* FIXME! need to calculate Bandwidth */
98 break;
99 default:
100 printk("%s: Unknown parameter (param=%d)\n", __func__, param);
101 err = -EINVAL;
102 break;
103 }
104
105 return err;
106}
107
108static int tda8261_set_state(struct dvb_frontend *fe,
109 enum tuner_param param,
110 struct tuner_state *tstate)
111{
112 struct tda8261_state *state = fe->tuner_priv;
113 const struct tda8261_config *config = state->config;
114 u32 frequency, N, status = 0;
115 u8 buf[4];
116 int err = 0;
117
118 if (param & DVBFE_TUNER_FREQUENCY) {
119 /**
120 * N = Max VCO Frequency / Channel Spacing
121 * Max VCO Frequency = VCO frequency + (channel spacing - 1)
122 * (to account for half channel spacing on either side)
123 */
124 frequency = tstate->frequency;
125 if ((frequency < 950000) || (frequency > 2150000)) {
126 printk("%s: Frequency beyond limits, frequency=%d\n", __func__, frequency);
127 return -EINVAL;
128 }
129 N = (frequency + (div_tab[config->step_size] - 1)) / div_tab[config->step_size];
130 printk("%s: Step size=%d, Divider=%d, PG=0x%02x (%d)\n",
131 __func__, config->step_size, div_tab[config->step_size], N, N);
132
133 buf[0] = (N >> 8) & 0xff;
134 buf[1] = N & 0xff;
135 buf[2] = (0x01 << 7) | ((ref_div[config->step_size] & 0x07) << 1);
136
137 if (frequency < 1450000)
138 buf[3] = 0x00;
139 if (frequency < 2000000)
140 buf[3] = 0x40;
141 if (frequency < 2150000)
142 buf[3] = 0x80;
143
144 /* Set params */
145 if ((err = tda8261_write(state, buf)) < 0) {
146 printk("%s: I/O Error\n", __func__);
147 return err;
148 }
149 /* sleep for some time */
150 printk("%s: Waiting to Phase LOCK\n", __func__);
151 msleep(20);
152 /* check status */
153 if ((err = tda8261_get_status(fe, &status)) < 0) {
154 printk("%s: I/O Error\n", __func__);
155 return err;
156 }
157 if (status == 1) {
158 printk("%s: Tuner Phase locked: status=%d\n", __func__, status);
159 state->frequency = frequency; /* cache successful state */
160 } else {
161 printk("%s: No Phase lock: status=%d\n", __func__, status);
162 }
163 } else {
164 printk("%s: Unknown parameter (param=%d)\n", __func__, param);
165 return -EINVAL;
166 }
167
168 return 0;
169}
170
171static int tda8261_release(struct dvb_frontend *fe)
172{
173 struct tda8261_state *state = fe->tuner_priv;
174
175 fe->tuner_priv = NULL;
176 kfree(state);
177 return 0;
178}
179
180static struct dvb_tuner_ops tda8261_ops = {
181
182 .info = {
183 .name = "TDA8261",
184// .tuner_name = NULL,
185 .frequency_min = 950000,
186 .frequency_max = 2150000,
187 .frequency_step = 0
188 },
189
190 .set_state = tda8261_set_state,
191 .get_state = tda8261_get_state,
192 .get_status = tda8261_get_status,
193 .release = tda8261_release
194};
195
196struct dvb_frontend *tda8261_attach(struct dvb_frontend *fe,
197 const struct tda8261_config *config,
198 struct i2c_adapter *i2c)
199{
200 struct tda8261_state *state = NULL;
201
202 if ((state = kzalloc(sizeof (struct tda8261_state), GFP_KERNEL)) == NULL)
203 goto exit;
204
205 state->config = config;
206 state->i2c = i2c;
207 state->fe = fe;
208 fe->tuner_priv = state;
209 fe->ops.tuner_ops = tda8261_ops;
210
211 fe->ops.tuner_ops.info.frequency_step = div_tab[config->step_size];
212// fe->ops.tuner_ops.tuner_name = &config->buf;
213
214// printk("%s: Attaching %s TDA8261 8PSK/QPSK tuner\n",
215// __func__, fe->ops.tuner_ops.tuner_name);
216 printk("%s: Attaching TDA8261 8PSK/QPSK tuner\n", __func__);
217
218 return fe;
219
220exit:
221 kfree(state);
222 return NULL;
223}
224
225EXPORT_SYMBOL(tda8261_attach);
226MODULE_PARM_DESC(verbose, "Set verbosity level");
227
228MODULE_AUTHOR("Manu Abraham");
229MODULE_DESCRIPTION("TDA8261 8PSK/QPSK Tuner");
230MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/tda8261.h b/drivers/media/dvb/frontends/tda8261.h
new file mode 100644
index 000000000000..006e45351b94
--- /dev/null
+++ b/drivers/media/dvb/frontends/tda8261.h
@@ -0,0 +1,55 @@
1/*
2 TDA8261 8PSK/QPSK tuner driver
3 Copyright (C) Manu Abraham (abraham.manu@gmail.com)
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18*/
19
20#ifndef __TDA8261_H
21#define __TDA8261_H
22
23enum tda8261_step {
24 TDA8261_STEP_2000 = 0, /* 2000 kHz */
25 TDA8261_STEP_1000, /* 1000 kHz */
26 TDA8261_STEP_500, /* 500 kHz */
27 TDA8261_STEP_250, /* 250 kHz */
28 TDA8261_STEP_125 /* 125 kHz */
29};
30
31struct tda8261_config {
32// u8 buf[16];
33 u8 addr;
34 enum tda8261_step step_size;
35};
36
37#if defined(CONFIG_DVB_TDA8261) || (defined(CONFIG_DVB_TDA8261_MODULE) && defined(MODULE))
38
39extern struct dvb_frontend *tda8261_attach(struct dvb_frontend *fe,
40 const struct tda8261_config *config,
41 struct i2c_adapter *i2c);
42
43#else
44
45static inline struct dvb_frontend *tda8261_attach(struct dvb_frontend *fe,
46 const struct tda8261_config *config,
47 struct i2c_adapter *i2c)
48{
49 printk(KERN_WARNING "%s: Driver disabled by Kconfig\n", __func__);
50 return NULL;
51}
52
53#endif //CONFIG_DVB_TDA8261
54
55#endif// __TDA8261_H
diff --git a/drivers/media/dvb/frontends/tda8261_cfg.h b/drivers/media/dvb/frontends/tda8261_cfg.h
new file mode 100644
index 000000000000..1af1ee49b542
--- /dev/null
+++ b/drivers/media/dvb/frontends/tda8261_cfg.h
@@ -0,0 +1,84 @@
1/*
2 TDA8261 8PSK/QPSK tuner driver
3 Copyright (C) Manu Abraham (abraham.manu@gmail.com)
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; 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 tda8261_get_frequency(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 t_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 ((err = tuner_ops->get_state(fe, DVBFE_TUNER_FREQUENCY, &t_state)) < 0) {
33 printk("%s: Invalid parameter\n", __func__);
34 return err;
35 }
36 *frequency = t_state.frequency;
37 printk("%s: Frequency=%d\n", __func__, t_state.frequency);
38 }
39 return 0;
40}
41
42static int tda8261_set_frequency(struct dvb_frontend *fe, u32 frequency)
43{
44 struct dvb_frontend_ops *frontend_ops = NULL;
45 struct dvb_tuner_ops *tuner_ops = NULL;
46 struct tuner_state t_state;
47 int err = 0;
48
49 t_state.frequency = frequency;
50 if (&fe->ops)
51 frontend_ops = &fe->ops;
52 if (&frontend_ops->tuner_ops)
53 tuner_ops = &frontend_ops->tuner_ops;
54 if (tuner_ops->set_state) {
55 if ((err = tuner_ops->set_state(fe, DVBFE_TUNER_FREQUENCY, &t_state)) < 0) {
56 printk("%s: Invalid parameter\n", __func__);
57 return err;
58 }
59 }
60 printk("%s: Frequency=%d\n", __func__, t_state.frequency);
61 return 0;
62}
63
64static int tda8261_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
65{
66 struct dvb_frontend_ops *frontend_ops = &fe->ops;
67 struct dvb_tuner_ops *tuner_ops = &frontend_ops->tuner_ops;
68 struct tuner_state t_state;
69 int err = 0;
70
71 if (&fe->ops)
72 frontend_ops = &fe->ops;
73 if (&frontend_ops->tuner_ops)
74 tuner_ops = &frontend_ops->tuner_ops;
75 if (tuner_ops->get_state) {
76 if ((err = tuner_ops->get_state(fe, DVBFE_TUNER_BANDWIDTH, &t_state)) < 0) {
77 printk("%s: Invalid parameter\n", __func__);
78 return err;
79 }
80 *bandwidth = t_state.bandwidth;
81 }
82 printk("%s: Bandwidth=%d\n", __func__, t_state.bandwidth);
83 return 0;
84}
diff --git a/drivers/media/dvb/frontends/zl10353.c b/drivers/media/dvb/frontends/zl10353.c
index 36a5a1c101d5..5506f80e180e 100644
--- a/drivers/media/dvb/frontends/zl10353.c
+++ b/drivers/media/dvb/frontends/zl10353.c
@@ -220,15 +220,18 @@ static int zl10353_set_parameters(struct dvb_frontend *fe,
220 /* These are extrapolated from the 7 and 8MHz values */ 220 /* These are extrapolated from the 7 and 8MHz values */
221 zl10353_single_write(fe, MCLK_RATIO, 0x97); 221 zl10353_single_write(fe, MCLK_RATIO, 0x97);
222 zl10353_single_write(fe, 0x64, 0x34); 222 zl10353_single_write(fe, 0x64, 0x34);
223 zl10353_single_write(fe, 0xcc, 0xdd);
223 break; 224 break;
224 case BANDWIDTH_7_MHZ: 225 case BANDWIDTH_7_MHZ:
225 zl10353_single_write(fe, MCLK_RATIO, 0x86); 226 zl10353_single_write(fe, MCLK_RATIO, 0x86);
226 zl10353_single_write(fe, 0x64, 0x35); 227 zl10353_single_write(fe, 0x64, 0x35);
228 zl10353_single_write(fe, 0xcc, 0x73);
227 break; 229 break;
228 case BANDWIDTH_8_MHZ: 230 case BANDWIDTH_8_MHZ:
229 default: 231 default:
230 zl10353_single_write(fe, MCLK_RATIO, 0x75); 232 zl10353_single_write(fe, MCLK_RATIO, 0x75);
231 zl10353_single_write(fe, 0x64, 0x36); 233 zl10353_single_write(fe, 0x64, 0x36);
234 zl10353_single_write(fe, 0xcc, 0x73);
232 } 235 }
233 236
234 zl10353_calc_nominal_rate(fe, op->bandwidth, &nominal_rate); 237 zl10353_calc_nominal_rate(fe, op->bandwidth, &nominal_rate);
diff --git a/drivers/media/dvb/siano/sms-cards.c b/drivers/media/dvb/siano/sms-cards.c
index e98d6caf2c23..fd62e0b85621 100644
--- a/drivers/media/dvb/siano/sms-cards.c
+++ b/drivers/media/dvb/siano/sms-cards.c
@@ -38,6 +38,16 @@ struct usb_device_id smsusb_id_table[] = {
38 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_OKEMO_A }, 38 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_OKEMO_A },
39 { USB_DEVICE(0x2040, 0x1801), 39 { USB_DEVICE(0x2040, 0x1801),
40 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_OKEMO_B }, 40 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_OKEMO_B },
41 { USB_DEVICE(0x2040, 0x2000),
42 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD },
43 { USB_DEVICE(0x2040, 0x2009),
44 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2 },
45 { USB_DEVICE(0x2040, 0x200a),
46 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD },
47 { USB_DEVICE(0x2040, 0x2010),
48 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD },
49 { USB_DEVICE(0x2040, 0x2019),
50 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD },
41 { USB_DEVICE(0x2040, 0x5500), 51 { USB_DEVICE(0x2040, 0x5500),
42 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, 52 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
43 { USB_DEVICE(0x2040, 0x5510), 53 { USB_DEVICE(0x2040, 0x5510),
@@ -96,6 +106,21 @@ static struct sms_board sms_boards[] = {
96 .name = "Hauppauge WinTV MiniStick", 106 .name = "Hauppauge WinTV MiniStick",
97 .type = SMS_NOVA_B0, 107 .type = SMS_NOVA_B0,
98 .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-hcw-55xxx-dvbt-02.fw", 108 .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-hcw-55xxx-dvbt-02.fw",
109 .led_power = 26,
110 .led_lo = 27,
111 .led_hi = 28,
112 },
113 [SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD] = {
114 .name = "Hauppauge WinTV MiniCard",
115 .type = SMS_NOVA_B0,
116 .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-hcw-55xxx-dvbt-02.fw",
117 .lna_ctrl = 29,
118 },
119 [SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2] = {
120 .name = "Hauppauge WinTV MiniCard",
121 .type = SMS_NOVA_B0,
122 .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-hcw-55xxx-dvbt-02.fw",
123 .lna_ctrl = 1,
99 }, 124 },
100}; 125};
101 126
@@ -106,3 +131,88 @@ struct sms_board *sms_get_board(int id)
106 return &sms_boards[id]; 131 return &sms_boards[id];
107} 132}
108 133
134static int sms_set_gpio(struct smscore_device_t *coredev, u32 pin, int enable)
135{
136 int ret;
137 struct smscore_gpio_config gpioconfig = {
138 .direction = SMS_GPIO_DIRECTION_OUTPUT,
139 .pullupdown = SMS_GPIO_PULLUPDOWN_NONE,
140 .inputcharacteristics = SMS_GPIO_INPUTCHARACTERISTICS_NORMAL,
141 .outputslewrate = SMS_GPIO_OUTPUTSLEWRATE_FAST,
142 .outputdriving = SMS_GPIO_OUTPUTDRIVING_4mA,
143 };
144
145 if (pin == 0)
146 return -EINVAL;
147
148 ret = smscore_configure_gpio(coredev, pin, &gpioconfig);
149
150 if (ret < 0)
151 return ret;
152
153 return smscore_set_gpio(coredev, pin, enable);
154}
155
156int sms_board_setup(struct smscore_device_t *coredev)
157{
158 int board_id = smscore_get_board_id(coredev);
159 struct sms_board *board = sms_get_board(board_id);
160
161 switch (board_id) {
162 case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM:
163 /* turn off all LEDs */
164 sms_set_gpio(coredev, board->led_power, 0);
165 sms_set_gpio(coredev, board->led_hi, 0);
166 sms_set_gpio(coredev, board->led_lo, 0);
167 break;
168 case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2:
169 case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD:
170 /* turn off LNA */
171 sms_set_gpio(coredev, board->lna_ctrl, 0);
172 break;
173 }
174 return 0;
175}
176
177int sms_board_power(struct smscore_device_t *coredev, int onoff)
178{
179 int board_id = smscore_get_board_id(coredev);
180 struct sms_board *board = sms_get_board(board_id);
181
182 switch (board_id) {
183 case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM:
184 /* power LED */
185 sms_set_gpio(coredev,
186 board->led_power, onoff ? 1 : 0);
187 break;
188 case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2:
189 case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD:
190 /* LNA */
191 sms_set_gpio(coredev,
192 board->lna_ctrl, onoff ? 1 : 0);
193 break;
194 }
195 return 0;
196}
197
198int sms_board_led_feedback(struct smscore_device_t *coredev, int led)
199{
200 int board_id = smscore_get_board_id(coredev);
201 struct sms_board *board = sms_get_board(board_id);
202
203 /* dont touch GPIO if LEDs are already set */
204 if (smscore_led_state(coredev, -1) == led)
205 return 0;
206
207 switch (board_id) {
208 case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM:
209 sms_set_gpio(coredev,
210 board->led_lo, (led & SMS_LED_LO) ? 1 : 0);
211 sms_set_gpio(coredev,
212 board->led_hi, (led & SMS_LED_HI) ? 1 : 0);
213
214 smscore_led_state(coredev, led);
215 break;
216 }
217 return 0;
218}
diff --git a/drivers/media/dvb/siano/sms-cards.h b/drivers/media/dvb/siano/sms-cards.h
index c8f3da6f9bc1..8e0fe9fd2610 100644
--- a/drivers/media/dvb/siano/sms-cards.h
+++ b/drivers/media/dvb/siano/sms-cards.h
@@ -32,14 +32,27 @@
32#define SMS1XXX_BOARD_HAUPPAUGE_OKEMO_A 6 32#define SMS1XXX_BOARD_HAUPPAUGE_OKEMO_A 6
33#define SMS1XXX_BOARD_HAUPPAUGE_OKEMO_B 7 33#define SMS1XXX_BOARD_HAUPPAUGE_OKEMO_B 7
34#define SMS1XXX_BOARD_HAUPPAUGE_WINDHAM 8 34#define SMS1XXX_BOARD_HAUPPAUGE_WINDHAM 8
35#define SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD 9
36#define SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2 10
35 37
36struct sms_board { 38struct sms_board {
37 enum sms_device_type_st type; 39 enum sms_device_type_st type;
38 char *name, *fw[DEVICE_MODE_MAX]; 40 char *name, *fw[DEVICE_MODE_MAX];
41
42 /* gpios */
43 int led_power, led_hi, led_lo, lna_ctrl;
39}; 44};
40 45
41struct sms_board *sms_get_board(int id); 46struct sms_board *sms_get_board(int id);
42 47
48int sms_board_setup(struct smscore_device_t *coredev);
49
50#define SMS_LED_OFF 0
51#define SMS_LED_LO 1
52#define SMS_LED_HI 2
53int sms_board_led_feedback(struct smscore_device_t *coredev, int led);
54int sms_board_power(struct smscore_device_t *coredev, int onoff);
55
43extern struct usb_device_id smsusb_id_table[]; 56extern struct usb_device_id smsusb_id_table[];
44 57
45#endif /* __SMS_CARDS_H__ */ 58#endif /* __SMS_CARDS_H__ */
diff --git a/drivers/media/dvb/siano/smscoreapi.c b/drivers/media/dvb/siano/smscoreapi.c
index 6576fbb40fc6..cf613f22fb8d 100644
--- a/drivers/media/dvb/siano/smscoreapi.c
+++ b/drivers/media/dvb/siano/smscoreapi.c
@@ -91,6 +91,7 @@ struct smscore_device_t {
91 struct completion init_device_done, reload_start_done, resume_done; 91 struct completion init_device_done, reload_start_done, resume_done;
92 92
93 int board_id; 93 int board_id;
94 int led_state;
94}; 95};
95 96
96void smscore_set_board_id(struct smscore_device_t *core, int id) 97void smscore_set_board_id(struct smscore_device_t *core, int id)
@@ -98,6 +99,13 @@ void smscore_set_board_id(struct smscore_device_t *core, int id)
98 core->board_id = id; 99 core->board_id = id;
99} 100}
100 101
102int smscore_led_state(struct smscore_device_t *core, int led)
103{
104 if (led >= 0)
105 core->led_state = led;
106 return core->led_state;
107}
108
101int smscore_get_board_id(struct smscore_device_t *core) 109int smscore_get_board_id(struct smscore_device_t *core)
102{ 110{
103 return core->board_id; 111 return core->board_id;
@@ -1187,6 +1195,76 @@ int smsclient_sendrequest(struct smscore_client_t *client,
1187} 1195}
1188 1196
1189 1197
1198int smscore_configure_gpio(struct smscore_device_t *coredev, u32 pin,
1199 struct smscore_gpio_config *pinconfig)
1200{
1201 struct {
1202 struct SmsMsgHdr_ST hdr;
1203 u32 data[6];
1204 } msg;
1205
1206 if (coredev->device_flags & SMS_DEVICE_FAMILY2) {
1207 msg.hdr.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
1208 msg.hdr.msgDstId = HIF_TASK;
1209 msg.hdr.msgFlags = 0;
1210 msg.hdr.msgType = MSG_SMS_GPIO_CONFIG_EX_REQ;
1211 msg.hdr.msgLength = sizeof(msg);
1212
1213 msg.data[0] = pin;
1214 msg.data[1] = pinconfig->pullupdown;
1215
1216 /* Convert slew rate for Nova: Fast(0) = 3 / Slow(1) = 0; */
1217 msg.data[2] = pinconfig->outputslewrate == 0 ? 3 : 0;
1218
1219 switch (pinconfig->outputdriving) {
1220 case SMS_GPIO_OUTPUTDRIVING_16mA:
1221 msg.data[3] = 7; /* Nova - 16mA */
1222 break;
1223 case SMS_GPIO_OUTPUTDRIVING_12mA:
1224 msg.data[3] = 5; /* Nova - 11mA */
1225 break;
1226 case SMS_GPIO_OUTPUTDRIVING_8mA:
1227 msg.data[3] = 3; /* Nova - 7mA */
1228 break;
1229 case SMS_GPIO_OUTPUTDRIVING_4mA:
1230 default:
1231 msg.data[3] = 2; /* Nova - 4mA */
1232 break;
1233 }
1234
1235 msg.data[4] = pinconfig->direction;
1236 msg.data[5] = 0;
1237 } else /* TODO: SMS_DEVICE_FAMILY1 */
1238 return -EINVAL;
1239
1240 return coredev->sendrequest_handler(coredev->context,
1241 &msg, sizeof(msg));
1242}
1243
1244int smscore_set_gpio(struct smscore_device_t *coredev, u32 pin, int level)
1245{
1246 struct {
1247 struct SmsMsgHdr_ST hdr;
1248 u32 data[3];
1249 } msg;
1250
1251 if (pin > MAX_GPIO_PIN_NUMBER)
1252 return -EINVAL;
1253
1254 msg.hdr.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
1255 msg.hdr.msgDstId = HIF_TASK;
1256 msg.hdr.msgFlags = 0;
1257 msg.hdr.msgType = MSG_SMS_GPIO_SET_LEVEL_REQ;
1258 msg.hdr.msgLength = sizeof(msg);
1259
1260 msg.data[0] = pin;
1261 msg.data[1] = level ? 1 : 0;
1262 msg.data[2] = 0;
1263
1264 return coredev->sendrequest_handler(coredev->context,
1265 &msg, sizeof(msg));
1266}
1267
1190static int __init smscore_module_init(void) 1268static int __init smscore_module_init(void)
1191{ 1269{
1192 int rc = 0; 1270 int rc = 0;
diff --git a/drivers/media/dvb/siano/smscoreapi.h b/drivers/media/dvb/siano/smscoreapi.h
index 8d973f726fb8..760e233fcbc5 100644
--- a/drivers/media/dvb/siano/smscoreapi.h
+++ b/drivers/media/dvb/siano/smscoreapi.h
@@ -186,6 +186,8 @@ struct smsclient_params_t {
186#define MSG_SW_RELOAD_EXEC_REQ 704 186#define MSG_SW_RELOAD_EXEC_REQ 704
187#define MSG_SW_RELOAD_EXEC_RES 705 187#define MSG_SW_RELOAD_EXEC_RES 705
188#define MSG_SMS_SPI_INT_LINE_SET_REQ 710 188#define MSG_SMS_SPI_INT_LINE_SET_REQ 710
189#define MSG_SMS_GPIO_CONFIG_EX_REQ 712
190#define MSG_SMS_GPIO_CONFIG_EX_RES 713
189#define MSG_SMS_ISDBT_TUNE_REQ 776 191#define MSG_SMS_ISDBT_TUNE_REQ 776
190#define MSG_SMS_ISDBT_TUNE_RES 777 192#define MSG_SMS_ISDBT_TUNE_RES 777
191 193
@@ -341,6 +343,32 @@ struct SmsMsgStatisticsInfo_ST {
341}; 343};
342 344
343 345
346struct smscore_gpio_config {
347#define SMS_GPIO_DIRECTION_INPUT 0
348#define SMS_GPIO_DIRECTION_OUTPUT 1
349 u8 direction;
350
351#define SMS_GPIO_PULLUPDOWN_NONE 0
352#define SMS_GPIO_PULLUPDOWN_PULLDOWN 1
353#define SMS_GPIO_PULLUPDOWN_PULLUP 2
354#define SMS_GPIO_PULLUPDOWN_KEEPER 3
355 u8 pullupdown;
356
357#define SMS_GPIO_INPUTCHARACTERISTICS_NORMAL 0
358#define SMS_GPIO_INPUTCHARACTERISTICS_SCHMITT 1
359 u8 inputcharacteristics;
360
361#define SMS_GPIO_OUTPUTSLEWRATE_FAST 0
362#define SMS_GPIO_OUTPUTSLEWRATE_SLOW 1
363 u8 outputslewrate;
364
365#define SMS_GPIO_OUTPUTDRIVING_4mA 0
366#define SMS_GPIO_OUTPUTDRIVING_8mA 1
367#define SMS_GPIO_OUTPUTDRIVING_12mA 2
368#define SMS_GPIO_OUTPUTDRIVING_16mA 3
369 u8 outputdriving;
370};
371
344struct smsdvb_client_t { 372struct smsdvb_client_t {
345 struct list_head entry; 373 struct list_head entry;
346 374
@@ -353,7 +381,7 @@ struct smsdvb_client_t {
353 struct dvb_frontend frontend; 381 struct dvb_frontend frontend;
354 382
355 fe_status_t fe_status; 383 fe_status_t fe_status;
356 int fe_ber, fe_snr, fe_signal_strength; 384 int fe_ber, fe_snr, fe_unc, fe_signal_strength;
357 385
358 struct completion tune_done, stat_done; 386 struct completion tune_done, stat_done;
359 387
@@ -396,9 +424,15 @@ struct smscore_buffer_t *smscore_getbuffer(struct smscore_device_t *coredev);
396extern void smscore_putbuffer(struct smscore_device_t *coredev, 424extern void smscore_putbuffer(struct smscore_device_t *coredev,
397 struct smscore_buffer_t *cb); 425 struct smscore_buffer_t *cb);
398 426
427int smscore_configure_gpio(struct smscore_device_t *coredev, u32 pin,
428 struct smscore_gpio_config *pinconfig);
429int smscore_set_gpio(struct smscore_device_t *coredev, u32 pin, int level);
430
399void smscore_set_board_id(struct smscore_device_t *core, int id); 431void smscore_set_board_id(struct smscore_device_t *core, int id);
400int smscore_get_board_id(struct smscore_device_t *core); 432int smscore_get_board_id(struct smscore_device_t *core);
401 433
434int smscore_led_state(struct smscore_device_t *core, int led);
435
402/* smsdvb.c */ 436/* smsdvb.c */
403int smsdvb_register(void); 437int smsdvb_register(void);
404void smsdvb_unregister(void); 438void smsdvb_unregister(void);
diff --git a/drivers/media/dvb/siano/smsdvb.c b/drivers/media/dvb/siano/smsdvb.c
index 8d490e133f35..2da953a4f4f5 100644
--- a/drivers/media/dvb/siano/smsdvb.c
+++ b/drivers/media/dvb/siano/smsdvb.c
@@ -60,6 +60,7 @@ static int smsdvb_onresponse(void *context, struct smscore_buffer_t *cb)
60 60
61 client->fe_snr = p->Stat.SNR; 61 client->fe_snr = p->Stat.SNR;
62 client->fe_ber = p->Stat.BER; 62 client->fe_ber = p->Stat.BER;
63 client->fe_unc = p->Stat.BERErrorCount;
63 64
64 if (p->Stat.InBandPwr < -95) 65 if (p->Stat.InBandPwr < -95)
65 client->fe_signal_strength = 0; 66 client->fe_signal_strength = 0;
@@ -72,6 +73,7 @@ static int smsdvb_onresponse(void *context, struct smscore_buffer_t *cb)
72 client->fe_status = 0; 73 client->fe_status = 0;
73 client->fe_snr = 74 client->fe_snr =
74 client->fe_ber = 75 client->fe_ber =
76 client->fe_unc =
75 client->fe_signal_strength = 0; 77 client->fe_signal_strength = 0;
76 } 78 }
77 79
@@ -165,8 +167,18 @@ static int smsdvb_send_statistics_request(struct smsdvb_client_t *client)
165 struct SmsMsgHdr_ST Msg = { MSG_SMS_GET_STATISTICS_REQ, 167 struct SmsMsgHdr_ST Msg = { MSG_SMS_GET_STATISTICS_REQ,
166 DVBT_BDA_CONTROL_MSG_ID, 168 DVBT_BDA_CONTROL_MSG_ID,
167 HIF_TASK, sizeof(struct SmsMsgHdr_ST), 0 }; 169 HIF_TASK, sizeof(struct SmsMsgHdr_ST), 0 };
168 return smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg), 170 int ret = smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg),
169 &client->stat_done); 171 &client->stat_done);
172 if (ret < 0)
173 return ret;
174
175 if (client->fe_status & FE_HAS_LOCK)
176 sms_board_led_feedback(client->coredev,
177 (client->fe_unc == 0) ?
178 SMS_LED_HI : SMS_LED_LO);
179 else
180 sms_board_led_feedback(client->coredev, SMS_LED_OFF);
181 return ret;
170} 182}
171 183
172static int smsdvb_read_status(struct dvb_frontend *fe, fe_status_t *stat) 184static int smsdvb_read_status(struct dvb_frontend *fe, fe_status_t *stat)
@@ -217,6 +229,18 @@ static int smsdvb_read_snr(struct dvb_frontend *fe, u16 *snr)
217 return rc; 229 return rc;
218} 230}
219 231
232static int smsdvb_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
233{
234 struct smsdvb_client_t *client =
235 container_of(fe, struct smsdvb_client_t, frontend);
236 int rc = smsdvb_send_statistics_request(client);
237
238 if (!rc)
239 *ucblocks = client->fe_unc;
240
241 return rc;
242}
243
220static int smsdvb_get_tune_settings(struct dvb_frontend *fe, 244static int smsdvb_get_tune_settings(struct dvb_frontend *fe,
221 struct dvb_frontend_tune_settings *tune) 245 struct dvb_frontend_tune_settings *tune)
222{ 246{
@@ -273,6 +297,28 @@ static int smsdvb_get_frontend(struct dvb_frontend *fe,
273 /* todo: */ 297 /* todo: */
274 memcpy(fep, &client->fe_params, 298 memcpy(fep, &client->fe_params,
275 sizeof(struct dvb_frontend_parameters)); 299 sizeof(struct dvb_frontend_parameters));
300
301 return 0;
302}
303
304static int smsdvb_init(struct dvb_frontend *fe)
305{
306 struct smsdvb_client_t *client =
307 container_of(fe, struct smsdvb_client_t, frontend);
308
309 sms_board_power(client->coredev, 1);
310
311 return 0;
312}
313
314static int smsdvb_sleep(struct dvb_frontend *fe)
315{
316 struct smsdvb_client_t *client =
317 container_of(fe, struct smsdvb_client_t, frontend);
318
319 sms_board_led_feedback(client->coredev, SMS_LED_OFF);
320 sms_board_power(client->coredev, 0);
321
276 return 0; 322 return 0;
277} 323}
278 324
@@ -308,6 +354,10 @@ static struct dvb_frontend_ops smsdvb_fe_ops = {
308 .read_ber = smsdvb_read_ber, 354 .read_ber = smsdvb_read_ber,
309 .read_signal_strength = smsdvb_read_signal_strength, 355 .read_signal_strength = smsdvb_read_signal_strength,
310 .read_snr = smsdvb_read_snr, 356 .read_snr = smsdvb_read_snr,
357 .read_ucblocks = smsdvb_read_ucblocks,
358
359 .init = smsdvb_init,
360 .sleep = smsdvb_sleep,
311}; 361};
312 362
313static int smsdvb_hotplug(struct smscore_device_t *coredev, 363static int smsdvb_hotplug(struct smscore_device_t *coredev,
@@ -402,6 +452,8 @@ static int smsdvb_hotplug(struct smscore_device_t *coredev,
402 452
403 sms_info("success"); 453 sms_info("success");
404 454
455 sms_board_setup(coredev);
456
405 return 0; 457 return 0;
406 458
407client_error: 459client_error:
diff --git a/drivers/media/dvb/siano/smsusb.c b/drivers/media/dvb/siano/smsusb.c
index 87a3c24454b9..5d7ca3417719 100644
--- a/drivers/media/dvb/siano/smsusb.c
+++ b/drivers/media/dvb/siano/smsusb.c
@@ -432,11 +432,56 @@ static void smsusb_disconnect(struct usb_interface *intf)
432 smsusb_term_device(intf); 432 smsusb_term_device(intf);
433} 433}
434 434
435static int smsusb_suspend(struct usb_interface *intf, pm_message_t msg)
436{
437 struct smsusb_device_t *dev =
438 (struct smsusb_device_t *)usb_get_intfdata(intf);
439 printk(KERN_INFO "%s Entering status %d.\n", __func__, msg.event);
440 smsusb_stop_streaming(dev);
441 return 0;
442}
443
444static int smsusb_resume(struct usb_interface *intf)
445{
446 int rc, i;
447 struct smsusb_device_t *dev =
448 (struct smsusb_device_t *)usb_get_intfdata(intf);
449 struct usb_device *udev = interface_to_usbdev(intf);
450
451 printk(KERN_INFO "%s Entering.\n", __func__);
452 usb_clear_halt(udev, usb_rcvbulkpipe(udev, 0x81));
453 usb_clear_halt(udev, usb_rcvbulkpipe(udev, 0x02));
454
455 for (i = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i++)
456 printk(KERN_INFO "endpoint %d %02x %02x %d\n", i,
457 intf->cur_altsetting->endpoint[i].desc.bEndpointAddress,
458 intf->cur_altsetting->endpoint[i].desc.bmAttributes,
459 intf->cur_altsetting->endpoint[i].desc.wMaxPacketSize);
460
461 if (intf->num_altsetting > 0) {
462 rc = usb_set_interface(udev,
463 intf->cur_altsetting->desc.
464 bInterfaceNumber, 0);
465 if (rc < 0) {
466 printk(KERN_INFO
467 "%s usb_set_interface failed, rc %d\n",
468 __func__, rc);
469 return rc;
470 }
471 }
472
473 smsusb_start_streaming(dev);
474 return 0;
475}
476
435static struct usb_driver smsusb_driver = { 477static struct usb_driver smsusb_driver = {
436 .name = "sms1xxx", 478 .name = "sms1xxx",
437 .probe = smsusb_probe, 479 .probe = smsusb_probe,
438 .disconnect = smsusb_disconnect, 480 .disconnect = smsusb_disconnect,
439 .id_table = smsusb_id_table, 481 .id_table = smsusb_id_table,
482
483 .suspend = smsusb_suspend,
484 .resume = smsusb_resume,
440}; 485};
441 486
442int smsusb_register(void) 487int smsusb_register(void)
diff --git a/drivers/media/dvb/ttpci/Kconfig b/drivers/media/dvb/ttpci/Kconfig
index 401a04effc06..ab0bcd208c78 100644
--- a/drivers/media/dvb/ttpci/Kconfig
+++ b/drivers/media/dvb/ttpci/Kconfig
@@ -104,6 +104,8 @@ config DVB_BUDGET_CI
104 select DVB_STV0297 if !DVB_FE_CUSTOMISE 104 select DVB_STV0297 if !DVB_FE_CUSTOMISE
105 select DVB_STV0299 if !DVB_FE_CUSTOMISE 105 select DVB_STV0299 if !DVB_FE_CUSTOMISE
106 select DVB_TDA1004X if !DVB_FE_CUSTOMISE 106 select DVB_TDA1004X if !DVB_FE_CUSTOMISE
107 select DVB_STB0899 if !DVB_FE_CUSTOMISE
108 select DVB_STB6100 if !DVB_FE_CUSTOMISE
107 select DVB_LNBP21 if !DVB_FE_CUSTOMISE 109 select DVB_LNBP21 if !DVB_FE_CUSTOMISE
108 select DVB_TDA10023 if !DVB_FE_CUSTOMISE 110 select DVB_TDA10023 if !DVB_FE_CUSTOMISE
109 select MEDIA_TUNER_TDA827X if !MEDIA_TUNER_CUSTOMIZE 111 select MEDIA_TUNER_TDA827X if !MEDIA_TUNER_CUSTOMIZE
@@ -131,6 +133,8 @@ config DVB_BUDGET_AV
131 select DVB_TDA1004X if !DVB_FE_CUSTOMISE 133 select DVB_TDA1004X if !DVB_FE_CUSTOMISE
132 select DVB_TDA10021 if !DVB_FE_CUSTOMISE 134 select DVB_TDA10021 if !DVB_FE_CUSTOMISE
133 select DVB_TDA10023 if !DVB_FE_CUSTOMISE 135 select DVB_TDA10023 if !DVB_FE_CUSTOMISE
136 select DVB_STB0899 if !DVB_FE_CUSTOMISE
137 select DVB_TDA8261 if !DVB_FE_CUSTOMISE
134 select DVB_TUA6100 if !DVB_FE_CUSTOMISE 138 select DVB_TUA6100 if !DVB_FE_CUSTOMISE
135 help 139 help
136 Support for simple SAA7146 based DVB cards 140 Support for simple SAA7146 based DVB cards
diff --git a/drivers/media/dvb/ttpci/budget-av.c b/drivers/media/dvb/ttpci/budget-av.c
index 1032ea77837e..f996cef79ec1 100644
--- a/drivers/media/dvb/ttpci/budget-av.c
+++ b/drivers/media/dvb/ttpci/budget-av.c
@@ -35,6 +35,11 @@
35 35
36#include "budget.h" 36#include "budget.h"
37#include "stv0299.h" 37#include "stv0299.h"
38#include "stb0899_drv.h"
39#include "stb0899_reg.h"
40#include "stb0899_cfg.h"
41#include "tda8261.h"
42#include "tda8261_cfg.h"
38#include "tda1002x.h" 43#include "tda1002x.h"
39#include "tda1004x.h" 44#include "tda1004x.h"
40#include "tua6100.h" 45#include "tua6100.h"
@@ -882,6 +887,281 @@ static struct stv0299_config philips_sd1878_config = {
882 .set_symbol_rate = philips_sd1878_ci_set_symbol_rate, 887 .set_symbol_rate = philips_sd1878_ci_set_symbol_rate,
883}; 888};
884 889
890/* KNC1 DVB-S (STB0899) Inittab */
891static const struct stb0899_s1_reg knc1_stb0899_s1_init_1[] = {
892
893 { STB0899_DEV_ID , 0x81 },
894 { STB0899_DISCNTRL1 , 0x32 },
895 { STB0899_DISCNTRL2 , 0x80 },
896 { STB0899_DISRX_ST0 , 0x04 },
897 { STB0899_DISRX_ST1 , 0x00 },
898 { STB0899_DISPARITY , 0x00 },
899 { STB0899_DISFIFO , 0x00 },
900 { STB0899_DISSTATUS , 0x20 },
901 { STB0899_DISF22 , 0x8c },
902 { STB0899_DISF22RX , 0x9a },
903 { STB0899_SYSREG , 0x0b },
904 { STB0899_ACRPRESC , 0x11 },
905 { STB0899_ACRDIV1 , 0x0a },
906 { STB0899_ACRDIV2 , 0x05 },
907 { STB0899_DACR1 , 0x00 },
908 { STB0899_DACR2 , 0x00 },
909 { STB0899_OUTCFG , 0x00 },
910 { STB0899_MODECFG , 0x00 },
911 { STB0899_IRQSTATUS_3 , 0x30 },
912 { STB0899_IRQSTATUS_2 , 0x00 },
913 { STB0899_IRQSTATUS_1 , 0x00 },
914 { STB0899_IRQSTATUS_0 , 0x00 },
915 { STB0899_IRQMSK_3 , 0xf3 },
916 { STB0899_IRQMSK_2 , 0xfc },
917 { STB0899_IRQMSK_1 , 0xff },
918 { STB0899_IRQMSK_0 , 0xff },
919 { STB0899_IRQCFG , 0x00 },
920 { STB0899_I2CCFG , 0x88 },
921 { STB0899_I2CRPT , 0x58 }, /* Repeater=8, Stop=disabled */
922 { STB0899_IOPVALUE5 , 0x00 },
923 { STB0899_IOPVALUE4 , 0x20 },
924 { STB0899_IOPVALUE3 , 0xc9 },
925 { STB0899_IOPVALUE2 , 0x90 },
926 { STB0899_IOPVALUE1 , 0x40 },
927 { STB0899_IOPVALUE0 , 0x00 },
928 { STB0899_GPIO00CFG , 0x82 },
929 { STB0899_GPIO01CFG , 0x82 },
930 { STB0899_GPIO02CFG , 0x82 },
931 { STB0899_GPIO03CFG , 0x82 },
932 { STB0899_GPIO04CFG , 0x82 },
933 { STB0899_GPIO05CFG , 0x82 },
934 { STB0899_GPIO06CFG , 0x82 },
935 { STB0899_GPIO07CFG , 0x82 },
936 { STB0899_GPIO08CFG , 0x82 },
937 { STB0899_GPIO09CFG , 0x82 },
938 { STB0899_GPIO10CFG , 0x82 },
939 { STB0899_GPIO11CFG , 0x82 },
940 { STB0899_GPIO12CFG , 0x82 },
941 { STB0899_GPIO13CFG , 0x82 },
942 { STB0899_GPIO14CFG , 0x82 },
943 { STB0899_GPIO15CFG , 0x82 },
944 { STB0899_GPIO16CFG , 0x82 },
945 { STB0899_GPIO17CFG , 0x82 },
946 { STB0899_GPIO18CFG , 0x82 },
947 { STB0899_GPIO19CFG , 0x82 },
948 { STB0899_GPIO20CFG , 0x82 },
949 { STB0899_SDATCFG , 0xb8 },
950 { STB0899_SCLTCFG , 0xba },
951 { STB0899_AGCRFCFG , 0x08 }, /* 0x1c */
952 { STB0899_GPIO22 , 0x82 }, /* AGCBB2CFG */
953 { STB0899_GPIO21 , 0x91 }, /* AGCBB1CFG */
954 { STB0899_DIRCLKCFG , 0x82 },
955 { STB0899_CLKOUT27CFG , 0x7e },
956 { STB0899_STDBYCFG , 0x82 },
957 { STB0899_CS0CFG , 0x82 },
958 { STB0899_CS1CFG , 0x82 },
959 { STB0899_DISEQCOCFG , 0x20 },
960 { STB0899_GPIO32CFG , 0x82 },
961 { STB0899_GPIO33CFG , 0x82 },
962 { STB0899_GPIO34CFG , 0x82 },
963 { STB0899_GPIO35CFG , 0x82 },
964 { STB0899_GPIO36CFG , 0x82 },
965 { STB0899_GPIO37CFG , 0x82 },
966 { STB0899_GPIO38CFG , 0x82 },
967 { STB0899_GPIO39CFG , 0x82 },
968 { STB0899_NCOARSE , 0x15 }, /* 0x15 = 27 Mhz Clock, F/3 = 198MHz, F/6 = 99MHz */
969 { STB0899_SYNTCTRL , 0x02 }, /* 0x00 = CLK from CLKI, 0x02 = CLK from XTALI */
970 { STB0899_FILTCTRL , 0x00 },
971 { STB0899_SYSCTRL , 0x00 },
972 { STB0899_STOPCLK1 , 0x20 },
973 { STB0899_STOPCLK2 , 0x00 },
974 { STB0899_INTBUFSTATUS , 0x00 },
975 { STB0899_INTBUFCTRL , 0x0a },
976 { 0xffff , 0xff },
977};
978
979static const struct stb0899_s1_reg knc1_stb0899_s1_init_3[] = {
980 { STB0899_DEMOD , 0x00 },
981 { STB0899_RCOMPC , 0xc9 },
982 { STB0899_AGC1CN , 0x41 },
983 { STB0899_AGC1REF , 0x08 },
984 { STB0899_RTC , 0x7a },
985 { STB0899_TMGCFG , 0x4e },
986 { STB0899_AGC2REF , 0x33 },
987 { STB0899_TLSR , 0x84 },
988 { STB0899_CFD , 0xee },
989 { STB0899_ACLC , 0x87 },
990 { STB0899_BCLC , 0x94 },
991 { STB0899_EQON , 0x41 },
992 { STB0899_LDT , 0xdd },
993 { STB0899_LDT2 , 0xc9 },
994 { STB0899_EQUALREF , 0xb4 },
995 { STB0899_TMGRAMP , 0x10 },
996 { STB0899_TMGTHD , 0x30 },
997 { STB0899_IDCCOMP , 0xfb },
998 { STB0899_QDCCOMP , 0x03 },
999 { STB0899_POWERI , 0x3b },
1000 { STB0899_POWERQ , 0x3d },
1001 { STB0899_RCOMP , 0x81 },
1002 { STB0899_AGCIQIN , 0x80 },
1003 { STB0899_AGC2I1 , 0x04 },
1004 { STB0899_AGC2I2 , 0xf5 },
1005 { STB0899_TLIR , 0x25 },
1006 { STB0899_RTF , 0x80 },
1007 { STB0899_DSTATUS , 0x00 },
1008 { STB0899_LDI , 0xca },
1009 { STB0899_CFRM , 0xf1 },
1010 { STB0899_CFRL , 0xf3 },
1011 { STB0899_NIRM , 0x2a },
1012 { STB0899_NIRL , 0x05 },
1013 { STB0899_ISYMB , 0x17 },
1014 { STB0899_QSYMB , 0xfa },
1015 { STB0899_SFRH , 0x2f },
1016 { STB0899_SFRM , 0x68 },
1017 { STB0899_SFRL , 0x40 },
1018 { STB0899_SFRUPH , 0x2f },
1019 { STB0899_SFRUPM , 0x68 },
1020 { STB0899_SFRUPL , 0x40 },
1021 { STB0899_EQUAI1 , 0xfd },
1022 { STB0899_EQUAQ1 , 0x04 },
1023 { STB0899_EQUAI2 , 0x0f },
1024 { STB0899_EQUAQ2 , 0xff },
1025 { STB0899_EQUAI3 , 0xdf },
1026 { STB0899_EQUAQ3 , 0xfa },
1027 { STB0899_EQUAI4 , 0x37 },
1028 { STB0899_EQUAQ4 , 0x0d },
1029 { STB0899_EQUAI5 , 0xbd },
1030 { STB0899_EQUAQ5 , 0xf7 },
1031 { STB0899_DSTATUS2 , 0x00 },
1032 { STB0899_VSTATUS , 0x00 },
1033 { STB0899_VERROR , 0xff },
1034 { STB0899_IQSWAP , 0x2a },
1035 { STB0899_ECNT1M , 0x00 },
1036 { STB0899_ECNT1L , 0x00 },
1037 { STB0899_ECNT2M , 0x00 },
1038 { STB0899_ECNT2L , 0x00 },
1039 { STB0899_ECNT3M , 0x00 },
1040 { STB0899_ECNT3L , 0x00 },
1041 { STB0899_FECAUTO1 , 0x06 },
1042 { STB0899_FECM , 0x01 },
1043 { STB0899_VTH12 , 0xf0 },
1044 { STB0899_VTH23 , 0xa0 },
1045 { STB0899_VTH34 , 0x78 },
1046 { STB0899_VTH56 , 0x4e },
1047 { STB0899_VTH67 , 0x48 },
1048 { STB0899_VTH78 , 0x38 },
1049 { STB0899_PRVIT , 0xff },
1050 { STB0899_VITSYNC , 0x19 },
1051 { STB0899_RSULC , 0xb1 }, /* DVB = 0xb1, DSS = 0xa1 */
1052 { STB0899_TSULC , 0x42 },
1053 { STB0899_RSLLC , 0x40 },
1054 { STB0899_TSLPL , 0x12 },
1055 { STB0899_TSCFGH , 0x0c },
1056 { STB0899_TSCFGM , 0x00 },
1057 { STB0899_TSCFGL , 0x0c },
1058 { STB0899_TSOUT , 0x0d }, /* 0x0d for CAM */
1059 { STB0899_RSSYNCDEL , 0x00 },
1060 { STB0899_TSINHDELH , 0x02 },
1061 { STB0899_TSINHDELM , 0x00 },
1062 { STB0899_TSINHDELL , 0x00 },
1063 { STB0899_TSLLSTKM , 0x00 },
1064 { STB0899_TSLLSTKL , 0x00 },
1065 { STB0899_TSULSTKM , 0x00 },
1066 { STB0899_TSULSTKL , 0xab },
1067 { STB0899_PCKLENUL , 0x00 },
1068 { STB0899_PCKLENLL , 0xcc },
1069 { STB0899_RSPCKLEN , 0xcc },
1070 { STB0899_TSSTATUS , 0x80 },
1071 { STB0899_ERRCTRL1 , 0xb6 },
1072 { STB0899_ERRCTRL2 , 0x96 },
1073 { STB0899_ERRCTRL3 , 0x89 },
1074 { STB0899_DMONMSK1 , 0x27 },
1075 { STB0899_DMONMSK0 , 0x03 },
1076 { STB0899_DEMAPVIT , 0x5c },
1077 { STB0899_PLPARM , 0x1f },
1078 { STB0899_PDELCTRL , 0x48 },
1079 { STB0899_PDELCTRL2 , 0x00 },
1080 { STB0899_BBHCTRL1 , 0x00 },
1081 { STB0899_BBHCTRL2 , 0x00 },
1082 { STB0899_HYSTTHRESH , 0x77 },
1083 { STB0899_MATCSTM , 0x00 },
1084 { STB0899_MATCSTL , 0x00 },
1085 { STB0899_UPLCSTM , 0x00 },
1086 { STB0899_UPLCSTL , 0x00 },
1087 { STB0899_DFLCSTM , 0x00 },
1088 { STB0899_DFLCSTL , 0x00 },
1089 { STB0899_SYNCCST , 0x00 },
1090 { STB0899_SYNCDCSTM , 0x00 },
1091 { STB0899_SYNCDCSTL , 0x00 },
1092 { STB0899_ISI_ENTRY , 0x00 },
1093 { STB0899_ISI_BIT_EN , 0x00 },
1094 { STB0899_MATSTRM , 0x00 },
1095 { STB0899_MATSTRL , 0x00 },
1096 { STB0899_UPLSTRM , 0x00 },
1097 { STB0899_UPLSTRL , 0x00 },
1098 { STB0899_DFLSTRM , 0x00 },
1099 { STB0899_DFLSTRL , 0x00 },
1100 { STB0899_SYNCSTR , 0x00 },
1101 { STB0899_SYNCDSTRM , 0x00 },
1102 { STB0899_SYNCDSTRL , 0x00 },
1103 { STB0899_CFGPDELSTATUS1 , 0x10 },
1104 { STB0899_CFGPDELSTATUS2 , 0x00 },
1105 { STB0899_BBFERRORM , 0x00 },
1106 { STB0899_BBFERRORL , 0x00 },
1107 { STB0899_UPKTERRORM , 0x00 },
1108 { STB0899_UPKTERRORL , 0x00 },
1109 { 0xffff , 0xff },
1110};
1111
1112/* STB0899 demodulator config for the KNC1 and clones */
1113static struct stb0899_config knc1_dvbs2_config = {
1114 .init_dev = knc1_stb0899_s1_init_1,
1115 .init_s2_demod = stb0899_s2_init_2,
1116 .init_s1_demod = knc1_stb0899_s1_init_3,
1117 .init_s2_fec = stb0899_s2_init_4,
1118 .init_tst = stb0899_s1_init_5,
1119
1120 .postproc = NULL,
1121
1122 .demod_address = 0x68,
1123// .ts_output_mode = STB0899_OUT_PARALLEL, /* types = SERIAL/PARALLEL */
1124 .block_sync_mode = STB0899_SYNC_FORCED, /* DSS, SYNC_FORCED/UNSYNCED */
1125// .ts_pfbit_toggle = STB0899_MPEG_NORMAL, /* DirecTV, MPEG toggling seq */
1126
1127 .xtal_freq = 27000000,
1128 .inversion = IQ_SWAP_OFF, /* 1 */
1129
1130 .lo_clk = 76500000,
1131 .hi_clk = 90000000,
1132
1133 .esno_ave = STB0899_DVBS2_ESNO_AVE,
1134 .esno_quant = STB0899_DVBS2_ESNO_QUANT,
1135 .avframes_coarse = STB0899_DVBS2_AVFRAMES_COARSE,
1136 .avframes_fine = STB0899_DVBS2_AVFRAMES_FINE,
1137 .miss_threshold = STB0899_DVBS2_MISS_THRESHOLD,
1138 .uwp_threshold_acq = STB0899_DVBS2_UWP_THRESHOLD_ACQ,
1139 .uwp_threshold_track = STB0899_DVBS2_UWP_THRESHOLD_TRACK,
1140 .uwp_threshold_sof = STB0899_DVBS2_UWP_THRESHOLD_SOF,
1141 .sof_search_timeout = STB0899_DVBS2_SOF_SEARCH_TIMEOUT,
1142
1143 .btr_nco_bits = STB0899_DVBS2_BTR_NCO_BITS,
1144 .btr_gain_shift_offset = STB0899_DVBS2_BTR_GAIN_SHIFT_OFFSET,
1145 .crl_nco_bits = STB0899_DVBS2_CRL_NCO_BITS,
1146 .ldpc_max_iter = STB0899_DVBS2_LDPC_MAX_ITER,
1147
1148 .tuner_get_frequency = tda8261_get_frequency,
1149 .tuner_set_frequency = tda8261_set_frequency,
1150 .tuner_set_bandwidth = NULL,
1151 .tuner_get_bandwidth = tda8261_get_bandwidth,
1152 .tuner_set_rfsiggain = NULL
1153};
1154
1155/*
1156 * SD1878/SHA tuner config
1157 * 1F, Single I/P, Horizontal mount, High Sensitivity
1158 */
1159static const struct tda8261_config sd1878c_config = {
1160// .name = "SD1878/SHA",
1161 .addr = 0x60,
1162 .step_size = TDA8261_STEP_1000 /* kHz */
1163};
1164
885static u8 read_pwm(struct budget_av *budget_av) 1165static u8 read_pwm(struct budget_av *budget_av)
886{ 1166{
887 u8 b = 0xff; 1167 u8 b = 0xff;
@@ -905,8 +1185,11 @@ static u8 read_pwm(struct budget_av *budget_av)
905#define SUBID_DVBS_TV_STAR 0x0014 1185#define SUBID_DVBS_TV_STAR 0x0014
906#define SUBID_DVBS_TV_STAR_PLUS_X4 0x0015 1186#define SUBID_DVBS_TV_STAR_PLUS_X4 0x0015
907#define SUBID_DVBS_TV_STAR_CI 0x0016 1187#define SUBID_DVBS_TV_STAR_CI 0x0016
1188#define SUBID_DVBS2_KNC1 0x0018
1189#define SUBID_DVBS2_KNC1_OEM 0x0019
908#define SUBID_DVBS_EASYWATCH_1 0x001a 1190#define SUBID_DVBS_EASYWATCH_1 0x001a
909#define SUBID_DVBS_EASYWATCH_2 0x001b 1191#define SUBID_DVBS_EASYWATCH_2 0x001b
1192#define SUBID_DVBS2_EASYWATCH 0x001d
910#define SUBID_DVBS_EASYWATCH 0x001e 1193#define SUBID_DVBS_EASYWATCH 0x001e
911 1194
912#define SUBID_DVBC_EASYWATCH 0x002a 1195#define SUBID_DVBC_EASYWATCH 0x002a
@@ -941,6 +1224,9 @@ static void frontend_init(struct budget_av *budget_av)
941 case SUBID_DVBT_KNC1_PLUS: 1224 case SUBID_DVBT_KNC1_PLUS:
942 case SUBID_DVBC_EASYWATCH: 1225 case SUBID_DVBC_EASYWATCH:
943 case SUBID_DVBC_KNC1_PLUS_MK3: 1226 case SUBID_DVBC_KNC1_PLUS_MK3:
1227 case SUBID_DVBS2_KNC1:
1228 case SUBID_DVBS2_KNC1_OEM:
1229 case SUBID_DVBS2_EASYWATCH:
944 saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTHI); 1230 saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTHI);
945 break; 1231 break;
946 } 1232 }
@@ -993,7 +1279,14 @@ static void frontend_init(struct budget_av *budget_av)
993 fe->ops.tuner_ops.set_params = philips_su1278_ty_ci_tuner_set_params; 1279 fe->ops.tuner_ops.set_params = philips_su1278_ty_ci_tuner_set_params;
994 } 1280 }
995 break; 1281 break;
1282 case SUBID_DVBS2_KNC1:
1283 case SUBID_DVBS2_KNC1_OEM:
1284 case SUBID_DVBS2_EASYWATCH:
1285 budget_av->reinitialise_demod = 1;
1286 if ((fe = dvb_attach(stb0899_attach, &knc1_dvbs2_config, &budget_av->budget.i2c_adap)))
1287 dvb_attach(tda8261_attach, fe, &sd1878c_config, &budget_av->budget.i2c_adap);
996 1288
1289 break;
997 case SUBID_DVBS_CINERGY1200: 1290 case SUBID_DVBS_CINERGY1200:
998 fe = dvb_attach(stv0299_attach, &cinergy_1200s_config, 1291 fe = dvb_attach(stv0299_attach, &cinergy_1200s_config,
999 &budget_av->budget.i2c_adap); 1292 &budget_av->budget.i2c_adap);
@@ -1260,6 +1553,8 @@ static struct saa7146_ext_vv vv_data = {
1260static struct saa7146_extension budget_extension; 1553static struct saa7146_extension budget_extension;
1261 1554
1262MAKE_BUDGET_INFO(knc1s, "KNC1 DVB-S", BUDGET_KNC1S); 1555MAKE_BUDGET_INFO(knc1s, "KNC1 DVB-S", BUDGET_KNC1S);
1556MAKE_BUDGET_INFO(knc1s2,"KNC1 DVB-S2", BUDGET_KNC1S2);
1557MAKE_BUDGET_INFO(sates2,"Satelco EasyWatch DVB-S2", BUDGET_KNC1S2);
1263MAKE_BUDGET_INFO(knc1c, "KNC1 DVB-C", BUDGET_KNC1C); 1558MAKE_BUDGET_INFO(knc1c, "KNC1 DVB-C", BUDGET_KNC1C);
1264MAKE_BUDGET_INFO(knc1t, "KNC1 DVB-T", BUDGET_KNC1T); 1559MAKE_BUDGET_INFO(knc1t, "KNC1 DVB-T", BUDGET_KNC1T);
1265MAKE_BUDGET_INFO(kncxs, "KNC TV STAR DVB-S", BUDGET_TVSTAR); 1560MAKE_BUDGET_INFO(kncxs, "KNC TV STAR DVB-S", BUDGET_TVSTAR);
@@ -1290,6 +1585,9 @@ static struct pci_device_id pci_tbl[] = {
1290 MAKE_EXTENSION_PCI(kncxs, 0x1894, 0x0014), 1585 MAKE_EXTENSION_PCI(kncxs, 0x1894, 0x0014),
1291 MAKE_EXTENSION_PCI(knc1spx4, 0x1894, 0x0015), 1586 MAKE_EXTENSION_PCI(knc1spx4, 0x1894, 0x0015),
1292 MAKE_EXTENSION_PCI(kncxs, 0x1894, 0x0016), 1587 MAKE_EXTENSION_PCI(kncxs, 0x1894, 0x0016),
1588 MAKE_EXTENSION_PCI(knc1s2, 0x1894, 0x0018),
1589 MAKE_EXTENSION_PCI(knc1s2, 0x1894, 0x0019),
1590 MAKE_EXTENSION_PCI(sates2, 0x1894, 0x001d),
1293 MAKE_EXTENSION_PCI(satewpls, 0x1894, 0x001e), 1591 MAKE_EXTENSION_PCI(satewpls, 0x1894, 0x001e),
1294 MAKE_EXTENSION_PCI(satewpls1, 0x1894, 0x001a), 1592 MAKE_EXTENSION_PCI(satewpls1, 0x1894, 0x001a),
1295 MAKE_EXTENSION_PCI(satewps, 0x1894, 0x001b), 1593 MAKE_EXTENSION_PCI(satewps, 0x1894, 0x001b),
diff --git a/drivers/media/dvb/ttpci/budget-ci.c b/drivers/media/dvb/ttpci/budget-ci.c
index 0a5aad45435d..3507463fdac9 100644
--- a/drivers/media/dvb/ttpci/budget-ci.c
+++ b/drivers/media/dvb/ttpci/budget-ci.c
@@ -43,6 +43,11 @@
43#include "stv0299.h" 43#include "stv0299.h"
44#include "stv0297.h" 44#include "stv0297.h"
45#include "tda1004x.h" 45#include "tda1004x.h"
46#include "stb0899_drv.h"
47#include "stb0899_reg.h"
48#include "stb0899_cfg.h"
49#include "stb6100.h"
50#include "stb6100_cfg.h"
46#include "lnbp21.h" 51#include "lnbp21.h"
47#include "bsbe1.h" 52#include "bsbe1.h"
48#include "bsru6.h" 53#include "bsru6.h"
@@ -1071,7 +1076,271 @@ static struct tda10023_config tda10023_config = {
1071 .deltaf = 0xa511, 1076 .deltaf = 0xa511,
1072}; 1077};
1073 1078
1079/* TT S2-3200 DVB-S (STB0899) Inittab */
1080static const struct stb0899_s1_reg tt3200_stb0899_s1_init_1[] = {
1081
1082 { STB0899_DEV_ID , 0x81 },
1083 { STB0899_DISCNTRL1 , 0x32 },
1084 { STB0899_DISCNTRL2 , 0x80 },
1085 { STB0899_DISRX_ST0 , 0x04 },
1086 { STB0899_DISRX_ST1 , 0x00 },
1087 { STB0899_DISPARITY , 0x00 },
1088 { STB0899_DISFIFO , 0x00 },
1089 { STB0899_DISSTATUS , 0x20 },
1090 { STB0899_DISF22 , 0x8c },
1091 { STB0899_DISF22RX , 0x9a },
1092 { STB0899_SYSREG , 0x0b },
1093 { STB0899_ACRPRESC , 0x11 },
1094 { STB0899_ACRDIV1 , 0x0a },
1095 { STB0899_ACRDIV2 , 0x05 },
1096 { STB0899_DACR1 , 0x00 },
1097 { STB0899_DACR2 , 0x00 },
1098 { STB0899_OUTCFG , 0x00 },
1099 { STB0899_MODECFG , 0x00 },
1100 { STB0899_IRQSTATUS_3 , 0x30 },
1101 { STB0899_IRQSTATUS_2 , 0x00 },
1102 { STB0899_IRQSTATUS_1 , 0x00 },
1103 { STB0899_IRQSTATUS_0 , 0x00 },
1104 { STB0899_IRQMSK_3 , 0xf3 },
1105 { STB0899_IRQMSK_2 , 0xfc },
1106 { STB0899_IRQMSK_1 , 0xff },
1107 { STB0899_IRQMSK_0 , 0xff },
1108 { STB0899_IRQCFG , 0x00 },
1109 { STB0899_I2CCFG , 0x88 },
1110 { STB0899_I2CRPT , 0x48 }, /* 12k Pullup, Repeater=16, Stop=disabled */
1111 { STB0899_IOPVALUE5 , 0x00 },
1112 { STB0899_IOPVALUE4 , 0x20 },
1113 { STB0899_IOPVALUE3 , 0xc9 },
1114 { STB0899_IOPVALUE2 , 0x90 },
1115 { STB0899_IOPVALUE1 , 0x40 },
1116 { STB0899_IOPVALUE0 , 0x00 },
1117 { STB0899_GPIO00CFG , 0x82 },
1118 { STB0899_GPIO01CFG , 0x82 },
1119 { STB0899_GPIO02CFG , 0x82 },
1120 { STB0899_GPIO03CFG , 0x82 },
1121 { STB0899_GPIO04CFG , 0x82 },
1122 { STB0899_GPIO05CFG , 0x82 },
1123 { STB0899_GPIO06CFG , 0x82 },
1124 { STB0899_GPIO07CFG , 0x82 },
1125 { STB0899_GPIO08CFG , 0x82 },
1126 { STB0899_GPIO09CFG , 0x82 },
1127 { STB0899_GPIO10CFG , 0x82 },
1128 { STB0899_GPIO11CFG , 0x82 },
1129 { STB0899_GPIO12CFG , 0x82 },
1130 { STB0899_GPIO13CFG , 0x82 },
1131 { STB0899_GPIO14CFG , 0x82 },
1132 { STB0899_GPIO15CFG , 0x82 },
1133 { STB0899_GPIO16CFG , 0x82 },
1134 { STB0899_GPIO17CFG , 0x82 },
1135 { STB0899_GPIO18CFG , 0x82 },
1136 { STB0899_GPIO19CFG , 0x82 },
1137 { STB0899_GPIO20CFG , 0x82 },
1138 { STB0899_SDATCFG , 0xb8 },
1139 { STB0899_SCLTCFG , 0xba },
1140 { STB0899_AGCRFCFG , 0x1c }, /* 0x11 */
1141 { STB0899_GPIO22 , 0x82 }, /* AGCBB2CFG */
1142 { STB0899_GPIO21 , 0x91 }, /* AGCBB1CFG */
1143 { STB0899_DIRCLKCFG , 0x82 },
1144 { STB0899_CLKOUT27CFG , 0x7e },
1145 { STB0899_STDBYCFG , 0x82 },
1146 { STB0899_CS0CFG , 0x82 },
1147 { STB0899_CS1CFG , 0x82 },
1148 { STB0899_DISEQCOCFG , 0x20 },
1149 { STB0899_GPIO32CFG , 0x82 },
1150 { STB0899_GPIO33CFG , 0x82 },
1151 { STB0899_GPIO34CFG , 0x82 },
1152 { STB0899_GPIO35CFG , 0x82 },
1153 { STB0899_GPIO36CFG , 0x82 },
1154 { STB0899_GPIO37CFG , 0x82 },
1155 { STB0899_GPIO38CFG , 0x82 },
1156 { STB0899_GPIO39CFG , 0x82 },
1157 { STB0899_NCOARSE , 0x15 }, /* 0x15 = 27 Mhz Clock, F/3 = 198MHz, F/6 = 99MHz */
1158 { STB0899_SYNTCTRL , 0x02 }, /* 0x00 = CLK from CLKI, 0x02 = CLK from XTALI */
1159 { STB0899_FILTCTRL , 0x00 },
1160 { STB0899_SYSCTRL , 0x00 },
1161 { STB0899_STOPCLK1 , 0x20 },
1162 { STB0899_STOPCLK2 , 0x00 },
1163 { STB0899_INTBUFSTATUS , 0x00 },
1164 { STB0899_INTBUFCTRL , 0x0a },
1165 { 0xffff , 0xff },
1166};
1167
1168static const struct stb0899_s1_reg tt3200_stb0899_s1_init_3[] = {
1169 { STB0899_DEMOD , 0x00 },
1170 { STB0899_RCOMPC , 0xc9 },
1171 { STB0899_AGC1CN , 0x41 },
1172 { STB0899_AGC1REF , 0x10 },
1173 { STB0899_RTC , 0x7a },
1174 { STB0899_TMGCFG , 0x4e },
1175 { STB0899_AGC2REF , 0x34 },
1176 { STB0899_TLSR , 0x84 },
1177 { STB0899_CFD , 0xc7 },
1178 { STB0899_ACLC , 0x87 },
1179 { STB0899_BCLC , 0x94 },
1180 { STB0899_EQON , 0x41 },
1181 { STB0899_LDT , 0xdd },
1182 { STB0899_LDT2 , 0xc9 },
1183 { STB0899_EQUALREF , 0xb4 },
1184 { STB0899_TMGRAMP , 0x10 },
1185 { STB0899_TMGTHD , 0x30 },
1186 { STB0899_IDCCOMP , 0xfb },
1187 { STB0899_QDCCOMP , 0x03 },
1188 { STB0899_POWERI , 0x3b },
1189 { STB0899_POWERQ , 0x3d },
1190 { STB0899_RCOMP , 0x81 },
1191 { STB0899_AGCIQIN , 0x80 },
1192 { STB0899_AGC2I1 , 0x04 },
1193 { STB0899_AGC2I2 , 0xf5 },
1194 { STB0899_TLIR , 0x25 },
1195 { STB0899_RTF , 0x80 },
1196 { STB0899_DSTATUS , 0x00 },
1197 { STB0899_LDI , 0xca },
1198 { STB0899_CFRM , 0xf1 },
1199 { STB0899_CFRL , 0xf3 },
1200 { STB0899_NIRM , 0x2a },
1201 { STB0899_NIRL , 0x05 },
1202 { STB0899_ISYMB , 0x17 },
1203 { STB0899_QSYMB , 0xfa },
1204 { STB0899_SFRH , 0x2f },
1205 { STB0899_SFRM , 0x68 },
1206 { STB0899_SFRL , 0x40 },
1207 { STB0899_SFRUPH , 0x2f },
1208 { STB0899_SFRUPM , 0x68 },
1209 { STB0899_SFRUPL , 0x40 },
1210 { STB0899_EQUAI1 , 0xfd },
1211 { STB0899_EQUAQ1 , 0x04 },
1212 { STB0899_EQUAI2 , 0x0f },
1213 { STB0899_EQUAQ2 , 0xff },
1214 { STB0899_EQUAI3 , 0xdf },
1215 { STB0899_EQUAQ3 , 0xfa },
1216 { STB0899_EQUAI4 , 0x37 },
1217 { STB0899_EQUAQ4 , 0x0d },
1218 { STB0899_EQUAI5 , 0xbd },
1219 { STB0899_EQUAQ5 , 0xf7 },
1220 { STB0899_DSTATUS2 , 0x00 },
1221 { STB0899_VSTATUS , 0x00 },
1222 { STB0899_VERROR , 0xff },
1223 { STB0899_IQSWAP , 0x2a },
1224 { STB0899_ECNT1M , 0x00 },
1225 { STB0899_ECNT1L , 0x00 },
1226 { STB0899_ECNT2M , 0x00 },
1227 { STB0899_ECNT2L , 0x00 },
1228 { STB0899_ECNT3M , 0x00 },
1229 { STB0899_ECNT3L , 0x00 },
1230 { STB0899_FECAUTO1 , 0x06 },
1231 { STB0899_FECM , 0x01 },
1232 { STB0899_VTH12 , 0xf0 },
1233 { STB0899_VTH23 , 0xa0 },
1234 { STB0899_VTH34 , 0x78 },
1235 { STB0899_VTH56 , 0x4e },
1236 { STB0899_VTH67 , 0x48 },
1237 { STB0899_VTH78 , 0x38 },
1238 { STB0899_PRVIT , 0xff },
1239 { STB0899_VITSYNC , 0x19 },
1240 { STB0899_RSULC , 0xb1 }, /* DVB = 0xb1, DSS = 0xa1 */
1241 { STB0899_TSULC , 0x42 },
1242 { STB0899_RSLLC , 0x40 },
1243 { STB0899_TSLPL , 0x12 },
1244 { STB0899_TSCFGH , 0x0c },
1245 { STB0899_TSCFGM , 0x00 },
1246 { STB0899_TSCFGL , 0x0c },
1247 { STB0899_TSOUT , 0x0d }, /* 0x0d for CAM */
1248 { STB0899_RSSYNCDEL , 0x00 },
1249 { STB0899_TSINHDELH , 0x02 },
1250 { STB0899_TSINHDELM , 0x00 },
1251 { STB0899_TSINHDELL , 0x00 },
1252 { STB0899_TSLLSTKM , 0x00 },
1253 { STB0899_TSLLSTKL , 0x00 },
1254 { STB0899_TSULSTKM , 0x00 },
1255 { STB0899_TSULSTKL , 0xab },
1256 { STB0899_PCKLENUL , 0x00 },
1257 { STB0899_PCKLENLL , 0xcc },
1258 { STB0899_RSPCKLEN , 0xcc },
1259 { STB0899_TSSTATUS , 0x80 },
1260 { STB0899_ERRCTRL1 , 0xb6 },
1261 { STB0899_ERRCTRL2 , 0x96 },
1262 { STB0899_ERRCTRL3 , 0x89 },
1263 { STB0899_DMONMSK1 , 0x27 },
1264 { STB0899_DMONMSK0 , 0x03 },
1265 { STB0899_DEMAPVIT , 0x5c },
1266 { STB0899_PLPARM , 0x1f },
1267 { STB0899_PDELCTRL , 0x48 },
1268 { STB0899_PDELCTRL2 , 0x00 },
1269 { STB0899_BBHCTRL1 , 0x00 },
1270 { STB0899_BBHCTRL2 , 0x00 },
1271 { STB0899_HYSTTHRESH , 0x77 },
1272 { STB0899_MATCSTM , 0x00 },
1273 { STB0899_MATCSTL , 0x00 },
1274 { STB0899_UPLCSTM , 0x00 },
1275 { STB0899_UPLCSTL , 0x00 },
1276 { STB0899_DFLCSTM , 0x00 },
1277 { STB0899_DFLCSTL , 0x00 },
1278 { STB0899_SYNCCST , 0x00 },
1279 { STB0899_SYNCDCSTM , 0x00 },
1280 { STB0899_SYNCDCSTL , 0x00 },
1281 { STB0899_ISI_ENTRY , 0x00 },
1282 { STB0899_ISI_BIT_EN , 0x00 },
1283 { STB0899_MATSTRM , 0x00 },
1284 { STB0899_MATSTRL , 0x00 },
1285 { STB0899_UPLSTRM , 0x00 },
1286 { STB0899_UPLSTRL , 0x00 },
1287 { STB0899_DFLSTRM , 0x00 },
1288 { STB0899_DFLSTRL , 0x00 },
1289 { STB0899_SYNCSTR , 0x00 },
1290 { STB0899_SYNCDSTRM , 0x00 },
1291 { STB0899_SYNCDSTRL , 0x00 },
1292 { STB0899_CFGPDELSTATUS1 , 0x10 },
1293 { STB0899_CFGPDELSTATUS2 , 0x00 },
1294 { STB0899_BBFERRORM , 0x00 },
1295 { STB0899_BBFERRORL , 0x00 },
1296 { STB0899_UPKTERRORM , 0x00 },
1297 { STB0899_UPKTERRORL , 0x00 },
1298 { 0xffff , 0xff },
1299};
1074 1300
1301static struct stb0899_config tt3200_config = {
1302 .init_dev = tt3200_stb0899_s1_init_1,
1303 .init_s2_demod = stb0899_s2_init_2,
1304 .init_s1_demod = tt3200_stb0899_s1_init_3,
1305 .init_s2_fec = stb0899_s2_init_4,
1306 .init_tst = stb0899_s1_init_5,
1307
1308 .postproc = NULL,
1309
1310 .demod_address = 0x68,
1311
1312 .xtal_freq = 27000000,
1313 .inversion = IQ_SWAP_ON, /* 1 */
1314
1315 .lo_clk = 76500000,
1316 .hi_clk = 99000000,
1317
1318 .esno_ave = STB0899_DVBS2_ESNO_AVE,
1319 .esno_quant = STB0899_DVBS2_ESNO_QUANT,
1320 .avframes_coarse = STB0899_DVBS2_AVFRAMES_COARSE,
1321 .avframes_fine = STB0899_DVBS2_AVFRAMES_FINE,
1322 .miss_threshold = STB0899_DVBS2_MISS_THRESHOLD,
1323 .uwp_threshold_acq = STB0899_DVBS2_UWP_THRESHOLD_ACQ,
1324 .uwp_threshold_track = STB0899_DVBS2_UWP_THRESHOLD_TRACK,
1325 .uwp_threshold_sof = STB0899_DVBS2_UWP_THRESHOLD_SOF,
1326 .sof_search_timeout = STB0899_DVBS2_SOF_SEARCH_TIMEOUT,
1327
1328 .btr_nco_bits = STB0899_DVBS2_BTR_NCO_BITS,
1329 .btr_gain_shift_offset = STB0899_DVBS2_BTR_GAIN_SHIFT_OFFSET,
1330 .crl_nco_bits = STB0899_DVBS2_CRL_NCO_BITS,
1331 .ldpc_max_iter = STB0899_DVBS2_LDPC_MAX_ITER,
1332
1333 .tuner_get_frequency = stb6100_get_frequency,
1334 .tuner_set_frequency = stb6100_set_frequency,
1335 .tuner_set_bandwidth = stb6100_set_bandwidth,
1336 .tuner_get_bandwidth = stb6100_get_bandwidth,
1337 .tuner_set_rfsiggain = NULL
1338};
1339
1340struct stb6100_config tt3200_stb6100_config = {
1341 .tuner_address = 0x60,
1342 .refclock = 27000000,
1343};
1075 1344
1076static void frontend_init(struct budget_ci *budget_ci) 1345static void frontend_init(struct budget_ci *budget_ci)
1077{ 1346{
@@ -1152,6 +1421,46 @@ static void frontend_init(struct budget_ci *budget_ci)
1152 } 1421 }
1153 } 1422 }
1154 break; 1423 break;
1424
1425 case 0x1019: // TT S2-3200 PCI
1426 /*
1427 * NOTE! on some STB0899 versions, the internal PLL takes a longer time
1428 * to settle, aka LOCK. On the older revisions of the chip, we don't see
1429 * this, as a result on the newer chips the entire clock tree, will not
1430 * be stable after a freshly POWER 'ed up situation.
1431 * In this case, we should RESET the STB0899 (Active LOW) and wait for
1432 * PLL stabilization.
1433 *
1434 * On the TT S2 3200 and clones, the STB0899 demodulator's RESETB is
1435 * connected to the SAA7146 GPIO, GPIO2, Pin 142
1436 */
1437 /* Reset Demodulator */
1438 saa7146_setgpio(budget_ci->budget.dev, 2, SAA7146_GPIO_OUTLO);
1439 /* Wait for everything to die */
1440 msleep(50);
1441 /* Pull it up out of Reset state */
1442 saa7146_setgpio(budget_ci->budget.dev, 2, SAA7146_GPIO_OUTHI);
1443 /* Wait for PLL to stabilize */
1444 msleep(250);
1445 /*
1446 * PLL state should be stable now. Ideally, we should check
1447 * for PLL LOCK status. But well, never mind!
1448 */
1449 budget_ci->budget.dvb_frontend = dvb_attach(stb0899_attach, &tt3200_config, &budget_ci->budget.i2c_adap);
1450 if (budget_ci->budget.dvb_frontend) {
1451 if (dvb_attach(stb6100_attach, budget_ci->budget.dvb_frontend, &tt3200_stb6100_config, &budget_ci->budget.i2c_adap)) {
1452 if (!dvb_attach(lnbp21_attach, budget_ci->budget.dvb_frontend, &budget_ci->budget.i2c_adap, 0, 0)) {
1453 printk("%s: No LNBP21 found!\n", __FUNCTION__);
1454 dvb_frontend_detach(budget_ci->budget.dvb_frontend);
1455 budget_ci->budget.dvb_frontend = NULL;
1456 }
1457 } else {
1458 dvb_frontend_detach(budget_ci->budget.dvb_frontend);
1459 budget_ci->budget.dvb_frontend = NULL;
1460 }
1461 }
1462 break;
1463
1155 } 1464 }
1156 1465
1157 if (budget_ci->budget.dvb_frontend == NULL) { 1466 if (budget_ci->budget.dvb_frontend == NULL) {
@@ -1242,6 +1551,7 @@ MAKE_BUDGET_INFO(ttbt2, "TT-Budget/WinTV-NOVA-T PCI", BUDGET_TT);
1242MAKE_BUDGET_INFO(ttbtci, "TT-Budget-T-CI PCI", BUDGET_TT); 1551MAKE_BUDGET_INFO(ttbtci, "TT-Budget-T-CI PCI", BUDGET_TT);
1243MAKE_BUDGET_INFO(ttbcci, "TT-Budget-C-CI PCI", BUDGET_TT); 1552MAKE_BUDGET_INFO(ttbcci, "TT-Budget-C-CI PCI", BUDGET_TT);
1244MAKE_BUDGET_INFO(ttc1501, "TT-Budget C-1501 PCI", BUDGET_TT); 1553MAKE_BUDGET_INFO(ttc1501, "TT-Budget C-1501 PCI", BUDGET_TT);
1554MAKE_BUDGET_INFO(tt3200, "TT-Budget S2-3200 PCI", BUDGET_TT);
1245 1555
1246static struct pci_device_id pci_tbl[] = { 1556static struct pci_device_id pci_tbl[] = {
1247 MAKE_EXTENSION_PCI(ttbci, 0x13c2, 0x100c), 1557 MAKE_EXTENSION_PCI(ttbci, 0x13c2, 0x100c),
@@ -1251,6 +1561,7 @@ static struct pci_device_id pci_tbl[] = {
1251 MAKE_EXTENSION_PCI(ttbtci, 0x13c2, 0x1012), 1561 MAKE_EXTENSION_PCI(ttbtci, 0x13c2, 0x1012),
1252 MAKE_EXTENSION_PCI(ttbs2, 0x13c2, 0x1017), 1562 MAKE_EXTENSION_PCI(ttbs2, 0x13c2, 0x1017),
1253 MAKE_EXTENSION_PCI(ttc1501, 0x13c2, 0x101a), 1563 MAKE_EXTENSION_PCI(ttc1501, 0x13c2, 0x101a),
1564 MAKE_EXTENSION_PCI(tt3200, 0x13c2, 0x1019),
1254 { 1565 {
1255 .vendor = 0, 1566 .vendor = 0,
1256 } 1567 }
diff --git a/drivers/media/dvb/ttpci/budget.h b/drivers/media/dvb/ttpci/budget.h
index 86435bf16260..3ad0c6789ba7 100644
--- a/drivers/media/dvb/ttpci/budget.h
+++ b/drivers/media/dvb/ttpci/budget.h
@@ -103,6 +103,7 @@ static struct saa7146_pci_extension_data x_var = { \
103#define BUDGET_CIN1200C_MK3 15 103#define BUDGET_CIN1200C_MK3 15
104#define BUDGET_KNC1C_MK3 16 104#define BUDGET_KNC1C_MK3 16
105#define BUDGET_KNC1CP_MK3 17 105#define BUDGET_KNC1CP_MK3 17
106#define BUDGET_KNC1S2 18
106 107
107#define BUDGET_VIDEO_PORTA 0 108#define BUDGET_VIDEO_PORTA 0
108#define BUDGET_VIDEO_PORTB 1 109#define BUDGET_VIDEO_PORTB 1
diff --git a/drivers/media/radio/dsbr100.c b/drivers/media/radio/dsbr100.c
index a5ca176a7b08..5474a22c1b22 100644
--- a/drivers/media/radio/dsbr100.c
+++ b/drivers/media/radio/dsbr100.c
@@ -1,5 +1,5 @@
1/* A driver for the D-Link DSB-R100 USB radio. The R100 plugs 1/* A driver for the D-Link DSB-R100 USB radio and Gemtek USB Radio 21.
2 into both the USB and an analog audio input, so this thing 2 The device plugs into both the USB and an analog audio input, so this thing
3 only deals with initialisation and frequency setting, the 3 only deals with initialisation and frequency setting, the
4 audio data has to be handled by a sound driver. 4 audio data has to be handled by a sound driver.
5 5
@@ -33,6 +33,10 @@
33 33
34 History: 34 History:
35 35
36 Version 0.44:
37 Add suspend/resume functions, fix unplug of device,
38 a lot of cleanups and fixes by Alexey Klimov <klimov.linux@gmail.com>
39
36 Version 0.43: 40 Version 0.43:
37 Oliver Neukum: avoided DMA coherency issue 41 Oliver Neukum: avoided DMA coherency issue
38 42
@@ -93,8 +97,8 @@
93 */ 97 */
94#include <linux/version.h> /* for KERNEL_VERSION MACRO */ 98#include <linux/version.h> /* for KERNEL_VERSION MACRO */
95 99
96#define DRIVER_VERSION "v0.41" 100#define DRIVER_VERSION "v0.44"
97#define RADIO_VERSION KERNEL_VERSION(0,4,1) 101#define RADIO_VERSION KERNEL_VERSION(0, 4, 4)
98 102
99static struct v4l2_queryctrl radio_qctrl[] = { 103static struct v4l2_queryctrl radio_qctrl[] = {
100 { 104 {
@@ -104,7 +108,27 @@ static struct v4l2_queryctrl radio_qctrl[] = {
104 .maximum = 1, 108 .maximum = 1,
105 .default_value = 1, 109 .default_value = 1,
106 .type = V4L2_CTRL_TYPE_BOOLEAN, 110 .type = V4L2_CTRL_TYPE_BOOLEAN,
107 } 111 },
112/* HINT: the disabled controls are only here to satify kradio and such apps */
113 { .id = V4L2_CID_AUDIO_VOLUME,
114 .flags = V4L2_CTRL_FLAG_DISABLED,
115 },
116 {
117 .id = V4L2_CID_AUDIO_BALANCE,
118 .flags = V4L2_CTRL_FLAG_DISABLED,
119 },
120 {
121 .id = V4L2_CID_AUDIO_BASS,
122 .flags = V4L2_CTRL_FLAG_DISABLED,
123 },
124 {
125 .id = V4L2_CID_AUDIO_TREBLE,
126 .flags = V4L2_CTRL_FLAG_DISABLED,
127 },
128 {
129 .id = V4L2_CID_AUDIO_LOUDNESS,
130 .flags = V4L2_CTRL_FLAG_DISABLED,
131 },
108}; 132};
109 133
110#define DRIVER_AUTHOR "Markus Demleitner <msdemlei@tucana.harvard.edu>" 134#define DRIVER_AUTHOR "Markus Demleitner <msdemlei@tucana.harvard.edu>"
@@ -125,12 +149,16 @@ devices, that would be 76 and 91. */
125#define FREQ_MAX 108.0 149#define FREQ_MAX 108.0
126#define FREQ_MUL 16000 150#define FREQ_MUL 16000
127 151
152#define videodev_to_radio(d) container_of(d, struct dsbr100_device, videodev)
128 153
129static int usb_dsbr100_probe(struct usb_interface *intf, 154static int usb_dsbr100_probe(struct usb_interface *intf,
130 const struct usb_device_id *id); 155 const struct usb_device_id *id);
131static void usb_dsbr100_disconnect(struct usb_interface *intf); 156static void usb_dsbr100_disconnect(struct usb_interface *intf);
132static int usb_dsbr100_open(struct inode *inode, struct file *file); 157static int usb_dsbr100_open(struct inode *inode, struct file *file);
133static int usb_dsbr100_close(struct inode *inode, struct file *file); 158static int usb_dsbr100_close(struct inode *inode, struct file *file);
159static int usb_dsbr100_suspend(struct usb_interface *intf,
160 pm_message_t message);
161static int usb_dsbr100_resume(struct usb_interface *intf);
134 162
135static int radio_nr = -1; 163static int radio_nr = -1;
136module_param(radio_nr, int, 0); 164module_param(radio_nr, int, 0);
@@ -138,8 +166,9 @@ module_param(radio_nr, int, 0);
138/* Data for one (physical) device */ 166/* Data for one (physical) device */
139struct dsbr100_device { 167struct dsbr100_device {
140 struct usb_device *usbdev; 168 struct usb_device *usbdev;
141 struct video_device *videodev; 169 struct video_device videodev;
142 u8 *transfer_buffer; 170 u8 *transfer_buffer;
171 struct mutex lock; /* buffer locking */
143 int curfreq; 172 int curfreq;
144 int stereo; 173 int stereo;
145 int users; 174 int users;
@@ -147,7 +176,6 @@ struct dsbr100_device {
147 int muted; 176 int muted;
148}; 177};
149 178
150
151static struct usb_device_id usb_dsbr100_device_table [] = { 179static struct usb_device_id usb_dsbr100_device_table [] = {
152 { USB_DEVICE(DSB100_VENDOR, DSB100_PRODUCT) }, 180 { USB_DEVICE(DSB100_VENDOR, DSB100_PRODUCT) },
153 { } /* Terminating entry */ 181 { } /* Terminating entry */
@@ -157,10 +185,14 @@ MODULE_DEVICE_TABLE (usb, usb_dsbr100_device_table);
157 185
158/* USB subsystem interface */ 186/* USB subsystem interface */
159static struct usb_driver usb_dsbr100_driver = { 187static struct usb_driver usb_dsbr100_driver = {
160 .name = "dsbr100", 188 .name = "dsbr100",
161 .probe = usb_dsbr100_probe, 189 .probe = usb_dsbr100_probe,
162 .disconnect = usb_dsbr100_disconnect, 190 .disconnect = usb_dsbr100_disconnect,
163 .id_table = usb_dsbr100_device_table, 191 .id_table = usb_dsbr100_device_table,
192 .suspend = usb_dsbr100_suspend,
193 .resume = usb_dsbr100_resume,
194 .reset_resume = usb_dsbr100_resume,
195 .supports_autosuspend = 0,
164}; 196};
165 197
166/* Low-level device interface begins here */ 198/* Low-level device interface begins here */
@@ -168,95 +200,190 @@ static struct usb_driver usb_dsbr100_driver = {
168/* switch on radio */ 200/* switch on radio */
169static int dsbr100_start(struct dsbr100_device *radio) 201static int dsbr100_start(struct dsbr100_device *radio)
170{ 202{
171 if (usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0), 203 int retval;
172 USB_REQ_GET_STATUS, 204 int request;
173 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, 205
174 0x00, 0xC7, radio->transfer_buffer, 8, 300) < 0 || 206 mutex_lock(&radio->lock);
175 usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0), 207
176 DSB100_ONOFF, 208 retval = usb_control_msg(radio->usbdev,
177 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, 209 usb_rcvctrlpipe(radio->usbdev, 0),
178 0x01, 0x00, radio->transfer_buffer, 8, 300) < 0) 210 USB_REQ_GET_STATUS,
179 return -1; 211 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
180 radio->muted=0; 212 0x00, 0xC7, radio->transfer_buffer, 8, 300);
213
214 if (retval < 0) {
215 request = USB_REQ_GET_STATUS;
216 goto usb_control_msg_failed;
217 }
218
219 retval = usb_control_msg(radio->usbdev,
220 usb_rcvctrlpipe(radio->usbdev, 0),
221 DSB100_ONOFF,
222 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
223 0x01, 0x00, radio->transfer_buffer, 8, 300);
224
225 if (retval < 0) {
226 request = DSB100_ONOFF;
227 goto usb_control_msg_failed;
228 }
229
230 radio->muted = 0;
231 mutex_unlock(&radio->lock);
181 return (radio->transfer_buffer)[0]; 232 return (radio->transfer_buffer)[0];
182}
183 233
234usb_control_msg_failed:
235 mutex_unlock(&radio->lock);
236 dev_err(&radio->usbdev->dev,
237 "%s - usb_control_msg returned %i, request %i\n",
238 __func__, retval, request);
239 return retval;
240
241}
184 242
185/* switch off radio */ 243/* switch off radio */
186static int dsbr100_stop(struct dsbr100_device *radio) 244static int dsbr100_stop(struct dsbr100_device *radio)
187{ 245{
188 if (usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0), 246 int retval;
189 USB_REQ_GET_STATUS, 247 int request;
190 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, 248
191 0x16, 0x1C, radio->transfer_buffer, 8, 300) < 0 || 249 mutex_lock(&radio->lock);
192 usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0), 250
193 DSB100_ONOFF, 251 retval = usb_control_msg(radio->usbdev,
194 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, 252 usb_rcvctrlpipe(radio->usbdev, 0),
195 0x00, 0x00, radio->transfer_buffer, 8, 300) < 0) 253 USB_REQ_GET_STATUS,
196 return -1; 254 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
197 radio->muted=1; 255 0x16, 0x1C, radio->transfer_buffer, 8, 300);
256
257 if (retval < 0) {
258 request = USB_REQ_GET_STATUS;
259 goto usb_control_msg_failed;
260 }
261
262 retval = usb_control_msg(radio->usbdev,
263 usb_rcvctrlpipe(radio->usbdev, 0),
264 DSB100_ONOFF,
265 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
266 0x00, 0x00, radio->transfer_buffer, 8, 300);
267
268 if (retval < 0) {
269 request = DSB100_ONOFF;
270 goto usb_control_msg_failed;
271 }
272
273 radio->muted = 1;
274 mutex_unlock(&radio->lock);
198 return (radio->transfer_buffer)[0]; 275 return (radio->transfer_buffer)[0];
276
277usb_control_msg_failed:
278 mutex_unlock(&radio->lock);
279 dev_err(&radio->usbdev->dev,
280 "%s - usb_control_msg returned %i, request %i\n",
281 __func__, retval, request);
282 return retval;
283
199} 284}
200 285
201/* set a frequency, freq is defined by v4l's TUNER_LOW, i.e. 1/16th kHz */ 286/* set a frequency, freq is defined by v4l's TUNER_LOW, i.e. 1/16th kHz */
202static int dsbr100_setfreq(struct dsbr100_device *radio, int freq) 287static int dsbr100_setfreq(struct dsbr100_device *radio, int freq)
203{ 288{
289 int retval;
290 int request;
291
204 freq = (freq / 16 * 80) / 1000 + 856; 292 freq = (freq / 16 * 80) / 1000 + 856;
205 if (usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0), 293 mutex_lock(&radio->lock);
206 DSB100_TUNE, 294
207 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, 295 retval = usb_control_msg(radio->usbdev,
208 (freq >> 8) & 0x00ff, freq & 0xff, 296 usb_rcvctrlpipe(radio->usbdev, 0),
209 radio->transfer_buffer, 8, 300) < 0 || 297 DSB100_TUNE,
210 usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0), 298 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
211 USB_REQ_GET_STATUS, 299 (freq >> 8) & 0x00ff, freq & 0xff,
212 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, 300 radio->transfer_buffer, 8, 300);
213 0x96, 0xB7, radio->transfer_buffer, 8, 300) < 0 || 301
214 usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0), 302 if (retval < 0) {
215 USB_REQ_GET_STATUS, 303 request = DSB100_TUNE;
216 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, 304 goto usb_control_msg_failed;
217 0x00, 0x24, radio->transfer_buffer, 8, 300) < 0) {
218 radio->stereo = -1;
219 return -1;
220 } 305 }
306
307 retval = usb_control_msg(radio->usbdev,
308 usb_rcvctrlpipe(radio->usbdev, 0),
309 USB_REQ_GET_STATUS,
310 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
311 0x96, 0xB7, radio->transfer_buffer, 8, 300);
312
313 if (retval < 0) {
314 request = USB_REQ_GET_STATUS;
315 goto usb_control_msg_failed;
316 }
317
318 retval = usb_control_msg(radio->usbdev,
319 usb_rcvctrlpipe(radio->usbdev, 0),
320 USB_REQ_GET_STATUS,
321 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
322 0x00, 0x24, radio->transfer_buffer, 8, 300);
323
324 if (retval < 0) {
325 request = USB_REQ_GET_STATUS;
326 goto usb_control_msg_failed;
327 }
328
221 radio->stereo = !((radio->transfer_buffer)[0] & 0x01); 329 radio->stereo = !((radio->transfer_buffer)[0] & 0x01);
330 mutex_unlock(&radio->lock);
222 return (radio->transfer_buffer)[0]; 331 return (radio->transfer_buffer)[0];
332
333usb_control_msg_failed:
334 radio->stereo = -1;
335 mutex_unlock(&radio->lock);
336 dev_err(&radio->usbdev->dev,
337 "%s - usb_control_msg returned %i, request %i\n",
338 __func__, retval, request);
339 return retval;
223} 340}
224 341
225/* return the device status. This is, in effect, just whether it 342/* return the device status. This is, in effect, just whether it
226sees a stereo signal or not. Pity. */ 343sees a stereo signal or not. Pity. */
227static void dsbr100_getstat(struct dsbr100_device *radio) 344static void dsbr100_getstat(struct dsbr100_device *radio)
228{ 345{
229 if (usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0), 346 int retval;
347
348 mutex_lock(&radio->lock);
349
350 retval = usb_control_msg(radio->usbdev,
351 usb_rcvctrlpipe(radio->usbdev, 0),
230 USB_REQ_GET_STATUS, 352 USB_REQ_GET_STATUS,
231 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, 353 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
232 0x00 , 0x24, radio->transfer_buffer, 8, 300) < 0) 354 0x00 , 0x24, radio->transfer_buffer, 8, 300);
355
356 if (retval < 0) {
233 radio->stereo = -1; 357 radio->stereo = -1;
234 else 358 dev_err(&radio->usbdev->dev,
359 "%s - usb_control_msg returned %i, request %i\n",
360 __func__, retval, USB_REQ_GET_STATUS);
361 } else {
235 radio->stereo = !(radio->transfer_buffer[0] & 0x01); 362 radio->stereo = !(radio->transfer_buffer[0] & 0x01);
236} 363 }
237 364
365 mutex_unlock(&radio->lock);
366}
238 367
239/* USB subsystem interface begins here */ 368/* USB subsystem interface begins here */
240 369
241/* handle unplugging of the device, release data structures 370/*
242if nothing keeps us from doing it. If something is still 371 * Handle unplugging of the device.
243keeping us busy, the release callback of v4l will take care 372 * We call video_unregister_device in any case.
244of releasing it. */ 373 * The last function called in this procedure is
374 * usb_dsbr100_video_device_release
375 */
245static void usb_dsbr100_disconnect(struct usb_interface *intf) 376static void usb_dsbr100_disconnect(struct usb_interface *intf)
246{ 377{
247 struct dsbr100_device *radio = usb_get_intfdata(intf); 378 struct dsbr100_device *radio = usb_get_intfdata(intf);
248 379
249 usb_set_intfdata (intf, NULL); 380 usb_set_intfdata (intf, NULL);
250 if (radio) { 381
251 video_unregister_device(radio->videodev); 382 mutex_lock(&radio->lock);
252 radio->videodev = NULL; 383 radio->removed = 1;
253 if (radio->users) { 384 mutex_unlock(&radio->lock);
254 kfree(radio->transfer_buffer); 385
255 kfree(radio); 386 video_unregister_device(&radio->videodev);
256 } else {
257 radio->removed = 1;
258 }
259 }
260} 387}
261 388
262 389
@@ -276,6 +403,10 @@ static int vidioc_g_tuner(struct file *file, void *priv,
276{ 403{
277 struct dsbr100_device *radio = video_drvdata(file); 404 struct dsbr100_device *radio = video_drvdata(file);
278 405
406 /* safety check */
407 if (radio->removed)
408 return -EIO;
409
279 if (v->index > 0) 410 if (v->index > 0)
280 return -EINVAL; 411 return -EINVAL;
281 412
@@ -297,6 +428,12 @@ static int vidioc_g_tuner(struct file *file, void *priv,
297static int vidioc_s_tuner(struct file *file, void *priv, 428static int vidioc_s_tuner(struct file *file, void *priv,
298 struct v4l2_tuner *v) 429 struct v4l2_tuner *v)
299{ 430{
431 struct dsbr100_device *radio = video_drvdata(file);
432
433 /* safety check */
434 if (radio->removed)
435 return -EIO;
436
300 if (v->index > 0) 437 if (v->index > 0)
301 return -EINVAL; 438 return -EINVAL;
302 439
@@ -307,9 +444,15 @@ static int vidioc_s_frequency(struct file *file, void *priv,
307 struct v4l2_frequency *f) 444 struct v4l2_frequency *f)
308{ 445{
309 struct dsbr100_device *radio = video_drvdata(file); 446 struct dsbr100_device *radio = video_drvdata(file);
447 int retval;
448
449 /* safety check */
450 if (radio->removed)
451 return -EIO;
310 452
311 radio->curfreq = f->frequency; 453 radio->curfreq = f->frequency;
312 if (dsbr100_setfreq(radio, radio->curfreq) == -1) 454 retval = dsbr100_setfreq(radio, radio->curfreq);
455 if (retval < 0)
313 dev_warn(&radio->usbdev->dev, "Set frequency failed\n"); 456 dev_warn(&radio->usbdev->dev, "Set frequency failed\n");
314 return 0; 457 return 0;
315} 458}
@@ -319,6 +462,10 @@ static int vidioc_g_frequency(struct file *file, void *priv,
319{ 462{
320 struct dsbr100_device *radio = video_drvdata(file); 463 struct dsbr100_device *radio = video_drvdata(file);
321 464
465 /* safety check */
466 if (radio->removed)
467 return -EIO;
468
322 f->type = V4L2_TUNER_RADIO; 469 f->type = V4L2_TUNER_RADIO;
323 f->frequency = radio->curfreq; 470 f->frequency = radio->curfreq;
324 return 0; 471 return 0;
@@ -343,6 +490,10 @@ static int vidioc_g_ctrl(struct file *file, void *priv,
343{ 490{
344 struct dsbr100_device *radio = video_drvdata(file); 491 struct dsbr100_device *radio = video_drvdata(file);
345 492
493 /* safety check */
494 if (radio->removed)
495 return -EIO;
496
346 switch (ctrl->id) { 497 switch (ctrl->id) {
347 case V4L2_CID_AUDIO_MUTE: 498 case V4L2_CID_AUDIO_MUTE:
348 ctrl->value = radio->muted; 499 ctrl->value = radio->muted;
@@ -355,17 +506,24 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
355 struct v4l2_control *ctrl) 506 struct v4l2_control *ctrl)
356{ 507{
357 struct dsbr100_device *radio = video_drvdata(file); 508 struct dsbr100_device *radio = video_drvdata(file);
509 int retval;
510
511 /* safety check */
512 if (radio->removed)
513 return -EIO;
358 514
359 switch (ctrl->id) { 515 switch (ctrl->id) {
360 case V4L2_CID_AUDIO_MUTE: 516 case V4L2_CID_AUDIO_MUTE:
361 if (ctrl->value) { 517 if (ctrl->value) {
362 if (dsbr100_stop(radio) == -1) { 518 retval = dsbr100_stop(radio);
519 if (retval < 0) {
363 dev_warn(&radio->usbdev->dev, 520 dev_warn(&radio->usbdev->dev,
364 "Radio did not respond properly\n"); 521 "Radio did not respond properly\n");
365 return -EBUSY; 522 return -EBUSY;
366 } 523 }
367 } else { 524 } else {
368 if (dsbr100_start(radio) == -1) { 525 retval = dsbr100_start(radio);
526 if (retval < 0) {
369 dev_warn(&radio->usbdev->dev, 527 dev_warn(&radio->usbdev->dev,
370 "Radio did not respond properly\n"); 528 "Radio did not respond properly\n");
371 return -EBUSY; 529 return -EBUSY;
@@ -417,7 +575,8 @@ static int usb_dsbr100_open(struct inode *inode, struct file *file)
417 radio->users = 1; 575 radio->users = 1;
418 radio->muted = 1; 576 radio->muted = 1;
419 577
420 if (dsbr100_start(radio) < 0) { 578 retval = dsbr100_start(radio);
579 if (retval < 0) {
421 dev_warn(&radio->usbdev->dev, 580 dev_warn(&radio->usbdev->dev,
422 "Radio did not start up properly\n"); 581 "Radio did not start up properly\n");
423 radio->users = 0; 582 radio->users = 0;
@@ -426,9 +585,9 @@ static int usb_dsbr100_open(struct inode *inode, struct file *file)
426 } 585 }
427 586
428 retval = dsbr100_setfreq(radio, radio->curfreq); 587 retval = dsbr100_setfreq(radio, radio->curfreq);
429 588 if (retval < 0)
430 if (retval == -1) 589 dev_warn(&radio->usbdev->dev,
431 printk(KERN_WARNING KBUILD_MODNAME ": Set frequency failed\n"); 590 "set frequency failed\n");
432 591
433 unlock_kernel(); 592 unlock_kernel();
434 return 0; 593 return 0;
@@ -437,17 +596,62 @@ static int usb_dsbr100_open(struct inode *inode, struct file *file)
437static int usb_dsbr100_close(struct inode *inode, struct file *file) 596static int usb_dsbr100_close(struct inode *inode, struct file *file)
438{ 597{
439 struct dsbr100_device *radio = video_drvdata(file); 598 struct dsbr100_device *radio = video_drvdata(file);
599 int retval;
440 600
441 if (!radio) 601 if (!radio)
442 return -ENODEV; 602 return -ENODEV;
603
443 radio->users = 0; 604 radio->users = 0;
444 if (radio->removed) { 605 if (!radio->removed) {
445 kfree(radio->transfer_buffer); 606 retval = dsbr100_stop(radio);
446 kfree(radio); 607 if (retval < 0) {
608 dev_warn(&radio->usbdev->dev,
609 "dsbr100_stop failed\n");
610 }
611
447 } 612 }
448 return 0; 613 return 0;
449} 614}
450 615
616/* Suspend device - stop device. */
617static int usb_dsbr100_suspend(struct usb_interface *intf, pm_message_t message)
618{
619 struct dsbr100_device *radio = usb_get_intfdata(intf);
620 int retval;
621
622 retval = dsbr100_stop(radio);
623 if (retval < 0)
624 dev_warn(&intf->dev, "dsbr100_stop failed\n");
625
626 dev_info(&intf->dev, "going into suspend..\n");
627
628 return 0;
629}
630
631/* Resume device - start device. */
632static int usb_dsbr100_resume(struct usb_interface *intf)
633{
634 struct dsbr100_device *radio = usb_get_intfdata(intf);
635 int retval;
636
637 retval = dsbr100_start(radio);
638 if (retval < 0)
639 dev_warn(&intf->dev, "dsbr100_start failed\n");
640
641 dev_info(&intf->dev, "coming out of suspend..\n");
642
643 return 0;
644}
645
646/* free data structures */
647static void usb_dsbr100_video_device_release(struct video_device *videodev)
648{
649 struct dsbr100_device *radio = videodev_to_radio(videodev);
650
651 kfree(radio->transfer_buffer);
652 kfree(radio);
653}
654
451/* File system interface */ 655/* File system interface */
452static const struct file_operations usb_dsbr100_fops = { 656static const struct file_operations usb_dsbr100_fops = {
453 .owner = THIS_MODULE, 657 .owner = THIS_MODULE,
@@ -476,19 +680,19 @@ static const struct v4l2_ioctl_ops usb_dsbr100_ioctl_ops = {
476}; 680};
477 681
478/* V4L2 interface */ 682/* V4L2 interface */
479static struct video_device dsbr100_videodev_template = { 683static struct video_device dsbr100_videodev_data = {
480 .name = "D-Link DSB-R 100", 684 .name = "D-Link DSB-R 100",
481 .fops = &usb_dsbr100_fops, 685 .fops = &usb_dsbr100_fops,
482 .ioctl_ops = &usb_dsbr100_ioctl_ops, 686 .ioctl_ops = &usb_dsbr100_ioctl_ops,
483 .release = video_device_release, 687 .release = usb_dsbr100_video_device_release,
484}; 688};
485 689
486/* check if the device is present and register with v4l and 690/* check if the device is present and register with v4l and usb if it is */
487usb if it is */
488static int usb_dsbr100_probe(struct usb_interface *intf, 691static int usb_dsbr100_probe(struct usb_interface *intf,
489 const struct usb_device_id *id) 692 const struct usb_device_id *id)
490{ 693{
491 struct dsbr100_device *radio; 694 struct dsbr100_device *radio;
695 int retval;
492 696
493 radio = kmalloc(sizeof(struct dsbr100_device), GFP_KERNEL); 697 radio = kmalloc(sizeof(struct dsbr100_device), GFP_KERNEL);
494 698
@@ -501,23 +705,18 @@ static int usb_dsbr100_probe(struct usb_interface *intf,
501 kfree(radio); 705 kfree(radio);
502 return -ENOMEM; 706 return -ENOMEM;
503 } 707 }
504 radio->videodev = video_device_alloc();
505 708
506 if (!(radio->videodev)) { 709 mutex_init(&radio->lock);
507 kfree(radio->transfer_buffer); 710 radio->videodev = dsbr100_videodev_data;
508 kfree(radio); 711
509 return -ENOMEM;
510 }
511 memcpy(radio->videodev, &dsbr100_videodev_template,
512 sizeof(dsbr100_videodev_template));
513 radio->removed = 0; 712 radio->removed = 0;
514 radio->users = 0; 713 radio->users = 0;
515 radio->usbdev = interface_to_usbdev(intf); 714 radio->usbdev = interface_to_usbdev(intf);
516 radio->curfreq = FREQ_MIN * FREQ_MUL; 715 radio->curfreq = FREQ_MIN * FREQ_MUL;
517 video_set_drvdata(radio->videodev, radio); 716 video_set_drvdata(&radio->videodev, radio);
518 if (video_register_device(radio->videodev, VFL_TYPE_RADIO, radio_nr) < 0) { 717 retval = video_register_device(&radio->videodev, VFL_TYPE_RADIO, radio_nr);
519 dev_warn(&intf->dev, "Could not register video device\n"); 718 if (retval < 0) {
520 video_device_release(radio->videodev); 719 dev_err(&intf->dev, "couldn't register video device\n");
521 kfree(radio->transfer_buffer); 720 kfree(radio->transfer_buffer);
522 kfree(radio); 721 kfree(radio);
523 return -EIO; 722 return -EIO;
diff --git a/drivers/media/radio/radio-aimslab.c b/drivers/media/radio/radio-aimslab.c
index 9305e958fc66..dd6d3dfcd7d2 100644
--- a/drivers/media/radio/radio-aimslab.c
+++ b/drivers/media/radio/radio-aimslab.c
@@ -1,7 +1,7 @@
1/* radiotrack (radioreveal) driver for Linux radio support 1/* radiotrack (radioreveal) driver for Linux radio support
2 * (c) 1997 M. Kirkwood 2 * (c) 1997 M. Kirkwood
3 * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@infradead.org> 3 * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@infradead.org>
4 * Converted to new API by Alan Cox <Alan.Cox@linux.org> 4 * Converted to new API by Alan Cox <alan@lxorguk.ukuu.org.uk>
5 * Various bugfixes and enhancements by Russell Kroll <rkroll@exploits.org> 5 * Various bugfixes and enhancements by Russell Kroll <rkroll@exploits.org>
6 * 6 *
7 * History: 7 * History:
diff --git a/drivers/media/radio/radio-cadet.c b/drivers/media/radio/radio-cadet.c
index 0490a1fa999d..bfd37f38b9ab 100644
--- a/drivers/media/radio/radio-cadet.c
+++ b/drivers/media/radio/radio-cadet.c
@@ -23,7 +23,7 @@
23 * 2002-01-17 Adam Belay <ambx1@neo.rr.com> 23 * 2002-01-17 Adam Belay <ambx1@neo.rr.com>
24 * Updated to latest pnp code 24 * Updated to latest pnp code
25 * 25 *
26 * 2003-01-31 Alan Cox <alan@redhat.com> 26 * 2003-01-31 Alan Cox <alan@lxorguk.ukuu.org.uk>
27 * Cleaned up locking, delay code, general odds and ends 27 * Cleaned up locking, delay code, general odds and ends
28 * 28 *
29 * 2006-07-30 Hans J. Koch <koch@hjk-az.de> 29 * 2006-07-30 Hans J. Koch <koch@hjk-az.de>
diff --git a/drivers/media/radio/radio-gemtek.c b/drivers/media/radio/radio-gemtek.c
index d131a5d38128..e13118da307b 100644
--- a/drivers/media/radio/radio-gemtek.c
+++ b/drivers/media/radio/radio-gemtek.c
@@ -8,7 +8,7 @@
8 * RadioTrack II driver for Linux radio support (C) 1998 Ben Pfaff 8 * RadioTrack II driver for Linux radio support (C) 1998 Ben Pfaff
9 * 9 *
10 * Based on RadioTrack I/RadioReveal (C) 1997 M. Kirkwood 10 * Based on RadioTrack I/RadioReveal (C) 1997 M. Kirkwood
11 * Converted to new API by Alan Cox <Alan.Cox@linux.org> 11 * Converted to new API by Alan Cox <alan@lxorguk.ukuu.org.uk>
12 * Various bugfixes and enhancements by Russell Kroll <rkroll@exploits.org> 12 * Various bugfixes and enhancements by Russell Kroll <rkroll@exploits.org>
13 * 13 *
14 * TODO: Allow for more than one of these foolish entities :-) 14 * TODO: Allow for more than one of these foolish entities :-)
diff --git a/drivers/media/radio/radio-mr800.c b/drivers/media/radio/radio-mr800.c
index 256cbeffdcb6..e730eddb2bb5 100644
--- a/drivers/media/radio/radio-mr800.c
+++ b/drivers/media/radio/radio-mr800.c
@@ -72,6 +72,11 @@ MODULE_LICENSE("GPL");
72#define USB_AMRADIO_VENDOR 0x07ca 72#define USB_AMRADIO_VENDOR 0x07ca
73#define USB_AMRADIO_PRODUCT 0xb800 73#define USB_AMRADIO_PRODUCT 0xb800
74 74
75/* dev_warn macro with driver name */
76#define MR800_DRIVER_NAME "radio-mr800"
77#define amradio_dev_warn(dev, fmt, arg...) \
78 dev_warn(dev, MR800_DRIVER_NAME " - " fmt, ##arg)
79
75/* Probably USB_TIMEOUT should be modified in module parameter */ 80/* Probably USB_TIMEOUT should be modified in module parameter */
76#define BUFFER_LENGTH 8 81#define BUFFER_LENGTH 8
77#define USB_TIMEOUT 500 82#define USB_TIMEOUT 500
@@ -154,14 +159,14 @@ MODULE_DEVICE_TABLE(usb, usb_amradio_device_table);
154 159
155/* USB subsystem interface */ 160/* USB subsystem interface */
156static struct usb_driver usb_amradio_driver = { 161static struct usb_driver usb_amradio_driver = {
157 .name = "radio-mr800", 162 .name = MR800_DRIVER_NAME,
158 .probe = usb_amradio_probe, 163 .probe = usb_amradio_probe,
159 .disconnect = usb_amradio_disconnect, 164 .disconnect = usb_amradio_disconnect,
160 .suspend = usb_amradio_suspend, 165 .suspend = usb_amradio_suspend,
161 .resume = usb_amradio_resume, 166 .resume = usb_amradio_resume,
162 .reset_resume = usb_amradio_resume, 167 .reset_resume = usb_amradio_resume,
163 .id_table = usb_amradio_device_table, 168 .id_table = usb_amradio_device_table,
164 .supports_autosuspend = 1, 169 .supports_autosuspend = 0,
165}; 170};
166 171
167/* switch on radio. Send 8 bytes to device. */ 172/* switch on radio. Send 8 bytes to device. */
@@ -202,6 +207,10 @@ static int amradio_stop(struct amradio_device *radio)
202 int retval; 207 int retval;
203 int size; 208 int size;
204 209
210 /* safety check */
211 if (radio->removed)
212 return -EIO;
213
205 mutex_lock(&radio->lock); 214 mutex_lock(&radio->lock);
206 215
207 radio->buffer[0] = 0x00; 216 radio->buffer[0] = 0x00;
@@ -235,6 +244,10 @@ static int amradio_setfreq(struct amradio_device *radio, int freq)
235 int size; 244 int size;
236 unsigned short freq_send = 0x13 + (freq >> 3) / 25; 245 unsigned short freq_send = 0x13 + (freq >> 3) / 25;
237 246
247 /* safety check */
248 if (radio->removed)
249 return -EIO;
250
238 mutex_lock(&radio->lock); 251 mutex_lock(&radio->lock);
239 252
240 radio->buffer[0] = 0x00; 253 radio->buffer[0] = 0x00;
@@ -288,18 +301,12 @@ static void usb_amradio_disconnect(struct usb_interface *intf)
288{ 301{
289 struct amradio_device *radio = usb_get_intfdata(intf); 302 struct amradio_device *radio = usb_get_intfdata(intf);
290 303
291 usb_set_intfdata(intf, NULL); 304 mutex_lock(&radio->lock);
305 radio->removed = 1;
306 mutex_unlock(&radio->lock);
292 307
293 if (radio) { 308 usb_set_intfdata(intf, NULL);
294 video_unregister_device(radio->videodev); 309 video_unregister_device(radio->videodev);
295 radio->videodev = NULL;
296 if (radio->users) {
297 kfree(radio->buffer);
298 kfree(radio);
299 } else {
300 radio->removed = 1;
301 }
302 }
303} 310}
304 311
305/* vidioc_querycap - query device capabilities */ 312/* vidioc_querycap - query device capabilities */
@@ -320,6 +327,10 @@ static int vidioc_g_tuner(struct file *file, void *priv,
320{ 327{
321 struct amradio_device *radio = video_get_drvdata(video_devdata(file)); 328 struct amradio_device *radio = video_get_drvdata(video_devdata(file));
322 329
330 /* safety check */
331 if (radio->removed)
332 return -EIO;
333
323 if (v->index > 0) 334 if (v->index > 0)
324 return -EINVAL; 335 return -EINVAL;
325 336
@@ -346,6 +357,12 @@ static int vidioc_g_tuner(struct file *file, void *priv,
346static int vidioc_s_tuner(struct file *file, void *priv, 357static int vidioc_s_tuner(struct file *file, void *priv,
347 struct v4l2_tuner *v) 358 struct v4l2_tuner *v)
348{ 359{
360 struct amradio_device *radio = video_get_drvdata(video_devdata(file));
361
362 /* safety check */
363 if (radio->removed)
364 return -EIO;
365
349 if (v->index > 0) 366 if (v->index > 0)
350 return -EINVAL; 367 return -EINVAL;
351 return 0; 368 return 0;
@@ -357,9 +374,14 @@ static int vidioc_s_frequency(struct file *file, void *priv,
357{ 374{
358 struct amradio_device *radio = video_get_drvdata(video_devdata(file)); 375 struct amradio_device *radio = video_get_drvdata(video_devdata(file));
359 376
377 /* safety check */
378 if (radio->removed)
379 return -EIO;
380
360 radio->curfreq = f->frequency; 381 radio->curfreq = f->frequency;
361 if (amradio_setfreq(radio, radio->curfreq) < 0) 382 if (amradio_setfreq(radio, radio->curfreq) < 0)
362 warn("Set frequency failed"); 383 amradio_dev_warn(&radio->videodev->dev,
384 "set frequency failed\n");
363 return 0; 385 return 0;
364} 386}
365 387
@@ -369,6 +391,10 @@ static int vidioc_g_frequency(struct file *file, void *priv,
369{ 391{
370 struct amradio_device *radio = video_get_drvdata(video_devdata(file)); 392 struct amradio_device *radio = video_get_drvdata(video_devdata(file));
371 393
394 /* safety check */
395 if (radio->removed)
396 return -EIO;
397
372 f->type = V4L2_TUNER_RADIO; 398 f->type = V4L2_TUNER_RADIO;
373 f->frequency = radio->curfreq; 399 f->frequency = radio->curfreq;
374 return 0; 400 return 0;
@@ -382,8 +408,7 @@ static int vidioc_queryctrl(struct file *file, void *priv,
382 408
383 for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) { 409 for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
384 if (qc->id && qc->id == radio_qctrl[i].id) { 410 if (qc->id && qc->id == radio_qctrl[i].id) {
385 memcpy(qc, &(radio_qctrl[i]), 411 memcpy(qc, &(radio_qctrl[i]), sizeof(*qc));
386 sizeof(*qc));
387 return 0; 412 return 0;
388 } 413 }
389 } 414 }
@@ -396,6 +421,10 @@ static int vidioc_g_ctrl(struct file *file, void *priv,
396{ 421{
397 struct amradio_device *radio = video_get_drvdata(video_devdata(file)); 422 struct amradio_device *radio = video_get_drvdata(video_devdata(file));
398 423
424 /* safety check */
425 if (radio->removed)
426 return -EIO;
427
399 switch (ctrl->id) { 428 switch (ctrl->id) {
400 case V4L2_CID_AUDIO_MUTE: 429 case V4L2_CID_AUDIO_MUTE:
401 ctrl->value = radio->muted; 430 ctrl->value = radio->muted;
@@ -410,16 +439,22 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
410{ 439{
411 struct amradio_device *radio = video_get_drvdata(video_devdata(file)); 440 struct amradio_device *radio = video_get_drvdata(video_devdata(file));
412 441
442 /* safety check */
443 if (radio->removed)
444 return -EIO;
445
413 switch (ctrl->id) { 446 switch (ctrl->id) {
414 case V4L2_CID_AUDIO_MUTE: 447 case V4L2_CID_AUDIO_MUTE:
415 if (ctrl->value) { 448 if (ctrl->value) {
416 if (amradio_stop(radio) < 0) { 449 if (amradio_stop(radio) < 0) {
417 warn("amradio_stop() failed"); 450 amradio_dev_warn(&radio->videodev->dev,
451 "amradio_stop failed\n");
418 return -1; 452 return -1;
419 } 453 }
420 } else { 454 } else {
421 if (amradio_start(radio) < 0) { 455 if (amradio_start(radio) < 0) {
422 warn("amradio_start() failed"); 456 amradio_dev_warn(&radio->videodev->dev,
457 "amradio_start failed\n");
423 return -1; 458 return -1;
424 } 459 }
425 } 460 }
@@ -475,30 +510,38 @@ static int usb_amradio_open(struct inode *inode, struct file *file)
475 radio->muted = 1; 510 radio->muted = 1;
476 511
477 if (amradio_start(radio) < 0) { 512 if (amradio_start(radio) < 0) {
478 warn("Radio did not start up properly"); 513 amradio_dev_warn(&radio->videodev->dev,
514 "radio did not start up properly\n");
479 radio->users = 0; 515 radio->users = 0;
480 unlock_kernel(); 516 unlock_kernel();
481 return -EIO; 517 return -EIO;
482 } 518 }
483 if (amradio_setfreq(radio, radio->curfreq) < 0) 519 if (amradio_setfreq(radio, radio->curfreq) < 0)
484 warn("Set frequency failed"); 520 amradio_dev_warn(&radio->videodev->dev,
521 "set frequency failed\n");
485 522
486 unlock_kernel(); 523 unlock_kernel();
487 return 0; 524 return 0;
488} 525}
489 526
490/*close device - free driver structures */ 527/*close device */
491static int usb_amradio_close(struct inode *inode, struct file *file) 528static int usb_amradio_close(struct inode *inode, struct file *file)
492{ 529{
493 struct amradio_device *radio = video_get_drvdata(video_devdata(file)); 530 struct amradio_device *radio = video_get_drvdata(video_devdata(file));
531 int retval;
494 532
495 if (!radio) 533 if (!radio)
496 return -ENODEV; 534 return -ENODEV;
535
497 radio->users = 0; 536 radio->users = 0;
498 if (radio->removed) { 537
499 kfree(radio->buffer); 538 if (!radio->removed) {
500 kfree(radio); 539 retval = amradio_stop(radio);
540 if (retval < 0)
541 amradio_dev_warn(&radio->videodev->dev,
542 "amradio_stop failed\n");
501 } 543 }
544
502 return 0; 545 return 0;
503} 546}
504 547
@@ -508,9 +551,9 @@ static int usb_amradio_suspend(struct usb_interface *intf, pm_message_t message)
508 struct amradio_device *radio = usb_get_intfdata(intf); 551 struct amradio_device *radio = usb_get_intfdata(intf);
509 552
510 if (amradio_stop(radio) < 0) 553 if (amradio_stop(radio) < 0)
511 warn("amradio_stop() failed"); 554 dev_warn(&intf->dev, "amradio_stop failed\n");
512 555
513 info("radio-mr800: Going into suspend.."); 556 dev_info(&intf->dev, "going into suspend..\n");
514 557
515 return 0; 558 return 0;
516} 559}
@@ -521,9 +564,9 @@ static int usb_amradio_resume(struct usb_interface *intf)
521 struct amradio_device *radio = usb_get_intfdata(intf); 564 struct amradio_device *radio = usb_get_intfdata(intf);
522 565
523 if (amradio_start(radio) < 0) 566 if (amradio_start(radio) < 0)
524 warn("amradio_start() failed"); 567 dev_warn(&intf->dev, "amradio_start failed\n");
525 568
526 info("radio-mr800: Coming out of suspend.."); 569 dev_info(&intf->dev, "coming out of suspend..\n");
527 570
528 return 0; 571 return 0;
529} 572}
@@ -555,12 +598,24 @@ static const struct v4l2_ioctl_ops usb_amradio_ioctl_ops = {
555 .vidioc_s_input = vidioc_s_input, 598 .vidioc_s_input = vidioc_s_input,
556}; 599};
557 600
601static void usb_amradio_device_release(struct video_device *videodev)
602{
603 struct amradio_device *radio = video_get_drvdata(videodev);
604
605 /* we call v4l to free radio->videodev */
606 video_device_release(videodev);
607
608 /* free rest memory */
609 kfree(radio->buffer);
610 kfree(radio);
611}
612
558/* V4L2 interface */ 613/* V4L2 interface */
559static struct video_device amradio_videodev_template = { 614static struct video_device amradio_videodev_template = {
560 .name = "AverMedia MR 800 USB FM Radio", 615 .name = "AverMedia MR 800 USB FM Radio",
561 .fops = &usb_amradio_fops, 616 .fops = &usb_amradio_fops,
562 .ioctl_ops = &usb_amradio_ioctl_ops, 617 .ioctl_ops = &usb_amradio_ioctl_ops,
563 .release = video_device_release, 618 .release = usb_amradio_device_release,
564}; 619};
565 620
566/* check if the device is present and register with v4l and 621/* check if the device is present and register with v4l and
@@ -602,7 +657,7 @@ static int usb_amradio_probe(struct usb_interface *intf,
602 657
603 video_set_drvdata(radio->videodev, radio); 658 video_set_drvdata(radio->videodev, radio);
604 if (video_register_device(radio->videodev, VFL_TYPE_RADIO, radio_nr)) { 659 if (video_register_device(radio->videodev, VFL_TYPE_RADIO, radio_nr)) {
605 warn("Could not register video device"); 660 dev_warn(&intf->dev, "could not register video device\n");
606 video_device_release(radio->videodev); 661 video_device_release(radio->videodev);
607 kfree(radio->buffer); 662 kfree(radio->buffer);
608 kfree(radio); 663 kfree(radio);
@@ -617,9 +672,13 @@ static int __init amradio_init(void)
617{ 672{
618 int retval = usb_register(&usb_amradio_driver); 673 int retval = usb_register(&usb_amradio_driver);
619 674
620 info(DRIVER_VERSION " " DRIVER_DESC); 675 pr_info(KBUILD_MODNAME
676 ": version " DRIVER_VERSION " " DRIVER_DESC "\n");
677
621 if (retval) 678 if (retval)
622 err("usb_register failed. Error number %d", retval); 679 pr_err(KBUILD_MODNAME
680 ": usb_register failed. Error number %d\n", retval);
681
623 return retval; 682 return retval;
624} 683}
625 684
diff --git a/drivers/media/radio/radio-rtrack2.c b/drivers/media/radio/radio-rtrack2.c
index a67079777419..7704f243b6f0 100644
--- a/drivers/media/radio/radio-rtrack2.c
+++ b/drivers/media/radio/radio-rtrack2.c
@@ -1,7 +1,7 @@
1/* RadioTrack II driver for Linux radio support (C) 1998 Ben Pfaff 1/* RadioTrack II driver for Linux radio support (C) 1998 Ben Pfaff
2 * 2 *
3 * Based on RadioTrack I/RadioReveal (C) 1997 M. Kirkwood 3 * Based on RadioTrack I/RadioReveal (C) 1997 M. Kirkwood
4 * Converted to new API by Alan Cox <Alan.Cox@linux.org> 4 * Converted to new API by Alan Cox <alan@lxorguk.ukuu.org.uk>
5 * Various bugfixes and enhancements by Russell Kroll <rkroll@exploits.org> 5 * Various bugfixes and enhancements by Russell Kroll <rkroll@exploits.org>
6 * 6 *
7 * TODO: Allow for more than one of these foolish entities :-) 7 * TODO: Allow for more than one of these foolish entities :-)
diff --git a/drivers/media/radio/radio-sf16fmi.c b/drivers/media/radio/radio-sf16fmi.c
index 329c90bddadd..834d43651c70 100644
--- a/drivers/media/radio/radio-sf16fmi.c
+++ b/drivers/media/radio/radio-sf16fmi.c
@@ -3,7 +3,7 @@
3 * (c) 1997 M. Kirkwood 3 * (c) 1997 M. Kirkwood
4 * (c) 1998 Petr Vandrovec, vandrove@vc.cvut.cz 4 * (c) 1998 Petr Vandrovec, vandrove@vc.cvut.cz
5 * 5 *
6 * Fitted to new interface by Alan Cox <alan.cox@linux.org> 6 * Fitted to new interface by Alan Cox <alan@lxorguk.ukuu.org.uk>
7 * Made working and cleaned up functions <mikael.hedin@irf.se> 7 * Made working and cleaned up functions <mikael.hedin@irf.se>
8 * Support for ISAPnP by Ladislav Michl <ladis@psi.cz> 8 * Support for ISAPnP by Ladislav Michl <ladis@psi.cz>
9 * 9 *
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index 057fd7e160c4..19cf3b8f67c4 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -184,7 +184,7 @@ config VIDEO_MSP3400
184 184
185config VIDEO_CS5345 185config VIDEO_CS5345
186 tristate "Cirrus Logic CS5345 audio ADC" 186 tristate "Cirrus Logic CS5345 audio ADC"
187 depends on VIDEO_V4L2 && I2C && EXPERIMENTAL 187 depends on VIDEO_V4L2 && I2C
188 ---help--- 188 ---help---
189 Support for the Cirrus Logic CS5345 24-bit, 192 kHz 189 Support for the Cirrus Logic CS5345 24-bit, 192 kHz
190 stereo A/D converter. 190 stereo A/D converter.
@@ -204,7 +204,7 @@ config VIDEO_CS53L32A
204 204
205config VIDEO_M52790 205config VIDEO_M52790
206 tristate "Mitsubishi M52790 A/V switch" 206 tristate "Mitsubishi M52790 A/V switch"
207 depends on VIDEO_V4L2 && I2C && EXPERIMENTAL 207 depends on VIDEO_V4L2 && I2C
208 ---help--- 208 ---help---
209 Support for the Mitsubishi M52790 A/V switch. 209 Support for the Mitsubishi M52790 A/V switch.
210 210
@@ -242,7 +242,7 @@ config VIDEO_WM8739
242 242
243config VIDEO_VP27SMPX 243config VIDEO_VP27SMPX
244 tristate "Panasonic VP27s internal MPX" 244 tristate "Panasonic VP27s internal MPX"
245 depends on VIDEO_V4L2 && I2C && EXPERIMENTAL 245 depends on VIDEO_V4L2 && I2C
246 ---help--- 246 ---help---
247 Support for the internal MPX of the Panasonic VP27s tuner. 247 Support for the internal MPX of the Panasonic VP27s tuner.
248 248
@@ -361,6 +361,17 @@ config VIDEO_SAA7191
361 To compile this driver as a module, choose M here: the 361 To compile this driver as a module, choose M here: the
362 module will be called saa7191. 362 module will be called saa7191.
363 363
364config VIDEO_TVP514X
365 tristate "Texas Instruments TVP514x video decoder"
366 depends on VIDEO_V4L2 && I2C
367 ---help---
368 This is a Video4Linux2 sensor-level driver for the TI TVP5146/47
369 decoder. It is currently working with the TI OMAP3 camera
370 controller.
371
372 To compile this driver as a module, choose M here: the
373 module will be called tvp514x.
374
364config VIDEO_TVP5150 375config VIDEO_TVP5150
365 tristate "Texas Instruments TVP5150 video decoder" 376 tristate "Texas Instruments TVP5150 video decoder"
366 depends on VIDEO_V4L2 && I2C 377 depends on VIDEO_V4L2 && I2C
@@ -387,7 +398,7 @@ comment "MPEG video encoders"
387 398
388config VIDEO_CX2341X 399config VIDEO_CX2341X
389 tristate "Conexant CX2341x MPEG encoders" 400 tristate "Conexant CX2341x MPEG encoders"
390 depends on VIDEO_V4L2 && EXPERIMENTAL && VIDEO_V4L2_COMMON 401 depends on VIDEO_V4L2 && VIDEO_V4L2_COMMON
391 ---help--- 402 ---help---
392 Support for the Conexant CX23416 MPEG encoders 403 Support for the Conexant CX23416 MPEG encoders
393 and CX23415 MPEG encoder/decoders. 404 and CX23415 MPEG encoder/decoders.
@@ -725,10 +736,16 @@ config MT9M001_PCA9536_SWITCH
725 extender to switch between 8 and 10 bit datawidth modes 736 extender to switch between 8 and 10 bit datawidth modes
726 737
727config SOC_CAMERA_MT9M111 738config SOC_CAMERA_MT9M111
728 tristate "mt9m111 support" 739 tristate "mt9m111 and mt9m112 support"
740 depends on SOC_CAMERA && I2C
741 help
742 This driver supports MT9M111 and MT9M112 cameras from Micron
743
744config SOC_CAMERA_MT9T031
745 tristate "mt9t031 support"
729 depends on SOC_CAMERA && I2C 746 depends on SOC_CAMERA && I2C
730 help 747 help
731 This driver supports MT9M111 cameras from Micron 748 This driver supports MT9T031 cameras from Micron.
732 749
733config SOC_CAMERA_MT9V022 750config SOC_CAMERA_MT9V022
734 tristate "mt9v022 support" 751 tristate "mt9v022 support"
@@ -744,12 +761,24 @@ config MT9V022_PCA9536_SWITCH
744 Select this if your MT9V022 camera uses a PCA9536 I2C GPIO 761 Select this if your MT9V022 camera uses a PCA9536 I2C GPIO
745 extender to switch between 8 and 10 bit datawidth modes 762 extender to switch between 8 and 10 bit datawidth modes
746 763
764config SOC_CAMERA_TW9910
765 tristate "tw9910 support"
766 depends on SOC_CAMERA && I2C
767 help
768 This is a tw9910 video driver
769
747config SOC_CAMERA_PLATFORM 770config SOC_CAMERA_PLATFORM
748 tristate "platform camera support" 771 tristate "platform camera support"
749 depends on SOC_CAMERA 772 depends on SOC_CAMERA
750 help 773 help
751 This is a generic SoC camera platform driver, useful for testing 774 This is a generic SoC camera platform driver, useful for testing
752 775
776config SOC_CAMERA_OV772X
777 tristate "ov772x camera support"
778 depends on SOC_CAMERA && I2C
779 help
780 This is a ov772x camera driver
781
753config VIDEO_PXA27x 782config VIDEO_PXA27x
754 tristate "PXA27x Quick Capture Interface driver" 783 tristate "PXA27x Quick Capture Interface driver"
755 depends on VIDEO_DEV && PXA27x && SOC_CAMERA 784 depends on VIDEO_DEV && PXA27x && SOC_CAMERA
@@ -764,6 +793,13 @@ config VIDEO_SH_MOBILE_CEU
764 ---help--- 793 ---help---
765 This is a v4l2 driver for the SuperH Mobile CEU Interface 794 This is a v4l2 driver for the SuperH Mobile CEU Interface
766 795
796config VIDEO_OMAP2
797 tristate "OMAP2 Camera Capture Interface driver"
798 depends on VIDEO_DEV && ARCH_OMAP2
799 select VIDEOBUF_DMA_SG
800 ---help---
801 This is a v4l2 driver for the TI OMAP2 camera capture interface
802
767# 803#
768# USB Multimedia device configuration 804# USB Multimedia device configuration
769# 805#
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
index 16962f3aa157..1611c33b1aee 100644
--- a/drivers/media/video/Makefile
+++ b/drivers/media/video/Makefile
@@ -8,9 +8,11 @@ msp3400-objs := msp3400-driver.o msp3400-kthreads.o
8 8
9stkwebcam-objs := stk-webcam.o stk-sensor.o 9stkwebcam-objs := stk-webcam.o stk-sensor.o
10 10
11videodev-objs := v4l2-dev.o v4l2-ioctl.o 11omap2cam-objs := omap24xxcam.o omap24xxcam-dma.o
12 12
13obj-$(CONFIG_VIDEO_DEV) += videodev.o compat_ioctl32.o v4l2-int-device.o 13videodev-objs := v4l2-dev.o v4l2-ioctl.o v4l2-device.o v4l2-subdev.o
14
15obj-$(CONFIG_VIDEO_DEV) += videodev.o v4l2-compat-ioctl32.o v4l2-int-device.o
14 16
15obj-$(CONFIG_VIDEO_V4L2_COMMON) += v4l2-common.o 17obj-$(CONFIG_VIDEO_V4L2_COMMON) += v4l2-common.o
16 18
@@ -25,6 +27,7 @@ obj-$(CONFIG_VIDEO_IR_I2C) += ir-kbd-i2c.o
25obj-$(CONFIG_VIDEO_TVAUDIO) += tvaudio.o 27obj-$(CONFIG_VIDEO_TVAUDIO) += tvaudio.o
26obj-$(CONFIG_VIDEO_TDA7432) += tda7432.o 28obj-$(CONFIG_VIDEO_TDA7432) += tda7432.o
27obj-$(CONFIG_VIDEO_TDA9875) += tda9875.o 29obj-$(CONFIG_VIDEO_TDA9875) += tda9875.o
30obj-$(CONFIG_SOUND_TVMIXER) += tvmixer.o
28 31
29obj-$(CONFIG_VIDEO_SAA6588) += saa6588.o 32obj-$(CONFIG_VIDEO_SAA6588) += saa6588.o
30obj-$(CONFIG_VIDEO_SAA5246A) += saa5246a.o 33obj-$(CONFIG_VIDEO_SAA5246A) += saa5246a.o
@@ -66,6 +69,7 @@ obj-$(CONFIG_VIDEO_CX88) += cx88/
66obj-$(CONFIG_VIDEO_EM28XX) += em28xx/ 69obj-$(CONFIG_VIDEO_EM28XX) += em28xx/
67obj-$(CONFIG_VIDEO_USBVISION) += usbvision/ 70obj-$(CONFIG_VIDEO_USBVISION) += usbvision/
68obj-$(CONFIG_VIDEO_TVP5150) += tvp5150.o 71obj-$(CONFIG_VIDEO_TVP5150) += tvp5150.o
72obj-$(CONFIG_VIDEO_TVP514X) += tvp514x.o
69obj-$(CONFIG_VIDEO_PVRUSB2) += pvrusb2/ 73obj-$(CONFIG_VIDEO_PVRUSB2) += pvrusb2/
70obj-$(CONFIG_VIDEO_MSP3400) += msp3400.o 74obj-$(CONFIG_VIDEO_MSP3400) += msp3400.o
71obj-$(CONFIG_VIDEO_CS5345) += cs5345.o 75obj-$(CONFIG_VIDEO_CS5345) += cs5345.o
@@ -129,11 +133,15 @@ obj-$(CONFIG_VIDEO_CX23885) += cx23885/
129 133
130obj-$(CONFIG_VIDEO_PXA27x) += pxa_camera.o 134obj-$(CONFIG_VIDEO_PXA27x) += pxa_camera.o
131obj-$(CONFIG_VIDEO_SH_MOBILE_CEU) += sh_mobile_ceu_camera.o 135obj-$(CONFIG_VIDEO_SH_MOBILE_CEU) += sh_mobile_ceu_camera.o
136obj-$(CONFIG_VIDEO_OMAP2) += omap2cam.o
132obj-$(CONFIG_SOC_CAMERA) += soc_camera.o 137obj-$(CONFIG_SOC_CAMERA) += soc_camera.o
133obj-$(CONFIG_SOC_CAMERA_MT9M001) += mt9m001.o 138obj-$(CONFIG_SOC_CAMERA_MT9M001) += mt9m001.o
134obj-$(CONFIG_SOC_CAMERA_MT9M111) += mt9m111.o 139obj-$(CONFIG_SOC_CAMERA_MT9M111) += mt9m111.o
140obj-$(CONFIG_SOC_CAMERA_MT9T031) += mt9t031.o
135obj-$(CONFIG_SOC_CAMERA_MT9V022) += mt9v022.o 141obj-$(CONFIG_SOC_CAMERA_MT9V022) += mt9v022.o
142obj-$(CONFIG_SOC_CAMERA_OV772X) += ov772x.o
136obj-$(CONFIG_SOC_CAMERA_PLATFORM) += soc_camera_platform.o 143obj-$(CONFIG_SOC_CAMERA_PLATFORM) += soc_camera_platform.o
144obj-$(CONFIG_SOC_CAMERA_TW9910) += tw9910.o
137 145
138obj-$(CONFIG_VIDEO_AU0828) += au0828/ 146obj-$(CONFIG_VIDEO_AU0828) += au0828/
139 147
diff --git a/drivers/media/video/arv.c b/drivers/media/video/arv.c
index e09b00693230..2ba6abd92b6f 100644
--- a/drivers/media/video/arv.c
+++ b/drivers/media/video/arv.c
@@ -396,8 +396,7 @@ out_up:
396 return ret; 396 return ret;
397} 397}
398 398
399static int ar_do_ioctl(struct inode *inode, struct file *file, 399static int ar_do_ioctl(struct file *file, unsigned int cmd, void *arg)
400 unsigned int cmd, void *arg)
401{ 400{
402 struct video_device *dev = video_devdata(file); 401 struct video_device *dev = video_devdata(file);
403 struct ar_device *ar = video_get_drvdata(dev); 402 struct ar_device *ar = video_get_drvdata(dev);
@@ -543,7 +542,7 @@ static int ar_do_ioctl(struct inode *inode, struct file *file,
543static int ar_ioctl(struct inode *inode, struct file *file, unsigned int cmd, 542static int ar_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
544 unsigned long arg) 543 unsigned long arg)
545{ 544{
546 return video_usercopy(inode, file, cmd, arg, ar_do_ioctl); 545 return video_usercopy(file, cmd, arg, ar_do_ioctl);
547} 546}
548 547
549#if USE_INT 548#if USE_INT
diff --git a/drivers/media/video/bt8xx/bt832.c b/drivers/media/video/bt8xx/bt832.c
deleted file mode 100644
index 216fc9680e80..000000000000
--- a/drivers/media/video/bt8xx/bt832.c
+++ /dev/null
@@ -1,274 +0,0 @@
1/* Driver for Bt832 CMOS Camera Video Processor
2 i2c-addresses: 0x88 or 0x8a
3
4 The BT832 interfaces to a Quartzsight Digital Camera (352x288, 25 or 30 fps)
5 via a 9 pin connector ( 4-wire SDATA, 2-wire i2c, SCLK, VCC, GND).
6 It outputs an 8-bit 4:2:2 YUV or YCrCb video signal which can be directly
7 connected to bt848/bt878 GPIO pins on this purpose.
8 (see: VLSI Vision Ltd. www.vvl.co.uk for camera datasheets)
9
10 Supported Cards:
11 - Pixelview Rev.4E: 0x8a
12 GPIO 0x400000 toggles Bt832 RESET, and the chip changes to i2c 0x88 !
13
14 (c) Gunther Mayer, 2002
15
16 STATUS:
17 - detect chip and hexdump
18 - reset chip and leave low power mode
19 - detect camera present
20
21 TODO:
22 - make it work (find correct setup for Bt832 and Bt878)
23*/
24
25#include <linux/module.h>
26#include <linux/kernel.h>
27#include <linux/i2c.h>
28#include <linux/types.h>
29#include <linux/videodev.h>
30#include <linux/init.h>
31#include <linux/errno.h>
32#include <linux/slab.h>
33#include <media/v4l2-common.h>
34
35#include "bttv.h"
36#include "bt832.h"
37
38MODULE_LICENSE("GPL");
39
40/* Addresses to scan */
41static unsigned short normal_i2c[] = { I2C_ADDR_BT832_ALT1>>1, I2C_ADDR_BT832_ALT2>>1,
42 I2C_CLIENT_END };
43I2C_CLIENT_INSMOD;
44
45int debug; /* debug output */
46module_param(debug, int, 0644);
47
48/* ---------------------------------------------------------------------- */
49
50static int bt832_detach(struct i2c_client *client);
51
52
53static struct i2c_driver driver;
54static struct i2c_client client_template;
55
56struct bt832 {
57 struct i2c_client client;
58};
59
60int bt832_hexdump(struct i2c_client *i2c_client_s, unsigned char *buf)
61{
62 int i,rc;
63 buf[0]=0x80; // start at register 0 with auto-increment
64 if (1 != (rc = i2c_master_send(i2c_client_s,buf,1)))
65 v4l_err(i2c_client_s,"i2c i/o error: rc == %d (should be 1)\n",rc);
66
67 for(i=0;i<65;i++)
68 buf[i]=0;
69 if (65 != (rc=i2c_master_recv(i2c_client_s,buf,65)))
70 v4l_err(i2c_client_s,"i2c i/o error: rc == %d (should be 65)\n",rc);
71
72 // Note: On READ the first byte is the current index
73 // (e.g. 0x80, what we just wrote)
74
75 if(debug>1) {
76 int i;
77 v4l_dbg(2, debug,i2c_client_s,"hexdump:");
78 for(i=1;i<65;i++) {
79 if(i!=1) {
80 if(((i-1)%8)==0) printk(" ");
81 if(((i-1)%16)==0) {
82 printk("\n");
83 v4l_dbg(2, debug,i2c_client_s,"hexdump:");
84 }
85 }
86 printk(" %02x",buf[i]);
87 }
88 printk("\n");
89 }
90 return 0;
91}
92
93// Return: 1 (is a bt832), 0 (No bt832 here)
94int bt832_init(struct i2c_client *i2c_client_s)
95{
96 unsigned char *buf;
97 int rc;
98
99 buf=kmalloc(65,GFP_KERNEL);
100 if (!buf) {
101 v4l_err(&t->client,
102 "Unable to allocate memory. Detaching.\n");
103 return 0;
104 }
105 bt832_hexdump(i2c_client_s,buf);
106
107 if(buf[0x40] != 0x31) {
108 v4l_err(i2c_client_s,"This i2c chip is no bt832 (id=%02x). Detaching.\n",buf[0x40]);
109 kfree(buf);
110 return 0;
111 }
112
113 v4l_err(i2c_client_s,"Write 0 tp VPSTATUS\n");
114 buf[0]=BT832_VP_STATUS; // Reg.52
115 buf[1]= 0x00;
116 if (2 != (rc = i2c_master_send(i2c_client_s,buf,2)))
117 v4l_err(i2c_client_s,"i2c i/o error VPS: rc == %d (should be 2)\n",rc);
118
119 bt832_hexdump(i2c_client_s,buf);
120
121
122 // Leave low power mode:
123 v4l_err(i2c_client_s,"leave low power mode.\n");
124 buf[0]=BT832_CAM_SETUP0; //0x39 57
125 buf[1]=0x08;
126 if (2 != (rc = i2c_master_send(i2c_client_s,buf,2)))
127 v4l_err(i2c_client_s,"i2c i/o error LLPM: rc == %d (should be 2)\n",rc);
128
129 bt832_hexdump(i2c_client_s,buf);
130
131 v4l_info(i2c_client_s,"Write 0 tp VPSTATUS\n");
132 buf[0]=BT832_VP_STATUS; // Reg.52
133 buf[1]= 0x00;
134 if (2 != (rc = i2c_master_send(i2c_client_s,buf,2)))
135 v4l_err(i2c_client_s,"i2c i/o error VPS: rc == %d (should be 2)\n",rc);
136
137 bt832_hexdump(i2c_client_s,buf);
138
139
140 // Enable Output
141 v4l_info(i2c_client_s,"Enable Output\n");
142 buf[0]=BT832_VP_CONTROL1; // Reg.40
143 buf[1]= 0x27 & (~0x01); // Default | !skip
144 if (2 != (rc = i2c_master_send(i2c_client_s,buf,2)))
145 v4l_err(i2c_client_s,"i2c i/o error EO: rc == %d (should be 2)\n",rc);
146
147 bt832_hexdump(i2c_client_s,buf);
148
149
150 // for testing (even works when no camera attached)
151 v4l_info(i2c_client_s,"*** Generate NTSC M Bars *****\n");
152 buf[0]=BT832_VP_TESTCONTROL0; // Reg. 42
153 buf[1]=3; // Generate NTSC System M bars, Generate Frame timing internally
154 if (2 != (rc = i2c_master_send(i2c_client_s,buf,2)))
155 v4l_info(i2c_client_s,"i2c i/o error MBAR: rc == %d (should be 2)\n",rc);
156
157 v4l_info(i2c_client_s,"Camera Present: %s\n",
158 (buf[1+BT832_CAM_STATUS] & BT832_56_CAMERA_PRESENT) ? "yes":"no");
159
160 bt832_hexdump(i2c_client_s,buf);
161 kfree(buf);
162 return 1;
163}
164
165
166
167static int bt832_attach(struct i2c_adapter *adap, int addr, int kind)
168{
169 struct bt832 *t;
170
171 client_template.adapter = adap;
172 client_template.addr = addr;
173
174 if (NULL == (t = kzalloc(sizeof(*t), GFP_KERNEL)))
175 return -ENOMEM;
176 t->client = client_template;
177 i2c_set_clientdata(&t->client, t);
178 i2c_attach_client(&t->client);
179
180 v4l_info(&t->client,"chip found @ 0x%x\n", addr<<1);
181
182 if(! bt832_init(&t->client)) {
183 bt832_detach(&t->client);
184 return -1;
185 }
186
187 return 0;
188}
189
190static int bt832_probe(struct i2c_adapter *adap)
191{
192 if (adap->class & I2C_CLASS_TV_ANALOG)
193 return i2c_probe(adap, &addr_data, bt832_attach);
194 return 0;
195}
196
197static int bt832_detach(struct i2c_client *client)
198{
199 struct bt832 *t = i2c_get_clientdata(client);
200
201 v4l_info(&t->client,"dettach\n");
202 i2c_detach_client(client);
203 kfree(t);
204 return 0;
205}
206
207static int
208bt832_command(struct i2c_client *client, unsigned int cmd, void *arg)
209{
210 struct bt832 *t = i2c_get_clientdata(client);
211
212 if (debug>1)
213 v4l_i2c_print_ioctl(&t->client,cmd);
214
215 switch (cmd) {
216 case BT832_HEXDUMP: {
217 unsigned char *buf;
218 buf = kmalloc(65, GFP_KERNEL);
219 if (!buf) {
220 v4l_err(&t->client,
221 "Unable to allocate memory\n");
222 break;
223 }
224 bt832_hexdump(&t->client,buf);
225 kfree(buf);
226 }
227 break;
228 case BT832_REATTACH:
229 v4l_info(&t->client,"re-attach\n");
230 i2c_del_driver(&driver);
231 i2c_add_driver(&driver);
232 break;
233 }
234 return 0;
235}
236
237/* ----------------------------------------------------------------------- */
238
239static struct i2c_driver driver = {
240 .driver = {
241 .name = "bt832",
242 },
243 .id = 0, /* FIXME */
244 .attach_adapter = bt832_probe,
245 .detach_client = bt832_detach,
246 .command = bt832_command,
247};
248static struct i2c_client client_template =
249{
250 .name = "bt832",
251 .driver = &driver,
252};
253
254
255static int __init bt832_init_module(void)
256{
257 return i2c_add_driver(&driver);
258}
259
260static void __exit bt832_cleanup_module(void)
261{
262 i2c_del_driver(&driver);
263}
264
265module_init(bt832_init_module);
266module_exit(bt832_cleanup_module);
267
268/*
269 * Overrides for Emacs so that we follow Linus's tabbing style.
270 * ---------------------------------------------------------------------------
271 * Local variables:
272 * c-basic-offset: 8
273 * End:
274 */
diff --git a/drivers/media/video/bt8xx/bt832.h b/drivers/media/video/bt8xx/bt832.h
deleted file mode 100644
index 1ce8fa71f7db..000000000000
--- a/drivers/media/video/bt8xx/bt832.h
+++ /dev/null
@@ -1,305 +0,0 @@
1/* Bt832 CMOS Camera Video Processor (VP)
2
3 The Bt832 CMOS Camera Video Processor chip connects a Quartsight CMOS
4 color digital camera directly to video capture devices via an 8-bit,
5 4:2:2 YUV or YCrCb video interface.
6
7 i2c addresses: 0x88 or 0x8a
8 */
9
10/* The 64 registers: */
11
12// Input Processor
13#define BT832_OFFSET 0
14#define BT832_RCOMP 1
15#define BT832_G1COMP 2
16#define BT832_G2COMP 3
17#define BT832_BCOMP 4
18// Exposures:
19#define BT832_FINEH 5
20#define BT832_FINEL 6
21#define BT832_COARSEH 7
22#define BT832_COARSEL 8
23#define BT832_CAMGAIN 9
24// Main Processor:
25#define BT832_M00 10
26#define BT832_M01 11
27#define BT832_M02 12
28#define BT832_M10 13
29#define BT832_M11 14
30#define BT832_M12 15
31#define BT832_M20 16
32#define BT832_M21 17
33#define BT832_M22 18
34#define BT832_APCOR 19
35#define BT832_GAMCOR 20
36// Level Accumulator Inputs
37#define BT832_VPCONTROL2 21
38#define BT832_ZONECODE0 22
39#define BT832_ZONECODE1 23
40#define BT832_ZONECODE2 24
41#define BT832_ZONECODE3 25
42// Level Accumulator Outputs:
43#define BT832_RACC 26
44#define BT832_GACC 27
45#define BT832_BACC 28
46#define BT832_BLACKACC 29
47#define BT832_EXP_AGC 30
48#define BT832_LACC0 31
49#define BT832_LACC1 32
50#define BT832_LACC2 33
51#define BT832_LACC3 34
52#define BT832_LACC4 35
53#define BT832_LACC5 36
54#define BT832_LACC6 37
55#define BT832_LACC7 38
56// System:
57#define BT832_VP_CONTROL0 39
58#define BT832_VP_CONTROL1 40
59#define BT832_THRESH 41
60#define BT832_VP_TESTCONTROL0 42
61#define BT832_VP_DMCODE 43
62#define BT832_ACB_CONFIG 44
63#define BT832_ACB_GNBASE 45
64#define BT832_ACB_MU 46
65#define BT832_CAM_TEST0 47
66#define BT832_AEC_CONFIG 48
67#define BT832_AEC_TL 49
68#define BT832_AEC_TC 50
69#define BT832_AEC_TH 51
70// Status:
71#define BT832_VP_STATUS 52
72#define BT832_VP_LINECOUNT 53
73#define BT832_CAM_DEVICEL 54 // e.g. 0x19
74#define BT832_CAM_DEVICEH 55 // e.g. 0x40 == 0x194 Mask0, 0x194 = 404 decimal (VVL-404 camera)
75#define BT832_CAM_STATUS 56
76 #define BT832_56_CAMERA_PRESENT 0x20
77//Camera Setups:
78#define BT832_CAM_SETUP0 57
79#define BT832_CAM_SETUP1 58
80#define BT832_CAM_SETUP2 59
81#define BT832_CAM_SETUP3 60
82// System:
83#define BT832_DEFCOR 61
84#define BT832_VP_TESTCONTROL1 62
85#define BT832_DEVICE_ID 63
86# define BT832_DEVICE_ID__31 0x31 // Bt832 has ID 0x31
87
88/* STMicroelectronivcs VV5404 camera module
89 i2c: 0x20: sensor address
90 i2c: 0xa0: eeprom for ccd defect map
91 */
92#define VV5404_device_h 0x00 // 0x19
93#define VV5404_device_l 0x01 // 0x40
94#define VV5404_status0 0x02
95#define VV5404_linecountc 0x03 // current line counter
96#define VV5404_linecountl 0x04
97#define VV5404_setup0 0x10
98#define VV5404_setup1 0x11
99#define VV5404_setup2 0x12
100#define VV5404_setup4 0x14
101#define VV5404_setup5 0x15
102#define VV5404_fine_h 0x20 // fine exposure
103#define VV5404_fine_l 0x21
104#define VV5404_coarse_h 0x22 //coarse exposure
105#define VV5404_coarse_l 0x23
106#define VV5404_gain 0x24 // ADC pre-amp gain setting
107#define VV5404_clk_div 0x25
108#define VV5404_cr 0x76 // control register
109#define VV5404_as0 0x77 // ADC setup register
110
111
112// IOCTL
113#define BT832_HEXDUMP _IOR('b',1,int)
114#define BT832_REATTACH _IOR('b',2,int)
115
116/* from BT8x8VXD/capdrv/dialogs.cpp */
117
118/*
119typedef enum { SVI, Logitech, Rockwell } CAMERA;
120
121static COMBOBOX_ENTRY gwCameraOptions[] =
122{
123 { SVI, "Silicon Vision 512N" },
124 { Logitech, "Logitech VideoMan 1.3" },
125 { Rockwell, "Rockwell QuartzSight PCI 1.0" }
126};
127
128// SRAM table values
129//===========================================================================
130typedef enum { TGB_NTSC624, TGB_NTSC780, TGB_NTSC858, TGB_NTSC392 } TimeGenByte;
131
132BYTE SRAMTable[][ 60 ] =
133{
134 // TGB_NTSC624
135 {
136 0x33, // size of table = 51
137 0x0E, 0xC0, 0x00, 0x00, 0x90, 0x02, 0x03, 0x10, 0x03, 0x06,
138 0x10, 0x04, 0x12, 0x12, 0x05, 0x02, 0x13, 0x04, 0x19, 0x00,
139 0x04, 0x39, 0x00, 0x06, 0x59, 0x08, 0x03, 0x85, 0x08, 0x07,
140 0x03, 0x50, 0x00, 0x91, 0x40, 0x00, 0x11, 0x01, 0x01, 0x4D,
141 0x0D, 0x02, 0x03, 0x11, 0x01, 0x05, 0x37, 0x00, 0x37, 0x21, 0x00
142 },
143 // TGB_NTSC780
144 {
145 0x33, // size of table = 51
146 0x0e, 0xc0, 0x00, 0x00, 0x90, 0xe2, 0x03, 0x10, 0x03, 0x06,
147 0x10, 0x34, 0x12, 0x12, 0x65, 0x02, 0x13, 0x24, 0x19, 0x00,
148 0x24, 0x39, 0x00, 0x96, 0x59, 0x08, 0x93, 0x85, 0x08, 0x97,
149 0x03, 0x50, 0x50, 0xaf, 0x40, 0x30, 0x5f, 0x01, 0xf1, 0x7f,
150 0x0d, 0xf2, 0x03, 0x11, 0xf1, 0x05, 0x37, 0x30, 0x85, 0x21, 0x50
151 },
152 // TGB_NTSC858
153 {
154 0x33, // size of table = 51
155 0x0c, 0xc0, 0x00, 0x00, 0x90, 0xc2, 0x03, 0x10, 0x03, 0x06,
156 0x10, 0x34, 0x12, 0x12, 0x65, 0x02, 0x13, 0x24, 0x19, 0x00,
157 0x24, 0x39, 0x00, 0x96, 0x59, 0x08, 0x93, 0x83, 0x08, 0x97,
158 0x03, 0x50, 0x30, 0xc0, 0x40, 0x30, 0x86, 0x01, 0x01, 0xa6,
159 0x0d, 0x62, 0x03, 0x11, 0x61, 0x05, 0x37, 0x30, 0xac, 0x21, 0x50
160 },
161 // TGB_NTSC392
162 // This table has been modified to be used for Fusion Rev D
163 {
164 0x2A, // size of table = 42
165 0x06, 0x08, 0x04, 0x0a, 0xc0, 0x00, 0x18, 0x08, 0x03, 0x24,
166 0x08, 0x07, 0x02, 0x90, 0x02, 0x08, 0x10, 0x04, 0x0c, 0x10,
167 0x05, 0x2c, 0x11, 0x04, 0x55, 0x48, 0x00, 0x05, 0x50, 0x00,
168 0xbf, 0x0c, 0x02, 0x2f, 0x3d, 0x00, 0x2f, 0x3f, 0x00, 0xc3,
169 0x20, 0x00
170 }
171};
172
173//===========================================================================
174// This is the structure of the camera specifications
175//===========================================================================
176typedef struct tag_cameraSpec
177{
178 SignalFormat signal; // which digital signal format the camera has
179 VideoFormat vidFormat; // video standard
180 SyncVideoRef syncRef; // which sync video reference is used
181 State syncOutput; // enable sync output for sync video input?
182 DecInputClk iClk; // which input clock is used
183 TimeGenByte tgb; // which timing generator byte does the camera use
184 int HReset; // select 64, 48, 32, or 16 CLKx1 for HReset
185 PLLFreq pllFreq; // what synthesized frequency to set PLL to
186 VSIZEPARMS vSize; // video size the camera produces
187 int lineCount; // expected total number of half-line per frame - 1
188 BOOL interlace; // interlace signal?
189} CameraSpec;
190
191//===========================================================================
192// <UPDATE REQUIRED>
193// Camera specifications database. Update this table whenever camera spec
194// has been changed or added/deleted supported camera models
195//===========================================================================
196static CameraSpec dbCameraSpec[ N_CAMERAOPTIONS ] =
197{ // Silicon Vision 512N
198 { Signal_CCIR656, VFormat_NTSC, VRef_alignedCb, Off, DecClk_GPCLK, TGB_NTSC624, 64, KHz19636,
199 // Clkx1_HACTIVE, Clkx1_HDELAY, VActive, VDelay, linesPerField; lineCount, Interlace
200 { 512, 0x64, 480, 0x13, 240 }, 0, TRUE
201 },
202 // Logitech VideoMan 1.3
203 { Signal_CCIR656, VFormat_NTSC, VRef_alignedCb, Off, DecClk_GPCLK, TGB_NTSC780, 64, KHz24545,
204 // Clkx1_HACTIVE, Clkx1_HDELAY, VActive, VDelay, linesPerField; lineCount, Interlace
205 { 640, 0x80, 480, 0x1A, 240 }, 0, TRUE
206 },
207 // Rockwell QuartzSight
208 // Note: Fusion Rev D (rev ID 0x02) and later supports 16 pixels for HReset which is preferable.
209 // Use 32 for earlier version of hardware. Clkx1_HDELAY also changed from 0x27 to 0x20.
210 { Signal_CCIR656, VFormat_NTSC, VRef_alignedCb, Off, DecClk_GPCLK, TGB_NTSC392, 16, KHz28636,
211 // Clkx1_HACTIVE, Clkx1_HDELAY, VActive, VDelay, linesPerField; lineCount, Interlace
212 { 352, 0x20, 576, 0x08, 288 }, 607, FALSE
213 }
214};
215*/
216
217/*
218The corresponding APIs required to be invoked are:
219SetConnector( ConCamera, TRUE/FALSE );
220SetSignalFormat( spec.signal );
221SetVideoFormat( spec.vidFormat );
222SetSyncVideoRef( spec.syncRef );
223SetEnableSyncOutput( spec.syncOutput );
224SetTimGenByte( SRAMTable[ spec.tgb ], SRAMTableSize[ spec.tgb ] );
225SetHReset( spec.HReset );
226SetPLL( spec.pllFreq );
227SetDecInputClock( spec.iClk );
228SetVideoInfo( spec.vSize );
229SetTotalLineCount( spec.lineCount );
230SetInterlaceMode( spec.interlace );
231*/
232
233/* from web:
234 Video Sampling
235Digital video is a sampled form of analog video. The most common sampling schemes in use today are:
236 Pixel Clock Horiz Horiz Vert
237 Rate Total Active
238NTSC square pixel 12.27 MHz 780 640 525
239NTSC CCIR-601 13.5 MHz 858 720 525
240NTSC 4FSc 14.32 MHz 910 768 525
241PAL square pixel 14.75 MHz 944 768 625
242PAL CCIR-601 13.5 MHz 864 720 625
243PAL 4FSc 17.72 MHz 1135 948 625
244
245For the CCIR-601 standards, the sampling is based on a static orthogonal sampling grid. The luminance component (Y) is sampled at 13.5 MHz, while the two color difference signals, Cr and Cb are sampled at half that, or 6.75 MHz. The Cr and Cb samples are colocated with alternate Y samples, and they are taken at the same position on each line, such that one sample is coincident with the 50% point of the falling edge of analog sync. The samples are coded to either 8 or 10 bits per component.
246*/
247
248/* from DScaler:*/
249/*
250//===========================================================================
251// CCIR656 Digital Input Support: The tables were taken from DScaler proyect
252//
253// 13 Dec 2000 - Michael Eskin, Conexant Systems - Initial version
254//
255
256//===========================================================================
257// Timing generator SRAM table values for CCIR601 720x480 NTSC
258//===========================================================================
259// For NTSC CCIR656
260BYTE BtCard::SRAMTable_NTSC[] =
261{
262 // SRAM Timing Table for NTSC
263 0x0c, 0xc0, 0x00,
264 0x00, 0x90, 0xc2,
265 0x03, 0x10, 0x03,
266 0x06, 0x10, 0x34,
267 0x12, 0x12, 0x65,
268 0x02, 0x13, 0x24,
269 0x19, 0x00, 0x24,
270 0x39, 0x00, 0x96,
271 0x59, 0x08, 0x93,
272 0x83, 0x08, 0x97,
273 0x03, 0x50, 0x30,
274 0xc0, 0x40, 0x30,
275 0x86, 0x01, 0x01,
276 0xa6, 0x0d, 0x62,
277 0x03, 0x11, 0x61,
278 0x05, 0x37, 0x30,
279 0xac, 0x21, 0x50
280};
281
282//===========================================================================
283// Timing generator SRAM table values for CCIR601 720x576 NTSC
284//===========================================================================
285// For PAL CCIR656
286BYTE BtCard::SRAMTable_PAL[] =
287{
288 // SRAM Timing Table for PAL
289 0x36, 0x11, 0x01,
290 0x00, 0x90, 0x02,
291 0x05, 0x10, 0x04,
292 0x16, 0x14, 0x05,
293 0x11, 0x00, 0x04,
294 0x12, 0xc0, 0x00,
295 0x31, 0x00, 0x06,
296 0x51, 0x08, 0x03,
297 0x89, 0x08, 0x07,
298 0xc0, 0x44, 0x00,
299 0x81, 0x01, 0x01,
300 0xa9, 0x0d, 0x02,
301 0x02, 0x50, 0x03,
302 0x37, 0x3d, 0x00,
303 0xaf, 0x21, 0x00,
304};
305*/
diff --git a/drivers/media/video/bt8xx/bttv-cards.c b/drivers/media/video/bt8xx/bttv-cards.c
index 13742b0bbe3e..d24dcc025e37 100644
--- a/drivers/media/video/bt8xx/bttv-cards.c
+++ b/drivers/media/video/bt8xx/bttv-cards.c
@@ -44,7 +44,6 @@
44 44
45/* fwd decl */ 45/* fwd decl */
46static void boot_msp34xx(struct bttv *btv, int pin); 46static void boot_msp34xx(struct bttv *btv, int pin);
47static void boot_bt832(struct bttv *btv);
48static void hauppauge_eeprom(struct bttv *btv); 47static void hauppauge_eeprom(struct bttv *btv);
49static void avermedia_eeprom(struct bttv *btv); 48static void avermedia_eeprom(struct bttv *btv);
50static void osprey_eeprom(struct bttv *btv, const u8 ee[256]); 49static void osprey_eeprom(struct bttv *btv, const u8 ee[256]);
@@ -2217,9 +2216,9 @@ struct tvcard bttv_tvcards[] = {
2217 .tuner_addr = ADDR_UNSET, 2216 .tuner_addr = ADDR_UNSET,
2218 .radio_addr = ADDR_UNSET, 2217 .radio_addr = ADDR_UNSET,
2219 }, 2218 },
2220 [BTTV_BOARD_VD009X1_MINIDIN] = { 2219 [BTTV_BOARD_VD009X1_VD011_MINIDIN] = {
2221 /* M.Klahr@phytec.de */ 2220 /* M.Klahr@phytec.de */
2222 .name = "PHYTEC VD-009-X1 MiniDIN (bt878)", 2221 .name = "PHYTEC VD-009-X1 VD-011 MiniDIN (bt878)",
2223 .video_inputs = 4, 2222 .video_inputs = 4,
2224 .audio_inputs = 0, 2223 .audio_inputs = 0,
2225 .tuner = UNSET, /* card has no tuner */ 2224 .tuner = UNSET, /* card has no tuner */
@@ -2227,14 +2226,14 @@ struct tvcard bttv_tvcards[] = {
2227 .gpiomask = 0x00, 2226 .gpiomask = 0x00,
2228 .muxsel = { 2, 3, 1, 0 }, 2227 .muxsel = { 2, 3, 1, 0 },
2229 .gpiomux = { 0, 0, 0, 0 }, /* card has no audio */ 2228 .gpiomux = { 0, 0, 0, 0 }, /* card has no audio */
2230 .needs_tvaudio = 1, 2229 .needs_tvaudio = 0,
2231 .pll = PLL_28, 2230 .pll = PLL_28,
2232 .tuner_type = UNSET, 2231 .tuner_type = UNSET,
2233 .tuner_addr = ADDR_UNSET, 2232 .tuner_addr = ADDR_UNSET,
2234 .radio_addr = ADDR_UNSET, 2233 .radio_addr = ADDR_UNSET,
2235 }, 2234 },
2236 [BTTV_BOARD_VD009X1_COMBI] = { 2235 [BTTV_BOARD_VD009X1_VD011_COMBI] = {
2237 .name = "PHYTEC VD-009-X1 Combi (bt878)", 2236 .name = "PHYTEC VD-009-X1 VD-011 Combi (bt878)",
2238 .video_inputs = 4, 2237 .video_inputs = 4,
2239 .audio_inputs = 0, 2238 .audio_inputs = 0,
2240 .tuner = UNSET, /* card has no tuner */ 2239 .tuner = UNSET, /* card has no tuner */
@@ -2242,7 +2241,7 @@ struct tvcard bttv_tvcards[] = {
2242 .gpiomask = 0x00, 2241 .gpiomask = 0x00,
2243 .muxsel = { 2, 3, 1, 1 }, 2242 .muxsel = { 2, 3, 1, 1 },
2244 .gpiomux = { 0, 0, 0, 0 }, /* card has no audio */ 2243 .gpiomux = { 0, 0, 0, 0 }, /* card has no audio */
2245 .needs_tvaudio = 1, 2244 .needs_tvaudio = 0,
2246 .pll = PLL_28, 2245 .pll = PLL_28,
2247 .tuner_type = UNSET, 2246 .tuner_type = UNSET,
2248 .tuner_addr = ADDR_UNSET, 2247 .tuner_addr = ADDR_UNSET,
@@ -3061,6 +3060,54 @@ struct tvcard bttv_tvcards[] = {
3061 .pll = PLL_28, 3060 .pll = PLL_28,
3062 .has_radio = 1, 3061 .has_radio = 1,
3063 .has_remote = 1, 3062 .has_remote = 1,
3063 },
3064 [BTTV_BOARD_VD012] = {
3065 /* D.Heer@Phytec.de */
3066 .name = "PHYTEC VD-012 (bt878)",
3067 .video_inputs = 4,
3068 .audio_inputs = 0,
3069 .tuner = UNSET, /* card has no tuner */
3070 .svhs = UNSET, /* card has no s-video */
3071 .gpiomask = 0x00,
3072 .muxsel = { 0, 2, 3, 1 },
3073 .gpiomux = { 0, 0, 0, 0 }, /* card has no audio */
3074 .needs_tvaudio = 0,
3075 .pll = PLL_28,
3076 .tuner_type = UNSET,
3077 .tuner_addr = ADDR_UNSET,
3078 .radio_addr = ADDR_UNSET,
3079 },
3080 [BTTV_BOARD_VD012_X1] = {
3081 /* D.Heer@Phytec.de */
3082 .name = "PHYTEC VD-012-X1 (bt878)",
3083 .video_inputs = 4,
3084 .audio_inputs = 0,
3085 .tuner = UNSET, /* card has no tuner */
3086 .svhs = 3,
3087 .gpiomask = 0x00,
3088 .muxsel = { 2, 3, 1 },
3089 .gpiomux = { 0, 0, 0, 0 }, /* card has no audio */
3090 .needs_tvaudio = 0,
3091 .pll = PLL_28,
3092 .tuner_type = UNSET,
3093 .tuner_addr = ADDR_UNSET,
3094 .radio_addr = ADDR_UNSET,
3095 },
3096 [BTTV_BOARD_VD012_X2] = {
3097 /* D.Heer@Phytec.de */
3098 .name = "PHYTEC VD-012-X2 (bt878)",
3099 .video_inputs = 4,
3100 .audio_inputs = 0,
3101 .tuner = UNSET, /* card has no tuner */
3102 .svhs = 3,
3103 .gpiomask = 0x00,
3104 .muxsel = { 3, 2, 1 },
3105 .gpiomux = { 0, 0, 0, 0 }, /* card has no audio */
3106 .needs_tvaudio = 0,
3107 .pll = PLL_28,
3108 .tuner_type = UNSET,
3109 .tuner_addr = ADDR_UNSET,
3110 .radio_addr = ADDR_UNSET,
3064 } 3111 }
3065}; 3112};
3066 3113
@@ -3673,13 +3720,6 @@ void __devinit bttv_init_card2(struct bttv *btv)
3673 if (bttv_tvcards[btv->c.type].audio_mode_gpio) 3720 if (bttv_tvcards[btv->c.type].audio_mode_gpio)
3674 btv->audio_mode_gpio=bttv_tvcards[btv->c.type].audio_mode_gpio; 3721 btv->audio_mode_gpio=bttv_tvcards[btv->c.type].audio_mode_gpio;
3675 3722
3676 if (bttv_tvcards[btv->c.type].digital_mode == DIGITAL_MODE_CAMERA) {
3677 /* detect Bt832 chip for quartzsight digital camera */
3678 if ((bttv_I2CRead(btv, I2C_ADDR_BT832_ALT1, "Bt832") >=0) ||
3679 (bttv_I2CRead(btv, I2C_ADDR_BT832_ALT2, "Bt832") >=0))
3680 boot_bt832(btv);
3681 }
3682
3683 if (!autoload) 3723 if (!autoload)
3684 return; 3724 return;
3685 3725
@@ -4075,10 +4115,6 @@ static void __devinit boot_msp34xx(struct bttv *btv, int pin)
4075 "init [%d]\n", btv->c.nr, pin); 4115 "init [%d]\n", btv->c.nr, pin);
4076} 4116}
4077 4117
4078static void __devinit boot_bt832(struct bttv *btv)
4079{
4080}
4081
4082/* ----------------------------------------------------------------------- */ 4118/* ----------------------------------------------------------------------- */
4083/* Imagenation L-Model PXC200 Framegrabber */ 4119/* Imagenation L-Model PXC200 Framegrabber */
4084/* This is basically the same procedure as 4120/* This is basically the same procedure as
diff --git a/drivers/media/video/bt8xx/bttv-gpio.c b/drivers/media/video/bt8xx/bttv-gpio.c
index dce6dae5740e..74c325e594a2 100644
--- a/drivers/media/video/bt8xx/bttv-gpio.c
+++ b/drivers/media/video/bt8xx/bttv-gpio.c
@@ -42,7 +42,7 @@ static int bttv_sub_bus_match(struct device *dev, struct device_driver *drv)
42 struct bttv_sub_driver *sub = to_bttv_sub_drv(drv); 42 struct bttv_sub_driver *sub = to_bttv_sub_drv(drv);
43 int len = strlen(sub->wanted); 43 int len = strlen(sub->wanted);
44 44
45 if (0 == strncmp(dev->bus_id, sub->wanted, len)) 45 if (0 == strncmp(dev_name(dev), sub->wanted, len))
46 return 1; 46 return 1;
47 return 0; 47 return 0;
48} 48}
@@ -91,15 +91,14 @@ int bttv_sub_add_device(struct bttv_core *core, char *name)
91 sub->dev.parent = &core->pci->dev; 91 sub->dev.parent = &core->pci->dev;
92 sub->dev.bus = &bttv_sub_bus_type; 92 sub->dev.bus = &bttv_sub_bus_type;
93 sub->dev.release = release_sub_device; 93 sub->dev.release = release_sub_device;
94 snprintf(sub->dev.bus_id,sizeof(sub->dev.bus_id),"%s%d", 94 dev_set_name(&sub->dev, "%s%d", name, core->nr);
95 name, core->nr);
96 95
97 err = device_register(&sub->dev); 96 err = device_register(&sub->dev);
98 if (0 != err) { 97 if (0 != err) {
99 kfree(sub); 98 kfree(sub);
100 return err; 99 return err;
101 } 100 }
102 printk("bttv%d: add subdevice \"%s\"\n", core->nr, sub->dev.bus_id); 101 printk("bttv%d: add subdevice \"%s\"\n", core->nr, dev_name(&sub->dev));
103 list_add_tail(&sub->list,&core->subs); 102 list_add_tail(&sub->list,&core->subs);
104 return 0; 103 return 0;
105} 104}
diff --git a/drivers/media/video/bt8xx/bttv.h b/drivers/media/video/bt8xx/bttv.h
index 46cb90e0985b..529bf6cf634d 100644
--- a/drivers/media/video/bt8xx/bttv.h
+++ b/drivers/media/video/bt8xx/bttv.h
@@ -130,8 +130,8 @@
130#define BTTV_BOARD_XGUARD 0x67 130#define BTTV_BOARD_XGUARD 0x67
131#define BTTV_BOARD_NEBULA_DIGITV 0x68 131#define BTTV_BOARD_NEBULA_DIGITV 0x68
132#define BTTV_BOARD_PV143 0x69 132#define BTTV_BOARD_PV143 0x69
133#define BTTV_BOARD_VD009X1_MINIDIN 0x6a 133#define BTTV_BOARD_VD009X1_VD011_MINIDIN 0x6a
134#define BTTV_BOARD_VD009X1_COMBI 0x6b 134#define BTTV_BOARD_VD009X1_VD011_COMBI 0x6b
135#define BTTV_BOARD_VD009_MINIDIN 0x6c 135#define BTTV_BOARD_VD009_MINIDIN 0x6c
136#define BTTV_BOARD_VD009_COMBI 0x6d 136#define BTTV_BOARD_VD009_COMBI 0x6d
137#define BTTV_BOARD_IVC100 0x6e 137#define BTTV_BOARD_IVC100 0x6e
@@ -177,6 +177,10 @@
177#define BTTV_BOARD_GEOVISION_GV600 0x96 177#define BTTV_BOARD_GEOVISION_GV600 0x96
178#define BTTV_BOARD_KOZUMI_KTV_01C 0x97 178#define BTTV_BOARD_KOZUMI_KTV_01C 0x97
179#define BTTV_BOARD_ENLTV_FM_2 0x98 179#define BTTV_BOARD_ENLTV_FM_2 0x98
180#define BTTV_BOARD_VD012 0x99
181#define BTTV_BOARD_VD012_X1 0x9a
182#define BTTV_BOARD_VD012_X2 0x9b
183
180 184
181/* more card-specific defines */ 185/* more card-specific defines */
182#define PT2254_L_CHANNEL 0x10 186#define PT2254_L_CHANNEL 0x10
@@ -308,7 +312,7 @@ struct bttv_sub_device {
308 312
309struct bttv_sub_driver { 313struct bttv_sub_driver {
310 struct device_driver drv; 314 struct device_driver drv;
311 char wanted[BUS_ID_SIZE]; 315 char wanted[20];
312 int (*probe)(struct bttv_sub_device *sub); 316 int (*probe)(struct bttv_sub_device *sub);
313 void (*remove)(struct bttv_sub_device *sub); 317 void (*remove)(struct bttv_sub_device *sub);
314}; 318};
diff --git a/drivers/media/video/bt8xx/bttvp.h b/drivers/media/video/bt8xx/bttvp.h
index b4d940b2e447..199a4d225caf 100644
--- a/drivers/media/video/bt8xx/bttvp.h
+++ b/drivers/media/video/bt8xx/bttvp.h
@@ -459,7 +459,7 @@ struct bttv {
459}; 459};
460 460
461/* our devices */ 461/* our devices */
462#define BTTV_MAX 16 462#define BTTV_MAX 32
463extern unsigned int bttv_num; 463extern unsigned int bttv_num;
464extern struct bttv bttvs[BTTV_MAX]; 464extern struct bttv bttvs[BTTV_MAX];
465 465
diff --git a/drivers/media/video/bw-qcam.c b/drivers/media/video/bw-qcam.c
index ace4ff9ea023..17f80d03f38e 100644
--- a/drivers/media/video/bw-qcam.c
+++ b/drivers/media/video/bw-qcam.c
@@ -706,8 +706,7 @@ static long qc_capture(struct qcam_device * q, char __user *buf, unsigned long l
706 * Video4linux interfacing 706 * Video4linux interfacing
707 */ 707 */
708 708
709static int qcam_do_ioctl(struct inode *inode, struct file *file, 709static int qcam_do_ioctl(struct file *file, unsigned int cmd, void *arg)
710 unsigned int cmd, void *arg)
711{ 710{
712 struct video_device *dev = video_devdata(file); 711 struct video_device *dev = video_devdata(file);
713 struct qcam_device *qcam=(struct qcam_device *)dev; 712 struct qcam_device *qcam=(struct qcam_device *)dev;
@@ -867,7 +866,7 @@ static int qcam_do_ioctl(struct inode *inode, struct file *file,
867static int qcam_ioctl(struct inode *inode, struct file *file, 866static int qcam_ioctl(struct inode *inode, struct file *file,
868 unsigned int cmd, unsigned long arg) 867 unsigned int cmd, unsigned long arg)
869{ 868{
870 return video_usercopy(inode, file, cmd, arg, qcam_do_ioctl); 869 return video_usercopy(file, cmd, arg, qcam_do_ioctl);
871} 870}
872 871
873static ssize_t qcam_read(struct file *file, char __user *buf, 872static ssize_t qcam_read(struct file *file, char __user *buf,
diff --git a/drivers/media/video/c-qcam.c b/drivers/media/video/c-qcam.c
index 0f930d351466..21c71eb085db 100644
--- a/drivers/media/video/c-qcam.c
+++ b/drivers/media/video/c-qcam.c
@@ -500,8 +500,7 @@ static long qc_capture(struct qcam_device *q, char __user *buf, unsigned long le
500 * Video4linux interfacing 500 * Video4linux interfacing
501 */ 501 */
502 502
503static int qcam_do_ioctl(struct inode *inode, struct file *file, 503static int qcam_do_ioctl(struct file *file, unsigned int cmd, void *arg)
504 unsigned int cmd, void *arg)
505{ 504{
506 struct video_device *dev = video_devdata(file); 505 struct video_device *dev = video_devdata(file);
507 struct qcam_device *qcam=(struct qcam_device *)dev; 506 struct qcam_device *qcam=(struct qcam_device *)dev;
@@ -667,9 +666,9 @@ static int qcam_do_ioctl(struct inode *inode, struct file *file,
667} 666}
668 667
669static int qcam_ioctl(struct inode *inode, struct file *file, 668static int qcam_ioctl(struct inode *inode, struct file *file,
670 unsigned int cmd, unsigned long arg) 669 unsigned int cmd, unsigned long arg)
671{ 670{
672 return video_usercopy(inode, file, cmd, arg, qcam_do_ioctl); 671 return video_usercopy(file, cmd, arg, qcam_do_ioctl);
673} 672}
674 673
675static ssize_t qcam_read(struct file *file, char __user *buf, 674static ssize_t qcam_read(struct file *file, char __user *buf,
diff --git a/drivers/media/video/cpia.c b/drivers/media/video/cpia.c
index 16c094f77852..028a400d2453 100644
--- a/drivers/media/video/cpia.c
+++ b/drivers/media/video/cpia.c
@@ -3333,8 +3333,7 @@ static ssize_t cpia_read(struct file *file, char __user *buf,
3333 return cam->decompressed_frame.count; 3333 return cam->decompressed_frame.count;
3334} 3334}
3335 3335
3336static int cpia_do_ioctl(struct inode *inode, struct file *file, 3336static int cpia_do_ioctl(struct file *file, unsigned int cmd, void *arg)
3337 unsigned int ioctlnr, void *arg)
3338{ 3337{
3339 struct video_device *dev = file->private_data; 3338 struct video_device *dev = file->private_data;
3340 struct cam_data *cam = video_get_drvdata(dev); 3339 struct cam_data *cam = video_get_drvdata(dev);
@@ -3347,9 +3346,9 @@ static int cpia_do_ioctl(struct inode *inode, struct file *file,
3347 if (mutex_lock_interruptible(&cam->busy_lock)) 3346 if (mutex_lock_interruptible(&cam->busy_lock))
3348 return -EINTR; 3347 return -EINTR;
3349 3348
3350 //DBG("cpia_ioctl: %u\n", ioctlnr); 3349 /* DBG("cpia_ioctl: %u\n", cmd); */
3351 3350
3352 switch (ioctlnr) { 3351 switch (cmd) {
3353 /* query capabilities */ 3352 /* query capabilities */
3354 case VIDIOCGCAP: 3353 case VIDIOCGCAP:
3355 { 3354 {
@@ -3724,7 +3723,7 @@ static int cpia_do_ioctl(struct inode *inode, struct file *file,
3724static int cpia_ioctl(struct inode *inode, struct file *file, 3723static int cpia_ioctl(struct inode *inode, struct file *file,
3725 unsigned int cmd, unsigned long arg) 3724 unsigned int cmd, unsigned long arg)
3726{ 3725{
3727 return video_usercopy(inode, file, cmd, arg, cpia_do_ioctl); 3726 return video_usercopy(file, cmd, arg, cpia_do_ioctl);
3728} 3727}
3729 3728
3730 3729
diff --git a/drivers/media/video/cpia2/cpia2_core.c b/drivers/media/video/cpia2/cpia2_core.c
index 7e791b6923f9..1cc0df8befff 100644
--- a/drivers/media/video/cpia2/cpia2_core.c
+++ b/drivers/media/video/cpia2/cpia2_core.c
@@ -25,7 +25,7 @@
25 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 25 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 * 26 *
27 * Stripped of 2.4 stuff ready for main kernel submit by 27 * Stripped of 2.4 stuff ready for main kernel submit by
28 * Alan Cox <alan@redhat.com> 28 * Alan Cox <alan@lxorguk.ukuu.org.uk>
29 * 29 *
30 ****************************************************************************/ 30 ****************************************************************************/
31 31
diff --git a/drivers/media/video/cpia2/cpia2_usb.c b/drivers/media/video/cpia2/cpia2_usb.c
index 73511a542077..dc5b07a20f69 100644
--- a/drivers/media/video/cpia2/cpia2_usb.c
+++ b/drivers/media/video/cpia2/cpia2_usb.c
@@ -25,7 +25,7 @@
25 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 25 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 * 26 *
27 * Stripped of 2.4 stuff ready for main kernel submit by 27 * Stripped of 2.4 stuff ready for main kernel submit by
28 * Alan Cox <alan@redhat.com> 28 * Alan Cox <alan@lxorguk.ukuu.org.uk>
29 ****************************************************************************/ 29 ****************************************************************************/
30 30
31#include <linux/kernel.h> 31#include <linux/kernel.h>
diff --git a/drivers/media/video/cpia2/cpia2_v4l.c b/drivers/media/video/cpia2/cpia2_v4l.c
index 1c6bd633f193..3c2d7eac1197 100644
--- a/drivers/media/video/cpia2/cpia2_v4l.c
+++ b/drivers/media/video/cpia2/cpia2_v4l.c
@@ -26,7 +26,7 @@
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 * 27 *
28 * Stripped of 2.4 stuff ready for main kernel submit by 28 * Stripped of 2.4 stuff ready for main kernel submit by
29 * Alan Cox <alan@redhat.com> 29 * Alan Cox <alan@lxorguk.ukuu.org.uk>
30 ****************************************************************************/ 30 ****************************************************************************/
31 31
32#include <linux/version.h> 32#include <linux/version.h>
@@ -1572,8 +1572,7 @@ static int ioctl_dqbuf(void *arg,struct camera_data *cam, struct file *file)
1572 * cpia2_ioctl 1572 * cpia2_ioctl
1573 * 1573 *
1574 *****************************************************************************/ 1574 *****************************************************************************/
1575static int cpia2_do_ioctl(struct inode *inode, struct file *file, 1575static int cpia2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
1576 unsigned int ioctl_nr, void *arg)
1577{ 1576{
1578 struct camera_data *cam = video_drvdata(file); 1577 struct camera_data *cam = video_drvdata(file);
1579 int retval = 0; 1578 int retval = 0;
@@ -1591,7 +1590,7 @@ static int cpia2_do_ioctl(struct inode *inode, struct file *file,
1591 } 1590 }
1592 1591
1593 /* Priority check */ 1592 /* Priority check */
1594 switch (ioctl_nr) { 1593 switch (cmd) {
1595 case VIDIOCSWIN: 1594 case VIDIOCSWIN:
1596 case VIDIOCMCAPTURE: 1595 case VIDIOCMCAPTURE:
1597 case VIDIOC_S_FMT: 1596 case VIDIOC_S_FMT:
@@ -1618,7 +1617,7 @@ static int cpia2_do_ioctl(struct inode *inode, struct file *file,
1618 break; 1617 break;
1619 } 1618 }
1620 1619
1621 switch (ioctl_nr) { 1620 switch (cmd) {
1622 case VIDIOCGCAP: /* query capabilities */ 1621 case VIDIOCGCAP: /* query capabilities */
1623 retval = ioctl_cap_query(arg, cam); 1622 retval = ioctl_cap_query(arg, cam);
1624 break; 1623 break;
@@ -1683,7 +1682,7 @@ static int cpia2_do_ioctl(struct inode *inode, struct file *file,
1683 case VIDIOC_ENUMINPUT: 1682 case VIDIOC_ENUMINPUT:
1684 case VIDIOC_G_INPUT: 1683 case VIDIOC_G_INPUT:
1685 case VIDIOC_S_INPUT: 1684 case VIDIOC_S_INPUT:
1686 retval = ioctl_input(ioctl_nr, arg,cam); 1685 retval = ioctl_input(cmd, arg, cam);
1687 break; 1686 break;
1688 1687
1689 case VIDIOC_ENUM_FMT: 1688 case VIDIOC_ENUM_FMT:
@@ -1843,9 +1842,9 @@ static int cpia2_do_ioctl(struct inode *inode, struct file *file,
1843} 1842}
1844 1843
1845static int cpia2_ioctl(struct inode *inode, struct file *file, 1844static int cpia2_ioctl(struct inode *inode, struct file *file,
1846 unsigned int ioctl_nr, unsigned long iarg) 1845 unsigned int cmd, unsigned long arg)
1847{ 1846{
1848 return video_usercopy(inode, file, ioctl_nr, iarg, cpia2_do_ioctl); 1847 return video_usercopy(file, cmd, arg, cpia2_do_ioctl);
1849} 1848}
1850 1849
1851/****************************************************************************** 1850/******************************************************************************
diff --git a/drivers/media/video/cs5345.c b/drivers/media/video/cs5345.c
index a662b15d5b90..70fcd0d5de13 100644
--- a/drivers/media/video/cs5345.c
+++ b/drivers/media/video/cs5345.c
@@ -23,9 +23,9 @@
23#include <linux/kernel.h> 23#include <linux/kernel.h>
24#include <linux/i2c.h> 24#include <linux/i2c.h>
25#include <linux/videodev2.h> 25#include <linux/videodev2.h>
26#include <media/v4l2-i2c-drv.h> 26#include <media/v4l2-device.h>
27#include <media/v4l2-common.h>
28#include <media/v4l2-chip-ident.h> 27#include <media/v4l2-chip-ident.h>
28#include <media/v4l2-i2c-drv.h>
29 29
30MODULE_DESCRIPTION("i2c device driver for cs5345 Audio ADC"); 30MODULE_DESCRIPTION("i2c device driver for cs5345 Audio ADC");
31MODULE_AUTHOR("Hans Verkuil"); 31MODULE_AUTHOR("Hans Verkuil");
@@ -40,111 +40,143 @@ MODULE_PARM_DESC(debug, "Debugging messages, 0=Off (default), 1=On");
40 40
41/* ----------------------------------------------------------------------- */ 41/* ----------------------------------------------------------------------- */
42 42
43static inline int cs5345_write(struct i2c_client *client, u8 reg, u8 value) 43static inline int cs5345_write(struct v4l2_subdev *sd, u8 reg, u8 value)
44{ 44{
45 struct i2c_client *client = v4l2_get_subdevdata(sd);
46
45 return i2c_smbus_write_byte_data(client, reg, value); 47 return i2c_smbus_write_byte_data(client, reg, value);
46} 48}
47 49
48static inline int cs5345_read(struct i2c_client *client, u8 reg) 50static inline int cs5345_read(struct v4l2_subdev *sd, u8 reg)
49{ 51{
52 struct i2c_client *client = v4l2_get_subdevdata(sd);
53
50 return i2c_smbus_read_byte_data(client, reg); 54 return i2c_smbus_read_byte_data(client, reg);
51} 55}
52 56
53static int cs5345_command(struct i2c_client *client, unsigned cmd, void *arg) 57static int cs5345_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
54{ 58{
55 struct v4l2_routing *route = arg; 59 if ((route->input & 0xf) > 6) {
56 struct v4l2_control *ctrl = arg; 60 v4l2_err(sd, "Invalid input %d.\n", route->input);
57 61 return -EINVAL;
58 switch (cmd) {
59 case VIDIOC_INT_G_AUDIO_ROUTING:
60 route->input = cs5345_read(client, 0x09) & 7;
61 route->input |= cs5345_read(client, 0x05) & 0x70;
62 route->output = 0;
63 break;
64
65 case VIDIOC_INT_S_AUDIO_ROUTING:
66 if ((route->input & 0xf) > 6) {
67 v4l_err(client, "Invalid input %d.\n", route->input);
68 return -EINVAL;
69 }
70 cs5345_write(client, 0x09, route->input & 0xf);
71 cs5345_write(client, 0x05, route->input & 0xf0);
72 break;
73
74 case VIDIOC_G_CTRL:
75 if (ctrl->id == V4L2_CID_AUDIO_MUTE) {
76 ctrl->value = (cs5345_read(client, 0x04) & 0x08) != 0;
77 break;
78 }
79 if (ctrl->id != V4L2_CID_AUDIO_VOLUME)
80 return -EINVAL;
81 ctrl->value = cs5345_read(client, 0x07) & 0x3f;
82 if (ctrl->value >= 32)
83 ctrl->value = ctrl->value - 64;
84 break;
85
86 case VIDIOC_S_CTRL:
87 break;
88 if (ctrl->id == V4L2_CID_AUDIO_MUTE) {
89 cs5345_write(client, 0x04, ctrl->value ? 0x80 : 0);
90 break;
91 }
92 if (ctrl->id != V4L2_CID_AUDIO_VOLUME)
93 return -EINVAL;
94 if (ctrl->value > 24 || ctrl->value < -24)
95 return -EINVAL;
96 cs5345_write(client, 0x07, ((u8)ctrl->value) & 0x3f);
97 cs5345_write(client, 0x08, ((u8)ctrl->value) & 0x3f);
98 break;
99
100#ifdef CONFIG_VIDEO_ADV_DEBUG
101 case VIDIOC_DBG_G_REGISTER:
102 case VIDIOC_DBG_S_REGISTER:
103 {
104 struct v4l2_register *reg = arg;
105
106 if (!v4l2_chip_match_i2c_client(client,
107 reg->match_type, reg->match_chip))
108 return -EINVAL;
109 if (!capable(CAP_SYS_ADMIN))
110 return -EPERM;
111 if (cmd == VIDIOC_DBG_G_REGISTER)
112 reg->val = cs5345_read(client, reg->reg & 0x1f);
113 else
114 cs5345_write(client, reg->reg & 0x1f, reg->val & 0xff);
115 break;
116 } 62 }
117#endif 63 cs5345_write(sd, 0x09, route->input & 0xf);
64 cs5345_write(sd, 0x05, route->input & 0xf0);
65 return 0;
66}
118 67
119 case VIDIOC_G_CHIP_IDENT: 68static int cs5345_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
120 return v4l2_chip_ident_i2c_client(client, 69{
121 arg, V4L2_IDENT_CS5345, 0); 70 if (ctrl->id == V4L2_CID_AUDIO_MUTE) {
122 71 ctrl->value = (cs5345_read(sd, 0x04) & 0x08) != 0;
123 case VIDIOC_LOG_STATUS: 72 return 0;
124 { 73 }
125 u8 v = cs5345_read(client, 0x09) & 7; 74 if (ctrl->id != V4L2_CID_AUDIO_VOLUME)
126 u8 m = cs5345_read(client, 0x04);
127 int vol = cs5345_read(client, 0x08) & 0x3f;
128
129 v4l_info(client, "Input: %d%s\n", v,
130 (m & 0x80) ? " (muted)" : "");
131 if (vol >= 32)
132 vol = vol - 64;
133 v4l_info(client, "Volume: %d dB\n", vol);
134 break;
135 }
136
137 default:
138 return -EINVAL; 75 return -EINVAL;
76 ctrl->value = cs5345_read(sd, 0x07) & 0x3f;
77 if (ctrl->value >= 32)
78 ctrl->value = ctrl->value - 64;
79 return 0;
80}
81
82static int cs5345_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
83{
84 if (ctrl->id == V4L2_CID_AUDIO_MUTE) {
85 cs5345_write(sd, 0x04, ctrl->value ? 0x80 : 0);
86 return 0;
139 } 87 }
88 if (ctrl->id != V4L2_CID_AUDIO_VOLUME)
89 return -EINVAL;
90 if (ctrl->value > 24 || ctrl->value < -24)
91 return -EINVAL;
92 cs5345_write(sd, 0x07, ((u8)ctrl->value) & 0x3f);
93 cs5345_write(sd, 0x08, ((u8)ctrl->value) & 0x3f);
94 return 0;
95}
96
97#ifdef CONFIG_VIDEO_ADV_DEBUG
98static int cs5345_g_register(struct v4l2_subdev *sd, struct v4l2_register *reg)
99{
100 struct i2c_client *client = v4l2_get_subdevdata(sd);
101
102 if (!v4l2_chip_match_i2c_client(client,
103 reg->match_type, reg->match_chip))
104 return -EINVAL;
105 if (!capable(CAP_SYS_ADMIN))
106 return -EPERM;
107 reg->val = cs5345_read(sd, reg->reg & 0x1f);
108 return 0;
109}
110
111static int cs5345_s_register(struct v4l2_subdev *sd, struct v4l2_register *reg)
112{
113 struct i2c_client *client = v4l2_get_subdevdata(sd);
114
115 if (!v4l2_chip_match_i2c_client(client,
116 reg->match_type, reg->match_chip))
117 return -EINVAL;
118 if (!capable(CAP_SYS_ADMIN))
119 return -EPERM;
120 cs5345_write(sd, reg->reg & 0x1f, reg->val & 0xff);
140 return 0; 121 return 0;
141} 122}
123#endif
124
125static int cs5345_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_chip_ident *chip)
126{
127 struct i2c_client *client = v4l2_get_subdevdata(sd);
128
129 return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_CS5345, 0);
130}
131
132static int cs5345_log_status(struct v4l2_subdev *sd)
133{
134 u8 v = cs5345_read(sd, 0x09) & 7;
135 u8 m = cs5345_read(sd, 0x04);
136 int vol = cs5345_read(sd, 0x08) & 0x3f;
137
138 v4l2_info(sd, "Input: %d%s\n", v,
139 (m & 0x80) ? " (muted)" : "");
140 if (vol >= 32)
141 vol = vol - 64;
142 v4l2_info(sd, "Volume: %d dB\n", vol);
143 return 0;
144}
145
146static int cs5345_command(struct i2c_client *client, unsigned cmd, void *arg)
147{
148 return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
149}
150
151/* ----------------------------------------------------------------------- */
152
153static const struct v4l2_subdev_core_ops cs5345_core_ops = {
154 .log_status = cs5345_log_status,
155 .g_chip_ident = cs5345_g_chip_ident,
156 .g_ctrl = cs5345_g_ctrl,
157 .s_ctrl = cs5345_s_ctrl,
158#ifdef CONFIG_VIDEO_ADV_DEBUG
159 .g_register = cs5345_g_register,
160 .s_register = cs5345_s_register,
161#endif
162};
163
164static const struct v4l2_subdev_audio_ops cs5345_audio_ops = {
165 .s_routing = cs5345_s_routing,
166};
167
168static const struct v4l2_subdev_ops cs5345_ops = {
169 .core = &cs5345_core_ops,
170 .audio = &cs5345_audio_ops,
171};
142 172
143/* ----------------------------------------------------------------------- */ 173/* ----------------------------------------------------------------------- */
144 174
145static int cs5345_probe(struct i2c_client *client, 175static int cs5345_probe(struct i2c_client *client,
146 const struct i2c_device_id *id) 176 const struct i2c_device_id *id)
147{ 177{
178 struct v4l2_subdev *sd;
179
148 /* Check if the adapter supports the needed features */ 180 /* Check if the adapter supports the needed features */
149 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) 181 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
150 return -EIO; 182 return -EIO;
@@ -152,9 +184,25 @@ static int cs5345_probe(struct i2c_client *client,
152 v4l_info(client, "chip found @ 0x%x (%s)\n", 184 v4l_info(client, "chip found @ 0x%x (%s)\n",
153 client->addr << 1, client->adapter->name); 185 client->addr << 1, client->adapter->name);
154 186
155 cs5345_write(client, 0x02, 0x00); 187 sd = kzalloc(sizeof(struct v4l2_subdev), GFP_KERNEL);
156 cs5345_write(client, 0x04, 0x01); 188 if (sd == NULL)
157 cs5345_write(client, 0x09, 0x01); 189 return -ENOMEM;
190 v4l2_i2c_subdev_init(sd, client, &cs5345_ops);
191
192 cs5345_write(sd, 0x02, 0x00);
193 cs5345_write(sd, 0x04, 0x01);
194 cs5345_write(sd, 0x09, 0x01);
195 return 0;
196}
197
198/* ----------------------------------------------------------------------- */
199
200static int cs5345_remove(struct i2c_client *client)
201{
202 struct v4l2_subdev *sd = i2c_get_clientdata(client);
203
204 v4l2_device_unregister_subdev(sd);
205 kfree(sd);
158 return 0; 206 return 0;
159} 207}
160 208
@@ -171,5 +219,6 @@ static struct v4l2_i2c_driver_data v4l2_i2c_data = {
171 .driverid = I2C_DRIVERID_CS5345, 219 .driverid = I2C_DRIVERID_CS5345,
172 .command = cs5345_command, 220 .command = cs5345_command,
173 .probe = cs5345_probe, 221 .probe = cs5345_probe,
222 .remove = cs5345_remove,
174 .id_table = cs5345_id, 223 .id_table = cs5345_id,
175}; 224};
diff --git a/drivers/media/video/cs53l32a.c b/drivers/media/video/cs53l32a.c
index c4444500b330..cb65d519cf78 100644
--- a/drivers/media/video/cs53l32a.c
+++ b/drivers/media/video/cs53l32a.c
@@ -27,7 +27,7 @@
27#include <linux/i2c.h> 27#include <linux/i2c.h>
28#include <linux/i2c-id.h> 28#include <linux/i2c-id.h>
29#include <linux/videodev2.h> 29#include <linux/videodev2.h>
30#include <media/v4l2-common.h> 30#include <media/v4l2-device.h>
31#include <media/v4l2-chip-ident.h> 31#include <media/v4l2-chip-ident.h>
32#include <media/v4l2-i2c-drv-legacy.h> 32#include <media/v4l2-i2c-drv-legacy.h>
33 33
@@ -47,84 +47,104 @@ I2C_CLIENT_INSMOD;
47 47
48/* ----------------------------------------------------------------------- */ 48/* ----------------------------------------------------------------------- */
49 49
50static int cs53l32a_write(struct i2c_client *client, u8 reg, u8 value) 50static int cs53l32a_write(struct v4l2_subdev *sd, u8 reg, u8 value)
51{ 51{
52 struct i2c_client *client = v4l2_get_subdevdata(sd);
53
52 return i2c_smbus_write_byte_data(client, reg, value); 54 return i2c_smbus_write_byte_data(client, reg, value);
53} 55}
54 56
55static int cs53l32a_read(struct i2c_client *client, u8 reg) 57static int cs53l32a_read(struct v4l2_subdev *sd, u8 reg)
56{ 58{
59 struct i2c_client *client = v4l2_get_subdevdata(sd);
60
57 return i2c_smbus_read_byte_data(client, reg); 61 return i2c_smbus_read_byte_data(client, reg);
58} 62}
59 63
60static int cs53l32a_command(struct i2c_client *client, unsigned cmd, void *arg) 64static int cs53l32a_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
61{ 65{
62 struct v4l2_routing *route = arg; 66 /* There are 2 physical inputs, but the second input can be
63 struct v4l2_control *ctrl = arg; 67 placed in two modes, the first mode bypasses the PGA (gain),
64 68 the second goes through the PGA. Hence there are three
65 switch (cmd) { 69 possible inputs to choose from. */
66 case VIDIOC_INT_G_AUDIO_ROUTING: 70 if (route->input > 2) {
67 route->input = (cs53l32a_read(client, 0x01) >> 4) & 3; 71 v4l2_err(sd, "Invalid input %d.\n", route->input);
68 route->output = 0;
69 break;
70
71 case VIDIOC_INT_S_AUDIO_ROUTING:
72 /* There are 2 physical inputs, but the second input can be
73 placed in two modes, the first mode bypasses the PGA (gain),
74 the second goes through the PGA. Hence there are three
75 possible inputs to choose from. */
76 if (route->input > 2) {
77 v4l_err(client, "Invalid input %d.\n", route->input);
78 return -EINVAL;
79 }
80 cs53l32a_write(client, 0x01, 0x01 + (route->input << 4));
81 break;
82
83 case VIDIOC_G_CTRL:
84 if (ctrl->id == V4L2_CID_AUDIO_MUTE) {
85 ctrl->value = (cs53l32a_read(client, 0x03) & 0xc0) != 0;
86 break;
87 }
88 if (ctrl->id != V4L2_CID_AUDIO_VOLUME)
89 return -EINVAL;
90 ctrl->value = (s8)cs53l32a_read(client, 0x04);
91 break;
92
93 case VIDIOC_S_CTRL:
94 if (ctrl->id == V4L2_CID_AUDIO_MUTE) {
95 cs53l32a_write(client, 0x03, ctrl->value ? 0xf0 : 0x30);
96 break;
97 }
98 if (ctrl->id != V4L2_CID_AUDIO_VOLUME)
99 return -EINVAL;
100 if (ctrl->value > 12 || ctrl->value < -96)
101 return -EINVAL;
102 cs53l32a_write(client, 0x04, (u8) ctrl->value);
103 cs53l32a_write(client, 0x05, (u8) ctrl->value);
104 break;
105
106 case VIDIOC_G_CHIP_IDENT:
107 return v4l2_chip_ident_i2c_client(client,
108 arg, V4L2_IDENT_CS53l32A, 0);
109
110 case VIDIOC_LOG_STATUS:
111 {
112 u8 v = cs53l32a_read(client, 0x01);
113 u8 m = cs53l32a_read(client, 0x03);
114 s8 vol = cs53l32a_read(client, 0x04);
115
116 v4l_info(client, "Input: %d%s\n", (v >> 4) & 3,
117 (m & 0xC0) ? " (muted)" : "");
118 v4l_info(client, "Volume: %d dB\n", vol);
119 break;
120 }
121
122 default:
123 return -EINVAL; 72 return -EINVAL;
124 } 73 }
74 cs53l32a_write(sd, 0x01, 0x01 + (route->input << 4));
75 return 0;
76}
77
78static int cs53l32a_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
79{
80 if (ctrl->id == V4L2_CID_AUDIO_MUTE) {
81 ctrl->value = (cs53l32a_read(sd, 0x03) & 0xc0) != 0;
82 return 0;
83 }
84 if (ctrl->id != V4L2_CID_AUDIO_VOLUME)
85 return -EINVAL;
86 ctrl->value = (s8)cs53l32a_read(sd, 0x04);
87 return 0;
88}
89
90static int cs53l32a_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
91{
92 if (ctrl->id == V4L2_CID_AUDIO_MUTE) {
93 cs53l32a_write(sd, 0x03, ctrl->value ? 0xf0 : 0x30);
94 return 0;
95 }
96 if (ctrl->id != V4L2_CID_AUDIO_VOLUME)
97 return -EINVAL;
98 if (ctrl->value > 12 || ctrl->value < -96)
99 return -EINVAL;
100 cs53l32a_write(sd, 0x04, (u8) ctrl->value);
101 cs53l32a_write(sd, 0x05, (u8) ctrl->value);
125 return 0; 102 return 0;
126} 103}
127 104
105static int cs53l32a_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_chip_ident *chip)
106{
107 struct i2c_client *client = v4l2_get_subdevdata(sd);
108
109 return v4l2_chip_ident_i2c_client(client,
110 chip, V4L2_IDENT_CS53l32A, 0);
111}
112
113static int cs53l32a_log_status(struct v4l2_subdev *sd)
114{
115 u8 v = cs53l32a_read(sd, 0x01);
116 u8 m = cs53l32a_read(sd, 0x03);
117 s8 vol = cs53l32a_read(sd, 0x04);
118
119 v4l2_info(sd, "Input: %d%s\n", (v >> 4) & 3,
120 (m & 0xC0) ? " (muted)" : "");
121 v4l2_info(sd, "Volume: %d dB\n", vol);
122 return 0;
123}
124
125static int cs53l32a_command(struct i2c_client *client, unsigned cmd, void *arg)
126{
127 return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
128}
129
130/* ----------------------------------------------------------------------- */
131
132static const struct v4l2_subdev_core_ops cs53l32a_core_ops = {
133 .log_status = cs53l32a_log_status,
134 .g_chip_ident = cs53l32a_g_chip_ident,
135 .g_ctrl = cs53l32a_g_ctrl,
136 .s_ctrl = cs53l32a_s_ctrl,
137};
138
139static const struct v4l2_subdev_audio_ops cs53l32a_audio_ops = {
140 .s_routing = cs53l32a_s_routing,
141};
142
143static const struct v4l2_subdev_ops cs53l32a_ops = {
144 .core = &cs53l32a_core_ops,
145 .audio = &cs53l32a_audio_ops,
146};
147
128/* ----------------------------------------------------------------------- */ 148/* ----------------------------------------------------------------------- */
129 149
130/* i2c implementation */ 150/* i2c implementation */
@@ -137,6 +157,7 @@ static int cs53l32a_command(struct i2c_client *client, unsigned cmd, void *arg)
137static int cs53l32a_probe(struct i2c_client *client, 157static int cs53l32a_probe(struct i2c_client *client,
138 const struct i2c_device_id *id) 158 const struct i2c_device_id *id)
139{ 159{
160 struct v4l2_subdev *sd;
140 int i; 161 int i;
141 162
142 /* Check if the adapter supports the needed features */ 163 /* Check if the adapter supports the needed features */
@@ -149,32 +170,46 @@ static int cs53l32a_probe(struct i2c_client *client,
149 v4l_info(client, "chip found @ 0x%x (%s)\n", 170 v4l_info(client, "chip found @ 0x%x (%s)\n",
150 client->addr << 1, client->adapter->name); 171 client->addr << 1, client->adapter->name);
151 172
173 sd = kmalloc(sizeof(struct v4l2_subdev), GFP_KERNEL);
174 if (sd == NULL)
175 return -ENOMEM;
176 v4l2_i2c_subdev_init(sd, client, &cs53l32a_ops);
177
152 for (i = 1; i <= 7; i++) { 178 for (i = 1; i <= 7; i++) {
153 u8 v = cs53l32a_read(client, i); 179 u8 v = cs53l32a_read(sd, i);
154 180
155 v4l_dbg(1, debug, client, "Read Reg %d %02x\n", i, v); 181 v4l2_dbg(1, debug, sd, "Read Reg %d %02x\n", i, v);
156 } 182 }
157 183
158 /* Set cs53l32a internal register for Adaptec 2010/2410 setup */ 184 /* Set cs53l32a internal register for Adaptec 2010/2410 setup */
159 185
160 cs53l32a_write(client, 0x01, (u8) 0x21); 186 cs53l32a_write(sd, 0x01, (u8) 0x21);
161 cs53l32a_write(client, 0x02, (u8) 0x29); 187 cs53l32a_write(sd, 0x02, (u8) 0x29);
162 cs53l32a_write(client, 0x03, (u8) 0x30); 188 cs53l32a_write(sd, 0x03, (u8) 0x30);
163 cs53l32a_write(client, 0x04, (u8) 0x00); 189 cs53l32a_write(sd, 0x04, (u8) 0x00);
164 cs53l32a_write(client, 0x05, (u8) 0x00); 190 cs53l32a_write(sd, 0x05, (u8) 0x00);
165 cs53l32a_write(client, 0x06, (u8) 0x00); 191 cs53l32a_write(sd, 0x06, (u8) 0x00);
166 cs53l32a_write(client, 0x07, (u8) 0x00); 192 cs53l32a_write(sd, 0x07, (u8) 0x00);
167 193
168 /* Display results, should be 0x21,0x29,0x30,0x00,0x00,0x00,0x00 */ 194 /* Display results, should be 0x21,0x29,0x30,0x00,0x00,0x00,0x00 */
169 195
170 for (i = 1; i <= 7; i++) { 196 for (i = 1; i <= 7; i++) {
171 u8 v = cs53l32a_read(client, i); 197 u8 v = cs53l32a_read(sd, i);
172 198
173 v4l_dbg(1, debug, client, "Read Reg %d %02x\n", i, v); 199 v4l2_dbg(1, debug, sd, "Read Reg %d %02x\n", i, v);
174 } 200 }
175 return 0; 201 return 0;
176} 202}
177 203
204static int cs53l32a_remove(struct i2c_client *client)
205{
206 struct v4l2_subdev *sd = i2c_get_clientdata(client);
207
208 v4l2_device_unregister_subdev(sd);
209 kfree(sd);
210 return 0;
211}
212
178static const struct i2c_device_id cs53l32a_id[] = { 213static const struct i2c_device_id cs53l32a_id[] = {
179 { "cs53l32a", 0 }, 214 { "cs53l32a", 0 },
180 { } 215 { }
@@ -185,6 +220,7 @@ static struct v4l2_i2c_driver_data v4l2_i2c_data = {
185 .name = "cs53l32a", 220 .name = "cs53l32a",
186 .driverid = I2C_DRIVERID_CS53L32A, 221 .driverid = I2C_DRIVERID_CS53L32A,
187 .command = cs53l32a_command, 222 .command = cs53l32a_command,
223 .remove = cs53l32a_remove,
188 .probe = cs53l32a_probe, 224 .probe = cs53l32a_probe,
189 .id_table = cs53l32a_id, 225 .id_table = cs53l32a_id,
190}; 226};
diff --git a/drivers/media/video/cx18/cx18-av-audio.c b/drivers/media/video/cx18/cx18-av-audio.c
index 0b55837880a7..a2f0ad570434 100644
--- a/drivers/media/video/cx18/cx18-av-audio.c
+++ b/drivers/media/video/cx18/cx18-av-audio.c
@@ -4,6 +4,7 @@
4 * Derived from cx25840-audio.c 4 * Derived from cx25840-audio.c
5 * 5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> 6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 * Copyright (C) 2008 Andy Walls <awalls@radix.net>
7 * 8 *
8 * This program is free software; you can redistribute it and/or 9 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License 10 * modify it under the terms of the GNU General Public License
@@ -30,98 +31,165 @@ static int set_audclk_freq(struct cx18 *cx, u32 freq)
30 if (freq != 32000 && freq != 44100 && freq != 48000) 31 if (freq != 32000 && freq != 44100 && freq != 48000)
31 return -EINVAL; 32 return -EINVAL;
32 33
33 /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x10 */ 34 /*
34 cx18_av_write(cx, 0x127, 0x50); 35 * The PLL parameters are based on the external crystal frequency that
36 * would ideally be:
37 *
38 * NTSC Color subcarrier freq * 8 =
39 * 4.5 MHz/286 * 455/2 * 8 = 28.63636363... MHz
40 *
41 * The accidents of history and rationale that explain from where this
42 * combination of magic numbers originate can be found in:
43 *
44 * [1] Abrahams, I. C., "Choice of Chrominance Subcarrier Frequency in
45 * the NTSC Standards", Proceedings of the I-R-E, January 1954, pp 79-80
46 *
47 * [2] Abrahams, I. C., "The 'Frequency Interleaving' Principle in the
48 * NTSC Standards", Proceedings of the I-R-E, January 1954, pp 81-83
49 *
50 * As Mike Bradley has rightly pointed out, it's not the exact crystal
51 * frequency that matters, only that all parts of the driver and
52 * firmware are using the same value (close to the ideal value).
53 *
54 * Since I have a strong suspicion that, if the firmware ever assumes a
55 * crystal value at all, it will assume 28.636360 MHz, the crystal
56 * freq used in calculations in this driver will be:
57 *
58 * xtal_freq = 28.636360 MHz
59 *
60 * an error of less than 0.13 ppm which is way, way better than any off
61 * the shelf crystal will have for accuracy anyway.
62 *
63 * Below I aim to run the PLLs' VCOs near 400 MHz to minimze error.
64 *
65 * Many thanks to Jeff Campbell and Mike Bradley for their extensive
66 * investigation, experimentation, testing, and suggested solutions of
67 * of audio/video sync problems with SVideo and CVBS captures.
68 */
35 69
36 if (state->aud_input > CX18_AV_AUDIO_SERIAL2) { 70 if (state->aud_input > CX18_AV_AUDIO_SERIAL2) {
37 switch (freq) { 71 switch (freq) {
38 case 32000: 72 case 32000:
39 /* VID_PLL and AUX_PLL */ 73 /*
40 cx18_av_write4(cx, 0x108, 0x1408040f); 74 * VID_PLL Integer = 0x0f, VID_PLL Post Divider = 0x04
75 * AUX_PLL Integer = 0x0d, AUX PLL Post Divider = 0x20
76 */
77 cx18_av_write4(cx, 0x108, 0x200d040f);
41 78
42 /* AUX_PLL_FRAC */ 79 /* VID_PLL Fraction = 0x2be2fe */
43 /* 0x8.9504318a * 28,636,363.636 / 0x14 = 32000 * 384 */ 80 /* xtal * 0xf.15f17f0/4 = 108 MHz: 432 MHz pre-postdiv*/
44 cx18_av_write4(cx, 0x110, 0x012a0863); 81 cx18_av_write4(cx, 0x10c, 0x002be2fe);
82
83 /* AUX_PLL Fraction = 0x176740c */
84 /* xtal * 0xd.bb3a060/0x20 = 32000 * 384: 393 MHz p-pd*/
85 cx18_av_write4(cx, 0x110, 0x0176740c);
45 86
46 /* src3/4/6_ctl */ 87 /* src3/4/6_ctl */
47 /* 0x1.f77f = (4 * 15734.26) / 32000 */ 88 /* 0x1.f77f = (4 * xtal/8*2/455) / 32000 */
48 cx18_av_write4(cx, 0x900, 0x0801f77f); 89 cx18_av_write4(cx, 0x900, 0x0801f77f);
49 cx18_av_write4(cx, 0x904, 0x0801f77f); 90 cx18_av_write4(cx, 0x904, 0x0801f77f);
50 cx18_av_write4(cx, 0x90c, 0x0801f77f); 91 cx18_av_write4(cx, 0x90c, 0x0801f77f);
51 92
52 /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x14 */ 93 /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x20 */
53 cx18_av_write(cx, 0x127, 0x54); 94 cx18_av_write(cx, 0x127, 0x60);
54 95
55 /* AUD_COUNT = 0x2fff = 8 samples * 4 * 384 - 1 */ 96 /* AUD_COUNT = 0x2fff = 8 samples * 4 * 384 - 1 */
56 cx18_av_write4(cx, 0x12c, 0x11202fff); 97 cx18_av_write4(cx, 0x12c, 0x11202fff);
57 98
58 /* 99 /*
59 * EN_AV_LOCK = 1 100 * EN_AV_LOCK = 0
60 * VID_COUNT = 0x0d2ef8 = 107999.000 * 8 = 101 * VID_COUNT = 0x0d2ef8 = 107999.000 * 8 =
61 * ((8 samples/32,000) * (13,500,000 * 8) * 4 - 1) * 8 102 * ((8 samples/32,000) * (13,500,000 * 8) * 4 - 1) * 8
62 */ 103 */
63 cx18_av_write4(cx, 0x128, 0xa10d2ef8); 104 cx18_av_write4(cx, 0x128, 0xa00d2ef8);
64 break; 105 break;
65 106
66 case 44100: 107 case 44100:
67 /* VID_PLL and AUX_PLL */ 108 /*
68 cx18_av_write4(cx, 0x108, 0x1009040f); 109 * VID_PLL Integer = 0x0f, VID_PLL Post Divider = 0x04
110 * AUX_PLL Integer = 0x0e, AUX PLL Post Divider = 0x18
111 */
112 cx18_av_write4(cx, 0x108, 0x180e040f);
113
114 /* VID_PLL Fraction = 0x2be2fe */
115 /* xtal * 0xf.15f17f0/4 = 108 MHz: 432 MHz pre-postdiv*/
116 cx18_av_write4(cx, 0x10c, 0x002be2fe);
69 117
70 /* AUX_PLL_FRAC */ 118 /* AUX_PLL Fraction = 0x062a1f2 */
71 /* 0x9.7635e7 * 28,636,363.63 / 0x10 = 44100 * 384 */ 119 /* xtal * 0xe.3150f90/0x18 = 44100 * 384: 406 MHz p-pd*/
72 cx18_av_write4(cx, 0x110, 0x00ec6bce); 120 cx18_av_write4(cx, 0x110, 0x0062a1f2);
73 121
74 /* src3/4/6_ctl */ 122 /* src3/4/6_ctl */
75 /* 0x1.6d59 = (4 * 15734.26) / 44100 */ 123 /* 0x1.6d59 = (4 * xtal/8*2/455) / 44100 */
76 cx18_av_write4(cx, 0x900, 0x08016d59); 124 cx18_av_write4(cx, 0x900, 0x08016d59);
77 cx18_av_write4(cx, 0x904, 0x08016d59); 125 cx18_av_write4(cx, 0x904, 0x08016d59);
78 cx18_av_write4(cx, 0x90c, 0x08016d59); 126 cx18_av_write4(cx, 0x90c, 0x08016d59);
79 127
128 /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x18 */
129 cx18_av_write(cx, 0x127, 0x58);
130
80 /* AUD_COUNT = 0x92ff = 49 samples * 2 * 384 - 1 */ 131 /* AUD_COUNT = 0x92ff = 49 samples * 2 * 384 - 1 */
81 cx18_av_write4(cx, 0x12c, 0x112092ff); 132 cx18_av_write4(cx, 0x12c, 0x112092ff);
82 133
83 /* 134 /*
84 * EN_AV_LOCK = 1 135 * EN_AV_LOCK = 0
85 * VID_COUNT = 0x1d4bf8 = 239999.000 * 8 = 136 * VID_COUNT = 0x1d4bf8 = 239999.000 * 8 =
86 * ((49 samples/44,100) * (13,500,000 * 8) * 2 - 1) * 8 137 * ((49 samples/44,100) * (13,500,000 * 8) * 2 - 1) * 8
87 */ 138 */
88 cx18_av_write4(cx, 0x128, 0xa11d4bf8); 139 cx18_av_write4(cx, 0x128, 0xa01d4bf8);
89 break; 140 break;
90 141
91 case 48000: 142 case 48000:
92 /* VID_PLL and AUX_PLL */ 143 /*
93 cx18_av_write4(cx, 0x108, 0x100a040f); 144 * VID_PLL Integer = 0x0f, VID_PLL Post Divider = 0x04
145 * AUX_PLL Integer = 0x0e, AUX PLL Post Divider = 0x16
146 */
147 cx18_av_write4(cx, 0x108, 0x160e040f);
94 148
95 /* AUX_PLL_FRAC */ 149 /* VID_PLL Fraction = 0x2be2fe */
96 /* 0xa.4c6b6ea * 28,636,363.63 / 0x10 = 48000 * 384 */ 150 /* xtal * 0xf.15f17f0/4 = 108 MHz: 432 MHz pre-postdiv*/
97 cx18_av_write4(cx, 0x110, 0x0098d6dd); 151 cx18_av_write4(cx, 0x10c, 0x002be2fe);
152
153 /* AUX_PLL Fraction = 0x05227ad */
154 /* xtal * 0xe.2913d68/0x16 = 48000 * 384: 406 MHz p-pd*/
155 cx18_av_write4(cx, 0x110, 0x005227ad);
98 156
99 /* src3/4/6_ctl */ 157 /* src3/4/6_ctl */
100 /* 0x1.4faa = (4 * 15734.26) / 48000 */ 158 /* 0x1.4faa = (4 * xtal/8*2/455) / 48000 */
101 cx18_av_write4(cx, 0x900, 0x08014faa); 159 cx18_av_write4(cx, 0x900, 0x08014faa);
102 cx18_av_write4(cx, 0x904, 0x08014faa); 160 cx18_av_write4(cx, 0x904, 0x08014faa);
103 cx18_av_write4(cx, 0x90c, 0x08014faa); 161 cx18_av_write4(cx, 0x90c, 0x08014faa);
104 162
163 /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x16 */
164 cx18_av_write(cx, 0x127, 0x56);
165
105 /* AUD_COUNT = 0x5fff = 4 samples * 16 * 384 - 1 */ 166 /* AUD_COUNT = 0x5fff = 4 samples * 16 * 384 - 1 */
106 cx18_av_write4(cx, 0x12c, 0x11205fff); 167 cx18_av_write4(cx, 0x12c, 0x11205fff);
107 168
108 /* 169 /*
109 * EN_AV_LOCK = 1 170 * EN_AV_LOCK = 0
110 * VID_COUNT = 0x1193f8 = 143999.000 * 8 = 171 * VID_COUNT = 0x1193f8 = 143999.000 * 8 =
111 * ((4 samples/48,000) * (13,500,000 * 8) * 16 - 1) * 8 172 * ((4 samples/48,000) * (13,500,000 * 8) * 16 - 1) * 8
112 */ 173 */
113 cx18_av_write4(cx, 0x128, 0xa11193f8); 174 cx18_av_write4(cx, 0x128, 0xa01193f8);
114 break; 175 break;
115 } 176 }
116 } else { 177 } else {
117 switch (freq) { 178 switch (freq) {
118 case 32000: 179 case 32000:
119 /* VID_PLL and AUX_PLL */ 180 /*
120 cx18_av_write4(cx, 0x108, 0x1e08040f); 181 * VID_PLL Integer = 0x0f, VID_PLL Post Divider = 0x04
182 * AUX_PLL Integer = 0x0d, AUX PLL Post Divider = 0x30
183 */
184 cx18_av_write4(cx, 0x108, 0x300d040f);
185
186 /* VID_PLL Fraction = 0x2be2fe */
187 /* xtal * 0xf.15f17f0/4 = 108 MHz: 432 MHz pre-postdiv*/
188 cx18_av_write4(cx, 0x10c, 0x002be2fe);
121 189
122 /* AUX_PLL_FRAC */ 190 /* AUX_PLL Fraction = 0x176740c */
123 /* 0x8.9504318 * 28,636,363.63 / 0x1e = 32000 * 256 */ 191 /* xtal * 0xd.bb3a060/0x30 = 32000 * 256: 393 MHz p-pd*/
124 cx18_av_write4(cx, 0x110, 0x012a0863); 192 cx18_av_write4(cx, 0x110, 0x0176740c);
125 193
126 /* src1_ctl */ 194 /* src1_ctl */
127 /* 0x1.0000 = 32000/32000 */ 195 /* 0x1.0000 = 32000/32000 */
@@ -133,27 +201,34 @@ static int set_audclk_freq(struct cx18 *cx, u32 freq)
133 cx18_av_write4(cx, 0x904, 0x08020000); 201 cx18_av_write4(cx, 0x904, 0x08020000);
134 cx18_av_write4(cx, 0x90c, 0x08020000); 202 cx18_av_write4(cx, 0x90c, 0x08020000);
135 203
136 /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x14 */ 204 /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x30 */
137 cx18_av_write(cx, 0x127, 0x54); 205 cx18_av_write(cx, 0x127, 0x70);
138 206
139 /* AUD_COUNT = 0x1fff = 8 samples * 4 * 256 - 1 */ 207 /* AUD_COUNT = 0x1fff = 8 samples * 4 * 256 - 1 */
140 cx18_av_write4(cx, 0x12c, 0x11201fff); 208 cx18_av_write4(cx, 0x12c, 0x11201fff);
141 209
142 /* 210 /*
143 * EN_AV_LOCK = 1 211 * EN_AV_LOCK = 0
144 * VID_COUNT = 0x0d2ef8 = 107999.000 * 8 = 212 * VID_COUNT = 0x0d2ef8 = 107999.000 * 8 =
145 * ((8 samples/32,000) * (13,500,000 * 8) * 4 - 1) * 8 213 * ((8 samples/32,000) * (13,500,000 * 8) * 4 - 1) * 8
146 */ 214 */
147 cx18_av_write4(cx, 0x128, 0xa10d2ef8); 215 cx18_av_write4(cx, 0x128, 0xa00d2ef8);
148 break; 216 break;
149 217
150 case 44100: 218 case 44100:
151 /* VID_PLL and AUX_PLL */ 219 /*
152 cx18_av_write4(cx, 0x108, 0x1809040f); 220 * VID_PLL Integer = 0x0f, VID_PLL Post Divider = 0x04
221 * AUX_PLL Integer = 0x0e, AUX PLL Post Divider = 0x24
222 */
223 cx18_av_write4(cx, 0x108, 0x240e040f);
153 224
154 /* AUX_PLL_FRAC */ 225 /* VID_PLL Fraction = 0x2be2fe */
155 /* 0x9.7635e74 * 28,636,363.63 / 0x18 = 44100 * 256 */ 226 /* xtal * 0xf.15f17f0/4 = 108 MHz: 432 MHz pre-postdiv*/
156 cx18_av_write4(cx, 0x110, 0x00ec6bce); 227 cx18_av_write4(cx, 0x10c, 0x002be2fe);
228
229 /* AUX_PLL Fraction = 0x062a1f2 */
230 /* xtal * 0xe.3150f90/0x24 = 44100 * 256: 406 MHz p-pd*/
231 cx18_av_write4(cx, 0x110, 0x0062a1f2);
157 232
158 /* src1_ctl */ 233 /* src1_ctl */
159 /* 0x1.60cd = 44100/32000 */ 234 /* 0x1.60cd = 44100/32000 */
@@ -165,24 +240,34 @@ static int set_audclk_freq(struct cx18 *cx, u32 freq)
165 cx18_av_write4(cx, 0x904, 0x08017385); 240 cx18_av_write4(cx, 0x904, 0x08017385);
166 cx18_av_write4(cx, 0x90c, 0x08017385); 241 cx18_av_write4(cx, 0x90c, 0x08017385);
167 242
243 /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x24 */
244 cx18_av_write(cx, 0x127, 0x64);
245
168 /* AUD_COUNT = 0x61ff = 49 samples * 2 * 256 - 1 */ 246 /* AUD_COUNT = 0x61ff = 49 samples * 2 * 256 - 1 */
169 cx18_av_write4(cx, 0x12c, 0x112061ff); 247 cx18_av_write4(cx, 0x12c, 0x112061ff);
170 248
171 /* 249 /*
172 * EN_AV_LOCK = 1 250 * EN_AV_LOCK = 0
173 * VID_COUNT = 0x1d4bf8 = 239999.000 * 8 = 251 * VID_COUNT = 0x1d4bf8 = 239999.000 * 8 =
174 * ((49 samples/44,100) * (13,500,000 * 8) * 2 - 1) * 8 252 * ((49 samples/44,100) * (13,500,000 * 8) * 2 - 1) * 8
175 */ 253 */
176 cx18_av_write4(cx, 0x128, 0xa11d4bf8); 254 cx18_av_write4(cx, 0x128, 0xa01d4bf8);
177 break; 255 break;
178 256
179 case 48000: 257 case 48000:
180 /* VID_PLL and AUX_PLL */ 258 /*
181 cx18_av_write4(cx, 0x108, 0x180a040f); 259 * VID_PLL Integer = 0x0f, VID_PLL Post Divider = 0x04
260 * AUX_PLL Integer = 0x0d, AUX PLL Post Divider = 0x20
261 */
262 cx18_av_write4(cx, 0x108, 0x200d040f);
263
264 /* VID_PLL Fraction = 0x2be2fe */
265 /* xtal * 0xf.15f17f0/4 = 108 MHz: 432 MHz pre-postdiv*/
266 cx18_av_write4(cx, 0x10c, 0x002be2fe);
182 267
183 /* AUX_PLL_FRAC */ 268 /* AUX_PLL Fraction = 0x176740c */
184 /* 0xa.4c6b6ea * 28,636,363.63 / 0x18 = 48000 * 256 */ 269 /* xtal * 0xd.bb3a060/0x20 = 48000 * 256: 393 MHz p-pd*/
185 cx18_av_write4(cx, 0x110, 0x0098d6dd); 270 cx18_av_write4(cx, 0x110, 0x0176740c);
186 271
187 /* src1_ctl */ 272 /* src1_ctl */
188 /* 0x1.8000 = 48000/32000 */ 273 /* 0x1.8000 = 48000/32000 */
@@ -194,15 +279,18 @@ static int set_audclk_freq(struct cx18 *cx, u32 freq)
194 cx18_av_write4(cx, 0x904, 0x08015555); 279 cx18_av_write4(cx, 0x904, 0x08015555);
195 cx18_av_write4(cx, 0x90c, 0x08015555); 280 cx18_av_write4(cx, 0x90c, 0x08015555);
196 281
282 /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x20 */
283 cx18_av_write(cx, 0x127, 0x60);
284
197 /* AUD_COUNT = 0x3fff = 4 samples * 16 * 256 - 1 */ 285 /* AUD_COUNT = 0x3fff = 4 samples * 16 * 256 - 1 */
198 cx18_av_write4(cx, 0x12c, 0x11203fff); 286 cx18_av_write4(cx, 0x12c, 0x11203fff);
199 287
200 /* 288 /*
201 * EN_AV_LOCK = 1 289 * EN_AV_LOCK = 0
202 * VID_COUNT = 0x1193f8 = 143999.000 * 8 = 290 * VID_COUNT = 0x1193f8 = 143999.000 * 8 =
203 * ((4 samples/48,000) * (13,500,000 * 8) * 16 - 1) * 8 291 * ((4 samples/48,000) * (13,500,000 * 8) * 16 - 1) * 8
204 */ 292 */
205 cx18_av_write4(cx, 0x128, 0xa11193f8); 293 cx18_av_write4(cx, 0x128, 0xa01193f8);
206 break; 294 break;
207 } 295 }
208 } 296 }
@@ -215,12 +303,15 @@ static int set_audclk_freq(struct cx18 *cx, u32 freq)
215void cx18_av_audio_set_path(struct cx18 *cx) 303void cx18_av_audio_set_path(struct cx18 *cx)
216{ 304{
217 struct cx18_av_state *state = &cx->av_state; 305 struct cx18_av_state *state = &cx->av_state;
306 u8 v;
218 307
219 /* stop microcontroller */ 308 /* stop microcontroller */
220 cx18_av_and_or(cx, 0x803, ~0x10, 0); 309 v = cx18_av_read(cx, 0x803) & ~0x10;
310 cx18_av_write_expect(cx, 0x803, v, v, 0x1f);
221 311
222 /* assert soft reset */ 312 /* assert soft reset */
223 cx18_av_and_or(cx, 0x810, ~0x1, 0x01); 313 v = cx18_av_read(cx, 0x810) | 0x01;
314 cx18_av_write_expect(cx, 0x810, v, v, 0x0f);
224 315
225 /* Mute everything to prevent the PFFT! */ 316 /* Mute everything to prevent the PFFT! */
226 cx18_av_write(cx, 0x8d3, 0x1f); 317 cx18_av_write(cx, 0x8d3, 0x1f);
@@ -240,12 +331,14 @@ void cx18_av_audio_set_path(struct cx18 *cx)
240 set_audclk_freq(cx, state->audclk_freq); 331 set_audclk_freq(cx, state->audclk_freq);
241 332
242 /* deassert soft reset */ 333 /* deassert soft reset */
243 cx18_av_and_or(cx, 0x810, ~0x1, 0x00); 334 v = cx18_av_read(cx, 0x810) & ~0x01;
335 cx18_av_write_expect(cx, 0x810, v, v, 0x0f);
244 336
245 if (state->aud_input > CX18_AV_AUDIO_SERIAL2) { 337 if (state->aud_input > CX18_AV_AUDIO_SERIAL2) {
246 /* When the microcontroller detects the 338 /* When the microcontroller detects the
247 * audio format, it will unmute the lines */ 339 * audio format, it will unmute the lines */
248 cx18_av_and_or(cx, 0x803, ~0x10, 0x10); 340 v = cx18_av_read(cx, 0x803) | 0x10;
341 cx18_av_write_expect(cx, 0x803, v, v, 0x1f);
249 } 342 }
250} 343}
251 344
@@ -347,19 +440,23 @@ static int get_mute(struct cx18 *cx)
347static void set_mute(struct cx18 *cx, int mute) 440static void set_mute(struct cx18 *cx, int mute)
348{ 441{
349 struct cx18_av_state *state = &cx->av_state; 442 struct cx18_av_state *state = &cx->av_state;
443 u8 v;
350 444
351 if (state->aud_input > CX18_AV_AUDIO_SERIAL2) { 445 if (state->aud_input > CX18_AV_AUDIO_SERIAL2) {
352 /* Must turn off microcontroller in order to mute sound. 446 /* Must turn off microcontroller in order to mute sound.
353 * Not sure if this is the best method, but it does work. 447 * Not sure if this is the best method, but it does work.
354 * If the microcontroller is running, then it will undo any 448 * If the microcontroller is running, then it will undo any
355 * changes to the mute register. */ 449 * changes to the mute register. */
450 v = cx18_av_read(cx, 0x803);
356 if (mute) { 451 if (mute) {
357 /* disable microcontroller */ 452 /* disable microcontroller */
358 cx18_av_and_or(cx, 0x803, ~0x10, 0x00); 453 v &= ~0x10;
454 cx18_av_write_expect(cx, 0x803, v, v, 0x1f);
359 cx18_av_write(cx, 0x8d3, 0x1f); 455 cx18_av_write(cx, 0x8d3, 0x1f);
360 } else { 456 } else {
361 /* enable microcontroller */ 457 /* enable microcontroller */
362 cx18_av_and_or(cx, 0x803, ~0x10, 0x10); 458 v |= 0x10;
459 cx18_av_write_expect(cx, 0x803, v, v, 0x1f);
363 } 460 }
364 } else { 461 } else {
365 /* SRC1_MUTE_EN */ 462 /* SRC1_MUTE_EN */
@@ -375,16 +472,26 @@ int cx18_av_audio(struct cx18 *cx, unsigned int cmd, void *arg)
375 472
376 switch (cmd) { 473 switch (cmd) {
377 case VIDIOC_INT_AUDIO_CLOCK_FREQ: 474 case VIDIOC_INT_AUDIO_CLOCK_FREQ:
475 {
476 u8 v;
378 if (state->aud_input > CX18_AV_AUDIO_SERIAL2) { 477 if (state->aud_input > CX18_AV_AUDIO_SERIAL2) {
379 cx18_av_and_or(cx, 0x803, ~0x10, 0); 478 v = cx18_av_read(cx, 0x803) & ~0x10;
479 cx18_av_write_expect(cx, 0x803, v, v, 0x1f);
380 cx18_av_write(cx, 0x8d3, 0x1f); 480 cx18_av_write(cx, 0x8d3, 0x1f);
381 } 481 }
382 cx18_av_and_or(cx, 0x810, ~0x1, 1); 482 v = cx18_av_read(cx, 0x810) | 0x1;
483 cx18_av_write_expect(cx, 0x810, v, v, 0x0f);
484
383 retval = set_audclk_freq(cx, *(u32 *)arg); 485 retval = set_audclk_freq(cx, *(u32 *)arg);
384 cx18_av_and_or(cx, 0x810, ~0x1, 0); 486
385 if (state->aud_input > CX18_AV_AUDIO_SERIAL2) 487 v = cx18_av_read(cx, 0x810) & ~0x1;
386 cx18_av_and_or(cx, 0x803, ~0x10, 0x10); 488 cx18_av_write_expect(cx, 0x810, v, v, 0x0f);
489 if (state->aud_input > CX18_AV_AUDIO_SERIAL2) {
490 v = cx18_av_read(cx, 0x803) | 0x10;
491 cx18_av_write_expect(cx, 0x803, v, v, 0x1f);
492 }
387 return retval; 493 return retval;
494 }
388 495
389 case VIDIOC_G_CTRL: 496 case VIDIOC_G_CTRL:
390 switch (ctrl->id) { 497 switch (ctrl->id) {
diff --git a/drivers/media/video/cx18/cx18-av-core.c b/drivers/media/video/cx18/cx18-av-core.c
index 73f5141a42d1..0b1c84b4ddd6 100644
--- a/drivers/media/video/cx18/cx18-av-core.c
+++ b/drivers/media/video/cx18/cx18-av-core.c
@@ -4,6 +4,7 @@
4 * Derived from cx25840-core.c 4 * Derived from cx25840-core.c
5 * 5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> 6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 * Copyright (C) 2008 Andy Walls <awalls@radix.net>
7 * 8 *
8 * This program is free software; you can redistribute it and/or 9 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License 10 * modify it under the terms of the GNU General Public License
@@ -36,12 +37,31 @@ int cx18_av_write(struct cx18 *cx, u16 addr, u8 value)
36 return 0; 37 return 0;
37} 38}
38 39
40int cx18_av_write_expect(struct cx18 *cx, u16 addr, u8 value, u8 eval, u8 mask)
41{
42 u32 reg = 0xc40000 + (addr & ~3);
43 int shift = (addr & 3) * 8;
44 u32 x = cx18_read_reg(cx, reg);
45
46 x = (x & ~((u32)0xff << shift)) | ((u32)value << shift);
47 cx18_write_reg_expect(cx, x, reg,
48 ((u32)eval << shift), ((u32)mask << shift));
49 return 0;
50}
51
39int cx18_av_write4(struct cx18 *cx, u16 addr, u32 value) 52int cx18_av_write4(struct cx18 *cx, u16 addr, u32 value)
40{ 53{
41 cx18_write_reg(cx, value, 0xc40000 + addr); 54 cx18_write_reg(cx, value, 0xc40000 + addr);
42 return 0; 55 return 0;
43} 56}
44 57
58int
59cx18_av_write4_expect(struct cx18 *cx, u16 addr, u32 value, u32 eval, u32 mask)
60{
61 cx18_write_reg_expect(cx, value, 0xc40000 + addr, eval, mask);
62 return 0;
63}
64
45int cx18_av_write4_noretry(struct cx18 *cx, u16 addr, u32 value) 65int cx18_av_write4_noretry(struct cx18 *cx, u16 addr, u32 value)
46{ 66{
47 cx18_write_reg_noretry(cx, value, 0xc40000 + addr); 67 cx18_write_reg_noretry(cx, value, 0xc40000 + addr);
@@ -61,11 +81,6 @@ u32 cx18_av_read4(struct cx18 *cx, u16 addr)
61 return cx18_read_reg(cx, 0xc40000 + addr); 81 return cx18_read_reg(cx, 0xc40000 + addr);
62} 82}
63 83
64u32 cx18_av_read4_noretry(struct cx18 *cx, u16 addr)
65{
66 return cx18_read_reg_noretry(cx, 0xc40000 + addr);
67}
68
69int cx18_av_and_or(struct cx18 *cx, u16 addr, unsigned and_mask, 84int cx18_av_and_or(struct cx18 *cx, u16 addr, unsigned and_mask,
70 u8 or_value) 85 u8 or_value)
71{ 86{
@@ -98,14 +113,16 @@ static void cx18_av_initialize(struct cx18 *cx)
98 113
99 cx18_av_loadfw(cx); 114 cx18_av_loadfw(cx);
100 /* Stop 8051 code execution */ 115 /* Stop 8051 code execution */
101 cx18_av_write4(cx, CXADEC_DL_CTL, 0x03000000); 116 cx18_av_write4_expect(cx, CXADEC_DL_CTL, 0x03000000,
117 0x03000000, 0x13000000);
102 118
103 /* initallize the PLL by toggling sleep bit */ 119 /* initallize the PLL by toggling sleep bit */
104 v = cx18_av_read4(cx, CXADEC_HOST_REG1); 120 v = cx18_av_read4(cx, CXADEC_HOST_REG1);
105 /* enable sleep mode */ 121 /* enable sleep mode - register appears to be read only... */
106 cx18_av_write4(cx, CXADEC_HOST_REG1, v | 1); 122 cx18_av_write4_expect(cx, CXADEC_HOST_REG1, v | 1, v, 0xfffe);
107 /* disable sleep mode */ 123 /* disable sleep mode */
108 cx18_av_write4(cx, CXADEC_HOST_REG1, v & 0xfffe); 124 cx18_av_write4_expect(cx, CXADEC_HOST_REG1, v & 0xfffe,
125 v & 0xfffe, 0xffff);
109 126
110 /* initialize DLLs */ 127 /* initialize DLLs */
111 v = cx18_av_read4(cx, CXADEC_DLL1_DIAG_CTRL) & 0xE1FFFEFF; 128 v = cx18_av_read4(cx, CXADEC_DLL1_DIAG_CTRL) & 0xE1FFFEFF;
@@ -125,9 +142,10 @@ static void cx18_av_initialize(struct cx18 *cx)
125 142
126 v = cx18_av_read4(cx, CXADEC_AFE_DIAG_CTRL3) | 1; 143 v = cx18_av_read4(cx, CXADEC_AFE_DIAG_CTRL3) | 1;
127 /* enable TUNE_FIL_RST */ 144 /* enable TUNE_FIL_RST */
128 cx18_av_write4(cx, CXADEC_AFE_DIAG_CTRL3, v); 145 cx18_av_write4_expect(cx, CXADEC_AFE_DIAG_CTRL3, v, v, 0x03009F0F);
129 /* disable TUNE_FIL_RST */ 146 /* disable TUNE_FIL_RST */
130 cx18_av_write4(cx, CXADEC_AFE_DIAG_CTRL3, v & 0xFFFFFFFE); 147 cx18_av_write4_expect(cx, CXADEC_AFE_DIAG_CTRL3,
148 v & 0xFFFFFFFE, v & 0xFFFFFFFE, 0x03009F0F);
131 149
132 /* enable 656 output */ 150 /* enable 656 output */
133 cx18_av_and_or4(cx, CXADEC_PIN_CTRL1, ~0, 0x040C00); 151 cx18_av_and_or4(cx, CXADEC_PIN_CTRL1, ~0, 0x040C00);
@@ -251,10 +269,9 @@ void cx18_av_std_setup(struct cx18 *cx)
251 pll_int, pll_frac, pll_post); 269 pll_int, pll_frac, pll_post);
252 270
253 if (pll_post) { 271 if (pll_post) {
254 int fin, fsc; 272 int fin, fsc, pll;
255 int pll = 28636363L * ((((u64)pll_int) << 25) + pll_frac);
256 273
257 pll >>= 25; 274 pll = (28636360L * ((((u64)pll_int) << 25) + pll_frac)) >> 25;
258 pll /= pll_post; 275 pll /= pll_post;
259 CX18_DEBUG_INFO("PLL = %d.%06d MHz\n", 276 CX18_DEBUG_INFO("PLL = %d.%06d MHz\n",
260 pll / 1000000, pll % 1000000); 277 pll / 1000000, pll % 1000000);
@@ -324,6 +341,7 @@ static void input_change(struct cx18 *cx)
324{ 341{
325 struct cx18_av_state *state = &cx->av_state; 342 struct cx18_av_state *state = &cx->av_state;
326 v4l2_std_id std = state->std; 343 v4l2_std_id std = state->std;
344 u8 v;
327 345
328 /* Follow step 8c and 8d of section 3.16 in the cx18_av datasheet */ 346 /* Follow step 8c and 8d of section 3.16 in the cx18_av datasheet */
329 cx18_av_write(cx, 0x49f, (std & V4L2_STD_NTSC) ? 0x14 : 0x11); 347 cx18_av_write(cx, 0x49f, (std & V4L2_STD_NTSC) ? 0x14 : 0x11);
@@ -333,31 +351,34 @@ static void input_change(struct cx18 *cx)
333 if (std & V4L2_STD_525_60) { 351 if (std & V4L2_STD_525_60) {
334 if (std == V4L2_STD_NTSC_M_JP) { 352 if (std == V4L2_STD_NTSC_M_JP) {
335 /* Japan uses EIAJ audio standard */ 353 /* Japan uses EIAJ audio standard */
336 cx18_av_write(cx, 0x808, 0xf7); 354 cx18_av_write_expect(cx, 0x808, 0xf7, 0xf7, 0xff);
337 cx18_av_write(cx, 0x80b, 0x02); 355 cx18_av_write_expect(cx, 0x80b, 0x02, 0x02, 0x3f);
338 } else if (std == V4L2_STD_NTSC_M_KR) { 356 } else if (std == V4L2_STD_NTSC_M_KR) {
339 /* South Korea uses A2 audio standard */ 357 /* South Korea uses A2 audio standard */
340 cx18_av_write(cx, 0x808, 0xf8); 358 cx18_av_write_expect(cx, 0x808, 0xf8, 0xf8, 0xff);
341 cx18_av_write(cx, 0x80b, 0x03); 359 cx18_av_write_expect(cx, 0x80b, 0x03, 0x03, 0x3f);
342 } else { 360 } else {
343 /* Others use the BTSC audio standard */ 361 /* Others use the BTSC audio standard */
344 cx18_av_write(cx, 0x808, 0xf6); 362 cx18_av_write_expect(cx, 0x808, 0xf6, 0xf6, 0xff);
345 cx18_av_write(cx, 0x80b, 0x01); 363 cx18_av_write_expect(cx, 0x80b, 0x01, 0x01, 0x3f);
346 } 364 }
347 } else if (std & V4L2_STD_PAL) { 365 } else if (std & V4L2_STD_PAL) {
348 /* Follow tuner change procedure for PAL */ 366 /* Follow tuner change procedure for PAL */
349 cx18_av_write(cx, 0x808, 0xff); 367 cx18_av_write_expect(cx, 0x808, 0xff, 0xff, 0xff);
350 cx18_av_write(cx, 0x80b, 0x03); 368 cx18_av_write_expect(cx, 0x80b, 0x03, 0x03, 0x3f);
351 } else if (std & V4L2_STD_SECAM) { 369 } else if (std & V4L2_STD_SECAM) {
352 /* Select autodetect for SECAM */ 370 /* Select autodetect for SECAM */
353 cx18_av_write(cx, 0x808, 0xff); 371 cx18_av_write_expect(cx, 0x808, 0xff, 0xff, 0xff);
354 cx18_av_write(cx, 0x80b, 0x03); 372 cx18_av_write_expect(cx, 0x80b, 0x03, 0x03, 0x3f);
355 } 373 }
356 374
357 if (cx18_av_read(cx, 0x803) & 0x10) { 375 v = cx18_av_read(cx, 0x803);
376 if (v & 0x10) {
358 /* restart audio decoder microcontroller */ 377 /* restart audio decoder microcontroller */
359 cx18_av_and_or(cx, 0x803, ~0x10, 0x00); 378 v &= ~0x10;
360 cx18_av_and_or(cx, 0x803, ~0x10, 0x10); 379 cx18_av_write_expect(cx, 0x803, v, v, 0x1f);
380 v |= 0x10;
381 cx18_av_write_expect(cx, 0x803, v, v, 0x1f);
361 } 382 }
362} 383}
363 384
@@ -368,6 +389,7 @@ static int set_input(struct cx18 *cx, enum cx18_av_video_input vid_input,
368 u8 is_composite = (vid_input >= CX18_AV_COMPOSITE1 && 389 u8 is_composite = (vid_input >= CX18_AV_COMPOSITE1 &&
369 vid_input <= CX18_AV_COMPOSITE8); 390 vid_input <= CX18_AV_COMPOSITE8);
370 u8 reg; 391 u8 reg;
392 u8 v;
371 393
372 CX18_DEBUG_INFO("decoder set video input %d, audio input %d\n", 394 CX18_DEBUG_INFO("decoder set video input %d, audio input %d\n",
373 vid_input, aud_input); 395 vid_input, aud_input);
@@ -413,16 +435,23 @@ static int set_input(struct cx18 *cx, enum cx18_av_video_input vid_input,
413 return -EINVAL; 435 return -EINVAL;
414 } 436 }
415 437
416 cx18_av_write(cx, 0x103, reg); 438 cx18_av_write_expect(cx, 0x103, reg, reg, 0xf7);
417 /* Set INPUT_MODE to Composite (0) or S-Video (1) */ 439 /* Set INPUT_MODE to Composite (0) or S-Video (1) */
418 cx18_av_and_or(cx, 0x401, ~0x6, is_composite ? 0 : 0x02); 440 cx18_av_and_or(cx, 0x401, ~0x6, is_composite ? 0 : 0x02);
441
419 /* Set CH_SEL_ADC2 to 1 if input comes from CH3 */ 442 /* Set CH_SEL_ADC2 to 1 if input comes from CH3 */
420 cx18_av_and_or(cx, 0x102, ~0x2, (reg & 0x80) == 0 ? 2 : 0); 443 v = cx18_av_read(cx, 0x102);
444 if (reg & 0x80)
445 v &= ~0x2;
446 else
447 v |= 0x2;
421 /* Set DUAL_MODE_ADC2 to 1 if input comes from both CH2 and CH3 */ 448 /* Set DUAL_MODE_ADC2 to 1 if input comes from both CH2 and CH3 */
422 if ((reg & 0xc0) != 0xc0 && (reg & 0x30) != 0x30) 449 if ((reg & 0xc0) != 0xc0 && (reg & 0x30) != 0x30)
423 cx18_av_and_or(cx, 0x102, ~0x4, 4); 450 v |= 0x4;
424 else 451 else
425 cx18_av_and_or(cx, 0x102, ~0x4, 0); 452 v &= ~0x4;
453 cx18_av_write_expect(cx, 0x102, v, v, 0x17);
454
426 /*cx18_av_and_or4(cx, 0x104, ~0x001b4180, 0x00004180);*/ 455 /*cx18_av_and_or4(cx, 0x104, ~0x001b4180, 0x00004180);*/
427 456
428 state->vid_input = vid_input; 457 state->vid_input = vid_input;
@@ -799,40 +828,47 @@ int cx18_av_cmd(struct cx18 *cx, unsigned int cmd, void *arg)
799 } 828 }
800 829
801 case VIDIOC_S_TUNER: 830 case VIDIOC_S_TUNER:
831 {
832 u8 v;
833
802 if (state->radio) 834 if (state->radio)
803 break; 835 break;
804 836
837 v = cx18_av_read(cx, 0x809);
838 v &= ~0xf;
839
805 switch (vt->audmode) { 840 switch (vt->audmode) {
806 case V4L2_TUNER_MODE_MONO: 841 case V4L2_TUNER_MODE_MONO:
807 /* mono -> mono 842 /* mono -> mono
808 stereo -> mono 843 stereo -> mono
809 bilingual -> lang1 */ 844 bilingual -> lang1 */
810 cx18_av_and_or(cx, 0x809, ~0xf, 0x00);
811 break; 845 break;
812 case V4L2_TUNER_MODE_STEREO: 846 case V4L2_TUNER_MODE_STEREO:
813 case V4L2_TUNER_MODE_LANG1: 847 case V4L2_TUNER_MODE_LANG1:
814 /* mono -> mono 848 /* mono -> mono
815 stereo -> stereo 849 stereo -> stereo
816 bilingual -> lang1 */ 850 bilingual -> lang1 */
817 cx18_av_and_or(cx, 0x809, ~0xf, 0x04); 851 v |= 0x4;
818 break; 852 break;
819 case V4L2_TUNER_MODE_LANG1_LANG2: 853 case V4L2_TUNER_MODE_LANG1_LANG2:
820 /* mono -> mono 854 /* mono -> mono
821 stereo -> stereo 855 stereo -> stereo
822 bilingual -> lang1/lang2 */ 856 bilingual -> lang1/lang2 */
823 cx18_av_and_or(cx, 0x809, ~0xf, 0x07); 857 v |= 0x7;
824 break; 858 break;
825 case V4L2_TUNER_MODE_LANG2: 859 case V4L2_TUNER_MODE_LANG2:
826 /* mono -> mono 860 /* mono -> mono
827 stereo -> stereo 861 stereo -> stereo
828 bilingual -> lang2 */ 862 bilingual -> lang2 */
829 cx18_av_and_or(cx, 0x809, ~0xf, 0x01); 863 v |= 0x1;
830 break; 864 break;
831 default: 865 default:
832 return -EINVAL; 866 return -EINVAL;
833 } 867 }
868 cx18_av_write_expect(cx, 0x809, v, v, 0xff);
834 state->audmode = vt->audmode; 869 state->audmode = vt->audmode;
835 break; 870 break;
871 }
836 872
837 case VIDIOC_G_FMT: 873 case VIDIOC_G_FMT:
838 return get_v4lfmt(cx, (struct v4l2_format *)arg); 874 return get_v4lfmt(cx, (struct v4l2_format *)arg);
diff --git a/drivers/media/video/cx18/cx18-av-core.h b/drivers/media/video/cx18/cx18-av-core.h
index b67d8df20cc6..cf68a6039091 100644
--- a/drivers/media/video/cx18/cx18-av-core.h
+++ b/drivers/media/video/cx18/cx18-av-core.h
@@ -4,6 +4,7 @@
4 * Derived from cx25840-core.h 4 * Derived from cx25840-core.h
5 * 5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> 6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 * Copyright (C) 2008 Andy Walls <awalls@radix.net>
7 * 8 *
8 * This program is free software; you can redistribute it and/or 9 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License 10 * modify it under the terms of the GNU General Public License
@@ -302,9 +303,11 @@ struct cx18_av_state {
302int cx18_av_write(struct cx18 *cx, u16 addr, u8 value); 303int cx18_av_write(struct cx18 *cx, u16 addr, u8 value);
303int cx18_av_write4(struct cx18 *cx, u16 addr, u32 value); 304int cx18_av_write4(struct cx18 *cx, u16 addr, u32 value);
304int cx18_av_write4_noretry(struct cx18 *cx, u16 addr, u32 value); 305int cx18_av_write4_noretry(struct cx18 *cx, u16 addr, u32 value);
306int cx18_av_write_expect(struct cx18 *cx, u16 addr, u8 value, u8 eval, u8 mask);
307int cx18_av_write4_expect(struct cx18 *cx, u16 addr, u32 value, u32 eval,
308 u32 mask);
305u8 cx18_av_read(struct cx18 *cx, u16 addr); 309u8 cx18_av_read(struct cx18 *cx, u16 addr);
306u32 cx18_av_read4(struct cx18 *cx, u16 addr); 310u32 cx18_av_read4(struct cx18 *cx, u16 addr);
307u32 cx18_av_read4_noretry(struct cx18 *cx, u16 addr);
308int cx18_av_and_or(struct cx18 *cx, u16 addr, unsigned mask, u8 value); 311int cx18_av_and_or(struct cx18 *cx, u16 addr, unsigned mask, u8 value);
309int cx18_av_and_or4(struct cx18 *cx, u16 addr, u32 mask, u32 value); 312int cx18_av_and_or4(struct cx18 *cx, u16 addr, u32 mask, u32 value);
310int cx18_av_cmd(struct cx18 *cx, unsigned int cmd, void *arg); 313int cx18_av_cmd(struct cx18 *cx, unsigned int cmd, void *arg);
diff --git a/drivers/media/video/cx18/cx18-av-firmware.c b/drivers/media/video/cx18/cx18-av-firmware.c
index 522a035b2e8f..c64fd0a05a97 100644
--- a/drivers/media/video/cx18/cx18-av-firmware.c
+++ b/drivers/media/video/cx18/cx18-av-firmware.c
@@ -2,6 +2,7 @@
2 * cx18 ADEC firmware functions 2 * cx18 ADEC firmware functions
3 * 3 *
4 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> 4 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
5 * Copyright (C) 2008 Andy Walls <awalls@radix.net>
5 * 6 *
6 * This program is free software; you can redistribute it and/or 7 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License 8 * modify it under the terms of the GNU General Public License
@@ -43,11 +44,13 @@ int cx18_av_loadfw(struct cx18 *cx)
43 /* The firmware load often has byte errors, so allow for several 44 /* The firmware load often has byte errors, so allow for several
44 retries, both at byte level and at the firmware load level. */ 45 retries, both at byte level and at the firmware load level. */
45 while (retries1 < 5) { 46 while (retries1 < 5) {
46 cx18_av_write4(cx, CXADEC_CHIP_CTRL, 0x00010000); 47 cx18_av_write4_expect(cx, CXADEC_CHIP_CTRL, 0x00010000,
47 cx18_av_write(cx, CXADEC_STD_DET_CTL, 0xf6); 48 0x00008430, 0xffffffff); /* cx25843 */
49 cx18_av_write_expect(cx, CXADEC_STD_DET_CTL, 0xf6, 0xf6, 0xff);
48 50
49 /* Reset the Mako core (Register is undocumented.) */ 51 /* Reset the Mako core, Register is alias of CXADEC_CHIP_CTRL */
50 cx18_av_write4(cx, 0x8100, 0x00010000); 52 cx18_av_write4_expect(cx, 0x8100, 0x00010000,
53 0x00008430, 0xffffffff); /* cx25843 */
51 54
52 /* Put the 8051 in reset and enable firmware upload */ 55 /* Put the 8051 in reset and enable firmware upload */
53 cx18_av_write4_noretry(cx, CXADEC_DL_CTL, 0x0F000000); 56 cx18_av_write4_noretry(cx, CXADEC_DL_CTL, 0x0F000000);
@@ -61,13 +64,12 @@ int cx18_av_loadfw(struct cx18 *cx)
61 int retries2; 64 int retries2;
62 int unrec_err = 0; 65 int unrec_err = 0;
63 66
64 for (retries2 = 0; retries2 < CX18_MAX_MMIO_RETRIES; 67 for (retries2 = 0; retries2 < CX18_MAX_MMIO_WR_RETRIES;
65 retries2++) { 68 retries2++) {
66 cx18_av_write4_noretry(cx, CXADEC_DL_CTL, 69 cx18_av_write4_noretry(cx, CXADEC_DL_CTL,
67 dl_control); 70 dl_control);
68 udelay(10); 71 udelay(10);
69 value = cx18_av_read4_noretry(cx, 72 value = cx18_av_read4(cx, CXADEC_DL_CTL);
70 CXADEC_DL_CTL);
71 if (value == dl_control) 73 if (value == dl_control)
72 break; 74 break;
73 /* Check if we can correct the byte by changing 75 /* Check if we can correct the byte by changing
@@ -78,9 +80,7 @@ int cx18_av_loadfw(struct cx18 *cx)
78 break; 80 break;
79 } 81 }
80 } 82 }
81 cx18_log_write_retries(cx, retries2, 83 if (unrec_err || retries2 >= CX18_MAX_MMIO_WR_RETRIES)
82 cx->reg_mem + 0xc40000 + CXADEC_DL_CTL);
83 if (unrec_err || retries2 >= CX18_MAX_MMIO_RETRIES)
84 break; 84 break;
85 } 85 }
86 if (i == size) 86 if (i == size)
@@ -93,7 +93,8 @@ int cx18_av_loadfw(struct cx18 *cx)
93 return -EIO; 93 return -EIO;
94 } 94 }
95 95
96 cx18_av_write4(cx, CXADEC_DL_CTL, 0x13000000 | fw->size); 96 cx18_av_write4_expect(cx, CXADEC_DL_CTL,
97 0x13000000 | fw->size, 0x13000000, 0x13000000);
97 98
98 /* Output to the 416 */ 99 /* Output to the 416 */
99 cx18_av_and_or4(cx, CXADEC_PIN_CTRL1, ~0, 0x78000); 100 cx18_av_and_or4(cx, CXADEC_PIN_CTRL1, ~0, 0x78000);
@@ -118,7 +119,8 @@ int cx18_av_loadfw(struct cx18 *cx)
118 passthrough */ 119 passthrough */
119 cx18_av_write4(cx, CXADEC_PIN_CFG3, 0x5000B687); 120 cx18_av_write4(cx, CXADEC_PIN_CFG3, 0x5000B687);
120 121
121 cx18_av_write4(cx, CXADEC_STD_DET_CTL, 0x000000F6); 122 cx18_av_write4_expect(cx, CXADEC_STD_DET_CTL, 0x000000F6, 0x000000F6,
123 0x3F00FFFF);
122 /* CxDevWrReg(CXADEC_STD_DET_CTL, 0x000000FF); */ 124 /* CxDevWrReg(CXADEC_STD_DET_CTL, 0x000000FF); */
123 125
124 /* Set bit 0 in register 0x9CC to signify that this is MiniMe. */ 126 /* Set bit 0 in register 0x9CC to signify that this is MiniMe. */
@@ -136,7 +138,7 @@ int cx18_av_loadfw(struct cx18 *cx)
136 v |= 0xFF; /* Auto by default */ 138 v |= 0xFF; /* Auto by default */
137 v |= 0x400; /* Stereo by default */ 139 v |= 0x400; /* Stereo by default */
138 v |= 0x14000000; 140 v |= 0x14000000;
139 cx18_av_write4(cx, CXADEC_STD_DET_CTL, v); 141 cx18_av_write4_expect(cx, CXADEC_STD_DET_CTL, v, v, 0x3F00FFFF);
140 142
141 release_firmware(fw); 143 release_firmware(fw);
142 144
diff --git a/drivers/media/video/cx18/cx18-av-vbi.c b/drivers/media/video/cx18/cx18-av-vbi.c
index 02fdf57bb678..1527ea4f6b06 100644
--- a/drivers/media/video/cx18/cx18-av-vbi.c
+++ b/drivers/media/video/cx18/cx18-av-vbi.c
@@ -141,10 +141,11 @@ int cx18_av_vbi(struct cx18 *cx, unsigned int cmd, void *arg)
141 u8 lcr[24]; 141 u8 lcr[24];
142 142
143 fmt = arg; 143 fmt = arg;
144 if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) 144 if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE &&
145 fmt->type != V4L2_BUF_TYPE_VBI_CAPTURE)
145 return -EINVAL; 146 return -EINVAL;
146 svbi = &fmt->fmt.sliced; 147 svbi = &fmt->fmt.sliced;
147 if (svbi->service_set == 0) { 148 if (fmt->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
148 /* raw VBI */ 149 /* raw VBI */
149 memset(svbi, 0, sizeof(*svbi)); 150 memset(svbi, 0, sizeof(*svbi));
150 151
diff --git a/drivers/media/video/cx18/cx18-cards.c b/drivers/media/video/cx18/cx18-cards.c
index 5efe01ebe9db..e274043657dd 100644
--- a/drivers/media/video/cx18/cx18-cards.c
+++ b/drivers/media/video/cx18/cx18-cards.c
@@ -4,6 +4,7 @@
4 * Derived from ivtv-cards.c 4 * Derived from ivtv-cards.c
5 * 5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> 6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 * Copyright (C) 2008 Andy Walls <awalls@radix.net>
7 * 8 *
8 * This program is free software; you can redistribute it and/or modify 9 * 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 * it under the terms of the GNU General Public License as published by
@@ -50,7 +51,7 @@ static struct cx18_card_tuner_i2c cx18_i2c_std = {
50static const struct cx18_card cx18_card_hvr1600_esmt = { 51static const struct cx18_card cx18_card_hvr1600_esmt = {
51 .type = CX18_CARD_HVR_1600_ESMT, 52 .type = CX18_CARD_HVR_1600_ESMT,
52 .name = "Hauppauge HVR-1600", 53 .name = "Hauppauge HVR-1600",
53 .comment = "VBI is not yet supported\n", 54 .comment = "Raw VBI supported; Sliced VBI is not yet supported\n",
54 .v4l2_capabilities = CX18_CAP_ENCODER, 55 .v4l2_capabilities = CX18_CAP_ENCODER,
55 .hw_audio_ctrl = CX18_HW_CX23418, 56 .hw_audio_ctrl = CX18_HW_CX23418,
56 .hw_muxer = CX18_HW_CS5345, 57 .hw_muxer = CX18_HW_CS5345,
@@ -96,7 +97,7 @@ static const struct cx18_card cx18_card_hvr1600_esmt = {
96static const struct cx18_card cx18_card_hvr1600_samsung = { 97static const struct cx18_card cx18_card_hvr1600_samsung = {
97 .type = CX18_CARD_HVR_1600_SAMSUNG, 98 .type = CX18_CARD_HVR_1600_SAMSUNG,
98 .name = "Hauppauge HVR-1600 (Preproduction)", 99 .name = "Hauppauge HVR-1600 (Preproduction)",
99 .comment = "VBI is not yet supported\n", 100 .comment = "Raw VBI supported; Sliced VBI is not yet supported\n",
100 .v4l2_capabilities = CX18_CAP_ENCODER, 101 .v4l2_capabilities = CX18_CAP_ENCODER,
101 .hw_audio_ctrl = CX18_HW_CX23418, 102 .hw_audio_ctrl = CX18_HW_CX23418,
102 .hw_muxer = CX18_HW_CS5345, 103 .hw_muxer = CX18_HW_CS5345,
@@ -151,7 +152,7 @@ static const struct cx18_card_pci_info cx18_pci_h900[] = {
151static const struct cx18_card cx18_card_h900 = { 152static const struct cx18_card cx18_card_h900 = {
152 .type = CX18_CARD_COMPRO_H900, 153 .type = CX18_CARD_COMPRO_H900,
153 .name = "Compro VideoMate H900", 154 .name = "Compro VideoMate H900",
154 .comment = "VBI is not yet supported\n", 155 .comment = "Raw VBI supported; Sliced VBI is not yet supported\n",
155 .v4l2_capabilities = CX18_CAP_ENCODER, 156 .v4l2_capabilities = CX18_CAP_ENCODER,
156 .hw_audio_ctrl = CX18_HW_CX23418, 157 .hw_audio_ctrl = CX18_HW_CX23418,
157 .hw_all = CX18_HW_TUNER, 158 .hw_all = CX18_HW_TUNER,
@@ -248,7 +249,7 @@ static const struct cx18_card_pci_info cx18_pci_cnxt_raptor_pal[] = {
248static const struct cx18_card cx18_card_cnxt_raptor_pal = { 249static const struct cx18_card cx18_card_cnxt_raptor_pal = {
249 .type = CX18_CARD_CNXT_RAPTOR_PAL, 250 .type = CX18_CARD_CNXT_RAPTOR_PAL,
250 .name = "Conexant Raptor PAL/SECAM", 251 .name = "Conexant Raptor PAL/SECAM",
251 .comment = "VBI is not yet supported\n", 252 .comment = "Raw VBI supported; Sliced VBI is not yet supported\n",
252 .v4l2_capabilities = CX18_CAP_ENCODER, 253 .v4l2_capabilities = CX18_CAP_ENCODER,
253 .hw_audio_ctrl = CX18_HW_CX23418, 254 .hw_audio_ctrl = CX18_HW_CX23418,
254 .hw_muxer = CX18_HW_GPIO, 255 .hw_muxer = CX18_HW_GPIO,
diff --git a/drivers/media/video/cx18/cx18-cards.h b/drivers/media/video/cx18/cx18-cards.h
index 32155f6e6fe4..6fa7bcb42dde 100644
--- a/drivers/media/video/cx18/cx18-cards.h
+++ b/drivers/media/video/cx18/cx18-cards.h
@@ -4,6 +4,7 @@
4 * Derived from ivtv-cards.c 4 * Derived from ivtv-cards.c
5 * 5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> 6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 * Copyright (C) 2008 Andy Walls <awalls@radix.net>
7 * 8 *
8 * This program is free software; you can redistribute it and/or modify 9 * 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 * it under the terms of the GNU General Public License as published by
@@ -47,8 +48,9 @@
47 48
48/* V4L2 capability aliases */ 49/* V4L2 capability aliases */
49#define CX18_CAP_ENCODER (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_TUNER | \ 50#define CX18_CAP_ENCODER (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_TUNER | \
50 V4L2_CAP_AUDIO | V4L2_CAP_READWRITE) 51 V4L2_CAP_AUDIO | V4L2_CAP_READWRITE | \
51/* | V4L2_CAP_VBI_CAPTURE | V4L2_CAP_SLICED_VBI_CAPTURE) not yet */ 52 V4L2_CAP_VBI_CAPTURE)
53/* | V4L2_CAP_SLICED_VBI_CAPTURE) not yet */
52 54
53struct cx18_card_video_input { 55struct cx18_card_video_input {
54 u8 video_type; /* video input type */ 56 u8 video_type; /* video input type */
diff --git a/drivers/media/video/cx18/cx18-controls.c b/drivers/media/video/cx18/cx18-controls.c
index f46c7e5ed747..17edf305d649 100644
--- a/drivers/media/video/cx18/cx18-controls.c
+++ b/drivers/media/video/cx18/cx18-controls.c
@@ -259,6 +259,7 @@ int cx18_s_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *c)
259 return err; 259 return err;
260 } 260 }
261 if (c->ctrl_class == V4L2_CTRL_CLASS_MPEG) { 261 if (c->ctrl_class == V4L2_CTRL_CLASS_MPEG) {
262 struct cx18_api_func_private priv;
262 struct cx2341x_mpeg_params p = cx->params; 263 struct cx2341x_mpeg_params p = cx->params;
263 int err = cx2341x_ext_ctrls(&p, atomic_read(&cx->ana_capturing), 264 int err = cx2341x_ext_ctrls(&p, atomic_read(&cx->ana_capturing),
264 c, VIDIOC_S_EXT_CTRLS); 265 c, VIDIOC_S_EXT_CTRLS);
@@ -278,7 +279,9 @@ int cx18_s_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *c)
278 fmt.fmt.pix.height = cx->params.height; 279 fmt.fmt.pix.height = cx->params.height;
279 cx18_av_cmd(cx, VIDIOC_S_FMT, &fmt); 280 cx18_av_cmd(cx, VIDIOC_S_FMT, &fmt);
280 } 281 }
281 err = cx2341x_update(cx, cx18_api_func, &cx->params, &p); 282 priv.cx = cx;
283 priv.s = &cx->streams[id->type];
284 err = cx2341x_update(&priv, cx18_api_func, &cx->params, &p);
282 if (!err && cx->params.stream_vbi_fmt != p.stream_vbi_fmt) 285 if (!err && cx->params.stream_vbi_fmt != p.stream_vbi_fmt)
283 err = cx18_setup_vbi_fmt(cx, p.stream_vbi_fmt); 286 err = cx18_setup_vbi_fmt(cx, p.stream_vbi_fmt);
284 cx->params = p; 287 cx->params = p;
diff --git a/drivers/media/video/cx18/cx18-driver.c b/drivers/media/video/cx18/cx18-driver.c
index 7874d9790a51..f50cf2167adc 100644
--- a/drivers/media/video/cx18/cx18-driver.c
+++ b/drivers/media/video/cx18/cx18-driver.c
@@ -75,48 +75,76 @@ static int radio[CX18_MAX_CARDS] = { -1, -1, -1, -1, -1, -1, -1, -1,
75 -1, -1, -1, -1, -1, -1, -1, -1, 75 -1, -1, -1, -1, -1, -1, -1, -1,
76 -1, -1, -1, -1, -1, -1, -1, -1, 76 -1, -1, -1, -1, -1, -1, -1, -1,
77 -1, -1, -1, -1, -1, -1, -1, -1 }; 77 -1, -1, -1, -1, -1, -1, -1, -1 };
78static int mmio_ndelay[CX18_MAX_CARDS] = { -1, -1, -1, -1, -1, -1, -1, -1,
79 -1, -1, -1, -1, -1, -1, -1, -1,
80 -1, -1, -1, -1, -1, -1, -1, -1,
81 -1, -1, -1, -1, -1, -1, -1, -1 };
82static unsigned cardtype_c = 1; 78static unsigned cardtype_c = 1;
83static unsigned tuner_c = 1; 79static unsigned tuner_c = 1;
84static unsigned radio_c = 1; 80static unsigned radio_c = 1;
85static unsigned mmio_ndelay_c = 1;
86static char pal[] = "--"; 81static char pal[] = "--";
87static char secam[] = "--"; 82static char secam[] = "--";
88static char ntsc[] = "-"; 83static char ntsc[] = "-";
89 84
90/* Buffers */ 85/* Buffers */
91static int enc_mpg_buffers = CX18_DEFAULT_ENC_MPG_BUFFERS;
92static int enc_ts_buffers = CX18_DEFAULT_ENC_TS_BUFFERS; 86static int enc_ts_buffers = CX18_DEFAULT_ENC_TS_BUFFERS;
87static int enc_mpg_buffers = CX18_DEFAULT_ENC_MPG_BUFFERS;
88static int enc_idx_buffers = CX18_DEFAULT_ENC_IDX_BUFFERS;
93static int enc_yuv_buffers = CX18_DEFAULT_ENC_YUV_BUFFERS; 89static int enc_yuv_buffers = CX18_DEFAULT_ENC_YUV_BUFFERS;
94static int enc_vbi_buffers = CX18_DEFAULT_ENC_VBI_BUFFERS; 90static int enc_vbi_buffers = CX18_DEFAULT_ENC_VBI_BUFFERS;
95static int enc_pcm_buffers = CX18_DEFAULT_ENC_PCM_BUFFERS; 91static int enc_pcm_buffers = CX18_DEFAULT_ENC_PCM_BUFFERS;
96 92
93static int enc_ts_bufsize = CX18_DEFAULT_ENC_TS_BUFSIZE;
94static int enc_mpg_bufsize = CX18_DEFAULT_ENC_MPG_BUFSIZE;
95static int enc_idx_bufsize = CX18_DEFAULT_ENC_IDX_BUFSIZE;
96static int enc_yuv_bufsize = CX18_DEFAULT_ENC_YUV_BUFSIZE;
97/* VBI bufsize based on standards supported by card tuner for now */
98static int enc_pcm_bufsize = CX18_DEFAULT_ENC_PCM_BUFSIZE;
99
100static int enc_ts_bufs = -1;
101static int enc_mpg_bufs = -1;
102static int enc_idx_bufs = -1;
103static int enc_yuv_bufs = -1;
104static int enc_vbi_bufs = -1;
105static int enc_pcm_bufs = -1;
106
107
97static int cx18_pci_latency = 1; 108static int cx18_pci_latency = 1;
98 109
99int cx18_retry_mmio = 1; 110static int mmio_ndelay;
111static int retry_mmio = 1;
112
100int cx18_debug; 113int cx18_debug;
101 114
102module_param_array(tuner, int, &tuner_c, 0644); 115module_param_array(tuner, int, &tuner_c, 0644);
103module_param_array(radio, bool, &radio_c, 0644); 116module_param_array(radio, bool, &radio_c, 0644);
104module_param_array(cardtype, int, &cardtype_c, 0644); 117module_param_array(cardtype, int, &cardtype_c, 0644);
105module_param_array(mmio_ndelay, int, &mmio_ndelay_c, 0644);
106module_param_string(pal, pal, sizeof(pal), 0644); 118module_param_string(pal, pal, sizeof(pal), 0644);
107module_param_string(secam, secam, sizeof(secam), 0644); 119module_param_string(secam, secam, sizeof(secam), 0644);
108module_param_string(ntsc, ntsc, sizeof(ntsc), 0644); 120module_param_string(ntsc, ntsc, sizeof(ntsc), 0644);
109module_param_named(debug, cx18_debug, int, 0644); 121module_param_named(debug, cx18_debug, int, 0644);
110module_param_named(retry_mmio, cx18_retry_mmio, int, 0644); 122module_param(mmio_ndelay, int, 0644);
123module_param(retry_mmio, int, 0644);
111module_param(cx18_pci_latency, int, 0644); 124module_param(cx18_pci_latency, int, 0644);
112module_param(cx18_first_minor, int, 0644); 125module_param(cx18_first_minor, int, 0644);
113 126
114module_param(enc_mpg_buffers, int, 0644);
115module_param(enc_ts_buffers, int, 0644); 127module_param(enc_ts_buffers, int, 0644);
128module_param(enc_mpg_buffers, int, 0644);
129module_param(enc_idx_buffers, int, 0644);
116module_param(enc_yuv_buffers, int, 0644); 130module_param(enc_yuv_buffers, int, 0644);
117module_param(enc_vbi_buffers, int, 0644); 131module_param(enc_vbi_buffers, int, 0644);
118module_param(enc_pcm_buffers, int, 0644); 132module_param(enc_pcm_buffers, int, 0644);
119 133
134module_param(enc_ts_bufsize, int, 0644);
135module_param(enc_mpg_bufsize, int, 0644);
136module_param(enc_idx_bufsize, int, 0644);
137module_param(enc_yuv_bufsize, int, 0644);
138/* VBI bufsize based on standards supported by card tuner for now */
139module_param(enc_pcm_bufsize, int, 0644);
140
141module_param(enc_ts_bufs, int, 0644);
142module_param(enc_mpg_bufs, int, 0644);
143module_param(enc_idx_bufs, int, 0644);
144module_param(enc_yuv_bufs, int, 0644);
145module_param(enc_vbi_bufs, int, 0644);
146module_param(enc_pcm_bufs, int, 0644);
147
120MODULE_PARM_DESC(tuner, "Tuner type selection,\n" 148MODULE_PARM_DESC(tuner, "Tuner type selection,\n"
121 "\t\t\tsee tuner.h for values"); 149 "\t\t\tsee tuner.h for values");
122MODULE_PARM_DESC(radio, 150MODULE_PARM_DESC(radio,
@@ -152,28 +180,62 @@ MODULE_PARM_DESC(cx18_pci_latency,
152 "Change the PCI latency to 64 if lower: 0 = No, 1 = Yes,\n" 180 "Change the PCI latency to 64 if lower: 0 = No, 1 = Yes,\n"
153 "\t\t\tDefault: Yes"); 181 "\t\t\tDefault: Yes");
154MODULE_PARM_DESC(retry_mmio, 182MODULE_PARM_DESC(retry_mmio,
155 "Check and retry memory mapped IO accesses\n" 183 "(Deprecated) MMIO writes are now always checked and retried\n"
156 "\t\t\tDefault: 1 [Yes]"); 184 "\t\t\tEffectively: 1 [Yes]");
157MODULE_PARM_DESC(mmio_ndelay, 185MODULE_PARM_DESC(mmio_ndelay,
158 "Delay (ns) for each CX23418 memory mapped IO access.\n" 186 "(Deprecated) MMIO accesses are now never purposely delayed\n"
159 "\t\t\tTry larger values that are close to a multiple of the\n" 187 "\t\t\tEffectively: 0 ns");
160 "\t\t\tPCI clock period, 30.3 ns, if your card doesn't work.\n"
161 "\t\t\tDefault: " __stringify(CX18_DEFAULT_MMIO_NDELAY));
162MODULE_PARM_DESC(enc_mpg_buffers,
163 "Encoder MPG Buffers (in MB)\n"
164 "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_MPG_BUFFERS));
165MODULE_PARM_DESC(enc_ts_buffers, 188MODULE_PARM_DESC(enc_ts_buffers,
166 "Encoder TS Buffers (in MB)\n" 189 "Encoder TS buffer memory (MB). (enc_ts_bufs can override)\n"
167 "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_TS_BUFFERS)); 190 "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_TS_BUFFERS));
191MODULE_PARM_DESC(enc_ts_bufsize,
192 "Size of an encoder TS buffer (kB)\n"
193 "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_TS_BUFSIZE));
194MODULE_PARM_DESC(enc_ts_bufs,
195 "Number of encoder TS buffers\n"
196 "\t\t\tDefault is computed from other enc_ts_* parameters");
197MODULE_PARM_DESC(enc_mpg_buffers,
198 "Encoder MPG buffer memory (MB). (enc_mpg_bufs can override)\n"
199 "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_MPG_BUFFERS));
200MODULE_PARM_DESC(enc_mpg_bufsize,
201 "Size of an encoder MPG buffer (kB)\n"
202 "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_MPG_BUFSIZE));
203MODULE_PARM_DESC(enc_mpg_bufs,
204 "Number of encoder MPG buffers\n"
205 "\t\t\tDefault is computed from other enc_mpg_* parameters");
206MODULE_PARM_DESC(enc_idx_buffers,
207 "Encoder IDX buffer memory (MB). (enc_idx_bufs can override)\n"
208 "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_IDX_BUFFERS));
209MODULE_PARM_DESC(enc_idx_bufsize,
210 "Size of an encoder IDX buffer (kB)\n"
211 "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_IDX_BUFSIZE));
212MODULE_PARM_DESC(enc_idx_bufs,
213 "Number of encoder IDX buffers\n"
214 "\t\t\tDefault is computed from other enc_idx_* parameters");
168MODULE_PARM_DESC(enc_yuv_buffers, 215MODULE_PARM_DESC(enc_yuv_buffers,
169 "Encoder YUV Buffers (in MB)\n" 216 "Encoder YUV buffer memory (MB). (enc_yuv_bufs can override)\n"
170 "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_YUV_BUFFERS)); 217 "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_YUV_BUFFERS));
218MODULE_PARM_DESC(enc_yuv_bufsize,
219 "Size of an encoder YUV buffer (kB)\n"
220 "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_YUV_BUFSIZE));
221MODULE_PARM_DESC(enc_yuv_bufs,
222 "Number of encoder YUV buffers\n"
223 "\t\t\tDefault is computed from other enc_yuv_* parameters");
171MODULE_PARM_DESC(enc_vbi_buffers, 224MODULE_PARM_DESC(enc_vbi_buffers,
172 "Encoder VBI Buffers (in MB)\n" 225 "Encoder VBI buffer memory (MB). (enc_vbi_bufs can override)\n"
173 "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_VBI_BUFFERS)); 226 "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_VBI_BUFFERS));
227MODULE_PARM_DESC(enc_vbi_bufs,
228 "Number of encoder VBI buffers\n"
229 "\t\t\tDefault is computed from enc_vbi_buffers & tuner std");
174MODULE_PARM_DESC(enc_pcm_buffers, 230MODULE_PARM_DESC(enc_pcm_buffers,
175 "Encoder PCM buffers (in MB)\n" 231 "Encoder PCM buffer memory (MB). (enc_pcm_bufs can override)\n"
176 "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_PCM_BUFFERS)); 232 "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_PCM_BUFFERS));
233MODULE_PARM_DESC(enc_pcm_bufsize,
234 "Size of an encoder PCM buffer (kB)\n"
235 "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_PCM_BUFSIZE));
236MODULE_PARM_DESC(enc_pcm_bufs,
237 "Number of encoder PCM buffers\n"
238 "\t\t\tDefault is computed from other enc_pcm_* parameters");
177 239
178MODULE_PARM_DESC(cx18_first_minor, "Set kernel number assigned to first card"); 240MODULE_PARM_DESC(cx18_first_minor, "Set kernel number assigned to first card");
179 241
@@ -187,7 +249,7 @@ MODULE_VERSION(CX18_VERSION);
187/* Generic utility functions */ 249/* Generic utility functions */
188int cx18_msleep_timeout(unsigned int msecs, int intr) 250int cx18_msleep_timeout(unsigned int msecs, int intr)
189{ 251{
190 int timeout = msecs_to_jiffies(msecs); 252 long int timeout = msecs_to_jiffies(msecs);
191 int sig; 253 int sig;
192 254
193 do { 255 do {
@@ -366,20 +428,69 @@ static void cx18_process_options(struct cx18 *cx)
366{ 428{
367 int i, j; 429 int i, j;
368 430
369 cx->options.megabytes[CX18_ENC_STREAM_TYPE_MPG] = enc_mpg_buffers;
370 cx->options.megabytes[CX18_ENC_STREAM_TYPE_TS] = enc_ts_buffers; 431 cx->options.megabytes[CX18_ENC_STREAM_TYPE_TS] = enc_ts_buffers;
432 cx->options.megabytes[CX18_ENC_STREAM_TYPE_MPG] = enc_mpg_buffers;
433 cx->options.megabytes[CX18_ENC_STREAM_TYPE_IDX] = enc_idx_buffers;
371 cx->options.megabytes[CX18_ENC_STREAM_TYPE_YUV] = enc_yuv_buffers; 434 cx->options.megabytes[CX18_ENC_STREAM_TYPE_YUV] = enc_yuv_buffers;
372 cx->options.megabytes[CX18_ENC_STREAM_TYPE_VBI] = enc_vbi_buffers; 435 cx->options.megabytes[CX18_ENC_STREAM_TYPE_VBI] = enc_vbi_buffers;
373 cx->options.megabytes[CX18_ENC_STREAM_TYPE_PCM] = enc_pcm_buffers; 436 cx->options.megabytes[CX18_ENC_STREAM_TYPE_PCM] = enc_pcm_buffers;
437 cx->options.megabytes[CX18_ENC_STREAM_TYPE_RAD] = 0; /* control only */
438
439 cx->stream_buffers[CX18_ENC_STREAM_TYPE_TS] = enc_ts_bufs;
440 cx->stream_buffers[CX18_ENC_STREAM_TYPE_MPG] = enc_mpg_bufs;
441 cx->stream_buffers[CX18_ENC_STREAM_TYPE_IDX] = enc_idx_bufs;
442 cx->stream_buffers[CX18_ENC_STREAM_TYPE_YUV] = enc_yuv_bufs;
443 cx->stream_buffers[CX18_ENC_STREAM_TYPE_VBI] = enc_vbi_bufs;
444 cx->stream_buffers[CX18_ENC_STREAM_TYPE_PCM] = enc_pcm_bufs;
445 cx->stream_buffers[CX18_ENC_STREAM_TYPE_RAD] = 0; /* control, no data */
446
447 cx->stream_buf_size[CX18_ENC_STREAM_TYPE_TS] = enc_ts_bufsize;
448 cx->stream_buf_size[CX18_ENC_STREAM_TYPE_MPG] = enc_mpg_bufsize;
449 cx->stream_buf_size[CX18_ENC_STREAM_TYPE_IDX] = enc_idx_bufsize;
450 cx->stream_buf_size[CX18_ENC_STREAM_TYPE_YUV] = enc_yuv_bufsize;
451 cx->stream_buf_size[CX18_ENC_STREAM_TYPE_VBI] = 0; /* computed later */
452 cx->stream_buf_size[CX18_ENC_STREAM_TYPE_PCM] = enc_pcm_bufsize;
453 cx->stream_buf_size[CX18_ENC_STREAM_TYPE_RAD] = 0; /* control no data */
454
455 /* Except for VBI ensure stream_buffers & stream_buf_size are valid */
456 for (i = 0; i < CX18_MAX_STREAMS; i++) {
457 /* User said to use 0 buffers */
458 if (cx->stream_buffers[i] == 0) {
459 cx->options.megabytes[i] = 0;
460 cx->stream_buf_size[i] = 0;
461 continue;
462 }
463 /* User said to use 0 MB total */
464 if (cx->options.megabytes[i] <= 0) {
465 cx->options.megabytes[i] = 0;
466 cx->stream_buffers[i] = 0;
467 cx->stream_buf_size[i] = 0;
468 continue;
469 }
470 /* VBI is computed later or user said buffer has size 0 */
471 if (cx->stream_buf_size[i] <= 0) {
472 if (i != CX18_ENC_STREAM_TYPE_VBI) {
473 cx->options.megabytes[i] = 0;
474 cx->stream_buffers[i] = 0;
475 cx->stream_buf_size[i] = 0;
476 }
477 continue;
478 }
479 if (cx->stream_buffers[i] < 0) {
480 cx->stream_buffers[i] = cx->options.megabytes[i] * 1024
481 / cx->stream_buf_size[i];
482 } else {
483 /* N.B. This might round down to 0 */
484 cx->options.megabytes[i] =
485 cx->stream_buffers[i] * cx->stream_buf_size[i] / 1024;
486 }
487 cx->stream_buf_size[i] *= 1024; /* convert from kB to bytes */
488 }
489
374 cx->options.cardtype = cardtype[cx->num]; 490 cx->options.cardtype = cardtype[cx->num];
375 cx->options.tuner = tuner[cx->num]; 491 cx->options.tuner = tuner[cx->num];
376 cx->options.radio = radio[cx->num]; 492 cx->options.radio = radio[cx->num];
377 493
378 if (mmio_ndelay[cx->num] < 0)
379 cx->options.mmio_ndelay = CX18_DEFAULT_MMIO_NDELAY;
380 else
381 cx->options.mmio_ndelay = mmio_ndelay[cx->num];
382
383 cx->std = cx18_parse_std(cx); 494 cx->std = cx18_parse_std(cx);
384 if (cx->options.cardtype == -1) { 495 if (cx->options.cardtype == -1) {
385 CX18_INFO("Ignore card\n"); 496 CX18_INFO("Ignore card\n");
@@ -440,22 +551,30 @@ done:
440 */ 551 */
441static int __devinit cx18_init_struct1(struct cx18 *cx) 552static int __devinit cx18_init_struct1(struct cx18 *cx)
442{ 553{
554 int i;
555
443 cx->base_addr = pci_resource_start(cx->dev, 0); 556 cx->base_addr = pci_resource_start(cx->dev, 0);
444 557
445 mutex_init(&cx->serialize_lock); 558 mutex_init(&cx->serialize_lock);
446 mutex_init(&cx->i2c_bus_lock[0]); 559 mutex_init(&cx->i2c_bus_lock[0]);
447 mutex_init(&cx->i2c_bus_lock[1]); 560 mutex_init(&cx->i2c_bus_lock[1]);
448 mutex_init(&cx->gpio_lock); 561 mutex_init(&cx->gpio_lock);
562 mutex_init(&cx->epu2apu_mb_lock);
563 mutex_init(&cx->epu2cpu_mb_lock);
449 564
450 spin_lock_init(&cx->lock); 565 spin_lock_init(&cx->lock);
451 566
452 cx->work_queue = create_singlethread_workqueue(cx->name); 567 cx->work_queue = create_singlethread_workqueue(cx->name);
453 if (cx->work_queue == NULL) { 568 if (cx->work_queue == NULL) {
454 CX18_ERR("Could not create work queue\n"); 569 CX18_ERR("Unable to create work hander thread\n");
455 return -1; 570 return -ENOMEM;
456 } 571 }
457 572
458 INIT_WORK(&cx->work, cx18_work_handler); 573 for (i = 0; i < CX18_MAX_EPU_WORK_ORDERS; i++) {
574 cx->epu_work_order[i].cx = cx;
575 cx->epu_work_order[i].str = cx->epu_debug_str;
576 INIT_WORK(&cx->epu_work_order[i].work, cx18_epu_work_handler);
577 }
459 578
460 /* start counting open_id at 1 */ 579 /* start counting open_id at 1 */
461 cx->open_id = 1; 580 cx->open_id = 1;
@@ -472,20 +591,55 @@ static int __devinit cx18_init_struct1(struct cx18 *cx)
472 init_waitqueue_head(&cx->cap_w); 591 init_waitqueue_head(&cx->cap_w);
473 init_waitqueue_head(&cx->mb_apu_waitq); 592 init_waitqueue_head(&cx->mb_apu_waitq);
474 init_waitqueue_head(&cx->mb_cpu_waitq); 593 init_waitqueue_head(&cx->mb_cpu_waitq);
475 init_waitqueue_head(&cx->mb_epu_waitq);
476 init_waitqueue_head(&cx->mb_hpu_waitq);
477 init_waitqueue_head(&cx->dma_waitq); 594 init_waitqueue_head(&cx->dma_waitq);
478 595
479 /* VBI */ 596 /* VBI */
480 cx->vbi.in.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE; 597 cx->vbi.in.type = V4L2_BUF_TYPE_VBI_CAPTURE;
481 cx->vbi.sliced_in = &cx->vbi.in.fmt.sliced; 598 cx->vbi.sliced_in = &cx->vbi.in.fmt.sliced;
482 cx->vbi.raw_size = 1456; 599
483 cx->vbi.raw_decoder_line_size = 1456; 600 /*
484 cx->vbi.raw_decoder_sav_odd_field = 0x20; 601 * The VBI line sizes depend on the pixel clock and the horiz rate
485 cx->vbi.raw_decoder_sav_even_field = 0x60; 602 *
486 cx->vbi.sliced_decoder_line_size = 272; 603 * (1/Fh)*(2*Fp) = Samples/line
487 cx->vbi.sliced_decoder_sav_odd_field = 0xB0; 604 * = 4 bytes EAV + Anc data in hblank + 4 bytes SAV + active samples
488 cx->vbi.sliced_decoder_sav_even_field = 0xF0; 605 *
606 * Sliced VBI is sent as ancillary data during horizontal blanking
607 * Raw VBI is sent as active video samples during vertcal blanking
608 *
609 * We use a BT.656 pxiel clock of 13.5 MHz and a BT.656 active line
610 * length of 720 pixels @ 4:2:2 sampling. Thus...
611 *
612 * For systems that use a 15.734 kHz horizontal rate, such as
613 * NTSC-M, PAL-M, PAL-60, and other 60 Hz/525 line systems, we have:
614 *
615 * (1/15.734 kHz) * 2 * 13.5 MHz = 1716 samples/line =
616 * 4 bytes SAV + 268 bytes anc data + 4 bytes SAV + 1440 active samples
617 *
618 * For systems that use a 15.625 kHz horizontal rate, such as
619 * PAL-B/G/H, PAL-I, SECAM-L and other 50 Hz/625 line systems, we have:
620 *
621 * (1/15.625 kHz) * 2 * 13.5 MHz = 1728 samples/line =
622 * 4 bytes SAV + 280 bytes anc data + 4 bytes SAV + 1440 active samples
623 *
624 */
625
626 /* FIXME: init these based on tuner std & modify when std changes */
627 /* CX18-AV-Core number of VBI samples output per horizontal line */
628 cx->vbi.raw_decoder_line_size = 1444; /* 4 byte SAV + 2 * 720 */
629 cx->vbi.sliced_decoder_line_size = 272; /* 60 Hz: 268+4, 50 Hz: 280+4 */
630
631 /* CX18-AV-Core VBI samples/line possibly rounded up */
632 cx->vbi.raw_size = 1444; /* Real max size is 1444 */
633 cx->vbi.sliced_size = 284; /* Real max size is 284 */
634
635 /*
636 * CX18-AV-Core SAV/EAV RP codes in VIP 1.x mode
637 * Task Field VerticalBlank HorizontalBlank 0 0 0 0
638 */
639 cx->vbi.raw_decoder_sav_odd_field = 0x20; /* V */
640 cx->vbi.raw_decoder_sav_even_field = 0x60; /* FV */
641 cx->vbi.sliced_decoder_sav_odd_field = 0xB0; /* T VH - actually EAV */
642 cx->vbi.sliced_decoder_sav_even_field = 0xF0; /* TFVH - actually EAV */
489 return 0; 643 return 0;
490} 644}
491 645
@@ -518,6 +672,7 @@ static void __devinit cx18_init_struct2(struct cx18 *cx)
518 cx->av_state.aud_input = CX18_AV_AUDIO8; 672 cx->av_state.aud_input = CX18_AV_AUDIO8;
519 cx->av_state.audclk_freq = 48000; 673 cx->av_state.audclk_freq = 48000;
520 cx->av_state.audmode = V4L2_TUNER_MODE_LANG1; 674 cx->av_state.audmode = V4L2_TUNER_MODE_LANG1;
675 /* FIXME - 8 is NTSC value, investigate */
521 cx->av_state.vbi_line_offset = 8; 676 cx->av_state.vbi_line_offset = 8;
522} 677}
523 678
@@ -662,12 +817,9 @@ static int __devinit cx18_probe(struct pci_dev *dev,
662 817
663 /* PCI Device Setup */ 818 /* PCI Device Setup */
664 retval = cx18_setup_pci(cx, dev, pci_id); 819 retval = cx18_setup_pci(cx, dev, pci_id);
665 if (retval != 0) { 820 if (retval != 0)
666 if (retval == -EIO) 821 goto free_workqueue;
667 goto free_workqueue; 822
668 else if (retval == -ENXIO)
669 goto free_mem;
670 }
671 /* save cx in the pci struct for later use */ 823 /* save cx in the pci struct for later use */
672 pci_set_drvdata(dev, cx); 824 pci_set_drvdata(dev, cx);
673 825
@@ -726,6 +878,7 @@ static int __devinit cx18_probe(struct pci_dev *dev,
726 goto free_i2c; 878 goto free_i2c;
727 } 879 }
728 cx18_init_memory(cx); 880 cx18_init_memory(cx);
881 cx18_init_scb(cx);
729 882
730 /* Register IRQ */ 883 /* Register IRQ */
731 retval = request_irq(cx->dev->irq, cx18_irq_handler, 884 retval = request_irq(cx->dev->irq, cx18_irq_handler,
@@ -739,8 +892,6 @@ static int __devinit cx18_probe(struct pci_dev *dev,
739 cx->std = V4L2_STD_NTSC_M; 892 cx->std = V4L2_STD_NTSC_M;
740 893
741 if (cx->options.tuner == -1) { 894 if (cx->options.tuner == -1) {
742 int i;
743
744 for (i = 0; i < CX18_CARD_MAX_TUNERS; i++) { 895 for (i = 0; i < CX18_CARD_MAX_TUNERS; i++) {
745 if ((cx->std & cx->card->tuners[i].std) == 0) 896 if ((cx->std & cx->card->tuners[i].std) == 0)
746 continue; 897 continue;
@@ -777,13 +928,23 @@ static int __devinit cx18_probe(struct pci_dev *dev,
777 } 928 }
778 cx->params.video_gop_size = cx->is_60hz ? 15 : 12; 929 cx->params.video_gop_size = cx->is_60hz ? 15 : 12;
779 930
780 cx->stream_buf_size[CX18_ENC_STREAM_TYPE_MPG] = 0x08000; 931 /*
781 cx->stream_buf_size[CX18_ENC_STREAM_TYPE_TS] = 0x08000; 932 * FIXME: setting the buffer size based on the tuner standard is
782 cx->stream_buf_size[CX18_ENC_STREAM_TYPE_PCM] = 0x01200; 933 * suboptimal, as the CVBS and SVideo inputs could use a different std
783 cx->stream_buf_size[CX18_ENC_STREAM_TYPE_YUV] = 0x20000; 934 * and the buffer could end up being too small in that case.
935 */
784 vbi_buf_size = cx->vbi.raw_size * (cx->is_60hz ? 24 : 36) / 2; 936 vbi_buf_size = cx->vbi.raw_size * (cx->is_60hz ? 24 : 36) / 2;
785 cx->stream_buf_size[CX18_ENC_STREAM_TYPE_VBI] = vbi_buf_size; 937 cx->stream_buf_size[CX18_ENC_STREAM_TYPE_VBI] = vbi_buf_size;
786 938
939 if (cx->stream_buffers[CX18_ENC_STREAM_TYPE_VBI] < 0)
940 cx->stream_buffers[CX18_ENC_STREAM_TYPE_VBI] =
941 cx->options.megabytes[CX18_ENC_STREAM_TYPE_VBI] * 1024 * 1024
942 / vbi_buf_size;
943 else
944 cx->options.megabytes[CX18_ENC_STREAM_TYPE_VBI] =
945 cx->stream_buffers[CX18_ENC_STREAM_TYPE_VBI] * vbi_buf_size
946 / (1024 * 1024);
947
787 if (cx->options.radio > 0) 948 if (cx->options.radio > 0)
788 cx->v4l2_cap |= V4L2_CAP_RADIO; 949 cx->v4l2_cap |= V4L2_CAP_RADIO;
789 950
@@ -844,7 +1005,6 @@ err:
844 if (retval == 0) 1005 if (retval == 0)
845 retval = -ENODEV; 1006 retval = -ENODEV;
846 CX18_ERR("Error %d on initialization\n", retval); 1007 CX18_ERR("Error %d on initialization\n", retval);
847 cx18_log_statistics(cx);
848 1008
849 i = cx->num; 1009 i = cx->num;
850 spin_lock(&cx18_cards_lock); 1010 spin_lock(&cx18_cards_lock);
@@ -923,6 +1083,13 @@ int cx18_init_on_first_open(struct cx18 *cx)
923 return 0; 1083 return 0;
924} 1084}
925 1085
1086static void cx18_cancel_epu_work_orders(struct cx18 *cx)
1087{
1088 int i;
1089 for (i = 0; i < CX18_MAX_EPU_WORK_ORDERS; i++)
1090 cancel_work_sync(&cx->epu_work_order[i].work);
1091}
1092
926static void cx18_remove(struct pci_dev *pci_dev) 1093static void cx18_remove(struct pci_dev *pci_dev)
927{ 1094{
928 struct cx18 *cx = pci_get_drvdata(pci_dev); 1095 struct cx18 *cx = pci_get_drvdata(pci_dev);
@@ -940,7 +1107,8 @@ static void cx18_remove(struct pci_dev *pci_dev)
940 1107
941 cx18_halt_firmware(cx); 1108 cx18_halt_firmware(cx);
942 1109
943 flush_workqueue(cx->work_queue); 1110 cx18_cancel_epu_work_orders(cx);
1111
944 destroy_workqueue(cx->work_queue); 1112 destroy_workqueue(cx->work_queue);
945 1113
946 cx18_streams_cleanup(cx, 1); 1114 cx18_streams_cleanup(cx, 1);
@@ -955,7 +1123,6 @@ static void cx18_remove(struct pci_dev *pci_dev)
955 1123
956 pci_disable_device(cx->dev); 1124 pci_disable_device(cx->dev);
957 1125
958 cx18_log_statistics(cx);
959 CX18_INFO("Removed %s, card #%d\n", cx->card_name, cx->num); 1126 CX18_INFO("Removed %s, card #%d\n", cx->card_name, cx->num);
960} 1127}
961 1128
@@ -1004,6 +1171,7 @@ static void module_cleanup(void)
1004 continue; 1171 continue;
1005 kfree(cx18_cards[i]); 1172 kfree(cx18_cards[i]);
1006 } 1173 }
1174
1007} 1175}
1008 1176
1009module_init(module_start); 1177module_init(module_start);
diff --git a/drivers/media/video/cx18/cx18-driver.h b/drivers/media/video/cx18/cx18-driver.h
index bbdd5f25041d..0d2edebc39b4 100644
--- a/drivers/media/video/cx18/cx18-driver.h
+++ b/drivers/media/video/cx18/cx18-driver.h
@@ -4,6 +4,7 @@
4 * Derived from ivtv-driver.h 4 * Derived from ivtv-driver.h
5 * 5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> 6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 * Copyright (C) 2008 Andy Walls <awalls@radix.net>
7 * 8 *
8 * This program is free software; you can redistribute it and/or modify 9 * 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 * it under the terms of the GNU General Public License as published by
@@ -64,9 +65,6 @@
64# error "This driver requires kernel PCI support." 65# error "This driver requires kernel PCI support."
65#endif 66#endif
66 67
67/* Default delay to throttle mmio access to the CX23418 */
68#define CX18_DEFAULT_MMIO_NDELAY 0 /* 0 ns = 0 PCI clock(s) / 33 MHz */
69
70#define CX18_MEM_OFFSET 0x00000000 68#define CX18_MEM_OFFSET 0x00000000
71#define CX18_MEM_SIZE 0x04000000 69#define CX18_MEM_SIZE 0x04000000
72#define CX18_REG_OFFSET 0x02000000 70#define CX18_REG_OFFSET 0x02000000
@@ -117,6 +115,17 @@
117#define CX18_DEFAULT_ENC_VBI_BUFFERS 1 115#define CX18_DEFAULT_ENC_VBI_BUFFERS 1
118#define CX18_DEFAULT_ENC_PCM_BUFFERS 1 116#define CX18_DEFAULT_ENC_PCM_BUFFERS 1
119 117
118/* Maximum firmware DMA buffers per stream */
119#define CX18_MAX_FW_MDLS_PER_STREAM 63
120
121/* DMA buffer, default size in kB allocated */
122#define CX18_DEFAULT_ENC_TS_BUFSIZE 32
123#define CX18_DEFAULT_ENC_MPG_BUFSIZE 32
124#define CX18_DEFAULT_ENC_IDX_BUFSIZE 32
125#define CX18_DEFAULT_ENC_YUV_BUFSIZE 128
126/* Default VBI bufsize based on standards supported by card tuner for now */
127#define CX18_DEFAULT_ENC_PCM_BUFSIZE 4
128
120/* i2c stuff */ 129/* i2c stuff */
121#define I2C_CLIENTS_MAX 16 130#define I2C_CLIENTS_MAX 16
122 131
@@ -176,7 +185,6 @@
176 185
177#define CX18_MAX_PGM_INDEX (400) 186#define CX18_MAX_PGM_INDEX (400)
178 187
179extern int cx18_retry_mmio; /* enable check & retry of mmio accesses */
180extern int cx18_debug; 188extern int cx18_debug;
181 189
182 190
@@ -185,7 +193,6 @@ struct cx18_options {
185 int cardtype; /* force card type on load */ 193 int cardtype; /* force card type on load */
186 int tuner; /* set tuner on load */ 194 int tuner; /* set tuner on load */
187 int radio; /* enable/disable radio */ 195 int radio; /* enable/disable radio */
188 unsigned long mmio_ndelay; /* delay in ns after every PCI mmio access */
189}; 196};
190 197
191/* per-buffer bit flags */ 198/* per-buffer bit flags */
@@ -203,11 +210,8 @@ struct cx18_options {
203#define CX18_F_I_EOS 4 /* End of encoder stream */ 210#define CX18_F_I_EOS 4 /* End of encoder stream */
204#define CX18_F_I_RADIO_USER 5 /* radio tuner is selected */ 211#define CX18_F_I_RADIO_USER 5 /* radio tuner is selected */
205#define CX18_F_I_ENC_PAUSED 13 /* the encoder is paused */ 212#define CX18_F_I_ENC_PAUSED 13 /* the encoder is paused */
206#define CX18_F_I_HAVE_WORK 15 /* there is work to be done */
207#define CX18_F_I_WORK_HANDLER_DVB 18 /* work to be done for DVB */
208#define CX18_F_I_INITED 21 /* set after first open */ 213#define CX18_F_I_INITED 21 /* set after first open */
209#define CX18_F_I_FAILED 22 /* set if first open failed */ 214#define CX18_F_I_FAILED 22 /* set if first open failed */
210#define CX18_F_I_WORK_INITED 23 /* worker thread initialized */
211 215
212/* These are the VBI types as they appear in the embedded VBI private packets. */ 216/* These are the VBI types as they appear in the embedded VBI private packets. */
213#define CX18_SLICED_TYPE_TELETEXT_B (1) 217#define CX18_SLICED_TYPE_TELETEXT_B (1)
@@ -220,6 +224,7 @@ struct cx18_buffer {
220 dma_addr_t dma_handle; 224 dma_addr_t dma_handle;
221 u32 id; 225 u32 id;
222 unsigned long b_flags; 226 unsigned long b_flags;
227 unsigned skipped;
223 char *buf; 228 char *buf;
224 229
225 u32 bytesused; 230 u32 bytesused;
@@ -248,6 +253,27 @@ struct cx18_dvb {
248struct cx18; /* forward reference */ 253struct cx18; /* forward reference */
249struct cx18_scb; /* forward reference */ 254struct cx18_scb; /* forward reference */
250 255
256
257#define CX18_MAX_MDL_ACKS 2
258#define CX18_MAX_EPU_WORK_ORDERS (CX18_MAX_FW_MDLS_PER_STREAM + 7)
259/* CPU_DE_RELEASE_MDL can burst CX18_MAX_FW_MDLS_PER_STREAM orders in a group */
260
261#define CX18_F_EWO_MB_STALE_UPON_RECEIPT 0x1
262#define CX18_F_EWO_MB_STALE_WHILE_PROC 0x2
263#define CX18_F_EWO_MB_STALE \
264 (CX18_F_EWO_MB_STALE_UPON_RECEIPT | CX18_F_EWO_MB_STALE_WHILE_PROC)
265
266struct cx18_epu_work_order {
267 struct work_struct work;
268 atomic_t pending;
269 struct cx18 *cx;
270 unsigned long flags;
271 int rpu;
272 struct cx18_mailbox mb;
273 struct cx18_mdl_ack mdl_ack[CX18_MAX_MDL_ACKS];
274 char *str;
275};
276
251#define CX18_INVALID_TASK_HANDLE 0xffffffff 277#define CX18_INVALID_TASK_HANDLE 0xffffffff
252 278
253struct cx18_stream { 279struct cx18_stream {
@@ -261,7 +287,7 @@ struct cx18_stream {
261 unsigned mdl_offset; 287 unsigned mdl_offset;
262 288
263 u32 id; 289 u32 id;
264 spinlock_t qlock; /* locks access to the queues */ 290 struct mutex qlock; /* locks access to the queues */
265 unsigned long s_flags; /* status flags, see above */ 291 unsigned long s_flags; /* status flags, see above */
266 int dma; /* can be PCI_DMA_TODEVICE, 292 int dma; /* can be PCI_DMA_TODEVICE,
267 PCI_DMA_FROMDEVICE or 293 PCI_DMA_FROMDEVICE or
@@ -275,8 +301,8 @@ struct cx18_stream {
275 301
276 /* Buffer Queues */ 302 /* Buffer Queues */
277 struct cx18_queue q_free; /* free buffers */ 303 struct cx18_queue q_free; /* free buffers */
278 struct cx18_queue q_full; /* full buffers */ 304 struct cx18_queue q_busy; /* busy buffers - in use by firmware */
279 struct cx18_queue q_io; /* waiting for I/O */ 305 struct cx18_queue q_full; /* full buffers - data for user apps */
280 306
281 /* DVB / Digital Transport */ 307 /* DVB / Digital Transport */
282 struct cx18_dvb dvb; 308 struct cx18_dvb dvb;
@@ -353,12 +379,7 @@ struct cx18_i2c_algo_callback_data {
353 int bus_index; /* 0 or 1 for the cx23418's 1st or 2nd I2C bus */ 379 int bus_index; /* 0 or 1 for the cx23418's 1st or 2nd I2C bus */
354}; 380};
355 381
356#define CX18_MAX_MMIO_RETRIES 10 382#define CX18_MAX_MMIO_WR_RETRIES 10
357
358struct cx18_mmio_stats {
359 atomic_t retried_write[CX18_MAX_MMIO_RETRIES+1];
360 atomic_t retried_read[CX18_MAX_MMIO_RETRIES+1];
361};
362 383
363/* Struct to hold info about cx18 cards */ 384/* Struct to hold info about cx18 cards */
364struct cx18 { 385struct cx18 {
@@ -378,7 +399,9 @@ struct cx18 {
378 u32 v4l2_cap; /* V4L2 capabilities of card */ 399 u32 v4l2_cap; /* V4L2 capabilities of card */
379 u32 hw_flags; /* Hardware description of the board */ 400 u32 hw_flags; /* Hardware description of the board */
380 unsigned mdl_offset; 401 unsigned mdl_offset;
381 struct cx18_scb __iomem *scb; /* pointer to SCB */ 402 struct cx18_scb __iomem *scb; /* pointer to SCB */
403 struct mutex epu2apu_mb_lock; /* protect driver to chip mailbox in SCB*/
404 struct mutex epu2cpu_mb_lock; /* protect driver to chip mailbox in SCB*/
382 405
383 struct cx18_av_state av_state; 406 struct cx18_av_state av_state;
384 407
@@ -397,6 +420,7 @@ struct cx18 {
397 420
398 struct mutex serialize_lock; /* mutex used to serialize open/close/start/stop/ioctl operations */ 421 struct mutex serialize_lock; /* mutex used to serialize open/close/start/stop/ioctl operations */
399 struct cx18_options options; /* User options */ 422 struct cx18_options options; /* User options */
423 int stream_buffers[CX18_MAX_STREAMS]; /* # of buffers for each stream */
400 int stream_buf_size[CX18_MAX_STREAMS]; /* Stream buffer size */ 424 int stream_buf_size[CX18_MAX_STREAMS]; /* Stream buffer size */
401 struct cx18_stream streams[CX18_MAX_STREAMS]; /* Stream data */ 425 struct cx18_stream streams[CX18_MAX_STREAMS]; /* Stream data */
402 unsigned long i_flags; /* global cx18 flags */ 426 unsigned long i_flags; /* global cx18 flags */
@@ -428,14 +452,17 @@ struct cx18 {
428 452
429 wait_queue_head_t mb_apu_waitq; 453 wait_queue_head_t mb_apu_waitq;
430 wait_queue_head_t mb_cpu_waitq; 454 wait_queue_head_t mb_cpu_waitq;
431 wait_queue_head_t mb_epu_waitq;
432 wait_queue_head_t mb_hpu_waitq;
433 wait_queue_head_t cap_w; 455 wait_queue_head_t cap_w;
434 /* when the current DMA is finished this queue is woken up */ 456 /* when the current DMA is finished this queue is woken up */
435 wait_queue_head_t dma_waitq; 457 wait_queue_head_t dma_waitq;
436 458
459 u32 sw1_irq_mask;
460 u32 sw2_irq_mask;
461 u32 hw2_irq_mask;
462
437 struct workqueue_struct *work_queue; 463 struct workqueue_struct *work_queue;
438 struct work_struct work; 464 struct cx18_epu_work_order epu_work_order[CX18_MAX_EPU_WORK_ORDERS];
465 char epu_debug_str[256]; /* CX18_EPU_DEBUG is rare: use shared space */
439 466
440 /* i2c */ 467 /* i2c */
441 struct i2c_adapter i2c_adap[2]; 468 struct i2c_adapter i2c_adap[2];
@@ -450,9 +477,6 @@ struct cx18 {
450 u32 gpio_val; 477 u32 gpio_val;
451 struct mutex gpio_lock; 478 struct mutex gpio_lock;
452 479
453 /* Statistics */
454 struct cx18_mmio_stats mmio_stats;
455
456 /* v4l2 and User settings */ 480 /* v4l2 and User settings */
457 481
458 /* codec settings */ 482 /* codec settings */
@@ -481,4 +505,10 @@ void cx18_read_eeprom(struct cx18 *cx, struct tveeprom *tv);
481/* First-open initialization: load firmware, etc. */ 505/* First-open initialization: load firmware, etc. */
482int cx18_init_on_first_open(struct cx18 *cx); 506int cx18_init_on_first_open(struct cx18 *cx);
483 507
508/* Test if the current VBI mode is raw (1) or sliced (0) */
509static inline int cx18_raw_vbi(const struct cx18 *cx)
510{
511 return cx->vbi.in.type == V4L2_BUF_TYPE_VBI_CAPTURE;
512}
513
484#endif /* CX18_DRIVER_H */ 514#endif /* CX18_DRIVER_H */
diff --git a/drivers/media/video/cx18/cx18-dvb.c b/drivers/media/video/cx18/cx18-dvb.c
index 4542e2e5e3d7..bd5e6f3fd4d0 100644
--- a/drivers/media/video/cx18/cx18-dvb.c
+++ b/drivers/media/video/cx18/cx18-dvb.c
@@ -2,6 +2,7 @@
2 * cx18 functions for DVB support 2 * cx18 functions for DVB support
3 * 3 *
4 * Copyright (c) 2008 Steven Toth <stoth@linuxtv.org> 4 * Copyright (c) 2008 Steven Toth <stoth@linuxtv.org>
5 * Copyright (C) 2008 Andy Walls <awalls@radix.net>
5 * 6 *
6 * 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
7 * 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
@@ -23,8 +24,6 @@
23#include "cx18-dvb.h" 24#include "cx18-dvb.h"
24#include "cx18-io.h" 25#include "cx18-io.h"
25#include "cx18-streams.h" 26#include "cx18-streams.h"
26#include "cx18-queue.h"
27#include "cx18-scb.h"
28#include "cx18-cards.h" 27#include "cx18-cards.h"
29#include "s5h1409.h" 28#include "s5h1409.h"
30#include "mxl5005s.h" 29#include "mxl5005s.h"
@@ -109,20 +108,23 @@ static int cx18_dvb_start_feed(struct dvb_demux_feed *feed)
109 if (!demux->dmx.frontend) 108 if (!demux->dmx.frontend)
110 return -EINVAL; 109 return -EINVAL;
111 110
112 if (stream) { 111 if (!stream)
113 mutex_lock(&stream->dvb.feedlock); 112 return -EINVAL;
114 if (stream->dvb.feeding++ == 0) { 113
115 CX18_DEBUG_INFO("Starting Transport DMA\n"); 114 mutex_lock(&stream->dvb.feedlock);
116 ret = cx18_start_v4l2_encode_stream(stream); 115 if (stream->dvb.feeding++ == 0) {
117 if (ret < 0) { 116 CX18_DEBUG_INFO("Starting Transport DMA\n");
118 CX18_DEBUG_INFO( 117 set_bit(CX18_F_S_STREAMING, &stream->s_flags);
119 "Failed to start Transport DMA\n"); 118 ret = cx18_start_v4l2_encode_stream(stream);
120 stream->dvb.feeding--; 119 if (ret < 0) {
121 } 120 CX18_DEBUG_INFO("Failed to start Transport DMA\n");
122 } else 121 stream->dvb.feeding--;
123 ret = 0; 122 if (stream->dvb.feeding == 0)
124 mutex_unlock(&stream->dvb.feedlock); 123 clear_bit(CX18_F_S_STREAMING, &stream->s_flags);
125 } 124 }
125 } else
126 ret = 0;
127 mutex_unlock(&stream->dvb.feedlock);
126 128
127 return ret; 129 return ret;
128} 130}
@@ -215,6 +217,10 @@ int cx18_dvb_register(struct cx18_stream *stream)
215 dvb_net_init(dvb_adapter, &dvb->dvbnet, dmx); 217 dvb_net_init(dvb_adapter, &dvb->dvbnet, dmx);
216 218
217 CX18_INFO("DVB Frontend registered\n"); 219 CX18_INFO("DVB Frontend registered\n");
220 CX18_INFO("Registered DVB adapter%d for %s (%d x %d kB)\n",
221 stream->dvb.dvb_adapter.num, stream->name,
222 stream->buffers, stream->buf_size/1024);
223
218 mutex_init(&dvb->feedlock); 224 mutex_init(&dvb->feedlock);
219 dvb->enabled = 1; 225 dvb->enabled = 1;
220 return ret; 226 return ret;
@@ -302,24 +308,3 @@ static int dvb_register(struct cx18_stream *stream)
302 308
303 return ret; 309 return ret;
304} 310}
305
306void cx18_dvb_work_handler(struct cx18 *cx)
307{
308 struct cx18_buffer *buf;
309 struct cx18_stream *s = &cx->streams[CX18_ENC_STREAM_TYPE_TS];
310
311 while ((buf = cx18_dequeue(s, &s->q_full)) != NULL) {
312 if (s->dvb.enabled)
313 dvb_dmx_swfilter(&s->dvb.demux, buf->buf,
314 buf->bytesused);
315
316 cx18_enqueue(s, buf, &s->q_free);
317 cx18_buf_sync_for_device(s, buf);
318 if (s->handle == CX18_INVALID_TASK_HANDLE) /* FIXME: improve */
319 continue;
320
321 cx18_vapi(cx, CX18_CPU_DE_SET_MDL, 5, s->handle,
322 (void __iomem *)&cx->scb->cpu_mdl[buf->id] - cx->enc_mem,
323 1, buf->id, s->buf_size);
324 }
325}
diff --git a/drivers/media/video/cx18/cx18-dvb.h b/drivers/media/video/cx18/cx18-dvb.h
index bbdcefc87f28..bf8d8f6f5455 100644
--- a/drivers/media/video/cx18/cx18-dvb.h
+++ b/drivers/media/video/cx18/cx18-dvb.h
@@ -23,4 +23,3 @@
23 23
24int cx18_dvb_register(struct cx18_stream *stream); 24int cx18_dvb_register(struct cx18_stream *stream);
25void cx18_dvb_unregister(struct cx18_stream *stream); 25void cx18_dvb_unregister(struct cx18_stream *stream);
26void cx18_dvb_work_handler(struct cx18 *cx);
diff --git a/drivers/media/video/cx18/cx18-fileops.c b/drivers/media/video/cx18/cx18-fileops.c
index 5f9089907544..425271a29517 100644
--- a/drivers/media/video/cx18/cx18-fileops.c
+++ b/drivers/media/video/cx18/cx18-fileops.c
@@ -4,6 +4,7 @@
4 * Derived from ivtv-fileops.c 4 * Derived from ivtv-fileops.c
5 * 5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> 6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 * Copyright (C) 2008 Andy Walls <awalls@radix.net>
7 * 8 *
8 * This program is free software; you can redistribute it and/or modify 9 * 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 * it under the terms of the GNU General Public License as published by
@@ -66,12 +67,11 @@ static int cx18_claim_stream(struct cx18_open_id *id, int type)
66 } 67 }
67 s->id = id->open_id; 68 s->id = id->open_id;
68 69
69 /* CX18_DEC_STREAM_TYPE_MPG needs to claim CX18_DEC_STREAM_TYPE_VBI, 70 /* CX18_ENC_STREAM_TYPE_MPG needs to claim CX18_ENC_STREAM_TYPE_VBI
70 CX18_ENC_STREAM_TYPE_MPG needs to claim CX18_ENC_STREAM_TYPE_VBI
71 (provided VBI insertion is on and sliced VBI is selected), for all 71 (provided VBI insertion is on and sliced VBI is selected), for all
72 other streams we're done */ 72 other streams we're done */
73 if (type == CX18_ENC_STREAM_TYPE_MPG && 73 if (type == CX18_ENC_STREAM_TYPE_MPG &&
74 cx->vbi.insert_mpeg && cx->vbi.sliced_in->service_set) { 74 cx->vbi.insert_mpeg && !cx18_raw_vbi(cx)) {
75 vbi_type = CX18_ENC_STREAM_TYPE_VBI; 75 vbi_type = CX18_ENC_STREAM_TYPE_VBI;
76 } else { 76 } else {
77 return 0; 77 return 0;
@@ -185,8 +185,10 @@ static struct cx18_buffer *cx18_get_buffer(struct cx18_stream *s, int non_block,
185 !test_bit(CX18_F_S_APPL_IO, &s_vbi->s_flags)) { 185 !test_bit(CX18_F_S_APPL_IO, &s_vbi->s_flags)) {
186 while ((buf = cx18_dequeue(s_vbi, &s_vbi->q_full))) { 186 while ((buf = cx18_dequeue(s_vbi, &s_vbi->q_full))) {
187 /* byteswap and process VBI data */ 187 /* byteswap and process VBI data */
188/* cx18_process_vbi_data(cx, buf, s_vbi->dma_pts, s_vbi->type); */ 188 cx18_process_vbi_data(cx, buf,
189 cx18_enqueue(s_vbi, buf, &s_vbi->q_free); 189 s_vbi->dma_pts,
190 s_vbi->type);
191 cx18_stream_put_buf_fw(s_vbi, buf);
190 } 192 }
191 } 193 }
192 buf = &cx->vbi.sliced_mpeg_buf; 194 buf = &cx->vbi.sliced_mpeg_buf;
@@ -194,11 +196,6 @@ static struct cx18_buffer *cx18_get_buffer(struct cx18_stream *s, int non_block,
194 return buf; 196 return buf;
195 } 197 }
196 198
197 /* do we have leftover data? */
198 buf = cx18_dequeue(s, &s->q_io);
199 if (buf)
200 return buf;
201
202 /* do we have new data? */ 199 /* do we have new data? */
203 buf = cx18_dequeue(s, &s->q_full); 200 buf = cx18_dequeue(s, &s->q_full);
204 if (buf) { 201 if (buf) {
@@ -262,7 +259,7 @@ static size_t cx18_copy_buf_to_user(struct cx18_stream *s,
262 if (len > ucount) 259 if (len > ucount)
263 len = ucount; 260 len = ucount;
264 if (cx->vbi.insert_mpeg && s->type == CX18_ENC_STREAM_TYPE_MPG && 261 if (cx->vbi.insert_mpeg && s->type == CX18_ENC_STREAM_TYPE_MPG &&
265 cx->vbi.sliced_in->service_set && buf != &cx->vbi.sliced_mpeg_buf) { 262 !cx18_raw_vbi(cx) && buf != &cx->vbi.sliced_mpeg_buf) {
266 const char *start = buf->buf + buf->readpos; 263 const char *start = buf->buf + buf->readpos;
267 const char *p = start + 1; 264 const char *p = start + 1;
268 const u8 *q; 265 const u8 *q;
@@ -337,8 +334,7 @@ static ssize_t cx18_read(struct cx18_stream *s, char __user *ubuf,
337 /* Each VBI buffer is one frame, the v4l2 API says that for VBI the 334 /* Each VBI buffer is one frame, the v4l2 API says that for VBI the
338 frames should arrive one-by-one, so make sure we never output more 335 frames should arrive one-by-one, so make sure we never output more
339 than one VBI frame at a time */ 336 than one VBI frame at a time */
340 if (s->type == CX18_ENC_STREAM_TYPE_VBI && 337 if (s->type == CX18_ENC_STREAM_TYPE_VBI && !cx18_raw_vbi(cx))
341 cx->vbi.sliced_in->service_set)
342 single_frame = 1; 338 single_frame = 1;
343 339
344 for (;;) { 340 for (;;) {
@@ -365,16 +361,10 @@ static ssize_t cx18_read(struct cx18_stream *s, char __user *ubuf,
365 tot_count - tot_written); 361 tot_count - tot_written);
366 362
367 if (buf != &cx->vbi.sliced_mpeg_buf) { 363 if (buf != &cx->vbi.sliced_mpeg_buf) {
368 if (buf->readpos == buf->bytesused) { 364 if (buf->readpos == buf->bytesused)
369 cx18_buf_sync_for_device(s, buf); 365 cx18_stream_put_buf_fw(s, buf);
370 cx18_enqueue(s, buf, &s->q_free); 366 else
371 cx18_vapi(cx, CX18_CPU_DE_SET_MDL, 5, 367 cx18_push(s, buf, &s->q_full);
372 s->handle,
373 (void __iomem *)&cx->scb->cpu_mdl[buf->id] -
374 cx->enc_mem,
375 1, buf->id, s->buf_size);
376 } else
377 cx18_enqueue(s, buf, &s->q_io);
378 } else if (buf->readpos == buf->bytesused) { 368 } else if (buf->readpos == buf->bytesused) {
379 int idx = cx->vbi.inserted_frame % CX18_VBI_FRAMES; 369 int idx = cx->vbi.inserted_frame % CX18_VBI_FRAMES;
380 370
@@ -518,7 +508,7 @@ unsigned int cx18_v4l2_enc_poll(struct file *filp, poll_table *wait)
518 CX18_DEBUG_HI_FILE("Encoder poll\n"); 508 CX18_DEBUG_HI_FILE("Encoder poll\n");
519 poll_wait(filp, &s->waitq, wait); 509 poll_wait(filp, &s->waitq, wait);
520 510
521 if (atomic_read(&s->q_full.buffers) || atomic_read(&s->q_io.buffers)) 511 if (atomic_read(&s->q_full.buffers))
522 return POLLIN | POLLRDNORM; 512 return POLLIN | POLLRDNORM;
523 if (eof) 513 if (eof)
524 return POLLHUP; 514 return POLLHUP;
diff --git a/drivers/media/video/cx18/cx18-firmware.c b/drivers/media/video/cx18/cx18-firmware.c
index 51534428cd00..1fa95da1575e 100644
--- a/drivers/media/video/cx18/cx18-firmware.c
+++ b/drivers/media/video/cx18/cx18-firmware.c
@@ -2,6 +2,7 @@
2 * cx18 firmware functions 2 * cx18 firmware functions
3 * 3 *
4 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> 4 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
5 * Copyright (C) 2008 Andy Walls <awalls@radix.net>
5 * 6 *
6 * 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
7 * 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
@@ -25,6 +26,7 @@
25#include "cx18-irq.h" 26#include "cx18-irq.h"
26#include "cx18-firmware.h" 27#include "cx18-firmware.h"
27#include "cx18-cards.h" 28#include "cx18-cards.h"
29#include "cx18-av-core.h"
28#include <linux/firmware.h> 30#include <linux/firmware.h>
29 31
30#define CX18_PROC_SOFT_RESET 0xc70010 32#define CX18_PROC_SOFT_RESET 0xc70010
@@ -121,6 +123,7 @@ static int load_cpu_fw_direct(const char *fn, u8 __iomem *mem, struct cx18 *cx)
121 if (cx18_raw_readl(cx, dst) != *src) { 123 if (cx18_raw_readl(cx, dst) != *src) {
122 CX18_ERR("Mismatch at offset %x\n", i); 124 CX18_ERR("Mismatch at offset %x\n", i);
123 release_firmware(fw); 125 release_firmware(fw);
126 cx18_setup_page(cx, 0);
124 return -EIO; 127 return -EIO;
125 } 128 }
126 dst++; 129 dst++;
@@ -131,10 +134,12 @@ static int load_cpu_fw_direct(const char *fn, u8 __iomem *mem, struct cx18 *cx)
131 CX18_INFO("loaded %s firmware (%zd bytes)\n", fn, fw->size); 134 CX18_INFO("loaded %s firmware (%zd bytes)\n", fn, fw->size);
132 size = fw->size; 135 size = fw->size;
133 release_firmware(fw); 136 release_firmware(fw);
137 cx18_setup_page(cx, SCB_OFFSET);
134 return size; 138 return size;
135} 139}
136 140
137static int load_apu_fw_direct(const char *fn, u8 __iomem *dst, struct cx18 *cx) 141static int load_apu_fw_direct(const char *fn, u8 __iomem *dst, struct cx18 *cx,
142 u32 *entry_addr)
138{ 143{
139 const struct firmware *fw = NULL; 144 const struct firmware *fw = NULL;
140 int i, j; 145 int i, j;
@@ -149,9 +154,11 @@ static int load_apu_fw_direct(const char *fn, u8 __iomem *dst, struct cx18 *cx)
149 if (request_firmware(&fw, fn, &cx->dev->dev)) { 154 if (request_firmware(&fw, fn, &cx->dev->dev)) {
150 CX18_ERR("unable to open firmware %s\n", fn); 155 CX18_ERR("unable to open firmware %s\n", fn);
151 CX18_ERR("did you put the firmware in the hotplug firmware directory?\n"); 156 CX18_ERR("did you put the firmware in the hotplug firmware directory?\n");
157 cx18_setup_page(cx, 0);
152 return -ENOMEM; 158 return -ENOMEM;
153 } 159 }
154 160
161 *entry_addr = 0;
155 src = (const u32 *)fw->data; 162 src = (const u32 *)fw->data;
156 vers = fw->data + sizeof(seghdr); 163 vers = fw->data + sizeof(seghdr);
157 sz = fw->size; 164 sz = fw->size;
@@ -168,10 +175,12 @@ static int load_apu_fw_direct(const char *fn, u8 __iomem *dst, struct cx18 *cx)
168 } 175 }
169 CX18_DEBUG_INFO("load segment %x-%x\n", seghdr.addr, 176 CX18_DEBUG_INFO("load segment %x-%x\n", seghdr.addr,
170 seghdr.addr + seghdr.size - 1); 177 seghdr.addr + seghdr.size - 1);
178 if (*entry_addr == 0)
179 *entry_addr = seghdr.addr;
171 if (offset + seghdr.size > sz) 180 if (offset + seghdr.size > sz)
172 break; 181 break;
173 for (i = 0; i < seghdr.size; i += 4096) { 182 for (i = 0; i < seghdr.size; i += 4096) {
174 cx18_setup_page(cx, offset + i); 183 cx18_setup_page(cx, seghdr.addr + i);
175 for (j = i; j < seghdr.size && j < i + 4096; j += 4) { 184 for (j = i; j < seghdr.size && j < i + 4096; j += 4) {
176 /* no need for endianness conversion on the ppc */ 185 /* no need for endianness conversion on the ppc */
177 cx18_raw_writel(cx, src[(offset + j) / 4], 186 cx18_raw_writel(cx, src[(offset + j) / 4],
@@ -181,6 +190,7 @@ static int load_apu_fw_direct(const char *fn, u8 __iomem *dst, struct cx18 *cx)
181 CX18_ERR("Mismatch at offset %x\n", 190 CX18_ERR("Mismatch at offset %x\n",
182 offset + j); 191 offset + j);
183 release_firmware(fw); 192 release_firmware(fw);
193 cx18_setup_page(cx, 0);
184 return -EIO; 194 return -EIO;
185 } 195 }
186 } 196 }
@@ -192,16 +202,17 @@ static int load_apu_fw_direct(const char *fn, u8 __iomem *dst, struct cx18 *cx)
192 fn, apu_version, fw->size); 202 fn, apu_version, fw->size);
193 size = fw->size; 203 size = fw->size;
194 release_firmware(fw); 204 release_firmware(fw);
195 /* Clear bit0 for APU to start from 0 */ 205 cx18_setup_page(cx, 0);
196 cx18_write_reg(cx, cx18_read_reg(cx, 0xc72030) & ~1, 0xc72030);
197 return size; 206 return size;
198} 207}
199 208
200void cx18_halt_firmware(struct cx18 *cx) 209void cx18_halt_firmware(struct cx18 *cx)
201{ 210{
202 CX18_DEBUG_INFO("Preparing for firmware halt.\n"); 211 CX18_DEBUG_INFO("Preparing for firmware halt.\n");
203 cx18_write_reg(cx, 0x000F000F, CX18_PROC_SOFT_RESET); /* stop the fw */ 212 cx18_write_reg_expect(cx, 0x000F000F, CX18_PROC_SOFT_RESET,
204 cx18_write_reg(cx, 0x00020002, CX18_ADEC_CONTROL); 213 0x0000000F, 0x000F000F);
214 cx18_write_reg_expect(cx, 0x00020002, CX18_ADEC_CONTROL,
215 0x00000002, 0x00020002);
205} 216}
206 217
207void cx18_init_power(struct cx18 *cx, int lowpwr) 218void cx18_init_power(struct cx18 *cx, int lowpwr)
@@ -211,9 +222,48 @@ void cx18_init_power(struct cx18 *cx, int lowpwr)
211 cx18_write_reg(cx, 0x00000008, CX18_PLL_POWER_DOWN); 222 cx18_write_reg(cx, 0x00000008, CX18_PLL_POWER_DOWN);
212 223
213 /* ADEC out of sleep */ 224 /* ADEC out of sleep */
214 cx18_write_reg(cx, 0x00020000, CX18_ADEC_CONTROL); 225 cx18_write_reg_expect(cx, 0x00020000, CX18_ADEC_CONTROL,
215 226 0x00000000, 0x00020002);
216 /* The fast clock is at 200/245 MHz */ 227
228 /*
229 * The PLL parameters are based on the external crystal frequency that
230 * would ideally be:
231 *
232 * NTSC Color subcarrier freq * 8 =
233 * 4.5 MHz/286 * 455/2 * 8 = 28.63636363... MHz
234 *
235 * The accidents of history and rationale that explain from where this
236 * combination of magic numbers originate can be found in:
237 *
238 * [1] Abrahams, I. C., "Choice of Chrominance Subcarrier Frequency in
239 * the NTSC Standards", Proceedings of the I-R-E, January 1954, pp 79-80
240 *
241 * [2] Abrahams, I. C., "The 'Frequency Interleaving' Principle in the
242 * NTSC Standards", Proceedings of the I-R-E, January 1954, pp 81-83
243 *
244 * As Mike Bradley has rightly pointed out, it's not the exact crystal
245 * frequency that matters, only that all parts of the driver and
246 * firmware are using the same value (close to the ideal value).
247 *
248 * Since I have a strong suspicion that, if the firmware ever assumes a
249 * crystal value at all, it will assume 28.636360 MHz, the crystal
250 * freq used in calculations in this driver will be:
251 *
252 * xtal_freq = 28.636360 MHz
253 *
254 * an error of less than 0.13 ppm which is way, way better than any off
255 * the shelf crystal will have for accuracy anyway.
256 *
257 * Below I aim to run the PLLs' VCOs near 400 MHz to minimze errors.
258 *
259 * Many thanks to Jeff Campbell and Mike Bradley for their extensive
260 * investigation, experimentation, testing, and suggested solutions of
261 * of audio/video sync problems with SVideo and CVBS captures.
262 */
263
264 /* the fast clock is at 200/245 MHz */
265 /* 1 * xtal_freq * 0x0d.f7df9b8 / 2 = 200 MHz: 400 MHz pre post-divide*/
266 /* 1 * xtal_freq * 0x11.1c71eb8 / 2 = 245 MHz: 490 MHz pre post-divide*/
217 cx18_write_reg(cx, lowpwr ? 0xD : 0x11, CX18_FAST_CLOCK_PLL_INT); 267 cx18_write_reg(cx, lowpwr ? 0xD : 0x11, CX18_FAST_CLOCK_PLL_INT);
218 cx18_write_reg(cx, lowpwr ? 0x1EFBF37 : 0x038E3D7, 268 cx18_write_reg(cx, lowpwr ? 0x1EFBF37 : 0x038E3D7,
219 CX18_FAST_CLOCK_PLL_FRAC); 269 CX18_FAST_CLOCK_PLL_FRAC);
@@ -223,16 +273,36 @@ void cx18_init_power(struct cx18 *cx, int lowpwr)
223 cx18_write_reg(cx, 4, CX18_FAST_CLOCK_PLL_ADJUST_BANDWIDTH); 273 cx18_write_reg(cx, 4, CX18_FAST_CLOCK_PLL_ADJUST_BANDWIDTH);
224 274
225 /* set slow clock to 125/120 MHz */ 275 /* set slow clock to 125/120 MHz */
226 cx18_write_reg(cx, lowpwr ? 0x11 : 0x10, CX18_SLOW_CLOCK_PLL_INT); 276 /* xtal_freq * 0x0d.1861a20 / 3 = 125 MHz: 375 MHz before post-divide */
227 cx18_write_reg(cx, lowpwr ? 0xEBAF05 : 0x18618A8, 277 /* xtal_freq * 0x0c.92493f8 / 3 = 120 MHz: 360 MHz before post-divide */
278 cx18_write_reg(cx, lowpwr ? 0xD : 0xC, CX18_SLOW_CLOCK_PLL_INT);
279 cx18_write_reg(cx, lowpwr ? 0x30C344 : 0x124927F,
228 CX18_SLOW_CLOCK_PLL_FRAC); 280 CX18_SLOW_CLOCK_PLL_FRAC);
229 cx18_write_reg(cx, 4, CX18_SLOW_CLOCK_PLL_POST); 281 cx18_write_reg(cx, 3, CX18_SLOW_CLOCK_PLL_POST);
230 282
231 /* mpeg clock pll 54MHz */ 283 /* mpeg clock pll 54MHz */
284 /* xtal_freq * 0xf.15f17f0 / 8 = 54 MHz: 432 MHz before post-divide */
232 cx18_write_reg(cx, 0xF, CX18_MPEG_CLOCK_PLL_INT); 285 cx18_write_reg(cx, 0xF, CX18_MPEG_CLOCK_PLL_INT);
233 cx18_write_reg(cx, 0x2BCFEF, CX18_MPEG_CLOCK_PLL_FRAC); 286 cx18_write_reg(cx, 0x2BE2FE, CX18_MPEG_CLOCK_PLL_FRAC);
234 cx18_write_reg(cx, 8, CX18_MPEG_CLOCK_PLL_POST); 287 cx18_write_reg(cx, 8, CX18_MPEG_CLOCK_PLL_POST);
235 288
289 /*
290 * VDCLK Integer = 0x0f, Post Divider = 0x04
291 * AIMCLK Integer = 0x0e, Post Divider = 0x16
292 */
293 cx18_av_write4(cx, CXADEC_PLL_CTRL1, 0x160e040f);
294
295 /* VDCLK Fraction = 0x2be2fe */
296 /* xtal * 0xf.15f17f0/4 = 108 MHz: 432 MHz before post divide */
297 cx18_av_write4(cx, CXADEC_VID_PLL_FRAC, 0x002be2fe);
298
299 /* AIMCLK Fraction = 0x05227ad */
300 /* xtal * 0xe.2913d68/0x16 = 48000 * 384: 406 MHz before post-divide */
301 cx18_av_write4(cx, CXADEC_AUX_PLL_FRAC, 0x005227ad);
302
303 /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x16 */
304 cx18_av_write(cx, CXADEC_I2S_MCLK, 0x56);
305
236 /* Defaults */ 306 /* Defaults */
237 /* APU = SC or SC/2 = 125/62.5 */ 307 /* APU = SC or SC/2 = 125/62.5 */
238 /* EPU = SC = 125 */ 308 /* EPU = SC = 125 */
@@ -248,22 +318,34 @@ void cx18_init_power(struct cx18 *cx, int lowpwr)
248 /* VFC = disabled */ 318 /* VFC = disabled */
249 /* USB = disabled */ 319 /* USB = disabled */
250 320
251 cx18_write_reg(cx, lowpwr ? 0xFFFF0020 : 0x00060004, 321 if (lowpwr) {
252 CX18_CLOCK_SELECT1); 322 cx18_write_reg_expect(cx, 0xFFFF0020, CX18_CLOCK_SELECT1,
253 cx18_write_reg(cx, lowpwr ? 0xFFFF0004 : 0x00060006, 323 0x00000020, 0xFFFFFFFF);
254 CX18_CLOCK_SELECT2); 324 cx18_write_reg_expect(cx, 0xFFFF0004, CX18_CLOCK_SELECT2,
255 325 0x00000004, 0xFFFFFFFF);
256 cx18_write_reg(cx, 0xFFFF0002, CX18_HALF_CLOCK_SELECT1); 326 } else {
257 cx18_write_reg(cx, 0xFFFF0104, CX18_HALF_CLOCK_SELECT2); 327 /* This doesn't explicitly set every clock select */
328 cx18_write_reg_expect(cx, 0x00060004, CX18_CLOCK_SELECT1,
329 0x00000004, 0x00060006);
330 cx18_write_reg_expect(cx, 0x00060006, CX18_CLOCK_SELECT2,
331 0x00000006, 0x00060006);
332 }
258 333
259 cx18_write_reg(cx, 0xFFFF9026, CX18_CLOCK_ENABLE1); 334 cx18_write_reg_expect(cx, 0xFFFF0002, CX18_HALF_CLOCK_SELECT1,
260 cx18_write_reg(cx, 0xFFFF3105, CX18_CLOCK_ENABLE2); 335 0x00000002, 0xFFFFFFFF);
336 cx18_write_reg_expect(cx, 0xFFFF0104, CX18_HALF_CLOCK_SELECT2,
337 0x00000104, 0xFFFFFFFF);
338 cx18_write_reg_expect(cx, 0xFFFF9026, CX18_CLOCK_ENABLE1,
339 0x00009026, 0xFFFFFFFF);
340 cx18_write_reg_expect(cx, 0xFFFF3105, CX18_CLOCK_ENABLE2,
341 0x00003105, 0xFFFFFFFF);
261} 342}
262 343
263void cx18_init_memory(struct cx18 *cx) 344void cx18_init_memory(struct cx18 *cx)
264{ 345{
265 cx18_msleep_timeout(10, 0); 346 cx18_msleep_timeout(10, 0);
266 cx18_write_reg(cx, 0x10000, CX18_DDR_SOFT_RESET); 347 cx18_write_reg_expect(cx, 0x00010000, CX18_DDR_SOFT_RESET,
348 0x00000000, 0x00010001);
267 cx18_msleep_timeout(10, 0); 349 cx18_msleep_timeout(10, 0);
268 350
269 cx18_write_reg(cx, cx->card->ddr.chip_config, CX18_DDR_CHIP_CONFIG); 351 cx18_write_reg(cx, cx->card->ddr.chip_config, CX18_DDR_CHIP_CONFIG);
@@ -282,13 +364,15 @@ void cx18_init_memory(struct cx18 *cx)
282 364
283 cx18_msleep_timeout(10, 0); 365 cx18_msleep_timeout(10, 0);
284 366
285 cx18_write_reg(cx, 0x20000, CX18_DDR_SOFT_RESET); 367 cx18_write_reg_expect(cx, 0x00020000, CX18_DDR_SOFT_RESET,
368 0x00000000, 0x00020002);
286 cx18_msleep_timeout(10, 0); 369 cx18_msleep_timeout(10, 0);
287 370
288 /* use power-down mode when idle */ 371 /* use power-down mode when idle */
289 cx18_write_reg(cx, 0x00000010, CX18_DDR_POWER_REG); 372 cx18_write_reg(cx, 0x00000010, CX18_DDR_POWER_REG);
290 373
291 cx18_write_reg(cx, 0x10001, CX18_REG_BUS_TIMEOUT_EN); 374 cx18_write_reg_expect(cx, 0x00010001, CX18_REG_BUS_TIMEOUT_EN,
375 0x00000001, 0x00010001);
292 376
293 cx18_write_reg(cx, 0x48, CX18_DDR_MB_PER_ROW_7); 377 cx18_write_reg(cx, 0x48, CX18_DDR_MB_PER_ROW_7);
294 cx18_write_reg(cx, 0xE0000, CX18_DDR_BASE_63_ADDR); 378 cx18_write_reg(cx, 0xE0000, CX18_DDR_BASE_63_ADDR);
@@ -307,51 +391,76 @@ void cx18_init_memory(struct cx18 *cx)
307 391
308int cx18_firmware_init(struct cx18 *cx) 392int cx18_firmware_init(struct cx18 *cx)
309{ 393{
394 u32 fw_entry_addr;
395 int sz, retries;
396 u32 api_args[MAX_MB_ARGUMENTS];
397
310 /* Allow chip to control CLKRUN */ 398 /* Allow chip to control CLKRUN */
311 cx18_write_reg(cx, 0x5, CX18_DSP0_INTERRUPT_MASK); 399 cx18_write_reg(cx, 0x5, CX18_DSP0_INTERRUPT_MASK);
312 400
313 cx18_write_reg(cx, 0x000F000F, CX18_PROC_SOFT_RESET); /* stop the fw */ 401 /* Stop the firmware */
402 cx18_write_reg_expect(cx, 0x000F000F, CX18_PROC_SOFT_RESET,
403 0x0000000F, 0x000F000F);
314 404
315 cx18_msleep_timeout(1, 0); 405 cx18_msleep_timeout(1, 0);
316 406
407 /* If the CPU is still running */
408 if ((cx18_read_reg(cx, CX18_PROC_SOFT_RESET) & 8) == 0) {
409 CX18_ERR("%s: couldn't stop CPU to load firmware\n", __func__);
410 return -EIO;
411 }
412
317 cx18_sw1_irq_enable(cx, IRQ_CPU_TO_EPU | IRQ_APU_TO_EPU); 413 cx18_sw1_irq_enable(cx, IRQ_CPU_TO_EPU | IRQ_APU_TO_EPU);
318 cx18_sw2_irq_enable(cx, IRQ_CPU_TO_EPU_ACK | IRQ_APU_TO_EPU_ACK); 414 cx18_sw2_irq_enable(cx, IRQ_CPU_TO_EPU_ACK | IRQ_APU_TO_EPU_ACK);
319 415
320 /* Only if the processor is not running */ 416 sz = load_cpu_fw_direct("v4l-cx23418-cpu.fw", cx->enc_mem, cx);
321 if (cx18_read_reg(cx, CX18_PROC_SOFT_RESET) & 8) { 417 if (sz <= 0)
322 int sz = load_apu_fw_direct("v4l-cx23418-apu.fw", 418 return sz;
323 cx->enc_mem, cx); 419
324 420 /* The SCB & IPC area *must* be correct before starting the firmwares */
325 cx18_write_enc(cx, 0xE51FF004, 0); 421 cx18_init_scb(cx);
326 cx18_write_enc(cx, 0xa00000, 4); /* todo: not hardcoded */ 422
327 /* Start APU */ 423 fw_entry_addr = 0;
328 cx18_write_reg(cx, 0x00010000, CX18_PROC_SOFT_RESET); 424 sz = load_apu_fw_direct("v4l-cx23418-apu.fw", cx->enc_mem, cx,
329 cx18_msleep_timeout(500, 0); 425 &fw_entry_addr);
330 426 if (sz <= 0)
331 sz = sz <= 0 ? sz : load_cpu_fw_direct("v4l-cx23418-cpu.fw", 427 return sz;
332 cx->enc_mem, cx); 428
333 429 /* Start the CPU. The CPU will take care of the APU for us. */
334 if (sz > 0) { 430 cx18_write_reg_expect(cx, 0x00080000, CX18_PROC_SOFT_RESET,
335 int retries = 0; 431 0x00000000, 0x00080008);
336 432
337 /* start the CPU */ 433 /* Wait up to 500 ms for the APU to come out of reset */
338 cx18_write_reg(cx, 0x00080000, CX18_PROC_SOFT_RESET); 434 for (retries = 0;
339 while (retries++ < 50) { /* Loop for max 500mS */ 435 retries < 50 && (cx18_read_reg(cx, CX18_PROC_SOFT_RESET) & 1) == 1;
340 if ((cx18_read_reg(cx, CX18_PROC_SOFT_RESET) 436 retries++)
341 & 1) == 0) 437 cx18_msleep_timeout(10, 0);
342 break; 438
343 cx18_msleep_timeout(10, 0); 439 cx18_msleep_timeout(200, 0);
344 } 440
345 cx18_msleep_timeout(200, 0); 441 if (retries == 50 &&
346 if (retries == 51) { 442 (cx18_read_reg(cx, CX18_PROC_SOFT_RESET) & 1) == 1) {
347 CX18_ERR("Could not start the CPU\n"); 443 CX18_ERR("Could not start the CPU\n");
348 return -EIO; 444 return -EIO;
349 }
350 }
351 if (sz <= 0)
352 return -EIO;
353 } 445 }
446
447 /*
448 * The CPU had once before set up to receive an interrupt for it's
449 * outgoing IRQ_CPU_TO_EPU_ACK to us. If it ever does this, we get an
450 * interrupt when it sends us an ack, but by the time we process it,
451 * that flag in the SW2 status register has been cleared by the CPU
452 * firmware. We'll prevent that not so useful condition from happening
453 * by clearing the CPU's interrupt enables for Ack IRQ's we want to
454 * process.
455 */
456 cx18_sw2_irq_disable_cpu(cx, IRQ_CPU_TO_EPU_ACK | IRQ_APU_TO_EPU_ACK);
457
458 /* Try a benign command to see if the CPU is alive and well */
459 sz = cx18_vapi_result(cx, api_args, CX18_CPU_DEBUG_PEEK32, 1, 0);
460 if (sz < 0)
461 return sz;
462
354 /* initialize GPIO */ 463 /* initialize GPIO */
355 cx18_write_reg(cx, 0x14001400, 0xC78110); 464 cx18_write_reg_expect(cx, 0x14001400, 0xc78110, 0x00001400, 0x14001400);
356 return 0; 465 return 0;
357} 466}
diff --git a/drivers/media/video/cx18/cx18-gpio.c b/drivers/media/video/cx18/cx18-gpio.c
index 0e560421989e..1a99329f33cb 100644
--- a/drivers/media/video/cx18/cx18-gpio.c
+++ b/drivers/media/video/cx18/cx18-gpio.c
@@ -4,6 +4,7 @@
4 * Derived from ivtv-gpio.c 4 * Derived from ivtv-gpio.c
5 * 5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> 6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 * Copyright (C) 2008 Andy Walls <awalls@radix.net>
7 * 8 *
8 * This program is free software; you can redistribute it and/or modify 9 * 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 * it under the terms of the GNU General Public License as published by
@@ -47,15 +48,19 @@
47 48
48static void gpio_write(struct cx18 *cx) 49static void gpio_write(struct cx18 *cx)
49{ 50{
50 u32 dir = cx->gpio_dir; 51 u32 dir_lo = cx->gpio_dir & 0xffff;
51 u32 val = cx->gpio_val; 52 u32 val_lo = cx->gpio_val & 0xffff;
52 53 u32 dir_hi = cx->gpio_dir >> 16;
53 cx18_write_reg(cx, (dir & 0xffff) << 16, CX18_REG_GPIO_DIR1); 54 u32 val_hi = cx->gpio_val >> 16;
54 cx18_write_reg(cx, ((dir & 0xffff) << 16) | (val & 0xffff), 55
55 CX18_REG_GPIO_OUT1); 56 cx18_write_reg_expect(cx, dir_lo << 16,
56 cx18_write_reg(cx, dir & 0xffff0000, CX18_REG_GPIO_DIR2); 57 CX18_REG_GPIO_DIR1, ~dir_lo, dir_lo);
57 cx18_write_reg_sync(cx, (dir & 0xffff0000) | ((val & 0xffff0000) >> 16), 58 cx18_write_reg_expect(cx, (dir_lo << 16) | val_lo,
58 CX18_REG_GPIO_OUT2); 59 CX18_REG_GPIO_OUT1, val_lo, dir_lo);
60 cx18_write_reg_expect(cx, dir_hi << 16,
61 CX18_REG_GPIO_DIR2, ~dir_hi, dir_hi);
62 cx18_write_reg_expect(cx, (dir_hi << 16) | val_hi,
63 CX18_REG_GPIO_OUT2, val_hi, dir_hi);
59} 64}
60 65
61void cx18_reset_i2c_slaves_gpio(struct cx18 *cx) 66void cx18_reset_i2c_slaves_gpio(struct cx18 *cx)
diff --git a/drivers/media/video/cx18/cx18-gpio.h b/drivers/media/video/cx18/cx18-gpio.h
index beb7424b9944..39ffccc19d8a 100644
--- a/drivers/media/video/cx18/cx18-gpio.h
+++ b/drivers/media/video/cx18/cx18-gpio.h
@@ -4,6 +4,7 @@
4 * Derived from ivtv-gpio.h 4 * Derived from ivtv-gpio.h
5 * 5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> 6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 * Copyright (C) 2008 Andy Walls <awalls@radix.net>
7 * 8 *
8 * This program is free software; you can redistribute it and/or modify 9 * 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 * it under the terms of the GNU General Public License as published by
diff --git a/drivers/media/video/cx18/cx18-i2c.c b/drivers/media/video/cx18/cx18-i2c.c
index aa09e557b195..8941f58bed7f 100644
--- a/drivers/media/video/cx18/cx18-i2c.c
+++ b/drivers/media/video/cx18/cx18-i2c.c
@@ -4,6 +4,7 @@
4 * Derived from ivtv-i2c.c 4 * Derived from ivtv-i2c.c
5 * 5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> 6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 * Copyright (C) 2008 Andy Walls <awalls@radix.net>
7 * 8 *
8 * This program is free software; you can redistribute it and/or modify 9 * 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 * it under the terms of the GNU General Public License as published by
@@ -27,6 +28,7 @@
27#include "cx18-gpio.h" 28#include "cx18-gpio.h"
28#include "cx18-av-core.h" 29#include "cx18-av-core.h"
29#include "cx18-i2c.h" 30#include "cx18-i2c.h"
31#include "cx18-irq.h"
30 32
31#define CX18_REG_I2C_1_WR 0xf15000 33#define CX18_REG_I2C_1_WR 0xf15000
32#define CX18_REG_I2C_1_RD 0xf15008 34#define CX18_REG_I2C_1_RD 0xf15008
@@ -160,9 +162,9 @@ static void cx18_setscl(void *data, int state)
160 u32 r = cx18_read_reg(cx, addr); 162 u32 r = cx18_read_reg(cx, addr);
161 163
162 if (state) 164 if (state)
163 cx18_write_reg_sync(cx, r | SETSCL_BIT, addr); 165 cx18_write_reg(cx, r | SETSCL_BIT, addr);
164 else 166 else
165 cx18_write_reg_sync(cx, r & ~SETSCL_BIT, addr); 167 cx18_write_reg(cx, r & ~SETSCL_BIT, addr);
166} 168}
167 169
168static void cx18_setsda(void *data, int state) 170static void cx18_setsda(void *data, int state)
@@ -173,9 +175,9 @@ static void cx18_setsda(void *data, int state)
173 u32 r = cx18_read_reg(cx, addr); 175 u32 r = cx18_read_reg(cx, addr);
174 176
175 if (state) 177 if (state)
176 cx18_write_reg_sync(cx, r | SETSDL_BIT, addr); 178 cx18_write_reg(cx, r | SETSDL_BIT, addr);
177 else 179 else
178 cx18_write_reg_sync(cx, r & ~SETSDL_BIT, addr); 180 cx18_write_reg(cx, r & ~SETSDL_BIT, addr);
179} 181}
180 182
181static int cx18_getscl(void *data) 183static int cx18_getscl(void *data)
@@ -396,30 +398,33 @@ int init_cx18_i2c(struct cx18 *cx)
396 if (cx18_read_reg(cx, CX18_REG_I2C_2_WR) != 0x0003c02f) { 398 if (cx18_read_reg(cx, CX18_REG_I2C_2_WR) != 0x0003c02f) {
397 /* Reset/Unreset I2C hardware block */ 399 /* Reset/Unreset I2C hardware block */
398 /* Clock select 220MHz */ 400 /* Clock select 220MHz */
399 cx18_write_reg(cx, 0x10000000, 0xc71004); 401 cx18_write_reg_expect(cx, 0x10000000, 0xc71004,
402 0x00000000, 0x10001000);
400 /* Clock Enable */ 403 /* Clock Enable */
401 cx18_write_reg_sync(cx, 0x10001000, 0xc71024); 404 cx18_write_reg_expect(cx, 0x10001000, 0xc71024,
405 0x00001000, 0x10001000);
402 } 406 }
403 /* courtesy of Steven Toth <stoth@hauppauge.com> */ 407 /* courtesy of Steven Toth <stoth@hauppauge.com> */
404 cx18_write_reg_sync(cx, 0x00c00000, 0xc7001c); 408 cx18_write_reg_expect(cx, 0x00c00000, 0xc7001c, 0x00000000, 0x00c000c0);
405 mdelay(10); 409 mdelay(10);
406 cx18_write_reg_sync(cx, 0x00c000c0, 0xc7001c); 410 cx18_write_reg_expect(cx, 0x00c000c0, 0xc7001c, 0x000000c0, 0x00c000c0);
407 mdelay(10); 411 mdelay(10);
408 cx18_write_reg_sync(cx, 0x00c00000, 0xc7001c); 412 cx18_write_reg_expect(cx, 0x00c00000, 0xc7001c, 0x00000000, 0x00c000c0);
409 mdelay(10); 413 mdelay(10);
410 414
411 /* Set to edge-triggered intrs. */ 415 /* Set to edge-triggered intrs. */
412 cx18_write_reg_sync(cx, 0x00c00000, 0xc730c8); 416 cx18_write_reg(cx, 0x00c00000, 0xc730c8);
413 /* Clear any stale intrs */ 417 /* Clear any stale intrs */
414 cx18_write_reg_sync(cx, 0x00c00000, 0xc730c4); 418 cx18_write_reg_expect(cx, HW2_I2C1_INT|HW2_I2C2_INT, HW2_INT_CLR_STATUS,
419 ~(HW2_I2C1_INT|HW2_I2C2_INT), HW2_I2C1_INT|HW2_I2C2_INT);
415 420
416 /* Hw I2C1 Clock Freq ~100kHz */ 421 /* Hw I2C1 Clock Freq ~100kHz */
417 cx18_write_reg_sync(cx, 0x00021c0f & ~4, CX18_REG_I2C_1_WR); 422 cx18_write_reg(cx, 0x00021c0f & ~4, CX18_REG_I2C_1_WR);
418 cx18_setscl(&cx->i2c_algo_cb_data[0], 1); 423 cx18_setscl(&cx->i2c_algo_cb_data[0], 1);
419 cx18_setsda(&cx->i2c_algo_cb_data[0], 1); 424 cx18_setsda(&cx->i2c_algo_cb_data[0], 1);
420 425
421 /* Hw I2C2 Clock Freq ~100kHz */ 426 /* Hw I2C2 Clock Freq ~100kHz */
422 cx18_write_reg_sync(cx, 0x00021c0f & ~4, CX18_REG_I2C_2_WR); 427 cx18_write_reg(cx, 0x00021c0f & ~4, CX18_REG_I2C_2_WR);
423 cx18_setscl(&cx->i2c_algo_cb_data[1], 1); 428 cx18_setscl(&cx->i2c_algo_cb_data[1], 1);
424 cx18_setsda(&cx->i2c_algo_cb_data[1], 1); 429 cx18_setsda(&cx->i2c_algo_cb_data[1], 1);
425 430
diff --git a/drivers/media/video/cx18/cx18-io.c b/drivers/media/video/cx18/cx18-io.c
index 220fae8d4ad7..ec5b3d7bcc6b 100644
--- a/drivers/media/video/cx18/cx18-io.c
+++ b/drivers/media/video/cx18/cx18-io.c
@@ -24,179 +24,6 @@
24#include "cx18-io.h" 24#include "cx18-io.h"
25#include "cx18-irq.h" 25#include "cx18-irq.h"
26 26
27void cx18_log_statistics(struct cx18 *cx)
28{
29 int i;
30
31 if (!(cx18_debug & CX18_DBGFLG_INFO))
32 return;
33
34 for (i = 0; i <= CX18_MAX_MMIO_RETRIES; i++)
35 CX18_DEBUG_INFO("retried_write[%d] = %d\n", i,
36 atomic_read(&cx->mmio_stats.retried_write[i]));
37 for (i = 0; i <= CX18_MAX_MMIO_RETRIES; i++)
38 CX18_DEBUG_INFO("retried_read[%d] = %d\n", i,
39 atomic_read(&cx->mmio_stats.retried_read[i]));
40 return;
41}
42
43void cx18_raw_writel_retry(struct cx18 *cx, u32 val, void __iomem *addr)
44{
45 int i;
46 for (i = 0; i < CX18_MAX_MMIO_RETRIES; i++) {
47 cx18_raw_writel_noretry(cx, val, addr);
48 if (val == cx18_raw_readl_noretry(cx, addr))
49 break;
50 }
51 cx18_log_write_retries(cx, i, addr);
52}
53
54u32 cx18_raw_readl_retry(struct cx18 *cx, const void __iomem *addr)
55{
56 int i;
57 u32 val;
58 for (i = 0; i < CX18_MAX_MMIO_RETRIES; i++) {
59 val = cx18_raw_readl_noretry(cx, addr);
60 if (val != 0xffffffff) /* PCI bus read error */
61 break;
62 }
63 cx18_log_read_retries(cx, i, addr);
64 return val;
65}
66
67u16 cx18_raw_readw_retry(struct cx18 *cx, const void __iomem *addr)
68{
69 int i;
70 u16 val;
71 for (i = 0; i < CX18_MAX_MMIO_RETRIES; i++) {
72 val = cx18_raw_readw_noretry(cx, addr);
73 if (val != 0xffff) /* PCI bus read error */
74 break;
75 }
76 cx18_log_read_retries(cx, i, addr);
77 return val;
78}
79
80void cx18_writel_retry(struct cx18 *cx, u32 val, void __iomem *addr)
81{
82 int i;
83 for (i = 0; i < CX18_MAX_MMIO_RETRIES; i++) {
84 cx18_writel_noretry(cx, val, addr);
85 if (val == cx18_readl_noretry(cx, addr))
86 break;
87 }
88 cx18_log_write_retries(cx, i, addr);
89}
90
91void _cx18_writel_expect(struct cx18 *cx, u32 val, void __iomem *addr,
92 u32 eval, u32 mask)
93{
94 int i;
95 eval &= mask;
96 for (i = 0; i < CX18_MAX_MMIO_RETRIES; i++) {
97 cx18_writel_noretry(cx, val, addr);
98 if (eval == (cx18_readl_noretry(cx, addr) & mask))
99 break;
100 }
101 cx18_log_write_retries(cx, i, addr);
102}
103
104void cx18_writew_retry(struct cx18 *cx, u16 val, void __iomem *addr)
105{
106 int i;
107 for (i = 0; i < CX18_MAX_MMIO_RETRIES; i++) {
108 cx18_writew_noretry(cx, val, addr);
109 if (val == cx18_readw_noretry(cx, addr))
110 break;
111 }
112 cx18_log_write_retries(cx, i, addr);
113}
114
115void cx18_writeb_retry(struct cx18 *cx, u8 val, void __iomem *addr)
116{
117 int i;
118 for (i = 0; i < CX18_MAX_MMIO_RETRIES; i++) {
119 cx18_writeb_noretry(cx, val, addr);
120 if (val == cx18_readb_noretry(cx, addr))
121 break;
122 }
123 cx18_log_write_retries(cx, i, addr);
124}
125
126u32 cx18_readl_retry(struct cx18 *cx, const void __iomem *addr)
127{
128 int i;
129 u32 val;
130 for (i = 0; i < CX18_MAX_MMIO_RETRIES; i++) {
131 val = cx18_readl_noretry(cx, addr);
132 if (val != 0xffffffff) /* PCI bus read error */
133 break;
134 }
135 cx18_log_read_retries(cx, i, addr);
136 return val;
137}
138
139u16 cx18_readw_retry(struct cx18 *cx, const void __iomem *addr)
140{
141 int i;
142 u16 val;
143 for (i = 0; i < CX18_MAX_MMIO_RETRIES; i++) {
144 val = cx18_readw_noretry(cx, addr);
145 if (val != 0xffff) /* PCI bus read error */
146 break;
147 }
148 cx18_log_read_retries(cx, i, addr);
149 return val;
150}
151
152u8 cx18_readb_retry(struct cx18 *cx, const void __iomem *addr)
153{
154 int i;
155 u8 val;
156 for (i = 0; i < CX18_MAX_MMIO_RETRIES; i++) {
157 val = cx18_readb_noretry(cx, addr);
158 if (val != 0xff) /* PCI bus read error */
159 break;
160 }
161 cx18_log_read_retries(cx, i, addr);
162 return val;
163}
164
165void cx18_memcpy_fromio(struct cx18 *cx, void *to,
166 const void __iomem *from, unsigned int len)
167{
168 const u8 __iomem *src = from;
169 u8 *dst = to;
170
171 /* Align reads on the CX23418's addresses */
172 if ((len > 0) && ((unsigned long) src & 1)) {
173 *dst = cx18_readb(cx, src);
174 len--;
175 dst++;
176 src++;
177 }
178 if ((len > 1) && ((unsigned long) src & 2)) {
179 *((u16 *)dst) = cx18_raw_readw(cx, src);
180 len -= 2;
181 dst += 2;
182 src += 2;
183 }
184 while (len > 3) {
185 *((u32 *)dst) = cx18_raw_readl(cx, src);
186 len -= 4;
187 dst += 4;
188 src += 4;
189 }
190 if (len > 1) {
191 *((u16 *)dst) = cx18_raw_readw(cx, src);
192 len -= 2;
193 dst += 2;
194 src += 2;
195 }
196 if (len > 0)
197 *dst = cx18_readb(cx, src);
198}
199
200void cx18_memset_io(struct cx18 *cx, void __iomem *addr, int val, size_t count) 27void cx18_memset_io(struct cx18 *cx, void __iomem *addr, int val, size_t count)
201{ 28{
202 u8 __iomem *dst = addr; 29 u8 __iomem *dst = addr;
@@ -230,32 +57,35 @@ void cx18_memset_io(struct cx18 *cx, void __iomem *addr, int val, size_t count)
230 57
231void cx18_sw1_irq_enable(struct cx18 *cx, u32 val) 58void cx18_sw1_irq_enable(struct cx18 *cx, u32 val)
232{ 59{
233 u32 r;
234 cx18_write_reg_expect(cx, val, SW1_INT_STATUS, ~val, val); 60 cx18_write_reg_expect(cx, val, SW1_INT_STATUS, ~val, val);
235 r = cx18_read_reg(cx, SW1_INT_ENABLE_PCI); 61 cx->sw1_irq_mask = cx18_read_reg(cx, SW1_INT_ENABLE_PCI) | val;
236 cx18_write_reg(cx, r | val, SW1_INT_ENABLE_PCI); 62 cx18_write_reg(cx, cx->sw1_irq_mask, SW1_INT_ENABLE_PCI);
237} 63}
238 64
239void cx18_sw1_irq_disable(struct cx18 *cx, u32 val) 65void cx18_sw1_irq_disable(struct cx18 *cx, u32 val)
240{ 66{
241 u32 r; 67 cx->sw1_irq_mask = cx18_read_reg(cx, SW1_INT_ENABLE_PCI) & ~val;
242 r = cx18_read_reg(cx, SW1_INT_ENABLE_PCI); 68 cx18_write_reg(cx, cx->sw1_irq_mask, SW1_INT_ENABLE_PCI);
243 cx18_write_reg(cx, r & ~val, SW1_INT_ENABLE_PCI);
244} 69}
245 70
246void cx18_sw2_irq_enable(struct cx18 *cx, u32 val) 71void cx18_sw2_irq_enable(struct cx18 *cx, u32 val)
247{ 72{
248 u32 r;
249 cx18_write_reg_expect(cx, val, SW2_INT_STATUS, ~val, val); 73 cx18_write_reg_expect(cx, val, SW2_INT_STATUS, ~val, val);
250 r = cx18_read_reg(cx, SW2_INT_ENABLE_PCI); 74 cx->sw2_irq_mask = cx18_read_reg(cx, SW2_INT_ENABLE_PCI) | val;
251 cx18_write_reg(cx, r | val, SW2_INT_ENABLE_PCI); 75 cx18_write_reg(cx, cx->sw2_irq_mask, SW2_INT_ENABLE_PCI);
252} 76}
253 77
254void cx18_sw2_irq_disable(struct cx18 *cx, u32 val) 78void cx18_sw2_irq_disable(struct cx18 *cx, u32 val)
255{ 79{
80 cx->sw2_irq_mask = cx18_read_reg(cx, SW2_INT_ENABLE_PCI) & ~val;
81 cx18_write_reg(cx, cx->sw2_irq_mask, SW2_INT_ENABLE_PCI);
82}
83
84void cx18_sw2_irq_disable_cpu(struct cx18 *cx, u32 val)
85{
256 u32 r; 86 u32 r;
257 r = cx18_read_reg(cx, SW2_INT_ENABLE_PCI); 87 r = cx18_read_reg(cx, SW2_INT_ENABLE_CPU);
258 cx18_write_reg(cx, r & ~val, SW2_INT_ENABLE_PCI); 88 cx18_write_reg(cx, r & ~val, SW2_INT_ENABLE_CPU);
259} 89}
260 90
261void cx18_setup_page(struct cx18 *cx, u32 addr) 91void cx18_setup_page(struct cx18 *cx, u32 addr)
diff --git a/drivers/media/video/cx18/cx18-io.h b/drivers/media/video/cx18/cx18-io.h
index 425244453ea7..2635b3a8cc96 100644
--- a/drivers/media/video/cx18/cx18-io.h
+++ b/drivers/media/video/cx18/cx18-io.h
@@ -25,232 +25,125 @@
25 25
26#include "cx18-driver.h" 26#include "cx18-driver.h"
27 27
28static inline void cx18_io_delay(struct cx18 *cx)
29{
30 if (cx->options.mmio_ndelay)
31 ndelay(cx->options.mmio_ndelay);
32}
33
34/* 28/*
35 * Readback and retry of MMIO access for reliability: 29 * Readback and retry of MMIO access for reliability:
36 * The concept was suggested by Steve Toth <stoth@linuxtv.org>. 30 * The concept was suggested by Steve Toth <stoth@linuxtv.org>.
37 * The implmentation is the fault of Andy Walls <awalls@radix.net>. 31 * The implmentation is the fault of Andy Walls <awalls@radix.net>.
32 *
33 * *write* functions are implied to retry the mmio unless suffixed with _noretry
34 * *read* functions never retry the mmio (it never helps to do so)
38 */ 35 */
39 36
40/* Statistics gathering */ 37/* Non byteswapping memory mapped IO */
41static inline 38static inline u32 cx18_raw_readl(struct cx18 *cx, const void __iomem *addr)
42void cx18_log_write_retries(struct cx18 *cx, int i, const void __iomem *addr)
43{
44 if (i > CX18_MAX_MMIO_RETRIES)
45 i = CX18_MAX_MMIO_RETRIES;
46 atomic_inc(&cx->mmio_stats.retried_write[i]);
47 return;
48}
49
50static inline
51void cx18_log_read_retries(struct cx18 *cx, int i, const void __iomem *addr)
52{ 39{
53 if (i > CX18_MAX_MMIO_RETRIES) 40 return __raw_readl(addr);
54 i = CX18_MAX_MMIO_RETRIES;
55 atomic_inc(&cx->mmio_stats.retried_read[i]);
56 return;
57} 41}
58 42
59void cx18_log_statistics(struct cx18 *cx);
60
61/* Non byteswapping memory mapped IO */
62static inline 43static inline
63void cx18_raw_writel_noretry(struct cx18 *cx, u32 val, void __iomem *addr) 44void cx18_raw_writel_noretry(struct cx18 *cx, u32 val, void __iomem *addr)
64{ 45{
65 __raw_writel(val, addr); 46 __raw_writel(val, addr);
66 cx18_io_delay(cx);
67} 47}
68 48
69void cx18_raw_writel_retry(struct cx18 *cx, u32 val, void __iomem *addr);
70
71static inline void cx18_raw_writel(struct cx18 *cx, u32 val, void __iomem *addr) 49static inline void cx18_raw_writel(struct cx18 *cx, u32 val, void __iomem *addr)
72{ 50{
73 if (cx18_retry_mmio) 51 int i;
74 cx18_raw_writel_retry(cx, val, addr); 52 for (i = 0; i < CX18_MAX_MMIO_WR_RETRIES; i++) {
75 else
76 cx18_raw_writel_noretry(cx, val, addr); 53 cx18_raw_writel_noretry(cx, val, addr);
54 if (val == cx18_raw_readl(cx, addr))
55 break;
56 }
77} 57}
78 58
79 59/* Normal memory mapped IO */
80static inline 60static inline u32 cx18_readl(struct cx18 *cx, const void __iomem *addr)
81u32 cx18_raw_readl_noretry(struct cx18 *cx, const void __iomem *addr)
82{
83 u32 ret = __raw_readl(addr);
84 cx18_io_delay(cx);
85 return ret;
86}
87
88u32 cx18_raw_readl_retry(struct cx18 *cx, const void __iomem *addr);
89
90static inline u32 cx18_raw_readl(struct cx18 *cx, const void __iomem *addr)
91{ 61{
92 if (cx18_retry_mmio) 62 return readl(addr);
93 return cx18_raw_readl_retry(cx, addr);
94
95 return cx18_raw_readl_noretry(cx, addr);
96} 63}
97 64
98
99static inline 65static inline
100u16 cx18_raw_readw_noretry(struct cx18 *cx, const void __iomem *addr) 66void cx18_writel_noretry(struct cx18 *cx, u32 val, void __iomem *addr)
101{ 67{
102 u16 ret = __raw_readw(addr); 68 writel(val, addr);
103 cx18_io_delay(cx);
104 return ret;
105} 69}
106 70
107u16 cx18_raw_readw_retry(struct cx18 *cx, const void __iomem *addr); 71static inline void cx18_writel(struct cx18 *cx, u32 val, void __iomem *addr)
108
109static inline u16 cx18_raw_readw(struct cx18 *cx, const void __iomem *addr)
110{ 72{
111 if (cx18_retry_mmio) 73 int i;
112 return cx18_raw_readw_retry(cx, addr); 74 for (i = 0; i < CX18_MAX_MMIO_WR_RETRIES; i++) {
113 75 cx18_writel_noretry(cx, val, addr);
114 return cx18_raw_readw_noretry(cx, addr); 76 if (val == cx18_readl(cx, addr))
77 break;
78 }
115} 79}
116 80
117
118/* Normal memory mapped IO */
119static inline 81static inline
120void cx18_writel_noretry(struct cx18 *cx, u32 val, void __iomem *addr) 82void cx18_writel_expect(struct cx18 *cx, u32 val, void __iomem *addr,
83 u32 eval, u32 mask)
121{ 84{
122 writel(val, addr); 85 int i;
123 cx18_io_delay(cx); 86 u32 r;
87 eval &= mask;
88 for (i = 0; i < CX18_MAX_MMIO_WR_RETRIES; i++) {
89 cx18_writel_noretry(cx, val, addr);
90 r = cx18_readl(cx, addr);
91 if (r == 0xffffffff && eval != 0xffffffff)
92 continue;
93 if (eval == (r & mask))
94 break;
95 }
124} 96}
125 97
126void cx18_writel_retry(struct cx18 *cx, u32 val, void __iomem *addr); 98static inline u16 cx18_readw(struct cx18 *cx, const void __iomem *addr)
127
128static inline void cx18_writel(struct cx18 *cx, u32 val, void __iomem *addr)
129{ 99{
130 if (cx18_retry_mmio) 100 return readw(addr);
131 cx18_writel_retry(cx, val, addr);
132 else
133 cx18_writel_noretry(cx, val, addr);
134} 101}
135 102
136void _cx18_writel_expect(struct cx18 *cx, u32 val, void __iomem *addr,
137 u32 eval, u32 mask);
138
139static inline 103static inline
140void cx18_writew_noretry(struct cx18 *cx, u16 val, void __iomem *addr) 104void cx18_writew_noretry(struct cx18 *cx, u16 val, void __iomem *addr)
141{ 105{
142 writew(val, addr); 106 writew(val, addr);
143 cx18_io_delay(cx);
144} 107}
145 108
146void cx18_writew_retry(struct cx18 *cx, u16 val, void __iomem *addr);
147
148static inline void cx18_writew(struct cx18 *cx, u16 val, void __iomem *addr) 109static inline void cx18_writew(struct cx18 *cx, u16 val, void __iomem *addr)
149{ 110{
150 if (cx18_retry_mmio) 111 int i;
151 cx18_writew_retry(cx, val, addr); 112 for (i = 0; i < CX18_MAX_MMIO_WR_RETRIES; i++) {
152 else
153 cx18_writew_noretry(cx, val, addr); 113 cx18_writew_noretry(cx, val, addr);
114 if (val == cx18_readw(cx, addr))
115 break;
116 }
154} 117}
155 118
119static inline u8 cx18_readb(struct cx18 *cx, const void __iomem *addr)
120{
121 return readb(addr);
122}
156 123
157static inline 124static inline
158void cx18_writeb_noretry(struct cx18 *cx, u8 val, void __iomem *addr) 125void cx18_writeb_noretry(struct cx18 *cx, u8 val, void __iomem *addr)
159{ 126{
160 writeb(val, addr); 127 writeb(val, addr);
161 cx18_io_delay(cx);
162} 128}
163 129
164void cx18_writeb_retry(struct cx18 *cx, u8 val, void __iomem *addr);
165
166static inline void cx18_writeb(struct cx18 *cx, u8 val, void __iomem *addr) 130static inline void cx18_writeb(struct cx18 *cx, u8 val, void __iomem *addr)
167{ 131{
168 if (cx18_retry_mmio) 132 int i;
169 cx18_writeb_retry(cx, val, addr); 133 for (i = 0; i < CX18_MAX_MMIO_WR_RETRIES; i++) {
170 else
171 cx18_writeb_noretry(cx, val, addr); 134 cx18_writeb_noretry(cx, val, addr);
172} 135 if (val == cx18_readb(cx, addr))
173 136 break;
174 137 }
175static inline u32 cx18_readl_noretry(struct cx18 *cx, const void __iomem *addr)
176{
177 u32 ret = readl(addr);
178 cx18_io_delay(cx);
179 return ret;
180}
181
182u32 cx18_readl_retry(struct cx18 *cx, const void __iomem *addr);
183
184static inline u32 cx18_readl(struct cx18 *cx, const void __iomem *addr)
185{
186 if (cx18_retry_mmio)
187 return cx18_readl_retry(cx, addr);
188
189 return cx18_readl_noretry(cx, addr);
190}
191
192
193static inline u16 cx18_readw_noretry(struct cx18 *cx, const void __iomem *addr)
194{
195 u16 ret = readw(addr);
196 cx18_io_delay(cx);
197 return ret;
198}
199
200u16 cx18_readw_retry(struct cx18 *cx, const void __iomem *addr);
201
202static inline u16 cx18_readw(struct cx18 *cx, const void __iomem *addr)
203{
204 if (cx18_retry_mmio)
205 return cx18_readw_retry(cx, addr);
206
207 return cx18_readw_noretry(cx, addr);
208}
209
210
211static inline u8 cx18_readb_noretry(struct cx18 *cx, const void __iomem *addr)
212{
213 u8 ret = readb(addr);
214 cx18_io_delay(cx);
215 return ret;
216}
217
218u8 cx18_readb_retry(struct cx18 *cx, const void __iomem *addr);
219
220static inline u8 cx18_readb(struct cx18 *cx, const void __iomem *addr)
221{
222 if (cx18_retry_mmio)
223 return cx18_readb_retry(cx, addr);
224
225 return cx18_readb_noretry(cx, addr);
226}
227
228
229static inline
230u32 cx18_write_sync_noretry(struct cx18 *cx, u32 val, void __iomem *addr)
231{
232 cx18_writel_noretry(cx, val, addr);
233 return cx18_readl_noretry(cx, addr);
234} 138}
235 139
236static inline 140static inline
237u32 cx18_write_sync_retry(struct cx18 *cx, u32 val, void __iomem *addr) 141void cx18_memcpy_fromio(struct cx18 *cx, void *to,
238{ 142 const void __iomem *from, unsigned int len)
239 cx18_writel_retry(cx, val, addr);
240 return cx18_readl_retry(cx, addr);
241}
242
243static inline u32 cx18_write_sync(struct cx18 *cx, u32 val, void __iomem *addr)
244{ 143{
245 if (cx18_retry_mmio) 144 memcpy_fromio(to, from, len);
246 return cx18_write_sync_retry(cx, val, addr);
247
248 return cx18_write_sync_noretry(cx, val, addr);
249} 145}
250 146
251
252void cx18_memcpy_fromio(struct cx18 *cx, void *to,
253 const void __iomem *from, unsigned int len);
254void cx18_memset_io(struct cx18 *cx, void __iomem *addr, int val, size_t count); 147void cx18_memset_io(struct cx18 *cx, void __iomem *addr, int val, size_t count);
255 148
256 149
@@ -260,136 +153,39 @@ static inline void cx18_write_reg_noretry(struct cx18 *cx, u32 val, u32 reg)
260 cx18_writel_noretry(cx, val, cx->reg_mem + reg); 153 cx18_writel_noretry(cx, val, cx->reg_mem + reg);
261} 154}
262 155
263static inline void cx18_write_reg_retry(struct cx18 *cx, u32 val, u32 reg)
264{
265 cx18_writel_retry(cx, val, cx->reg_mem + reg);
266}
267
268static inline void cx18_write_reg(struct cx18 *cx, u32 val, u32 reg) 156static inline void cx18_write_reg(struct cx18 *cx, u32 val, u32 reg)
269{ 157{
270 if (cx18_retry_mmio) 158 cx18_writel(cx, val, cx->reg_mem + reg);
271 cx18_write_reg_retry(cx, val, reg);
272 else
273 cx18_write_reg_noretry(cx, val, reg);
274}
275
276static inline void _cx18_write_reg_expect(struct cx18 *cx, u32 val, u32 reg,
277 u32 eval, u32 mask)
278{
279 _cx18_writel_expect(cx, val, cx->reg_mem + reg, eval, mask);
280} 159}
281 160
282static inline void cx18_write_reg_expect(struct cx18 *cx, u32 val, u32 reg, 161static inline void cx18_write_reg_expect(struct cx18 *cx, u32 val, u32 reg,
283 u32 eval, u32 mask) 162 u32 eval, u32 mask)
284{ 163{
285 if (cx18_retry_mmio) 164 cx18_writel_expect(cx, val, cx->reg_mem + reg, eval, mask);
286 _cx18_write_reg_expect(cx, val, reg, eval, mask);
287 else
288 cx18_write_reg_noretry(cx, val, reg);
289}
290
291
292static inline u32 cx18_read_reg_noretry(struct cx18 *cx, u32 reg)
293{
294 return cx18_readl_noretry(cx, cx->reg_mem + reg);
295}
296
297static inline u32 cx18_read_reg_retry(struct cx18 *cx, u32 reg)
298{
299 return cx18_readl_retry(cx, cx->reg_mem + reg);
300} 165}
301 166
302static inline u32 cx18_read_reg(struct cx18 *cx, u32 reg) 167static inline u32 cx18_read_reg(struct cx18 *cx, u32 reg)
303{ 168{
304 if (cx18_retry_mmio) 169 return cx18_readl(cx, cx->reg_mem + reg);
305 return cx18_read_reg_retry(cx, reg);
306
307 return cx18_read_reg_noretry(cx, reg);
308}
309
310
311static inline u32 cx18_write_reg_sync_noretry(struct cx18 *cx, u32 val, u32 reg)
312{
313 return cx18_write_sync_noretry(cx, val, cx->reg_mem + reg);
314}
315
316static inline u32 cx18_write_reg_sync_retry(struct cx18 *cx, u32 val, u32 reg)
317{
318 return cx18_write_sync_retry(cx, val, cx->reg_mem + reg);
319}
320
321static inline u32 cx18_write_reg_sync(struct cx18 *cx, u32 val, u32 reg)
322{
323 if (cx18_retry_mmio)
324 return cx18_write_reg_sync_retry(cx, val, reg);
325
326 return cx18_write_reg_sync_noretry(cx, val, reg);
327} 170}
328 171
329 172
330/* Access "encoder memory" region of CX23418 memory mapped I/O */ 173/* Access "encoder memory" region of CX23418 memory mapped I/O */
331static inline void cx18_write_enc_noretry(struct cx18 *cx, u32 val, u32 addr)
332{
333 cx18_writel_noretry(cx, val, cx->enc_mem + addr);
334}
335
336static inline void cx18_write_enc_retry(struct cx18 *cx, u32 val, u32 addr)
337{
338 cx18_writel_retry(cx, val, cx->enc_mem + addr);
339}
340
341static inline void cx18_write_enc(struct cx18 *cx, u32 val, u32 addr) 174static inline void cx18_write_enc(struct cx18 *cx, u32 val, u32 addr)
342{ 175{
343 if (cx18_retry_mmio) 176 cx18_writel(cx, val, cx->enc_mem + addr);
344 cx18_write_enc_retry(cx, val, addr);
345 else
346 cx18_write_enc_noretry(cx, val, addr);
347}
348
349
350static inline u32 cx18_read_enc_noretry(struct cx18 *cx, u32 addr)
351{
352 return cx18_readl_noretry(cx, cx->enc_mem + addr);
353}
354
355static inline u32 cx18_read_enc_retry(struct cx18 *cx, u32 addr)
356{
357 return cx18_readl_retry(cx, cx->enc_mem + addr);
358} 177}
359 178
360static inline u32 cx18_read_enc(struct cx18 *cx, u32 addr) 179static inline u32 cx18_read_enc(struct cx18 *cx, u32 addr)
361{ 180{
362 if (cx18_retry_mmio) 181 return cx18_readl(cx, cx->enc_mem + addr);
363 return cx18_read_enc_retry(cx, addr);
364
365 return cx18_read_enc_noretry(cx, addr);
366}
367
368static inline
369u32 cx18_write_enc_sync_noretry(struct cx18 *cx, u32 val, u32 addr)
370{
371 return cx18_write_sync_noretry(cx, val, cx->enc_mem + addr);
372}
373
374static inline
375u32 cx18_write_enc_sync_retry(struct cx18 *cx, u32 val, u32 addr)
376{
377 return cx18_write_sync_retry(cx, val, cx->enc_mem + addr);
378}
379
380static inline
381u32 cx18_write_enc_sync(struct cx18 *cx, u32 val, u32 addr)
382{
383 if (cx18_retry_mmio)
384 return cx18_write_enc_sync_retry(cx, val, addr);
385
386 return cx18_write_enc_sync_noretry(cx, val, addr);
387} 182}
388 183
389void cx18_sw1_irq_enable(struct cx18 *cx, u32 val); 184void cx18_sw1_irq_enable(struct cx18 *cx, u32 val);
390void cx18_sw1_irq_disable(struct cx18 *cx, u32 val); 185void cx18_sw1_irq_disable(struct cx18 *cx, u32 val);
391void cx18_sw2_irq_enable(struct cx18 *cx, u32 val); 186void cx18_sw2_irq_enable(struct cx18 *cx, u32 val);
392void cx18_sw2_irq_disable(struct cx18 *cx, u32 val); 187void cx18_sw2_irq_disable(struct cx18 *cx, u32 val);
188void cx18_sw2_irq_disable_cpu(struct cx18 *cx, u32 val);
393void cx18_setup_page(struct cx18 *cx, u32 addr); 189void cx18_setup_page(struct cx18 *cx, u32 addr);
394 190
395#endif /* CX18_IO_H */ 191#endif /* CX18_IO_H */
diff --git a/drivers/media/video/cx18/cx18-ioctl.c b/drivers/media/video/cx18/cx18-ioctl.c
index f0ca50f5fdde..e6087486f889 100644
--- a/drivers/media/video/cx18/cx18-ioctl.c
+++ b/drivers/media/video/cx18/cx18-ioctl.c
@@ -4,6 +4,7 @@
4 * Derived from ivtv-ioctl.c 4 * Derived from ivtv-ioctl.c
5 * 5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> 6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 * Copyright (C) 2008 Andy Walls <awalls@radix.net>
7 * 8 *
8 * This program is free software; you can redistribute it and/or modify 9 * 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 * it under the terms of the GNU General Public License as published by
@@ -237,13 +238,12 @@ static int cx18_s_fmt_vbi_cap(struct file *file, void *fh,
237 if (ret) 238 if (ret)
238 return ret; 239 return ret;
239 240
240 if (id->type == CX18_ENC_STREAM_TYPE_VBI && 241 if (!cx18_raw_vbi(cx) && atomic_read(&cx->ana_capturing) > 0)
241 cx->vbi.sliced_in->service_set &&
242 atomic_read(&cx->ana_capturing) > 0)
243 return -EBUSY; 242 return -EBUSY;
244 243
245 cx->vbi.sliced_in->service_set = 0; 244 cx->vbi.sliced_in->service_set = 0;
246 cx18_av_cmd(cx, VIDIOC_S_FMT, &cx->vbi.in); 245 cx->vbi.in.type = V4L2_BUF_TYPE_VBI_CAPTURE;
246 cx18_av_cmd(cx, VIDIOC_S_FMT, fmt);
247 return cx18_g_fmt_vbi_cap(file, fh, fmt); 247 return cx18_g_fmt_vbi_cap(file, fh, fmt);
248} 248}
249 249
@@ -745,14 +745,12 @@ static int cx18_log_status(struct file *file, void *fh)
745 continue; 745 continue;
746 CX18_INFO("Stream %s: status 0x%04lx, %d%% of %d KiB (%d buffers) in use\n", 746 CX18_INFO("Stream %s: status 0x%04lx, %d%% of %d KiB (%d buffers) in use\n",
747 s->name, s->s_flags, 747 s->name, s->s_flags,
748 (s->buffers - atomic_read(&s->q_free.buffers)) 748 atomic_read(&s->q_full.buffers) * 100 / s->buffers,
749 * 100 / s->buffers,
750 (s->buffers * s->buf_size) / 1024, s->buffers); 749 (s->buffers * s->buf_size) / 1024, s->buffers);
751 } 750 }
752 CX18_INFO("Read MPEG/VBI: %lld/%lld bytes\n", 751 CX18_INFO("Read MPEG/VBI: %lld/%lld bytes\n",
753 (long long)cx->mpg_data_received, 752 (long long)cx->mpg_data_received,
754 (long long)cx->vbi_data_inserted); 753 (long long)cx->vbi_data_inserted);
755 cx18_log_statistics(cx);
756 CX18_INFO("================== END STATUS CARD #%d ==================\n", cx->num); 754 CX18_INFO("================== END STATUS CARD #%d ==================\n", cx->num);
757 return 0; 755 return 0;
758} 756}
diff --git a/drivers/media/video/cx18/cx18-ioctl.h b/drivers/media/video/cx18/cx18-ioctl.h
index 2222f679d86d..08fe24e9510e 100644
--- a/drivers/media/video/cx18/cx18-ioctl.h
+++ b/drivers/media/video/cx18/cx18-ioctl.h
@@ -4,6 +4,7 @@
4 * Derived from ivtv-ioctl.h 4 * Derived from ivtv-ioctl.h
5 * 5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> 6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 * Copyright (C) 2008 Andy Walls <awalls@radix.net>
7 * 8 *
8 * This program is free software; you can redistribute it and/or modify 9 * 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 * it under the terms of the GNU General Public License as published by
diff --git a/drivers/media/video/cx18/cx18-irq.c b/drivers/media/video/cx18/cx18-irq.c
index 5fbfbd0f1493..af2f504eda2b 100644
--- a/drivers/media/video/cx18/cx18-irq.c
+++ b/drivers/media/video/cx18/cx18-irq.c
@@ -2,6 +2,7 @@
2 * cx18 interrupt handling 2 * cx18 interrupt handling
3 * 3 *
4 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> 4 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
5 * Copyright (C) 2008 Andy Walls <awalls@radix.net>
5 * 6 *
6 * 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
7 * 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
@@ -21,132 +22,9 @@
21 22
22#include "cx18-driver.h" 23#include "cx18-driver.h"
23#include "cx18-io.h" 24#include "cx18-io.h"
24#include "cx18-firmware.h"
25#include "cx18-fileops.h"
26#include "cx18-queue.h"
27#include "cx18-irq.h" 25#include "cx18-irq.h"
28#include "cx18-ioctl.h"
29#include "cx18-mailbox.h" 26#include "cx18-mailbox.h"
30#include "cx18-vbi.h"
31#include "cx18-scb.h" 27#include "cx18-scb.h"
32#include "cx18-dvb.h"
33
34void cx18_work_handler(struct work_struct *work)
35{
36 struct cx18 *cx = container_of(work, struct cx18, work);
37 if (test_and_clear_bit(CX18_F_I_WORK_INITED, &cx->i_flags)) {
38 struct sched_param param = { .sched_priority = MAX_RT_PRIO-1 };
39 /* This thread must use the FIFO scheduler as it
40 * is realtime sensitive. */
41 sched_setscheduler(current, SCHED_FIFO, &param);
42 }
43 if (test_and_clear_bit(CX18_F_I_WORK_HANDLER_DVB, &cx->i_flags))
44 cx18_dvb_work_handler(cx);
45}
46
47static void epu_dma_done(struct cx18 *cx, struct cx18_mailbox *mb)
48{
49 u32 handle = mb->args[0];
50 struct cx18_stream *s = NULL;
51 struct cx18_buffer *buf;
52 u32 off;
53 int i;
54 int id;
55
56 for (i = 0; i < CX18_MAX_STREAMS; i++) {
57 s = &cx->streams[i];
58 if ((handle == s->handle) && (s->dvb.enabled))
59 break;
60 if (s->v4l2dev && handle == s->handle)
61 break;
62 }
63 if (i == CX18_MAX_STREAMS) {
64 CX18_WARN("Got DMA done notification for unknown/inactive"
65 " handle %d\n", handle);
66 mb->error = CXERR_NOT_OPEN;
67 mb->cmd = 0;
68 cx18_mb_ack(cx, mb);
69 return;
70 }
71
72 off = mb->args[1];
73 if (mb->args[2] != 1)
74 CX18_WARN("Ack struct = %d for %s\n",
75 mb->args[2], s->name);
76 id = cx18_read_enc(cx, off);
77 buf = cx18_queue_get_buf_irq(s, id, cx18_read_enc(cx, off + 4));
78 CX18_DEBUG_HI_DMA("DMA DONE for %s (buffer %d)\n", s->name, id);
79 if (buf) {
80 cx18_buf_sync_for_cpu(s, buf);
81 if (s->type == CX18_ENC_STREAM_TYPE_TS && s->dvb.enabled) {
82 CX18_DEBUG_HI_DMA("TS recv bytesused = %d\n",
83 buf->bytesused);
84
85 set_bit(CX18_F_I_WORK_HANDLER_DVB, &cx->i_flags);
86 set_bit(CX18_F_I_HAVE_WORK, &cx->i_flags);
87 } else
88 set_bit(CX18_F_B_NEED_BUF_SWAP, &buf->b_flags);
89 } else {
90 CX18_WARN("Could not find buf %d for stream %s\n",
91 cx18_read_enc(cx, off), s->name);
92 }
93 mb->error = 0;
94 mb->cmd = 0;
95 cx18_mb_ack(cx, mb);
96 wake_up(&cx->dma_waitq);
97 if (s->id != -1)
98 wake_up(&s->waitq);
99}
100
101static void epu_debug(struct cx18 *cx, struct cx18_mailbox *mb)
102{
103 char str[256] = { 0 };
104 char *p;
105
106 if (mb->args[1]) {
107 cx18_setup_page(cx, mb->args[1]);
108 cx18_memcpy_fromio(cx, str, cx->enc_mem + mb->args[1], 252);
109 str[252] = 0;
110 }
111 cx18_mb_ack(cx, mb);
112 CX18_DEBUG_INFO("%x %s\n", mb->args[0], str);
113 p = strchr(str, '.');
114 if (!test_bit(CX18_F_I_LOADED_FW, &cx->i_flags) && p && p > str)
115 CX18_INFO("FW version: %s\n", p - 1);
116}
117
118static void epu_cmd(struct cx18 *cx, u32 sw1)
119{
120 struct cx18_mailbox mb;
121
122 if (sw1 & IRQ_CPU_TO_EPU) {
123 cx18_memcpy_fromio(cx, &mb, &cx->scb->cpu2epu_mb, sizeof(mb));
124 mb.error = 0;
125
126 switch (mb.cmd) {
127 case CX18_EPU_DMA_DONE:
128 epu_dma_done(cx, &mb);
129 break;
130 case CX18_EPU_DEBUG:
131 epu_debug(cx, &mb);
132 break;
133 default:
134 CX18_WARN("Unknown CPU_TO_EPU mailbox command %#08x\n",
135 mb.cmd);
136 break;
137 }
138 }
139
140 if (sw1 & IRQ_APU_TO_EPU) {
141 cx18_memcpy_fromio(cx, &mb, &cx->scb->apu2epu_mb, sizeof(mb));
142 CX18_WARN("Unknown APU_TO_EPU mailbox command %#08x\n", mb.cmd);
143 }
144
145 if (sw1 & IRQ_HPU_TO_EPU) {
146 cx18_memcpy_fromio(cx, &mb, &cx->scb->hpu2epu_mb, sizeof(mb));
147 CX18_WARN("Unknown HPU_TO_EPU mailbox command %#08x\n", mb.cmd);
148 }
149}
150 28
151static void xpu_ack(struct cx18 *cx, u32 sw2) 29static void xpu_ack(struct cx18 *cx, u32 sw2)
152{ 30{
@@ -154,23 +32,24 @@ static void xpu_ack(struct cx18 *cx, u32 sw2)
154 wake_up(&cx->mb_cpu_waitq); 32 wake_up(&cx->mb_cpu_waitq);
155 if (sw2 & IRQ_APU_TO_EPU_ACK) 33 if (sw2 & IRQ_APU_TO_EPU_ACK)
156 wake_up(&cx->mb_apu_waitq); 34 wake_up(&cx->mb_apu_waitq);
157 if (sw2 & IRQ_HPU_TO_EPU_ACK) 35}
158 wake_up(&cx->mb_hpu_waitq); 36
37static void epu_cmd(struct cx18 *cx, u32 sw1)
38{
39 if (sw1 & IRQ_CPU_TO_EPU)
40 cx18_api_epu_cmd_irq(cx, CPU);
41 if (sw1 & IRQ_APU_TO_EPU)
42 cx18_api_epu_cmd_irq(cx, APU);
159} 43}
160 44
161irqreturn_t cx18_irq_handler(int irq, void *dev_id) 45irqreturn_t cx18_irq_handler(int irq, void *dev_id)
162{ 46{
163 struct cx18 *cx = (struct cx18 *)dev_id; 47 struct cx18 *cx = (struct cx18 *)dev_id;
164 u32 sw1, sw1_mask; 48 u32 sw1, sw2, hw2;
165 u32 sw2, sw2_mask;
166 u32 hw2, hw2_mask;
167 49
168 sw1_mask = cx18_read_reg(cx, SW1_INT_ENABLE_PCI); 50 sw1 = cx18_read_reg(cx, SW1_INT_STATUS) & cx->sw1_irq_mask;
169 sw1 = cx18_read_reg(cx, SW1_INT_STATUS) & sw1_mask; 51 sw2 = cx18_read_reg(cx, SW2_INT_STATUS) & cx->sw2_irq_mask;
170 sw2_mask = cx18_read_reg(cx, SW2_INT_ENABLE_PCI); 52 hw2 = cx18_read_reg(cx, HW2_INT_CLR_STATUS) & cx->hw2_irq_mask;
171 sw2 = cx18_read_reg(cx, SW2_INT_STATUS) & sw2_mask;
172 hw2_mask = cx18_read_reg(cx, HW2_INT_MASK5_PCI);
173 hw2 = cx18_read_reg(cx, HW2_INT_CLR_STATUS) & hw2_mask;
174 53
175 if (sw1) 54 if (sw1)
176 cx18_write_reg_expect(cx, sw1, SW1_INT_STATUS, ~sw1, sw1); 55 cx18_write_reg_expect(cx, sw1, SW1_INT_STATUS, ~sw1, sw1);
@@ -180,7 +59,15 @@ irqreturn_t cx18_irq_handler(int irq, void *dev_id)
180 cx18_write_reg_expect(cx, hw2, HW2_INT_CLR_STATUS, ~hw2, hw2); 59 cx18_write_reg_expect(cx, hw2, HW2_INT_CLR_STATUS, ~hw2, hw2);
181 60
182 if (sw1 || sw2 || hw2) 61 if (sw1 || sw2 || hw2)
183 CX18_DEBUG_HI_IRQ("SW1: %x SW2: %x HW2: %x\n", sw1, sw2, hw2); 62 CX18_DEBUG_HI_IRQ("received interrupts "
63 "SW1: %x SW2: %x HW2: %x\n", sw1, sw2, hw2);
64
65 /*
66 * SW1 responses have to happen first. The sending XPU times out the
67 * incoming mailboxes on us rather rapidly.
68 */
69 if (sw1)
70 epu_cmd(cx, sw1);
184 71
185 /* To do: interrupt-based I2C handling 72 /* To do: interrupt-based I2C handling
186 if (hw2 & (HW2_I2C1_INT|HW2_I2C2_INT)) { 73 if (hw2 & (HW2_I2C1_INT|HW2_I2C2_INT)) {
@@ -190,11 +77,5 @@ irqreturn_t cx18_irq_handler(int irq, void *dev_id)
190 if (sw2) 77 if (sw2)
191 xpu_ack(cx, sw2); 78 xpu_ack(cx, sw2);
192 79
193 if (sw1)
194 epu_cmd(cx, sw1);
195
196 if (test_and_clear_bit(CX18_F_I_HAVE_WORK, &cx->i_flags))
197 queue_work(cx->work_queue, &cx->work);
198
199 return (sw1 || sw2 || hw2) ? IRQ_HANDLED : IRQ_NONE; 80 return (sw1 || sw2 || hw2) ? IRQ_HANDLED : IRQ_NONE;
200} 81}
diff --git a/drivers/media/video/cx18/cx18-irq.h b/drivers/media/video/cx18/cx18-irq.h
index 6173ca3bc9e4..91f0b5278ef9 100644
--- a/drivers/media/video/cx18/cx18-irq.h
+++ b/drivers/media/video/cx18/cx18-irq.h
@@ -2,6 +2,7 @@
2 * cx18 interrupt handling 2 * cx18 interrupt handling
3 * 3 *
4 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> 4 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
5 * Copyright (C) 2008 Andy Walls <awalls@radix.net>
5 * 6 *
6 * 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
7 * 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
@@ -28,8 +29,7 @@
28#define SW1_INT_ENABLE_PCI 0xc7311c 29#define SW1_INT_ENABLE_PCI 0xc7311c
29#define SW2_INT_SET 0xc73140 30#define SW2_INT_SET 0xc73140
30#define SW2_INT_STATUS 0xc73144 31#define SW2_INT_STATUS 0xc73144
32#define SW2_INT_ENABLE_CPU 0xc73158
31#define SW2_INT_ENABLE_PCI 0xc7315c 33#define SW2_INT_ENABLE_PCI 0xc7315c
32 34
33irqreturn_t cx18_irq_handler(int irq, void *dev_id); 35irqreturn_t cx18_irq_handler(int irq, void *dev_id);
34
35void cx18_work_handler(struct work_struct *work);
diff --git a/drivers/media/video/cx18/cx18-mailbox.c b/drivers/media/video/cx18/cx18-mailbox.c
index acff7dfb60df..de5e723fdf44 100644
--- a/drivers/media/video/cx18/cx18-mailbox.c
+++ b/drivers/media/video/cx18/cx18-mailbox.c
@@ -2,6 +2,7 @@
2 * cx18 mailbox functions 2 * cx18 mailbox functions
3 * 3 *
4 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> 4 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
5 * Copyright (C) 2008 Andy Walls <awalls@radix.net>
5 * 6 *
6 * 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
7 * 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
@@ -26,15 +27,14 @@
26#include "cx18-scb.h" 27#include "cx18-scb.h"
27#include "cx18-irq.h" 28#include "cx18-irq.h"
28#include "cx18-mailbox.h" 29#include "cx18-mailbox.h"
30#include "cx18-queue.h"
31#include "cx18-streams.h"
32
33static const char *rpu_str[] = { "APU", "CPU", "EPU", "HPU" };
29 34
30#define API_FAST (1 << 2) /* Short timeout */ 35#define API_FAST (1 << 2) /* Short timeout */
31#define API_SLOW (1 << 3) /* Additional 300ms timeout */ 36#define API_SLOW (1 << 3) /* Additional 300ms timeout */
32 37
33#define APU 0
34#define CPU 1
35#define EPU 2
36#define HPU 3
37
38struct cx18_api_info { 38struct cx18_api_info {
39 u32 cmd; 39 u32 cmd;
40 u8 flags; /* Flags, see above */ 40 u8 flags; /* Flags, see above */
@@ -82,8 +82,9 @@ static const struct cx18_api_info api_info[] = {
82 API_ENTRY(CPU, CX18_CPU_GET_ENC_PTS, 0), 82 API_ENTRY(CPU, CX18_CPU_GET_ENC_PTS, 0),
83 API_ENTRY(CPU, CX18_CPU_DE_SET_MDL_ACK, 0), 83 API_ENTRY(CPU, CX18_CPU_DE_SET_MDL_ACK, 0),
84 API_ENTRY(CPU, CX18_CPU_DE_SET_MDL, API_FAST), 84 API_ENTRY(CPU, CX18_CPU_DE_SET_MDL, API_FAST),
85 API_ENTRY(CPU, CX18_APU_RESETAI, API_FAST),
86 API_ENTRY(CPU, CX18_CPU_DE_RELEASE_MDL, API_SLOW), 85 API_ENTRY(CPU, CX18_CPU_DE_RELEASE_MDL, API_SLOW),
86 API_ENTRY(APU, CX18_APU_RESETAI, 0),
87 API_ENTRY(CPU, CX18_CPU_DEBUG_PEEK32, 0),
87 API_ENTRY(0, 0, 0), 88 API_ENTRY(0, 0, 0),
88}; 89};
89 90
@@ -97,70 +98,175 @@ static const struct cx18_api_info *find_api_info(u32 cmd)
97 return NULL; 98 return NULL;
98} 99}
99 100
100static struct cx18_mailbox __iomem *cx18_mb_is_complete(struct cx18 *cx, int rpu, 101static void dump_mb(struct cx18 *cx, struct cx18_mailbox *mb, char *name)
101 u32 *state, u32 *irq, u32 *req)
102{ 102{
103 struct cx18_mailbox __iomem *mb = NULL; 103 char argstr[MAX_MB_ARGUMENTS*11+1];
104 int wait_count = 0; 104 char *p;
105 u32 ack; 105 int i;
106
107 switch (rpu) {
108 case APU:
109 mb = &cx->scb->epu2apu_mb;
110 *state = cx18_readl(cx, &cx->scb->apu_state);
111 *irq = cx18_readl(cx, &cx->scb->epu2apu_irq);
112 break;
113 106
114 case CPU: 107 if (!(cx18_debug & CX18_DBGFLG_API))
115 mb = &cx->scb->epu2cpu_mb; 108 return;
116 *state = cx18_readl(cx, &cx->scb->cpu_state);
117 *irq = cx18_readl(cx, &cx->scb->epu2cpu_irq);
118 break;
119 109
120 case HPU: 110 for (i = 0, p = argstr; i < MAX_MB_ARGUMENTS; i++, p += 11) {
121 mb = &cx->scb->epu2hpu_mb; 111 /* kernel snprintf() appends '\0' always */
122 *state = cx18_readl(cx, &cx->scb->hpu_state); 112 snprintf(p, 12, " %#010x", mb->args[i]);
123 *irq = cx18_readl(cx, &cx->scb->epu2hpu_irq);
124 break;
125 } 113 }
114 CX18_DEBUG_API("%s: req %#010x ack %#010x cmd %#010x err %#010x args%s"
115 "\n", name, mb->request, mb->ack, mb->cmd, mb->error, argstr);
116}
126 117
127 if (mb == NULL)
128 return mb;
129 118
130 do { 119/*
131 *req = cx18_readl(cx, &mb->request); 120 * Functions that run in a work_queue work handling context
132 ack = cx18_readl(cx, &mb->ack); 121 */
133 wait_count++;
134 } while (*req != ack && wait_count < 600);
135 122
136 if (*req == ack) { 123static void epu_dma_done(struct cx18 *cx, struct cx18_epu_work_order *order)
137 (*req)++; 124{
138 if (*req == 0 || *req == 0xffffffff) 125 u32 handle, mdl_ack_count, id;
139 *req = 1; 126 struct cx18_mailbox *mb;
140 return mb; 127 struct cx18_mdl_ack *mdl_ack;
128 struct cx18_stream *s;
129 struct cx18_buffer *buf;
130 int i;
131
132 mb = &order->mb;
133 handle = mb->args[0];
134 s = cx18_handle_to_stream(cx, handle);
135
136 if (s == NULL) {
137 CX18_WARN("Got DMA done notification for unknown/inactive"
138 " handle %d, %s mailbox seq no %d\n", handle,
139 (order->flags & CX18_F_EWO_MB_STALE_UPON_RECEIPT) ?
140 "stale" : "good", mb->request);
141 return;
141 } 142 }
142 return NULL; 143
144 mdl_ack_count = mb->args[2];
145 mdl_ack = order->mdl_ack;
146 for (i = 0; i < mdl_ack_count; i++, mdl_ack++) {
147 id = mdl_ack->id;
148 /*
149 * Simple integrity check for processing a stale (and possibly
150 * inconsistent mailbox): make sure the buffer id is in the
151 * valid range for the stream.
152 *
153 * We go through the trouble of dealing with stale mailboxes
154 * because most of the time, the mailbox data is still valid and
155 * unchanged (and in practice the firmware ping-pongs the
156 * two mdl_ack buffers so mdl_acks are not stale).
157 *
158 * There are occasions when we get a half changed mailbox,
159 * which this check catches for a handle & id mismatch. If the
160 * handle and id do correspond, the worst case is that we
161 * completely lost the old buffer, but pick up the new buffer
162 * early (but the new mdl_ack is guaranteed to be good in this
163 * case as the firmware wouldn't point us to a new mdl_ack until
164 * it's filled in).
165 *
166 * cx18_queue_get buf() will detect the lost buffers
167 * and send them back to q_free for fw rotation eventually.
168 */
169 if ((order->flags & CX18_F_EWO_MB_STALE_UPON_RECEIPT) &&
170 !(id >= s->mdl_offset &&
171 id < (s->mdl_offset + s->buffers))) {
172 CX18_WARN("Fell behind! Ignoring stale mailbox with "
173 " inconsistent data. Lost buffer for mailbox "
174 "seq no %d\n", mb->request);
175 break;
176 }
177 buf = cx18_queue_get_buf(s, id, mdl_ack->data_used);
178
179 CX18_DEBUG_HI_DMA("DMA DONE for %s (buffer %d)\n", s->name, id);
180 if (buf == NULL) {
181 CX18_WARN("Could not find buf %d for stream %s\n",
182 id, s->name);
183 /* Put as many buffers as possible back into fw use */
184 cx18_stream_load_fw_queue(s);
185 continue;
186 }
187
188 if (s->type == CX18_ENC_STREAM_TYPE_TS && s->dvb.enabled) {
189 CX18_DEBUG_HI_DMA("TS recv bytesused = %d\n",
190 buf->bytesused);
191 dvb_dmx_swfilter(&s->dvb.demux, buf->buf,
192 buf->bytesused);
193 }
194 /* Put as many buffers as possible back into fw use */
195 cx18_stream_load_fw_queue(s);
196 /* Put back TS buffer, since it was removed from all queues */
197 if (s->type == CX18_ENC_STREAM_TYPE_TS)
198 cx18_stream_put_buf_fw(s, buf);
199 }
200 wake_up(&cx->dma_waitq);
201 if (s->id != -1)
202 wake_up(&s->waitq);
143} 203}
144 204
145long cx18_mb_ack(struct cx18 *cx, const struct cx18_mailbox *mb) 205static void epu_debug(struct cx18 *cx, struct cx18_epu_work_order *order)
146{ 206{
147 const struct cx18_api_info *info = find_api_info(mb->cmd); 207 char *p;
148 struct cx18_mailbox __iomem *ack_mb; 208 char *str = order->str;
149 u32 ack_irq;
150 u8 rpu = CPU;
151 209
152 if (info == NULL && mb->cmd) { 210 CX18_DEBUG_INFO("%x %s\n", order->mb.args[0], str);
153 CX18_WARN("Cannot ack unknown command %x\n", mb->cmd); 211 p = strchr(str, '.');
154 return -EINVAL; 212 if (!test_bit(CX18_F_I_LOADED_FW, &cx->i_flags) && p && p > str)
155 } 213 CX18_INFO("FW version: %s\n", p - 1);
156 if (info) 214}
157 rpu = info->rpu;
158 215
159 switch (rpu) { 216static void epu_cmd(struct cx18 *cx, struct cx18_epu_work_order *order)
160 case HPU: 217{
161 ack_irq = IRQ_EPU_TO_HPU_ACK; 218 switch (order->rpu) {
162 ack_mb = &cx->scb->hpu2epu_mb; 219 case CPU:
220 {
221 switch (order->mb.cmd) {
222 case CX18_EPU_DMA_DONE:
223 epu_dma_done(cx, order);
224 break;
225 case CX18_EPU_DEBUG:
226 epu_debug(cx, order);
227 break;
228 default:
229 CX18_WARN("Unknown CPU to EPU mailbox command %#0x\n",
230 order->mb.cmd);
231 break;
232 }
163 break; 233 break;
234 }
235 case APU:
236 CX18_WARN("Unknown APU to EPU mailbox command %#0x\n",
237 order->mb.cmd);
238 break;
239 default:
240 break;
241 }
242}
243
244static
245void free_epu_work_order(struct cx18 *cx, struct cx18_epu_work_order *order)
246{
247 atomic_set(&order->pending, 0);
248}
249
250void cx18_epu_work_handler(struct work_struct *work)
251{
252 struct cx18_epu_work_order *order =
253 container_of(work, struct cx18_epu_work_order, work);
254 struct cx18 *cx = order->cx;
255 epu_cmd(cx, order);
256 free_epu_work_order(cx, order);
257}
258
259
260/*
261 * Functions that run in an interrupt handling context
262 */
263
264static void mb_ack_irq(struct cx18 *cx, struct cx18_epu_work_order *order)
265{
266 struct cx18_mailbox __iomem *ack_mb;
267 u32 ack_irq, req;
268
269 switch (order->rpu) {
164 case APU: 270 case APU:
165 ack_irq = IRQ_EPU_TO_APU_ACK; 271 ack_irq = IRQ_EPU_TO_APU_ACK;
166 ack_mb = &cx->scb->apu2epu_mb; 272 ack_mb = &cx->scb->apu2epu_mb;
@@ -170,26 +276,197 @@ long cx18_mb_ack(struct cx18 *cx, const struct cx18_mailbox *mb)
170 ack_mb = &cx->scb->cpu2epu_mb; 276 ack_mb = &cx->scb->cpu2epu_mb;
171 break; 277 break;
172 default: 278 default:
173 CX18_WARN("Unknown RPU for command %x\n", mb->cmd); 279 CX18_WARN("Unhandled RPU (%d) for command %x ack\n",
174 return -EINVAL; 280 order->rpu, order->mb.cmd);
281 return;
175 } 282 }
176 283
177 cx18_setup_page(cx, SCB_OFFSET); 284 req = order->mb.request;
178 cx18_write_sync(cx, mb->request, &ack_mb->ack); 285 /* Don't ack if the RPU has gotten impatient and timed us out */
286 if (req != cx18_readl(cx, &ack_mb->request) ||
287 req == cx18_readl(cx, &ack_mb->ack)) {
288 CX18_DEBUG_WARN("Possibly falling behind: %s self-ack'ed our "
289 "incoming %s to EPU mailbox (sequence no. %u) "
290 "while processing\n",
291 rpu_str[order->rpu], rpu_str[order->rpu], req);
292 order->flags |= CX18_F_EWO_MB_STALE_WHILE_PROC;
293 return;
294 }
295 cx18_writel(cx, req, &ack_mb->ack);
179 cx18_write_reg_expect(cx, ack_irq, SW2_INT_SET, ack_irq, ack_irq); 296 cx18_write_reg_expect(cx, ack_irq, SW2_INT_SET, ack_irq, ack_irq);
180 return 0; 297 return;
298}
299
300static int epu_dma_done_irq(struct cx18 *cx, struct cx18_epu_work_order *order)
301{
302 u32 handle, mdl_ack_offset, mdl_ack_count;
303 struct cx18_mailbox *mb;
304
305 mb = &order->mb;
306 handle = mb->args[0];
307 mdl_ack_offset = mb->args[1];
308 mdl_ack_count = mb->args[2];
309
310 if (handle == CX18_INVALID_TASK_HANDLE ||
311 mdl_ack_count == 0 || mdl_ack_count > CX18_MAX_MDL_ACKS) {
312 if ((order->flags & CX18_F_EWO_MB_STALE) == 0)
313 mb_ack_irq(cx, order);
314 return -1;
315 }
316
317 cx18_memcpy_fromio(cx, order->mdl_ack, cx->enc_mem + mdl_ack_offset,
318 sizeof(struct cx18_mdl_ack) * mdl_ack_count);
319
320 if ((order->flags & CX18_F_EWO_MB_STALE) == 0)
321 mb_ack_irq(cx, order);
322 return 1;
323}
324
325static
326int epu_debug_irq(struct cx18 *cx, struct cx18_epu_work_order *order)
327{
328 u32 str_offset;
329 char *str = order->str;
330
331 str[0] = '\0';
332 str_offset = order->mb.args[1];
333 if (str_offset) {
334 cx18_setup_page(cx, str_offset);
335 cx18_memcpy_fromio(cx, str, cx->enc_mem + str_offset, 252);
336 str[252] = '\0';
337 cx18_setup_page(cx, SCB_OFFSET);
338 }
339
340 if ((order->flags & CX18_F_EWO_MB_STALE) == 0)
341 mb_ack_irq(cx, order);
342
343 return str_offset ? 1 : 0;
181} 344}
182 345
346static inline
347int epu_cmd_irq(struct cx18 *cx, struct cx18_epu_work_order *order)
348{
349 int ret = -1;
350
351 switch (order->rpu) {
352 case CPU:
353 {
354 switch (order->mb.cmd) {
355 case CX18_EPU_DMA_DONE:
356 ret = epu_dma_done_irq(cx, order);
357 break;
358 case CX18_EPU_DEBUG:
359 ret = epu_debug_irq(cx, order);
360 break;
361 default:
362 CX18_WARN("Unknown CPU to EPU mailbox command %#0x\n",
363 order->mb.cmd);
364 break;
365 }
366 break;
367 }
368 case APU:
369 CX18_WARN("Unknown APU to EPU mailbox command %#0x\n",
370 order->mb.cmd);
371 break;
372 default:
373 break;
374 }
375 return ret;
376}
377
378static inline
379struct cx18_epu_work_order *alloc_epu_work_order_irq(struct cx18 *cx)
380{
381 int i;
382 struct cx18_epu_work_order *order = NULL;
383
384 for (i = 0; i < CX18_MAX_EPU_WORK_ORDERS; i++) {
385 /*
386 * We only need "pending" atomic to inspect its contents,
387 * and need not do a check and set because:
388 * 1. Any work handler thread only clears "pending" and only
389 * on one, particular work order at a time, per handler thread.
390 * 2. "pending" is only set here, and we're serialized because
391 * we're called in an IRQ handler context.
392 */
393 if (atomic_read(&cx->epu_work_order[i].pending) == 0) {
394 order = &cx->epu_work_order[i];
395 atomic_set(&order->pending, 1);
396 break;
397 }
398 }
399 return order;
400}
401
402void cx18_api_epu_cmd_irq(struct cx18 *cx, int rpu)
403{
404 struct cx18_mailbox __iomem *mb;
405 struct cx18_mailbox *order_mb;
406 struct cx18_epu_work_order *order;
407 int submit;
408
409 switch (rpu) {
410 case CPU:
411 mb = &cx->scb->cpu2epu_mb;
412 break;
413 case APU:
414 mb = &cx->scb->apu2epu_mb;
415 break;
416 default:
417 return;
418 }
419
420 order = alloc_epu_work_order_irq(cx);
421 if (order == NULL) {
422 CX18_WARN("Unable to find blank work order form to schedule "
423 "incoming mailbox command processing\n");
424 return;
425 }
426
427 order->flags = 0;
428 order->rpu = rpu;
429 order_mb = &order->mb;
430
431 /* mb->cmd and mb->args[0] through mb->args[2] */
432 cx18_memcpy_fromio(cx, &order_mb->cmd, &mb->cmd, 4 * sizeof(u32));
433 /* mb->request and mb->ack. N.B. we want to read mb->ack last */
434 cx18_memcpy_fromio(cx, &order_mb->request, &mb->request,
435 2 * sizeof(u32));
436
437 if (order_mb->request == order_mb->ack) {
438 CX18_DEBUG_WARN("Possibly falling behind: %s self-ack'ed our "
439 "incoming %s to EPU mailbox (sequence no. %u)"
440 "\n",
441 rpu_str[rpu], rpu_str[rpu], order_mb->request);
442 dump_mb(cx, order_mb, "incoming");
443 order->flags = CX18_F_EWO_MB_STALE_UPON_RECEIPT;
444 }
445
446 /*
447 * Individual EPU command processing is responsible for ack-ing
448 * a non-stale mailbox as soon as possible
449 */
450 submit = epu_cmd_irq(cx, order);
451 if (submit > 0) {
452 queue_work(cx->work_queue, &order->work);
453 }
454}
455
456
457/*
458 * Functions called from a non-interrupt, non work_queue context
459 */
183 460
184static int cx18_api_call(struct cx18 *cx, u32 cmd, int args, u32 data[]) 461static int cx18_api_call(struct cx18 *cx, u32 cmd, int args, u32 data[])
185{ 462{
186 const struct cx18_api_info *info = find_api_info(cmd); 463 const struct cx18_api_info *info = find_api_info(cmd);
187 u32 state = 0, irq = 0, req, oldreq, err; 464 u32 state, irq, req, ack, err;
188 struct cx18_mailbox __iomem *mb; 465 struct cx18_mailbox __iomem *mb;
466 u32 __iomem *xpu_state;
189 wait_queue_head_t *waitq; 467 wait_queue_head_t *waitq;
190 int timeout = 100; 468 struct mutex *mb_lock;
191 int cnt = 0; 469 long int timeout, ret;
192 int sig = 0;
193 int i; 470 int i;
194 471
195 if (info == NULL) { 472 if (info == NULL) {
@@ -201,50 +478,104 @@ static int cx18_api_call(struct cx18 *cx, u32 cmd, int args, u32 data[])
201 CX18_DEBUG_HI_API("%s\n", info->name); 478 CX18_DEBUG_HI_API("%s\n", info->name);
202 else 479 else
203 CX18_DEBUG_API("%s\n", info->name); 480 CX18_DEBUG_API("%s\n", info->name);
204 cx18_setup_page(cx, SCB_OFFSET);
205 mb = cx18_mb_is_complete(cx, info->rpu, &state, &irq, &req);
206 481
207 if (mb == NULL) { 482 switch (info->rpu) {
208 CX18_ERR("mb %s busy\n", info->name); 483 case APU:
209 return -EBUSY; 484 waitq = &cx->mb_apu_waitq;
485 mb_lock = &cx->epu2apu_mb_lock;
486 irq = IRQ_EPU_TO_APU;
487 mb = &cx->scb->epu2apu_mb;
488 xpu_state = &cx->scb->apu_state;
489 break;
490 case CPU:
491 waitq = &cx->mb_cpu_waitq;
492 mb_lock = &cx->epu2cpu_mb_lock;
493 irq = IRQ_EPU_TO_CPU;
494 mb = &cx->scb->epu2cpu_mb;
495 xpu_state = &cx->scb->cpu_state;
496 break;
497 default:
498 CX18_WARN("Unknown RPU (%d) for API call\n", info->rpu);
499 return -EINVAL;
210 } 500 }
211 501
212 oldreq = req - 1; 502 mutex_lock(mb_lock);
503 /*
504 * Wait for an in-use mailbox to complete
505 *
506 * If the XPU is responding with Ack's, the mailbox shouldn't be in
507 * a busy state, since we serialize access to it on our end.
508 *
509 * If the wait for ack after sending a previous command was interrupted
510 * by a signal, we may get here and find a busy mailbox. After waiting,
511 * mark it "not busy" from our end, if the XPU hasn't ack'ed it still.
512 */
513 state = cx18_readl(cx, xpu_state);
514 req = cx18_readl(cx, &mb->request);
515 timeout = msecs_to_jiffies(10);
516 ret = wait_event_timeout(*waitq,
517 (ack = cx18_readl(cx, &mb->ack)) == req,
518 timeout);
519 if (req != ack) {
520 /* waited long enough, make the mbox "not busy" from our end */
521 cx18_writel(cx, req, &mb->ack);
522 CX18_ERR("mbox was found stuck busy when setting up for %s; "
523 "clearing busy and trying to proceed\n", info->name);
524 } else if (ret != timeout)
525 CX18_DEBUG_API("waited %u msecs for busy mbox to be acked\n",
526 jiffies_to_msecs(timeout-ret));
527
528 /* Build the outgoing mailbox */
529 req = ((req & 0xfffffffe) == 0xfffffffe) ? 1 : req + 1;
530
213 cx18_writel(cx, cmd, &mb->cmd); 531 cx18_writel(cx, cmd, &mb->cmd);
214 for (i = 0; i < args; i++) 532 for (i = 0; i < args; i++)
215 cx18_writel(cx, data[i], &mb->args[i]); 533 cx18_writel(cx, data[i], &mb->args[i]);
216 cx18_writel(cx, 0, &mb->error); 534 cx18_writel(cx, 0, &mb->error);
217 cx18_writel(cx, req, &mb->request); 535 cx18_writel(cx, req, &mb->request);
536 cx18_writel(cx, req - 1, &mb->ack); /* ensure ack & req are distinct */
218 537
219 switch (info->rpu) { 538 /*
220 case APU: waitq = &cx->mb_apu_waitq; break; 539 * Notify the XPU and wait for it to send an Ack back
221 case CPU: waitq = &cx->mb_cpu_waitq; break; 540 */
222 case EPU: waitq = &cx->mb_epu_waitq; break; 541 timeout = msecs_to_jiffies((info->flags & API_FAST) ? 10 : 20);
223 case HPU: waitq = &cx->mb_hpu_waitq; break; 542
224 default: return -EINVAL; 543 CX18_DEBUG_HI_IRQ("sending interrupt SW1: %x to send %s\n",
225 } 544 irq, info->name);
226 if (info->flags & API_FAST)
227 timeout /= 2;
228 cx18_write_reg_expect(cx, irq, SW1_INT_SET, irq, irq); 545 cx18_write_reg_expect(cx, irq, SW1_INT_SET, irq, irq);
229 546
230 while (!sig && cx18_readl(cx, &mb->ack) != cx18_readl(cx, &mb->request) 547 ret = wait_event_timeout(
231 && cnt < 660) { 548 *waitq,
232 if (cnt > 200 && !in_atomic()) 549 cx18_readl(cx, &mb->ack) == cx18_readl(cx, &mb->request),
233 sig = cx18_msleep_timeout(10, 1); 550 timeout);
234 cnt++; 551
235 } 552 if (ret == 0) {
236 if (sig) 553 /* Timed out */
237 return -EINTR; 554 mutex_unlock(mb_lock);
238 if (cnt == 660) { 555 CX18_DEBUG_WARN("sending %s timed out waiting %d msecs for RPU "
239 cx18_writel(cx, oldreq, &mb->request); 556 "acknowledgement\n",
240 CX18_ERR("mb %s failed\n", info->name); 557 info->name, jiffies_to_msecs(timeout));
241 return -EINVAL; 558 return -EINVAL;
242 } 559 }
560
561 if (ret != timeout)
562 CX18_DEBUG_HI_API("waited %u msecs for %s to be acked\n",
563 jiffies_to_msecs(timeout-ret), info->name);
564
565 /* Collect data returned by the XPU */
243 for (i = 0; i < MAX_MB_ARGUMENTS; i++) 566 for (i = 0; i < MAX_MB_ARGUMENTS; i++)
244 data[i] = cx18_readl(cx, &mb->args[i]); 567 data[i] = cx18_readl(cx, &mb->args[i]);
245 err = cx18_readl(cx, &mb->error); 568 err = cx18_readl(cx, &mb->error);
246 if (!in_atomic() && (info->flags & API_SLOW)) 569 mutex_unlock(mb_lock);
570
571 /*
572 * Wait for XPU to perform extra actions for the caller in some cases.
573 * e.g. CX18_CPU_DE_RELEASE_MDL will cause the CPU to send all buffers
574 * back in a burst shortly thereafter
575 */
576 if (info->flags & API_SLOW)
247 cx18_msleep_timeout(300, 0); 577 cx18_msleep_timeout(300, 0);
578
248 if (err) 579 if (err)
249 CX18_DEBUG_API("mailbox error %08x for command %s\n", err, 580 CX18_DEBUG_API("mailbox error %08x for command %s\n", err,
250 info->name); 581 info->name);
@@ -253,12 +584,7 @@ static int cx18_api_call(struct cx18 *cx, u32 cmd, int args, u32 data[])
253 584
254int cx18_api(struct cx18 *cx, u32 cmd, int args, u32 data[]) 585int cx18_api(struct cx18 *cx, u32 cmd, int args, u32 data[])
255{ 586{
256 int res = cx18_api_call(cx, cmd, args, data); 587 return cx18_api_call(cx, cmd, args, data);
257
258 /* Allow a single retry, probably already too late though.
259 If there is no free mailbox then that is usually an indication
260 of a more serious problem. */
261 return (res == -EBUSY) ? cx18_api_call(cx, cmd, args, data) : res;
262} 588}
263 589
264static int cx18_set_filter_param(struct cx18_stream *s) 590static int cx18_set_filter_param(struct cx18_stream *s)
@@ -281,8 +607,9 @@ static int cx18_set_filter_param(struct cx18_stream *s)
281int cx18_api_func(void *priv, u32 cmd, int in, int out, 607int cx18_api_func(void *priv, u32 cmd, int in, int out,
282 u32 data[CX2341X_MBOX_MAX_DATA]) 608 u32 data[CX2341X_MBOX_MAX_DATA])
283{ 609{
284 struct cx18 *cx = priv; 610 struct cx18_api_func_private *api_priv = priv;
285 struct cx18_stream *s = &cx->streams[CX18_ENC_STREAM_TYPE_MPG]; 611 struct cx18 *cx = api_priv->cx;
612 struct cx18_stream *s = api_priv->s;
286 613
287 switch (cmd) { 614 switch (cmd) {
288 case CX2341X_ENC_SET_OUTPUT_PORT: 615 case CX2341X_ENC_SET_OUTPUT_PORT:
diff --git a/drivers/media/video/cx18/cx18-mailbox.h b/drivers/media/video/cx18/cx18-mailbox.h
index d995641536b3..ce2b6686aa00 100644
--- a/drivers/media/video/cx18/cx18-mailbox.h
+++ b/drivers/media/video/cx18/cx18-mailbox.h
@@ -2,6 +2,7 @@
2 * cx18 mailbox functions 2 * cx18 mailbox functions
3 * 3 *
4 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> 4 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
5 * Copyright (C) 2008 Andy Walls <awalls@radix.net>
5 * 6 *
6 * 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
7 * 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
@@ -30,8 +31,24 @@
30#define MB_RESERVED_HANDLE_0 0 31#define MB_RESERVED_HANDLE_0 0
31#define MB_RESERVED_HANDLE_1 0xFFFFFFFF 32#define MB_RESERVED_HANDLE_1 0xFFFFFFFF
32 33
34#define APU 0
35#define CPU 1
36#define EPU 2
37#define HPU 3
38
33struct cx18; 39struct cx18;
34 40
41/*
42 * This structure is used by CPU to provide completed buffers information
43 * Its structure is dictrated by the layout of the SCB, required by the
44 * firmware, but its defintion needs to be here, instead of in cx18-scb.h,
45 * for mailbox work order scheduling
46 */
47struct cx18_mdl_ack {
48 u32 id; /* ID of a completed MDL */
49 u32 data_used; /* Total data filled in the MDL for buffer 'id' */
50};
51
35/* 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
36 messages between processors */ 53 messages between processors */
37struct cx18_mailbox { 54struct cx18_mailbox {
@@ -62,12 +79,22 @@ struct cx18_mailbox {
62 u32 error; 79 u32 error;
63}; 80};
64 81
82struct cx18_stream;
83
84struct cx18_api_func_private {
85 struct cx18 *cx;
86 struct cx18_stream *s;
87};
88
65int cx18_api(struct cx18 *cx, u32 cmd, int args, u32 data[]); 89int cx18_api(struct cx18 *cx, u32 cmd, int args, u32 data[]);
66int cx18_vapi_result(struct cx18 *cx, u32 data[MAX_MB_ARGUMENTS], u32 cmd, 90int cx18_vapi_result(struct cx18 *cx, u32 data[MAX_MB_ARGUMENTS], u32 cmd,
67 int args, ...); 91 int args, ...);
68int cx18_vapi(struct cx18 *cx, u32 cmd, int args, ...); 92int cx18_vapi(struct cx18 *cx, u32 cmd, int args, ...);
69int cx18_api_func(void *priv, u32 cmd, int in, int out, 93int cx18_api_func(void *priv, u32 cmd, int in, int out,
70 u32 data[CX2341X_MBOX_MAX_DATA]); 94 u32 data[CX2341X_MBOX_MAX_DATA]);
71long cx18_mb_ack(struct cx18 *cx, const struct cx18_mailbox *mb); 95
96void cx18_api_epu_cmd_irq(struct cx18 *cx, int rpu);
97
98void cx18_epu_work_handler(struct work_struct *work);
72 99
73#endif 100#endif
diff --git a/drivers/media/video/cx18/cx18-queue.c b/drivers/media/video/cx18/cx18-queue.c
index 174682c2582f..8d9441e88c4e 100644
--- a/drivers/media/video/cx18/cx18-queue.c
+++ b/drivers/media/video/cx18/cx18-queue.c
@@ -4,6 +4,7 @@
4 * Derived from ivtv-queue.c 4 * Derived from ivtv-queue.c
5 * 5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> 6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 * Copyright (C) 2008 Andy Walls <awalls@radix.net>
7 * 8 *
8 * This program is free software; you can redistribute it and/or modify 9 * 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 * it under the terms of the GNU General Public License as published by
@@ -41,91 +42,126 @@ void cx18_queue_init(struct cx18_queue *q)
41 q->bytesused = 0; 42 q->bytesused = 0;
42} 43}
43 44
44void cx18_enqueue(struct cx18_stream *s, struct cx18_buffer *buf, 45struct cx18_queue *_cx18_enqueue(struct cx18_stream *s, struct cx18_buffer *buf,
45 struct cx18_queue *q) 46 struct cx18_queue *q, int to_front)
46{ 47{
47 unsigned long flags = 0; 48 /* clear the buffer if it is not to be enqueued to the full queue */
48 49 if (q != &s->q_full) {
49 /* clear the buffer if it is going to be enqueued to the free queue */
50 if (q == &s->q_free) {
51 buf->bytesused = 0; 50 buf->bytesused = 0;
52 buf->readpos = 0; 51 buf->readpos = 0;
53 buf->b_flags = 0; 52 buf->b_flags = 0;
53 buf->skipped = 0;
54 } 54 }
55 spin_lock_irqsave(&s->qlock, flags); 55
56 list_add_tail(&buf->list, &q->list); 56 mutex_lock(&s->qlock);
57 atomic_inc(&q->buffers); 57
58 /* q_busy is restricted to a max buffer count imposed by firmware */
59 if (q == &s->q_busy &&
60 atomic_read(&q->buffers) >= CX18_MAX_FW_MDLS_PER_STREAM)
61 q = &s->q_free;
62
63 if (to_front)
64 list_add(&buf->list, &q->list); /* LIFO */
65 else
66 list_add_tail(&buf->list, &q->list); /* FIFO */
58 q->bytesused += buf->bytesused - buf->readpos; 67 q->bytesused += buf->bytesused - buf->readpos;
59 spin_unlock_irqrestore(&s->qlock, flags); 68 atomic_inc(&q->buffers);
69
70 mutex_unlock(&s->qlock);
71 return q;
60} 72}
61 73
62struct cx18_buffer *cx18_dequeue(struct cx18_stream *s, struct cx18_queue *q) 74struct cx18_buffer *cx18_dequeue(struct cx18_stream *s, struct cx18_queue *q)
63{ 75{
64 struct cx18_buffer *buf = NULL; 76 struct cx18_buffer *buf = NULL;
65 unsigned long flags = 0;
66 77
67 spin_lock_irqsave(&s->qlock, flags); 78 mutex_lock(&s->qlock);
68 if (!list_empty(&q->list)) { 79 if (!list_empty(&q->list)) {
69 buf = list_entry(q->list.next, struct cx18_buffer, list); 80 buf = list_first_entry(&q->list, struct cx18_buffer, list);
70 list_del_init(q->list.next); 81 list_del_init(&buf->list);
71 atomic_dec(&q->buffers);
72 q->bytesused -= buf->bytesused - buf->readpos; 82 q->bytesused -= buf->bytesused - buf->readpos;
83 buf->skipped = 0;
84 atomic_dec(&q->buffers);
73 } 85 }
74 spin_unlock_irqrestore(&s->qlock, flags); 86 mutex_unlock(&s->qlock);
75 return buf; 87 return buf;
76} 88}
77 89
78struct cx18_buffer *cx18_queue_get_buf_irq(struct cx18_stream *s, u32 id, 90struct cx18_buffer *cx18_queue_get_buf(struct cx18_stream *s, u32 id,
79 u32 bytesused) 91 u32 bytesused)
80{ 92{
81 struct cx18 *cx = s->cx; 93 struct cx18 *cx = s->cx;
82 struct list_head *p; 94 struct cx18_buffer *buf;
83 95 struct cx18_buffer *tmp;
84 spin_lock(&s->qlock); 96 struct cx18_buffer *ret = NULL;
85 list_for_each(p, &s->q_free.list) { 97
86 struct cx18_buffer *buf = 98 mutex_lock(&s->qlock);
87 list_entry(p, struct cx18_buffer, list); 99 list_for_each_entry_safe(buf, tmp, &s->q_busy.list, list) {
88 100 if (buf->id != id) {
89 if (buf->id != id) 101 buf->skipped++;
102 if (buf->skipped >= atomic_read(&s->q_busy.buffers)-1) {
103 /* buffer must have fallen out of rotation */
104 CX18_WARN("Skipped %s, buffer %d, %d "
105 "times - it must have dropped out of "
106 "rotation\n", s->name, buf->id,
107 buf->skipped);
108 /* move it to q_free */
109 list_move_tail(&buf->list, &s->q_free.list);
110 buf->bytesused = buf->readpos = buf->b_flags =
111 buf->skipped = 0;
112 atomic_dec(&s->q_busy.buffers);
113 atomic_inc(&s->q_free.buffers);
114 }
90 continue; 115 continue;
116 }
91 117
92 buf->bytesused = bytesused; 118 buf->bytesused = bytesused;
93 atomic_dec(&s->q_free.buffers); 119 /* Sync the buffer before we release the qlock */
94 atomic_inc(&s->q_full.buffers); 120 cx18_buf_sync_for_cpu(s, buf);
95 s->q_full.bytesused += buf->bytesused; 121 if (s->type == CX18_ENC_STREAM_TYPE_TS) {
96 list_move_tail(&buf->list, &s->q_full.list); 122 /*
123 * TS doesn't use q_full. As we pull the buffer off of
124 * the queue here, the caller will have to put it back.
125 */
126 list_del_init(&buf->list);
127 } else {
128 /* Move buffer from q_busy to q_full */
129 list_move_tail(&buf->list, &s->q_full.list);
130 set_bit(CX18_F_B_NEED_BUF_SWAP, &buf->b_flags);
131 s->q_full.bytesused += buf->bytesused;
132 atomic_inc(&s->q_full.buffers);
133 }
134 atomic_dec(&s->q_busy.buffers);
97 135
98 spin_unlock(&s->qlock); 136 ret = buf;
99 return buf; 137 break;
100 } 138 }
101 spin_unlock(&s->qlock); 139 mutex_unlock(&s->qlock);
102 CX18_ERR("Cannot find buffer %d for stream %s\n", id, s->name); 140 return ret;
103 return NULL;
104} 141}
105 142
106/* Move all buffers of a queue to q_free, while flushing the buffers */ 143/* Move all buffers of a queue to q_free, while flushing the buffers */
107static void cx18_queue_flush(struct cx18_stream *s, struct cx18_queue *q) 144static void cx18_queue_flush(struct cx18_stream *s, struct cx18_queue *q)
108{ 145{
109 unsigned long flags;
110 struct cx18_buffer *buf; 146 struct cx18_buffer *buf;
111 147
112 if (q == &s->q_free) 148 if (q == &s->q_free)
113 return; 149 return;
114 150
115 spin_lock_irqsave(&s->qlock, flags); 151 mutex_lock(&s->qlock);
116 while (!list_empty(&q->list)) { 152 while (!list_empty(&q->list)) {
117 buf = list_entry(q->list.next, struct cx18_buffer, list); 153 buf = list_first_entry(&q->list, struct cx18_buffer, list);
118 list_move_tail(q->list.next, &s->q_free.list); 154 list_move_tail(&buf->list, &s->q_free.list);
119 buf->bytesused = buf->readpos = buf->b_flags = 0; 155 buf->bytesused = buf->readpos = buf->b_flags = buf->skipped = 0;
120 atomic_inc(&s->q_free.buffers); 156 atomic_inc(&s->q_free.buffers);
121 } 157 }
122 cx18_queue_init(q); 158 cx18_queue_init(q);
123 spin_unlock_irqrestore(&s->qlock, flags); 159 mutex_unlock(&s->qlock);
124} 160}
125 161
126void cx18_flush_queues(struct cx18_stream *s) 162void cx18_flush_queues(struct cx18_stream *s)
127{ 163{
128 cx18_queue_flush(s, &s->q_io); 164 cx18_queue_flush(s, &s->q_busy);
129 cx18_queue_flush(s, &s->q_full); 165 cx18_queue_flush(s, &s->q_full);
130} 166}
131 167
diff --git a/drivers/media/video/cx18/cx18-queue.h b/drivers/media/video/cx18/cx18-queue.h
index 7f93bb13c09f..456cec3bc28f 100644
--- a/drivers/media/video/cx18/cx18-queue.h
+++ b/drivers/media/video/cx18/cx18-queue.h
@@ -4,6 +4,7 @@
4 * Derived from ivtv-queue.h 4 * Derived from ivtv-queue.h
5 * 5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> 6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 * Copyright (C) 2008 Andy Walls <awalls@radix.net>
7 * 8 *
8 * This program is free software; you can redistribute it and/or modify 9 * 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 * it under the terms of the GNU General Public License as published by
@@ -42,11 +43,26 @@ static inline void cx18_buf_sync_for_device(struct cx18_stream *s,
42void cx18_buf_swap(struct cx18_buffer *buf); 43void cx18_buf_swap(struct cx18_buffer *buf);
43 44
44/* cx18_queue utility functions */ 45/* cx18_queue utility functions */
46struct cx18_queue *_cx18_enqueue(struct cx18_stream *s, struct cx18_buffer *buf,
47 struct cx18_queue *q, int to_front);
48
49static inline
50struct cx18_queue *cx18_enqueue(struct cx18_stream *s, struct cx18_buffer *buf,
51 struct cx18_queue *q)
52{
53 return _cx18_enqueue(s, buf, q, 0); /* FIFO */
54}
55
56static inline
57struct cx18_queue *cx18_push(struct cx18_stream *s, struct cx18_buffer *buf,
58 struct cx18_queue *q)
59{
60 return _cx18_enqueue(s, buf, q, 1); /* LIFO */
61}
62
45void cx18_queue_init(struct cx18_queue *q); 63void cx18_queue_init(struct cx18_queue *q);
46void cx18_enqueue(struct cx18_stream *s, struct cx18_buffer *buf,
47 struct cx18_queue *q);
48struct cx18_buffer *cx18_dequeue(struct cx18_stream *s, struct cx18_queue *q); 64struct cx18_buffer *cx18_dequeue(struct cx18_stream *s, struct cx18_queue *q);
49struct cx18_buffer *cx18_queue_get_buf_irq(struct cx18_stream *s, u32 id, 65struct cx18_buffer *cx18_queue_get_buf(struct cx18_stream *s, u32 id,
50 u32 bytesused); 66 u32 bytesused);
51void cx18_flush_queues(struct cx18_stream *s); 67void cx18_flush_queues(struct cx18_stream *s);
52 68
diff --git a/drivers/media/video/cx18/cx18-scb.c b/drivers/media/video/cx18/cx18-scb.c
index f56d3772aa67..34b4d03c55cd 100644
--- a/drivers/media/video/cx18/cx18-scb.c
+++ b/drivers/media/video/cx18/cx18-scb.c
@@ -2,6 +2,7 @@
2 * cx18 System Control Block initialization 2 * cx18 System Control Block initialization
3 * 3 *
4 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> 4 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
5 * Copyright (C) 2008 Andy Walls <awalls@radix.net>
5 * 6 *
6 * 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
7 * 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
@@ -117,6 +118,5 @@ void cx18_init_scb(struct cx18 *cx)
117 cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, cpu_state), 118 cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, cpu_state),
118 &cx->scb->ipc_offset); 119 &cx->scb->ipc_offset);
119 120
120 cx18_writel(cx, 1, &cx->scb->hpu_state);
121 cx18_writel(cx, 1, &cx->scb->epu_state); 121 cx18_writel(cx, 1, &cx->scb->epu_state);
122} 122}
diff --git a/drivers/media/video/cx18/cx18-scb.h b/drivers/media/video/cx18/cx18-scb.h
index 594713bbed68..1dc1c431f5a1 100644
--- a/drivers/media/video/cx18/cx18-scb.h
+++ b/drivers/media/video/cx18/cx18-scb.h
@@ -2,6 +2,7 @@
2 * cx18 System Control Block initialization 2 * cx18 System Control Block initialization
3 * 3 *
4 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> 4 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
5 * Copyright (C) 2008 Andy Walls <awalls@radix.net>
5 * 6 *
6 * 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
7 * 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
@@ -85,12 +86,6 @@ struct cx18_mdl {
85 u32 length; /* Length of the buffer segment */ 86 u32 length; /* Length of the buffer segment */
86}; 87};
87 88
88/* This structure is used by CPU to provide completed buffers information */
89struct cx18_mdl_ack {
90 u32 id; /* ID of a completed MDL */
91 u32 data_used; /* Total data filled in the MDL for buffer 'id' */
92};
93
94struct cx18_scb { 89struct cx18_scb {
95 /* These fields form the System Control Block which is used at boot time 90 /* These fields form the System Control Block which is used at boot time
96 for localizing the IPC data as well as the code positions for all 91 for localizing the IPC data as well as the code positions for all
@@ -276,7 +271,7 @@ struct cx18_scb {
276 struct cx18_mailbox hpu2epu_mb; 271 struct cx18_mailbox hpu2epu_mb;
277 struct cx18_mailbox ppu2epu_mb; 272 struct cx18_mailbox ppu2epu_mb;
278 273
279 struct cx18_mdl_ack cpu_mdl_ack[CX18_MAX_STREAMS][2]; 274 struct cx18_mdl_ack cpu_mdl_ack[CX18_MAX_STREAMS][CX18_MAX_MDL_ACKS];
280 struct cx18_mdl cpu_mdl[1]; 275 struct cx18_mdl cpu_mdl[1];
281}; 276};
282 277
diff --git a/drivers/media/video/cx18/cx18-streams.c b/drivers/media/video/cx18/cx18-streams.c
index e5ff7705b7a1..63c336c95ff5 100644
--- a/drivers/media/video/cx18/cx18-streams.c
+++ b/drivers/media/video/cx18/cx18-streams.c
@@ -4,6 +4,7 @@
4 * Derived from ivtv-streams.c 4 * Derived from ivtv-streams.c
5 * 5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> 6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 * Copyright (C) 2008 Andy Walls <awalls@radix.net>
7 * 8 *
8 * This program is free software; you can redistribute it and/or modify 9 * 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 * it under the terms of the GNU General Public License as published by
@@ -110,7 +111,6 @@ static void cx18_stream_init(struct cx18 *cx, int type)
110{ 111{
111 struct cx18_stream *s = &cx->streams[type]; 112 struct cx18_stream *s = &cx->streams[type];
112 struct video_device *dev = s->v4l2dev; 113 struct video_device *dev = s->v4l2dev;
113 u32 max_size = cx->options.megabytes[type] * 1024 * 1024;
114 114
115 /* we need to keep v4l2dev, so restore it afterwards */ 115 /* we need to keep v4l2dev, so restore it afterwards */
116 memset(s, 0, sizeof(*s)); 116 memset(s, 0, sizeof(*s));
@@ -123,21 +123,15 @@ static void cx18_stream_init(struct cx18 *cx, int type)
123 s->handle = CX18_INVALID_TASK_HANDLE; 123 s->handle = CX18_INVALID_TASK_HANDLE;
124 124
125 s->dma = cx18_stream_info[type].dma; 125 s->dma = cx18_stream_info[type].dma;
126 s->buffers = cx->stream_buffers[type];
126 s->buf_size = cx->stream_buf_size[type]; 127 s->buf_size = cx->stream_buf_size[type];
127 if (s->buf_size) 128
128 s->buffers = max_size / s->buf_size; 129 mutex_init(&s->qlock);
129 if (s->buffers > 63) {
130 /* Each stream has a maximum of 63 buffers,
131 ensure we do not exceed that. */
132 s->buffers = 63;
133 s->buf_size = (max_size / s->buffers) & ~0xfff;
134 }
135 spin_lock_init(&s->qlock);
136 init_waitqueue_head(&s->waitq); 130 init_waitqueue_head(&s->waitq);
137 s->id = -1; 131 s->id = -1;
138 cx18_queue_init(&s->q_free); 132 cx18_queue_init(&s->q_free);
133 cx18_queue_init(&s->q_busy);
139 cx18_queue_init(&s->q_full); 134 cx18_queue_init(&s->q_full);
140 cx18_queue_init(&s->q_io);
141} 135}
142 136
143static int cx18_prep_dev(struct cx18 *cx, int type) 137static int cx18_prep_dev(struct cx18 *cx, int type)
@@ -167,7 +161,7 @@ static int cx18_prep_dev(struct cx18 *cx, int type)
167 /* User explicitly selected 0 buffers for these streams, so don't 161 /* User explicitly selected 0 buffers for these streams, so don't
168 create them. */ 162 create them. */
169 if (cx18_stream_info[type].dma != PCI_DMA_NONE && 163 if (cx18_stream_info[type].dma != PCI_DMA_NONE &&
170 cx->options.megabytes[type] == 0) { 164 cx->stream_buffers[type] == 0) {
171 CX18_INFO("Disabled %s device\n", cx18_stream_info[type].name); 165 CX18_INFO("Disabled %s device\n", cx18_stream_info[type].name);
172 return 0; 166 return 0;
173 } 167 }
@@ -267,8 +261,9 @@ static int cx18_reg_dev(struct cx18 *cx, int type)
267 261
268 switch (vfl_type) { 262 switch (vfl_type) {
269 case VFL_TYPE_GRABBER: 263 case VFL_TYPE_GRABBER:
270 CX18_INFO("Registered device video%d for %s (%d MB)\n", 264 CX18_INFO("Registered device video%d for %s (%d x %d kB)\n",
271 num, s->name, cx->options.megabytes[type]); 265 num, s->name, cx->stream_buffers[type],
266 cx->stream_buf_size[type]/1024);
272 break; 267 break;
273 268
274 case VFL_TYPE_RADIO: 269 case VFL_TYPE_RADIO:
@@ -277,10 +272,11 @@ static int cx18_reg_dev(struct cx18 *cx, int type)
277 break; 272 break;
278 273
279 case VFL_TYPE_VBI: 274 case VFL_TYPE_VBI:
280 if (cx->options.megabytes[type]) 275 if (cx->stream_buffers[type])
281 CX18_INFO("Registered device vbi%d for %s (%d MB)\n", 276 CX18_INFO("Registered device vbi%d for %s "
282 num, 277 "(%d x %d bytes)\n",
283 s->name, cx->options.megabytes[type]); 278 num, s->name, cx->stream_buffers[type],
279 cx->stream_buf_size[type]);
284 else 280 else
285 CX18_INFO("Registered device vbi%d for %s\n", 281 CX18_INFO("Registered device vbi%d for %s\n",
286 num, s->name); 282 num, s->name);
@@ -344,7 +340,7 @@ void cx18_streams_cleanup(struct cx18 *cx, int unregister)
344static void cx18_vbi_setup(struct cx18_stream *s) 340static void cx18_vbi_setup(struct cx18_stream *s)
345{ 341{
346 struct cx18 *cx = s->cx; 342 struct cx18 *cx = s->cx;
347 int raw = cx->vbi.sliced_in->service_set == 0; 343 int raw = cx18_raw_vbi(cx);
348 u32 data[CX2341X_MBOX_MAX_DATA]; 344 u32 data[CX2341X_MBOX_MAX_DATA];
349 int lines; 345 int lines;
350 346
@@ -362,8 +358,7 @@ static void cx18_vbi_setup(struct cx18_stream *s)
362 cx18_av_cmd(cx, VIDIOC_S_FMT, &cx->vbi.in); 358 cx18_av_cmd(cx, VIDIOC_S_FMT, &cx->vbi.in);
363 359
364 /* determine number of lines and total number of VBI bytes. 360 /* determine number of lines and total number of VBI bytes.
365 A raw line takes 1443 bytes: 2 * 720 + 4 byte frame header - 1 361 A raw line takes 1444 bytes: 4 byte SAV code + 2 * 720
366 The '- 1' byte is probably an unused U or V byte. Or something...
367 A sliced line takes 51 bytes: 4 byte frame header, 4 byte internal 362 A sliced line takes 51 bytes: 4 byte frame header, 4 byte internal
368 header, 42 data bytes + checksum (to be confirmed) */ 363 header, 42 data bytes + checksum (to be confirmed) */
369 if (raw) { 364 if (raw) {
@@ -381,14 +376,15 @@ static void cx18_vbi_setup(struct cx18_stream *s)
381 /* Lines per field */ 376 /* Lines per field */
382 data[1] = (lines / 2) | ((lines / 2) << 16); 377 data[1] = (lines / 2) | ((lines / 2) << 16);
383 /* bytes per line */ 378 /* bytes per line */
384 data[2] = (raw ? cx->vbi.raw_size : cx->vbi.sliced_size); 379 data[2] = (raw ? cx->vbi.raw_decoder_line_size
380 : cx->vbi.sliced_decoder_line_size);
385 /* Every X number of frames a VBI interrupt arrives 381 /* Every X number of frames a VBI interrupt arrives
386 (frames as in 25 or 30 fps) */ 382 (frames as in 25 or 30 fps) */
387 data[3] = 1; 383 data[3] = 1;
388 /* Setup VBI for the cx25840 digitizer */ 384 /* Setup VBI for the cx25840 digitizer */
389 if (raw) { 385 if (raw) {
390 data[4] = 0x20602060; 386 data[4] = 0x20602060;
391 data[5] = 0x30703070; 387 data[5] = 0x307090d0;
392 } else { 388 } else {
393 data[4] = 0xB0F0B0F0; 389 data[4] = 0xB0F0B0F0;
394 data[5] = 0xA0E0A0E0; 390 data[5] = 0xA0E0A0E0;
@@ -401,11 +397,52 @@ static void cx18_vbi_setup(struct cx18_stream *s)
401 cx18_api(cx, CX18_CPU_SET_RAW_VBI_PARAM, 6, data); 397 cx18_api(cx, CX18_CPU_SET_RAW_VBI_PARAM, 6, data);
402} 398}
403 399
400struct cx18_queue *cx18_stream_put_buf_fw(struct cx18_stream *s,
401 struct cx18_buffer *buf)
402{
403 struct cx18 *cx = s->cx;
404 struct cx18_queue *q;
405
406 /* Don't give it to the firmware, if we're not running a capture */
407 if (s->handle == CX18_INVALID_TASK_HANDLE ||
408 !test_bit(CX18_F_S_STREAMING, &s->s_flags))
409 return cx18_enqueue(s, buf, &s->q_free);
410
411 q = cx18_enqueue(s, buf, &s->q_busy);
412 if (q != &s->q_busy)
413 return q; /* The firmware has the max buffers it can handle */
414
415 cx18_buf_sync_for_device(s, buf);
416 cx18_vapi(cx, CX18_CPU_DE_SET_MDL, 5, s->handle,
417 (void __iomem *) &cx->scb->cpu_mdl[buf->id] - cx->enc_mem,
418 1, buf->id, s->buf_size);
419 return q;
420}
421
422void cx18_stream_load_fw_queue(struct cx18_stream *s)
423{
424 struct cx18_queue *q;
425 struct cx18_buffer *buf;
426
427 if (atomic_read(&s->q_free.buffers) == 0 ||
428 atomic_read(&s->q_busy.buffers) >= CX18_MAX_FW_MDLS_PER_STREAM)
429 return;
430
431 /* Move from q_free to q_busy notifying the firmware, until the limit */
432 do {
433 buf = cx18_dequeue(s, &s->q_free);
434 if (buf == NULL)
435 break;
436 q = cx18_stream_put_buf_fw(s, buf);
437 } while (atomic_read(&s->q_busy.buffers) < CX18_MAX_FW_MDLS_PER_STREAM
438 && q == &s->q_busy);
439}
440
404int cx18_start_v4l2_encode_stream(struct cx18_stream *s) 441int cx18_start_v4l2_encode_stream(struct cx18_stream *s)
405{ 442{
406 u32 data[MAX_MB_ARGUMENTS]; 443 u32 data[MAX_MB_ARGUMENTS];
407 struct cx18 *cx = s->cx; 444 struct cx18 *cx = s->cx;
408 struct list_head *p; 445 struct cx18_buffer *buf;
409 int ts = 0; 446 int ts = 0;
410 int captype = 0; 447 int captype = 0;
411 448
@@ -434,8 +471,8 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s)
434 captype = CAPTURE_CHANNEL_TYPE_PCM; 471 captype = CAPTURE_CHANNEL_TYPE_PCM;
435 break; 472 break;
436 case CX18_ENC_STREAM_TYPE_VBI: 473 case CX18_ENC_STREAM_TYPE_VBI:
437 captype = cx->vbi.sliced_in->service_set ? 474 captype = cx18_raw_vbi(cx) ?
438 CAPTURE_CHANNEL_TYPE_SLICED_VBI : CAPTURE_CHANNEL_TYPE_VBI; 475 CAPTURE_CHANNEL_TYPE_VBI : CAPTURE_CHANNEL_TYPE_SLICED_VBI;
439 cx->vbi.frame = 0; 476 cx->vbi.frame = 0;
440 cx->vbi.inserted_frame = 0; 477 cx->vbi.inserted_frame = 0;
441 memset(cx->vbi.sliced_mpeg_size, 478 memset(cx->vbi.sliced_mpeg_size,
@@ -457,6 +494,8 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s)
457 cx18_vapi(cx, CX18_CPU_SET_CHANNEL_TYPE, 2, s->handle, captype); 494 cx18_vapi(cx, CX18_CPU_SET_CHANNEL_TYPE, 2, s->handle, captype);
458 495
459 if (atomic_read(&cx->ana_capturing) == 0 && !ts) { 496 if (atomic_read(&cx->ana_capturing) == 0 && !ts) {
497 struct cx18_api_func_private priv;
498
460 /* Stuff from Windows, we don't know what it is */ 499 /* Stuff from Windows, we don't know what it is */
461 cx18_vapi(cx, CX18_CPU_SET_VER_CROP_LINE, 2, s->handle, 0); 500 cx18_vapi(cx, CX18_CPU_SET_VER_CROP_LINE, 2, s->handle, 0);
462 cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 3, s->handle, 3, 1); 501 cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 3, s->handle, 3, 1);
@@ -476,7 +515,9 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s)
476 cx18_vapi_result(cx, data, CX18_CPU_SET_INDEXTABLE, 1, 0); 515 cx18_vapi_result(cx, data, CX18_CPU_SET_INDEXTABLE, 1, 0);
477 516
478 /* Setup API for Stream */ 517 /* Setup API for Stream */
479 cx2341x_update(cx, cx18_api_func, NULL, &cx->params); 518 priv.cx = cx;
519 priv.s = s;
520 cx2341x_update(&priv, cx18_api_func, NULL, &cx->params);
480 } 521 }
481 522
482 if (atomic_read(&cx->tot_capturing) == 0) { 523 if (atomic_read(&cx->tot_capturing) == 0) {
@@ -488,16 +529,17 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s)
488 (void __iomem *)&cx->scb->cpu_mdl_ack[s->type][0] - cx->enc_mem, 529 (void __iomem *)&cx->scb->cpu_mdl_ack[s->type][0] - cx->enc_mem,
489 (void __iomem *)&cx->scb->cpu_mdl_ack[s->type][1] - cx->enc_mem); 530 (void __iomem *)&cx->scb->cpu_mdl_ack[s->type][1] - cx->enc_mem);
490 531
491 list_for_each(p, &s->q_free.list) { 532 /* Init all the cpu_mdls for this stream */
492 struct cx18_buffer *buf = list_entry(p, struct cx18_buffer, list); 533 cx18_flush_queues(s);
493 534 mutex_lock(&s->qlock);
535 list_for_each_entry(buf, &s->q_free.list, list) {
494 cx18_writel(cx, buf->dma_handle, 536 cx18_writel(cx, buf->dma_handle,
495 &cx->scb->cpu_mdl[buf->id].paddr); 537 &cx->scb->cpu_mdl[buf->id].paddr);
496 cx18_writel(cx, s->buf_size, &cx->scb->cpu_mdl[buf->id].length); 538 cx18_writel(cx, s->buf_size, &cx->scb->cpu_mdl[buf->id].length);
497 cx18_vapi(cx, CX18_CPU_DE_SET_MDL, 5, s->handle,
498 (void __iomem *)&cx->scb->cpu_mdl[buf->id] - cx->enc_mem,
499 1, buf->id, s->buf_size);
500 } 539 }
540 mutex_unlock(&s->qlock);
541 cx18_stream_load_fw_queue(s);
542
501 /* begin_capture */ 543 /* begin_capture */
502 if (cx18_vapi(cx, CX18_CPU_CAPTURE_START, 1, s->handle)) { 544 if (cx18_vapi(cx, CX18_CPU_CAPTURE_START, 1, s->handle)) {
503 CX18_DEBUG_WARN("Error starting capture!\n"); 545 CX18_DEBUG_WARN("Error starting capture!\n");
@@ -506,9 +548,15 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s)
506 cx18_vapi(cx, CX18_CPU_CAPTURE_STOP, 2, s->handle, 1); 548 cx18_vapi(cx, CX18_CPU_CAPTURE_STOP, 2, s->handle, 1);
507 else 549 else
508 cx18_vapi(cx, CX18_CPU_CAPTURE_STOP, 1, s->handle); 550 cx18_vapi(cx, CX18_CPU_CAPTURE_STOP, 1, s->handle);
551 clear_bit(CX18_F_S_STREAMING, &s->s_flags);
552 /* FIXME - CX18_F_S_STREAMOFF as well? */
509 cx18_vapi(cx, CX18_CPU_DE_RELEASE_MDL, 1, s->handle); 553 cx18_vapi(cx, CX18_CPU_DE_RELEASE_MDL, 1, s->handle);
510 cx18_vapi(cx, CX18_DESTROY_TASK, 1, s->handle); 554 cx18_vapi(cx, CX18_DESTROY_TASK, 1, s->handle);
511 /* FIXME - clean-up DSP0_INT mask, i_flags, s_flags, etc. */ 555 s->handle = CX18_INVALID_TASK_HANDLE;
556 if (atomic_read(&cx->tot_capturing) == 0) {
557 set_bit(CX18_F_I_EOS, &cx->i_flags);
558 cx18_write_reg(cx, 5, CX18_DSP0_INTERRUPT_MASK);
559 }
512 return -EINVAL; 560 return -EINVAL;
513 } 561 }
514 562
@@ -560,9 +608,6 @@ int cx18_stop_v4l2_encode_stream(struct cx18_stream *s, int gop_end)
560 CX18_INFO("ignoring gop_end: not (yet?) supported by the firmware\n"); 608 CX18_INFO("ignoring gop_end: not (yet?) supported by the firmware\n");
561 } 609 }
562 610
563 /* Tell the CX23418 it can't use our buffers anymore */
564 cx18_vapi(cx, CX18_CPU_DE_RELEASE_MDL, 1, s->handle);
565
566 if (s->type != CX18_ENC_STREAM_TYPE_TS) 611 if (s->type != CX18_ENC_STREAM_TYPE_TS)
567 atomic_dec(&cx->ana_capturing); 612 atomic_dec(&cx->ana_capturing);
568 atomic_dec(&cx->tot_capturing); 613 atomic_dec(&cx->tot_capturing);
@@ -570,6 +615,9 @@ int cx18_stop_v4l2_encode_stream(struct cx18_stream *s, int gop_end)
570 /* Clear capture and no-read bits */ 615 /* Clear capture and no-read bits */
571 clear_bit(CX18_F_S_STREAMING, &s->s_flags); 616 clear_bit(CX18_F_S_STREAMING, &s->s_flags);
572 617
618 /* Tell the CX23418 it can't use our buffers anymore */
619 cx18_vapi(cx, CX18_CPU_DE_RELEASE_MDL, 1, s->handle);
620
573 cx18_vapi(cx, CX18_DESTROY_TASK, 1, s->handle); 621 cx18_vapi(cx, CX18_DESTROY_TASK, 1, s->handle);
574 s->handle = CX18_INVALID_TASK_HANDLE; 622 s->handle = CX18_INVALID_TASK_HANDLE;
575 623
@@ -595,3 +643,21 @@ u32 cx18_find_handle(struct cx18 *cx)
595 } 643 }
596 return CX18_INVALID_TASK_HANDLE; 644 return CX18_INVALID_TASK_HANDLE;
597} 645}
646
647struct cx18_stream *cx18_handle_to_stream(struct cx18 *cx, u32 handle)
648{
649 int i;
650 struct cx18_stream *s;
651
652 if (handle == CX18_INVALID_TASK_HANDLE)
653 return NULL;
654
655 for (i = 0; i < CX18_MAX_STREAMS; i++) {
656 s = &cx->streams[i];
657 if (s->handle != handle)
658 continue;
659 if (s->v4l2dev || s->dvb.enabled)
660 return s;
661 }
662 return NULL;
663}
diff --git a/drivers/media/video/cx18/cx18-streams.h b/drivers/media/video/cx18/cx18-streams.h
index f327e947b24f..420e0a172945 100644
--- a/drivers/media/video/cx18/cx18-streams.h
+++ b/drivers/media/video/cx18/cx18-streams.h
@@ -4,6 +4,7 @@
4 * Derived from ivtv-streams.h 4 * Derived from ivtv-streams.h
5 * 5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> 6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 * Copyright (C) 2008 Andy Walls <awalls@radix.net>
7 * 8 *
8 * This program is free software; you can redistribute it and/or modify 9 * 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 * it under the terms of the GNU General Public License as published by
@@ -22,11 +23,15 @@
22 */ 23 */
23 24
24u32 cx18_find_handle(struct cx18 *cx); 25u32 cx18_find_handle(struct cx18 *cx);
26struct cx18_stream *cx18_handle_to_stream(struct cx18 *cx, u32 handle);
25int cx18_streams_setup(struct cx18 *cx); 27int cx18_streams_setup(struct cx18 *cx);
26int cx18_streams_register(struct cx18 *cx); 28int cx18_streams_register(struct cx18 *cx);
27void cx18_streams_cleanup(struct cx18 *cx, int unregister); 29void cx18_streams_cleanup(struct cx18 *cx, int unregister);
28 30
29/* Capture related */ 31/* Capture related */
32void cx18_stream_load_fw_queue(struct cx18_stream *s);
33struct cx18_queue *cx18_stream_put_buf_fw(struct cx18_stream *s,
34 struct cx18_buffer *buf);
30int cx18_start_v4l2_encode_stream(struct cx18_stream *s); 35int cx18_start_v4l2_encode_stream(struct cx18_stream *s);
31int cx18_stop_v4l2_encode_stream(struct cx18_stream *s, int gop_end); 36int cx18_stop_v4l2_encode_stream(struct cx18_stream *s, int gop_end);
32 37
diff --git a/drivers/media/video/cx18/cx18-vbi.c b/drivers/media/video/cx18/cx18-vbi.c
index 22e76ee3f447..fb595bd548e8 100644
--- a/drivers/media/video/cx18/cx18-vbi.c
+++ b/drivers/media/video/cx18/cx18-vbi.c
@@ -160,11 +160,14 @@ void cx18_process_vbi_data(struct cx18 *cx, struct cx18_buffer *buf,
160 return; 160 return;
161 161
162 /* Raw VBI data */ 162 /* Raw VBI data */
163 if (cx->vbi.sliced_in->service_set == 0) { 163 if (cx18_raw_vbi(cx)) {
164 u8 type; 164 u8 type;
165 165
166 cx18_buf_swap(buf); 166 cx18_buf_swap(buf);
167 167
168 /* Skip 12 bytes of header that gets stuffed in */
169 size -= 12;
170 memcpy(p, &buf->buf[12], size);
168 type = p[3]; 171 type = p[3];
169 172
170 size = buf->bytesused = compress_raw_buf(cx, p, size); 173 size = buf->bytesused = compress_raw_buf(cx, p, size);
diff --git a/drivers/media/video/cx18/cx18-version.h b/drivers/media/video/cx18/cx18-version.h
index 9f6be2d457fb..84c0ff13b607 100644
--- a/drivers/media/video/cx18/cx18-version.h
+++ b/drivers/media/video/cx18/cx18-version.h
@@ -25,7 +25,7 @@
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 0 27#define CX18_DRIVER_VERSION_MINOR 0
28#define CX18_DRIVER_VERSION_PATCHLEVEL 1 28#define CX18_DRIVER_VERSION_PATCHLEVEL 4
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)
31#define CX18_DRIVER_VERSION KERNEL_VERSION(CX18_DRIVER_VERSION_MAJOR, \ 31#define CX18_DRIVER_VERSION KERNEL_VERSION(CX18_DRIVER_VERSION_MAJOR, \
diff --git a/drivers/media/video/cx18/cx23418.h b/drivers/media/video/cx18/cx23418.h
index 668f968d7761..601f3a2ab742 100644
--- a/drivers/media/video/cx18/cx23418.h
+++ b/drivers/media/video/cx18/cx23418.h
@@ -44,6 +44,7 @@
44 44
45/* All commands for CPU have the following mask set */ 45/* All commands for CPU have the following mask set */
46#define CPU_CMD_MASK 0x20000000 46#define CPU_CMD_MASK 0x20000000
47#define CPU_CMD_MASK_DEBUG (CPU_CMD_MASK | 0x00000000)
47#define CPU_CMD_MASK_ACK (CPU_CMD_MASK | 0x80000000) 48#define CPU_CMD_MASK_ACK (CPU_CMD_MASK | 0x80000000)
48#define CPU_CMD_MASK_CAPTURE (CPU_CMD_MASK | 0x00020000) 49#define CPU_CMD_MASK_CAPTURE (CPU_CMD_MASK | 0x00020000)
49#define CPU_CMD_MASK_TS (CPU_CMD_MASK | 0x00040000) 50#define CPU_CMD_MASK_TS (CPU_CMD_MASK | 0x00040000)
@@ -71,6 +72,11 @@
71 0/zero/NULL means "I have nothing to say" */ 72 0/zero/NULL means "I have nothing to say" */
72#define CX18_EPU_DEBUG (EPU_CMD_MASK_DEBUG | 0x0003) 73#define CX18_EPU_DEBUG (EPU_CMD_MASK_DEBUG | 0x0003)
73 74
75/* Reads memory/registers (32-bit)
76 IN[0] - Address
77 OUT[1] - Value */
78#define CX18_CPU_DEBUG_PEEK32 (CPU_CMD_MASK_DEBUG | 0x0003)
79
74/* Description: This command starts streaming with the set channel type 80/* Description: This command starts streaming with the set channel type
75 IN[0] - Task handle. Handle of the task to start 81 IN[0] - Task handle. Handle of the task to start
76 ReturnCode - One of the ERR_CAPTURE_... */ 82 ReturnCode - One of the ERR_CAPTURE_... */
diff --git a/drivers/media/video/cx23885/cx23885-417.c b/drivers/media/video/cx23885/cx23885-417.c
index 00831f3ef8f5..798d24024353 100644
--- a/drivers/media/video/cx23885/cx23885-417.c
+++ b/drivers/media/video/cx23885/cx23885-417.c
@@ -2,7 +2,7 @@
2 * 2 *
3 * Support for a cx23417 mpeg encoder via cx23885 host port. 3 * Support for a cx23417 mpeg encoder via cx23885 host port.
4 * 4 *
5 * (c) 2004 Jelle Foks <jelle@foks.8m.com> 5 * (c) 2004 Jelle Foks <jelle@foks.us>
6 * (c) 2004 Gerd Knorr <kraxel@bytesex.org> 6 * (c) 2004 Gerd Knorr <kraxel@bytesex.org>
7 * (c) 2008 Steven Toth <stoth@linuxtv.org> 7 * (c) 2008 Steven Toth <stoth@linuxtv.org>
8 * - CX23885/7/8 support 8 * - CX23885/7/8 support
diff --git a/drivers/media/video/cx23885/cx23885-cards.c b/drivers/media/video/cx23885/cx23885-cards.c
index dac5ccc9ba72..caa098beeecf 100644
--- a/drivers/media/video/cx23885/cx23885-cards.c
+++ b/drivers/media/video/cx23885/cx23885-cards.c
@@ -158,6 +158,10 @@ struct cx23885_board cx23885_boards[] = {
158 .name = "Leadtek Winfast PxDVR3200 H", 158 .name = "Leadtek Winfast PxDVR3200 H",
159 .portc = CX23885_MPEG_DVB, 159 .portc = CX23885_MPEG_DVB,
160 }, 160 },
161 [CX23885_BOARD_COMPRO_VIDEOMATE_E650F] = {
162 .name = "Compro VideoMate E650F",
163 .portc = CX23885_MPEG_DVB,
164 },
161}; 165};
162const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards); 166const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards);
163 167
@@ -237,6 +241,10 @@ struct cx23885_subid cx23885_subids[] = {
237 .subvendor = 0x107d, 241 .subvendor = 0x107d,
238 .subdevice = 0x6681, 242 .subdevice = 0x6681,
239 .card = CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H, 243 .card = CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H,
244 }, {
245 .subvendor = 0x185b,
246 .subdevice = 0xe800,
247 .card = CX23885_BOARD_COMPRO_VIDEOMATE_E650F,
240 }, 248 },
241}; 249};
242const unsigned int cx23885_idcount = ARRAY_SIZE(cx23885_subids); 250const unsigned int cx23885_idcount = ARRAY_SIZE(cx23885_subids);
@@ -390,6 +398,7 @@ int cx23885_tuner_callback(void *priv, int component, int command, int arg)
390 case CX23885_BOARD_HAUPPAUGE_HVR1500: 398 case CX23885_BOARD_HAUPPAUGE_HVR1500:
391 case CX23885_BOARD_HAUPPAUGE_HVR1500Q: 399 case CX23885_BOARD_HAUPPAUGE_HVR1500Q:
392 case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H: 400 case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H:
401 case CX23885_BOARD_COMPRO_VIDEOMATE_E650F:
393 /* Tuner Reset Command */ 402 /* Tuner Reset Command */
394 bitmask = 0x04; 403 bitmask = 0x04;
395 break; 404 break;
@@ -530,6 +539,7 @@ void cx23885_gpio_setup(struct cx23885_dev *dev)
530 cx_set(GP0_IO, 0x000f000f); 539 cx_set(GP0_IO, 0x000f000f);
531 break; 540 break;
532 case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H: 541 case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H:
542 case CX23885_BOARD_COMPRO_VIDEOMATE_E650F:
533 /* GPIO-2 xc3028 tuner reset */ 543 /* GPIO-2 xc3028 tuner reset */
534 544
535 /* The following GPIO's are on the internal AVCore (cx25840) */ 545 /* The following GPIO's are on the internal AVCore (cx25840) */
@@ -630,6 +640,7 @@ void cx23885_card_setup(struct cx23885_dev *dev)
630 case CX23885_BOARD_HAUPPAUGE_HVR1700: 640 case CX23885_BOARD_HAUPPAUGE_HVR1700:
631 case CX23885_BOARD_HAUPPAUGE_HVR1400: 641 case CX23885_BOARD_HAUPPAUGE_HVR1400:
632 case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H: 642 case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H:
643 case CX23885_BOARD_COMPRO_VIDEOMATE_E650F:
633 default: 644 default:
634 ts2->gen_ctrl_val = 0xc; /* Serial bus + punctured clock */ 645 ts2->gen_ctrl_val = 0xc; /* Serial bus + punctured clock */
635 ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */ 646 ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */
@@ -644,6 +655,7 @@ void cx23885_card_setup(struct cx23885_dev *dev)
644 case CX23885_BOARD_HAUPPAUGE_HVR1800lp: 655 case CX23885_BOARD_HAUPPAUGE_HVR1800lp:
645 case CX23885_BOARD_HAUPPAUGE_HVR1700: 656 case CX23885_BOARD_HAUPPAUGE_HVR1700:
646 case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H: 657 case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H:
658 case CX23885_BOARD_COMPRO_VIDEOMATE_E650F:
647 request_module("cx25840"); 659 request_module("cx25840");
648 break; 660 break;
649 } 661 }
diff --git a/drivers/media/video/cx23885/cx23885-dvb.c b/drivers/media/video/cx23885/cx23885-dvb.c
index e1aac07b3158..1c454128a9df 100644
--- a/drivers/media/video/cx23885/cx23885-dvb.c
+++ b/drivers/media/video/cx23885/cx23885-dvb.c
@@ -502,6 +502,7 @@ static int dvb_register(struct cx23885_tsport *port)
502 break; 502 break;
503 } 503 }
504 case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H: 504 case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H:
505 case CX23885_BOARD_COMPRO_VIDEOMATE_E650F:
505 i2c_bus = &dev->i2c_bus[0]; 506 i2c_bus = &dev->i2c_bus[0];
506 507
507 fe0->dvb.frontend = dvb_attach(zl10353_attach, 508 fe0->dvb.frontend = dvb_attach(zl10353_attach,
diff --git a/drivers/media/video/cx23885/cx23885.h b/drivers/media/video/cx23885/cx23885.h
index 1d53f54cd943..67828029fc69 100644
--- a/drivers/media/video/cx23885/cx23885.h
+++ b/drivers/media/video/cx23885/cx23885.h
@@ -66,6 +66,7 @@
66#define CX23885_BOARD_DVICO_FUSIONHDTV_7_DUAL_EXP 10 66#define CX23885_BOARD_DVICO_FUSIONHDTV_7_DUAL_EXP 10
67#define CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP 11 67#define CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP 11
68#define CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H 12 68#define CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H 12
69#define CX23885_BOARD_COMPRO_VIDEOMATE_E650F 13
69 70
70/* Currently unsupported by the driver: PAL/H, NTSC/Kr, SECAM B/G/H/LC */ 71/* Currently unsupported by the driver: PAL/H, NTSC/Kr, SECAM B/G/H/LC */
71#define CX23885_NORMS (\ 72#define CX23885_NORMS (\
diff --git a/drivers/media/video/cx25840/Kconfig b/drivers/media/video/cx25840/Kconfig
index de515dadadc2..451133ad41ff 100644
--- a/drivers/media/video/cx25840/Kconfig
+++ b/drivers/media/video/cx25840/Kconfig
@@ -1,6 +1,6 @@
1config VIDEO_CX25840 1config VIDEO_CX25840
2 tristate "Conexant CX2584x audio/video decoders" 2 tristate "Conexant CX2584x audio/video decoders"
3 depends on VIDEO_V4L2 && I2C && EXPERIMENTAL 3 depends on VIDEO_V4L2 && I2C
4 ---help--- 4 ---help---
5 Support for the Conexant CX2584x audio/video decoders. 5 Support for the Conexant CX2584x audio/video decoders.
6 6
diff --git a/drivers/media/video/cx25840/cx25840-audio.c b/drivers/media/video/cx25840/cx25840-audio.c
index d6421e1e8f6a..d199d80ea0a3 100644
--- a/drivers/media/video/cx25840/cx25840-audio.c
+++ b/drivers/media/video/cx25840/cx25840-audio.c
@@ -25,7 +25,7 @@
25 25
26static int set_audclk_freq(struct i2c_client *client, u32 freq) 26static int set_audclk_freq(struct i2c_client *client, u32 freq)
27{ 27{
28 struct cx25840_state *state = i2c_get_clientdata(client); 28 struct cx25840_state *state = to_state(i2c_get_clientdata(client));
29 29
30 if (freq != 32000 && freq != 44100 && freq != 48000) 30 if (freq != 32000 && freq != 44100 && freq != 48000)
31 return -EINVAL; 31 return -EINVAL;
@@ -193,7 +193,7 @@ static int set_audclk_freq(struct i2c_client *client, u32 freq)
193 193
194void cx25840_audio_set_path(struct i2c_client *client) 194void cx25840_audio_set_path(struct i2c_client *client)
195{ 195{
196 struct cx25840_state *state = i2c_get_clientdata(client); 196 struct cx25840_state *state = to_state(i2c_get_clientdata(client));
197 197
198 /* assert soft reset */ 198 /* assert soft reset */
199 cx25840_and_or(client, 0x810, ~0x1, 0x01); 199 cx25840_and_or(client, 0x810, ~0x1, 0x01);
@@ -235,7 +235,7 @@ void cx25840_audio_set_path(struct i2c_client *client)
235 235
236static int get_volume(struct i2c_client *client) 236static int get_volume(struct i2c_client *client)
237{ 237{
238 struct cx25840_state *state = i2c_get_clientdata(client); 238 struct cx25840_state *state = to_state(i2c_get_clientdata(client));
239 int vol; 239 int vol;
240 240
241 if (state->unmute_volume >= 0) 241 if (state->unmute_volume >= 0)
@@ -252,7 +252,7 @@ static int get_volume(struct i2c_client *client)
252 252
253static void set_volume(struct i2c_client *client, int volume) 253static void set_volume(struct i2c_client *client, int volume)
254{ 254{
255 struct cx25840_state *state = i2c_get_clientdata(client); 255 struct cx25840_state *state = to_state(i2c_get_clientdata(client));
256 int vol; 256 int vol;
257 257
258 if (state->unmute_volume >= 0) { 258 if (state->unmute_volume >= 0) {
@@ -340,14 +340,14 @@ static void set_balance(struct i2c_client *client, int balance)
340 340
341static int get_mute(struct i2c_client *client) 341static int get_mute(struct i2c_client *client)
342{ 342{
343 struct cx25840_state *state = i2c_get_clientdata(client); 343 struct cx25840_state *state = to_state(i2c_get_clientdata(client));
344 344
345 return state->unmute_volume >= 0; 345 return state->unmute_volume >= 0;
346} 346}
347 347
348static void set_mute(struct i2c_client *client, int mute) 348static void set_mute(struct i2c_client *client, int mute)
349{ 349{
350 struct cx25840_state *state = i2c_get_clientdata(client); 350 struct cx25840_state *state = to_state(i2c_get_clientdata(client));
351 351
352 if (mute && state->unmute_volume == -1) { 352 if (mute && state->unmute_volume == -1) {
353 int vol = get_volume(client); 353 int vol = get_volume(client);
@@ -365,7 +365,7 @@ static void set_mute(struct i2c_client *client, int mute)
365 365
366int cx25840_audio(struct i2c_client *client, unsigned int cmd, void *arg) 366int cx25840_audio(struct i2c_client *client, unsigned int cmd, void *arg)
367{ 367{
368 struct cx25840_state *state = i2c_get_clientdata(client); 368 struct cx25840_state *state = to_state(i2c_get_clientdata(client));
369 struct v4l2_control *ctrl = arg; 369 struct v4l2_control *ctrl = arg;
370 int retval; 370 int retval;
371 371
diff --git a/drivers/media/video/cx25840/cx25840-core.c b/drivers/media/video/cx25840/cx25840-core.c
index 4da8cd74f00e..2ad277189da8 100644
--- a/drivers/media/video/cx25840/cx25840-core.c
+++ b/drivers/media/video/cx25840/cx25840-core.c
@@ -191,7 +191,7 @@ static void cx25840_work_handler(struct work_struct *work)
191static void cx25840_initialize(struct i2c_client *client) 191static void cx25840_initialize(struct i2c_client *client)
192{ 192{
193 DEFINE_WAIT(wait); 193 DEFINE_WAIT(wait);
194 struct cx25840_state *state = i2c_get_clientdata(client); 194 struct cx25840_state *state = to_state(i2c_get_clientdata(client));
195 struct workqueue_struct *q; 195 struct workqueue_struct *q;
196 196
197 /* datasheet startup in numbered steps, refer to page 3-77 */ 197 /* datasheet startup in numbered steps, refer to page 3-77 */
@@ -259,7 +259,7 @@ static void cx25840_initialize(struct i2c_client *client)
259static void cx23885_initialize(struct i2c_client *client) 259static void cx23885_initialize(struct i2c_client *client)
260{ 260{
261 DEFINE_WAIT(wait); 261 DEFINE_WAIT(wait);
262 struct cx25840_state *state = i2c_get_clientdata(client); 262 struct cx25840_state *state = to_state(i2c_get_clientdata(client));
263 struct workqueue_struct *q; 263 struct workqueue_struct *q;
264 264
265 /* Internal Reset */ 265 /* Internal Reset */
@@ -350,7 +350,7 @@ static void cx23885_initialize(struct i2c_client *client)
350 350
351void cx25840_std_setup(struct i2c_client *client) 351void cx25840_std_setup(struct i2c_client *client)
352{ 352{
353 struct cx25840_state *state = i2c_get_clientdata(client); 353 struct cx25840_state *state = to_state(i2c_get_clientdata(client));
354 v4l2_std_id std = state->std; 354 v4l2_std_id std = state->std;
355 int hblank, hactive, burst, vblank, vactive, sc; 355 int hblank, hactive, burst, vblank, vactive, sc;
356 int vblank656, src_decimation; 356 int vblank656, src_decimation;
@@ -497,7 +497,7 @@ void cx25840_std_setup(struct i2c_client *client)
497 497
498static void input_change(struct i2c_client *client) 498static void input_change(struct i2c_client *client)
499{ 499{
500 struct cx25840_state *state = i2c_get_clientdata(client); 500 struct cx25840_state *state = to_state(i2c_get_clientdata(client));
501 v4l2_std_id std = state->std; 501 v4l2_std_id std = state->std;
502 502
503 /* Follow step 8c and 8d of section 3.16 in the cx25840 datasheet */ 503 /* Follow step 8c and 8d of section 3.16 in the cx25840 datasheet */
@@ -551,7 +551,7 @@ static void input_change(struct i2c_client *client)
551static int set_input(struct i2c_client *client, enum cx25840_video_input vid_input, 551static int set_input(struct i2c_client *client, enum cx25840_video_input vid_input,
552 enum cx25840_audio_input aud_input) 552 enum cx25840_audio_input aud_input)
553{ 553{
554 struct cx25840_state *state = i2c_get_clientdata(client); 554 struct cx25840_state *state = to_state(i2c_get_clientdata(client));
555 u8 is_composite = (vid_input >= CX25840_COMPOSITE1 && 555 u8 is_composite = (vid_input >= CX25840_COMPOSITE1 &&
556 vid_input <= CX25840_COMPOSITE8); 556 vid_input <= CX25840_COMPOSITE8);
557 u8 reg; 557 u8 reg;
@@ -671,7 +671,7 @@ static int set_input(struct i2c_client *client, enum cx25840_video_input vid_inp
671 671
672static int set_v4lstd(struct i2c_client *client) 672static int set_v4lstd(struct i2c_client *client)
673{ 673{
674 struct cx25840_state *state = i2c_get_clientdata(client); 674 struct cx25840_state *state = to_state(i2c_get_clientdata(client));
675 u8 fmt = 0; /* zero is autodetect */ 675 u8 fmt = 0; /* zero is autodetect */
676 u8 pal_m = 0; 676 u8 pal_m = 0;
677 677
@@ -720,9 +720,10 @@ static int set_v4lstd(struct i2c_client *client)
720 720
721/* ----------------------------------------------------------------------- */ 721/* ----------------------------------------------------------------------- */
722 722
723static int set_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl) 723static int cx25840_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
724{ 724{
725 struct cx25840_state *state = i2c_get_clientdata(client); 725 struct cx25840_state *state = to_state(sd);
726 struct i2c_client *client = v4l2_get_subdevdata(sd);
726 727
727 switch (ctrl->id) { 728 switch (ctrl->id) {
728 case CX25840_CID_ENABLE_PVR150_WORKAROUND: 729 case CX25840_CID_ENABLE_PVR150_WORKAROUND:
@@ -786,9 +787,10 @@ static int set_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl)
786 return 0; 787 return 0;
787} 788}
788 789
789static int get_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl) 790static int cx25840_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
790{ 791{
791 struct cx25840_state *state = i2c_get_clientdata(client); 792 struct cx25840_state *state = to_state(sd);
793 struct i2c_client *client = v4l2_get_subdevdata(sd);
792 794
793 switch (ctrl->id) { 795 switch (ctrl->id) {
794 case CX25840_CID_ENABLE_PVR150_WORKAROUND: 796 case CX25840_CID_ENABLE_PVR150_WORKAROUND:
@@ -823,21 +825,23 @@ static int get_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl)
823 825
824/* ----------------------------------------------------------------------- */ 826/* ----------------------------------------------------------------------- */
825 827
826static int get_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt) 828static int cx25840_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
827{ 829{
830 struct i2c_client *client = v4l2_get_subdevdata(sd);
831
828 switch (fmt->type) { 832 switch (fmt->type) {
829 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: 833 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
830 return cx25840_vbi(client, VIDIOC_G_FMT, fmt); 834 return cx25840_vbi(client, VIDIOC_G_FMT, fmt);
831 default: 835 default:
832 return -EINVAL; 836 return -EINVAL;
833 } 837 }
834
835 return 0; 838 return 0;
836} 839}
837 840
838static int set_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt) 841static int cx25840_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
839{ 842{
840 struct cx25840_state *state = i2c_get_clientdata(client); 843 struct cx25840_state *state = to_state(sd);
844 struct i2c_client *client = v4l2_get_subdevdata(sd);
841 struct v4l2_pix_format *pix; 845 struct v4l2_pix_format *pix;
842 int HSC, VSC, Vsrc, Hsrc, filter, Vlines; 846 int HSC, VSC, Vsrc, Hsrc, filter, Vlines;
843 int is_50Hz = !(state->std & V4L2_STD_525_60); 847 int is_50Hz = !(state->std & V4L2_STD_525_60);
@@ -914,7 +918,7 @@ static void log_video_status(struct i2c_client *client)
914 "0xD", "0xE", "0xF" 918 "0xD", "0xE", "0xF"
915 }; 919 };
916 920
917 struct cx25840_state *state = i2c_get_clientdata(client); 921 struct cx25840_state *state = to_state(i2c_get_clientdata(client));
918 u8 vidfmt_sel = cx25840_read(client, 0x400) & 0xf; 922 u8 vidfmt_sel = cx25840_read(client, 0x400) & 0xf;
919 u8 gen_stat1 = cx25840_read(client, 0x40d); 923 u8 gen_stat1 = cx25840_read(client, 0x40d);
920 u8 gen_stat2 = cx25840_read(client, 0x40e); 924 u8 gen_stat2 = cx25840_read(client, 0x40e);
@@ -944,7 +948,7 @@ static void log_video_status(struct i2c_client *client)
944 948
945static void log_audio_status(struct i2c_client *client) 949static void log_audio_status(struct i2c_client *client)
946{ 950{
947 struct cx25840_state *state = i2c_get_clientdata(client); 951 struct cx25840_state *state = to_state(i2c_get_clientdata(client));
948 u8 download_ctl = cx25840_read(client, 0x803); 952 u8 download_ctl = cx25840_read(client, 0x803);
949 u8 mod_det_stat0 = cx25840_read(client, 0x804); 953 u8 mod_det_stat0 = cx25840_read(client, 0x804);
950 u8 mod_det_stat1 = cx25840_read(client, 0x805); 954 u8 mod_det_stat1 = cx25840_read(client, 0x805);
@@ -1097,21 +1101,12 @@ static void log_audio_status(struct i2c_client *client)
1097 1101
1098/* ----------------------------------------------------------------------- */ 1102/* ----------------------------------------------------------------------- */
1099 1103
1100static int cx25840_command(struct i2c_client *client, unsigned int cmd, 1104static int cx25840_init(struct v4l2_subdev *sd, u32 val)
1101 void *arg)
1102{ 1105{
1103 struct cx25840_state *state = i2c_get_clientdata(client); 1106 struct cx25840_state *state = to_state(sd);
1104 struct v4l2_tuner *vt = arg; 1107 struct i2c_client *client = v4l2_get_subdevdata(sd);
1105 struct v4l2_routing *route = arg;
1106
1107 /* ignore these commands */
1108 switch (cmd) {
1109 case TUNER_SET_TYPE_ADDR:
1110 return 0;
1111 }
1112 1108
1113 if (!state->is_initialized) { 1109 if (!state->is_initialized) {
1114 v4l_dbg(1, cx25840_debug, client, "cmd %08x triggered fw load\n", cmd);
1115 /* initialize on first use */ 1110 /* initialize on first use */
1116 state->is_initialized = 1; 1111 state->is_initialized = 1;
1117 if (state->is_cx25836) 1112 if (state->is_cx25836)
@@ -1121,50 +1116,69 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd,
1121 else 1116 else
1122 cx25840_initialize(client); 1117 cx25840_initialize(client);
1123 } 1118 }
1119 return 0;
1120}
1124 1121
1125 switch (cmd) {
1126#ifdef CONFIG_VIDEO_ADV_DEBUG 1122#ifdef CONFIG_VIDEO_ADV_DEBUG
1127 /* ioctls to allow direct access to the 1123static int cx25840_g_register(struct v4l2_subdev *sd, struct v4l2_register *reg)
1128 * cx25840 registers for testing */ 1124{
1129 case VIDIOC_DBG_G_REGISTER: 1125 struct i2c_client *client = v4l2_get_subdevdata(sd);
1130 case VIDIOC_DBG_S_REGISTER:
1131 {
1132 struct v4l2_register *reg = arg;
1133
1134 if (!v4l2_chip_match_i2c_client(client, reg->match_type, reg->match_chip))
1135 return -EINVAL;
1136 if (!capable(CAP_SYS_ADMIN))
1137 return -EPERM;
1138 1126
1139 if (cmd == VIDIOC_DBG_G_REGISTER) 1127 if (!v4l2_chip_match_i2c_client(client,
1140 reg->val = cx25840_read(client, reg->reg & 0x0fff); 1128 reg->match_type, reg->match_chip))
1141 else 1129 return -EINVAL;
1142 cx25840_write(client, reg->reg & 0x0fff, reg->val & 0xff); 1130 if (!capable(CAP_SYS_ADMIN))
1143 break; 1131 return -EPERM;
1144 } 1132 reg->val = cx25840_read(client, reg->reg & 0x0fff);
1133 return 0;
1134}
1135
1136static int cx25840_s_register(struct v4l2_subdev *sd, struct v4l2_register *reg)
1137{
1138 struct i2c_client *client = v4l2_get_subdevdata(sd);
1139
1140 if (!v4l2_chip_match_i2c_client(client,
1141 reg->match_type, reg->match_chip))
1142 return -EINVAL;
1143 if (!capable(CAP_SYS_ADMIN))
1144 return -EPERM;
1145 cx25840_write(client, reg->reg & 0x0fff, reg->val & 0xff);
1146 return 0;
1147}
1145#endif 1148#endif
1146 1149
1147 case VIDIOC_INT_DECODE_VBI_LINE: 1150static int cx25840_decode_vbi_line(struct v4l2_subdev *sd, struct v4l2_decode_vbi_line *vbi)
1148 return cx25840_vbi(client, cmd, arg); 1151{
1152 struct i2c_client *client = v4l2_get_subdevdata(sd);
1149 1153
1150 case VIDIOC_INT_AUDIO_CLOCK_FREQ: 1154 return cx25840_vbi(client, VIDIOC_INT_DECODE_VBI_LINE, vbi);
1151 return cx25840_audio(client, cmd, arg); 1155}
1156
1157static int cx25840_s_clock_freq(struct v4l2_subdev *sd, u32 freq)
1158{
1159 struct i2c_client *client = v4l2_get_subdevdata(sd);
1160
1161 return cx25840_audio(client, VIDIOC_INT_AUDIO_CLOCK_FREQ, &freq);
1162}
1163
1164static int cx25840_s_stream(struct v4l2_subdev *sd, int enable)
1165{
1166 struct cx25840_state *state = to_state(sd);
1167 struct i2c_client *client = v4l2_get_subdevdata(sd);
1152 1168
1153 case VIDIOC_STREAMON: 1169 v4l_dbg(1, cx25840_debug, client, "%s output\n",
1154 v4l_dbg(1, cx25840_debug, client, "enable output\n"); 1170 enable ? "enable" : "disable");
1171 if (enable) {
1155 if (state->is_cx23885) { 1172 if (state->is_cx23885) {
1156 u8 v = (cx25840_read(client, 0x421) | 0x0b); 1173 u8 v = (cx25840_read(client, 0x421) | 0x0b);
1157 cx25840_write(client, 0x421, v); 1174 cx25840_write(client, 0x421, v);
1158 } else { 1175 } else {
1159 cx25840_write(client, 0x115, 1176 cx25840_write(client, 0x115,
1160 state->is_cx25836 ? 0x0c : 0x8c); 1177 state->is_cx25836 ? 0x0c : 0x8c);
1161 cx25840_write(client, 0x116, 1178 cx25840_write(client, 0x116,
1162 state->is_cx25836 ? 0x04 : 0x07); 1179 state->is_cx25836 ? 0x04 : 0x07);
1163 } 1180 }
1164 break; 1181 } else {
1165
1166 case VIDIOC_STREAMOFF:
1167 v4l_dbg(1, cx25840_debug, client, "disable output\n");
1168 if (state->is_cx23885) { 1182 if (state->is_cx23885) {
1169 u8 v = cx25840_read(client, 0x421) & ~(0x0b); 1183 u8 v = cx25840_read(client, 0x421) & ~(0x0b);
1170 cx25840_write(client, 0x421, v); 1184 cx25840_write(client, 0x421, v);
@@ -1172,133 +1186,136 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd,
1172 cx25840_write(client, 0x115, 0x00); 1186 cx25840_write(client, 0x115, 0x00);
1173 cx25840_write(client, 0x116, 0x00); 1187 cx25840_write(client, 0x116, 0x00);
1174 } 1188 }
1175 break; 1189 }
1190 return 0;
1191}
1176 1192
1177 case VIDIOC_LOG_STATUS: 1193static int cx25840_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
1178 log_video_status(client); 1194{
1179 if (!state->is_cx25836) 1195 struct cx25840_state *state = to_state(sd);
1180 log_audio_status(client);
1181 break;
1182 1196
1183 case VIDIOC_G_CTRL: 1197 switch (qc->id) {
1184 return get_v4lctrl(client, (struct v4l2_control *)arg); 1198 case V4L2_CID_BRIGHTNESS:
1199 case V4L2_CID_CONTRAST:
1200 case V4L2_CID_SATURATION:
1201 case V4L2_CID_HUE:
1202 return v4l2_ctrl_query_fill_std(qc);
1203 default:
1204 break;
1205 }
1206 if (state->is_cx25836)
1207 return -EINVAL;
1185 1208
1186 case VIDIOC_S_CTRL: 1209 switch (qc->id) {
1187 return set_v4lctrl(client, (struct v4l2_control *)arg); 1210 case V4L2_CID_AUDIO_VOLUME:
1211 return v4l2_ctrl_query_fill(qc, 0, 65535,
1212 65535 / 100, state->default_volume);
1213 case V4L2_CID_AUDIO_MUTE:
1214 case V4L2_CID_AUDIO_BALANCE:
1215 case V4L2_CID_AUDIO_BASS:
1216 case V4L2_CID_AUDIO_TREBLE:
1217 return v4l2_ctrl_query_fill_std(qc);
1218 default:
1219 return -EINVAL;
1220 }
1221 return -EINVAL;
1222}
1188 1223
1189 case VIDIOC_QUERYCTRL: 1224static int cx25840_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
1190 { 1225{
1191 struct v4l2_queryctrl *qc = arg; 1226 struct cx25840_state *state = to_state(sd);
1227 struct i2c_client *client = v4l2_get_subdevdata(sd);
1192 1228
1193 switch (qc->id) { 1229 if (state->radio == 0 && state->std == std)
1194 case V4L2_CID_BRIGHTNESS: 1230 return 0;
1195 case V4L2_CID_CONTRAST: 1231 state->radio = 0;
1196 case V4L2_CID_SATURATION: 1232 state->std = std;
1197 case V4L2_CID_HUE: 1233 return set_v4lstd(client);
1198 return v4l2_ctrl_query_fill_std(qc); 1234}
1199 default:
1200 break;
1201 }
1202 if (state->is_cx25836)
1203 return -EINVAL;
1204 1235
1205 switch (qc->id) { 1236static int cx25840_s_radio(struct v4l2_subdev *sd)
1206 case V4L2_CID_AUDIO_VOLUME: 1237{
1207 return v4l2_ctrl_query_fill(qc, 0, 65535, 1238 struct cx25840_state *state = to_state(sd);
1208 65535 / 100, state->default_volume);
1209 case V4L2_CID_AUDIO_MUTE:
1210 case V4L2_CID_AUDIO_BALANCE:
1211 case V4L2_CID_AUDIO_BASS:
1212 case V4L2_CID_AUDIO_TREBLE:
1213 return v4l2_ctrl_query_fill_std(qc);
1214 default:
1215 return -EINVAL;
1216 }
1217 return -EINVAL;
1218 }
1219 1239
1220 case VIDIOC_G_STD: 1240 state->radio = 1;
1221 *(v4l2_std_id *)arg = state->std; 1241 return 0;
1222 break; 1242}
1223 1243
1224 case VIDIOC_S_STD: 1244static int cx25840_s_video_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
1225 if (state->radio == 0 && state->std == *(v4l2_std_id *)arg) 1245{
1226 return 0; 1246 struct cx25840_state *state = to_state(sd);
1227 state->radio = 0; 1247 struct i2c_client *client = v4l2_get_subdevdata(sd);
1228 state->std = *(v4l2_std_id *)arg;
1229 return set_v4lstd(client);
1230 1248
1231 case AUDC_SET_RADIO: 1249 return set_input(client, route->input, state->aud_input);
1232 state->radio = 1; 1250}
1233 break;
1234 1251
1235 case VIDIOC_INT_G_VIDEO_ROUTING: 1252static int cx25840_s_audio_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
1236 route->input = state->vid_input; 1253{
1237 route->output = 0; 1254 struct cx25840_state *state = to_state(sd);
1238 break; 1255 struct i2c_client *client = v4l2_get_subdevdata(sd);
1239 1256
1240 case VIDIOC_INT_S_VIDEO_ROUTING: 1257 if (state->is_cx25836)
1241 return set_input(client, route->input, state->aud_input); 1258 return -EINVAL;
1259 return set_input(client, state->vid_input, route->input);
1260}
1242 1261
1243 case VIDIOC_INT_G_AUDIO_ROUTING: 1262static int cx25840_s_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *freq)
1244 if (state->is_cx25836) 1263{
1245 return -EINVAL; 1264 struct cx25840_state *state = to_state(sd);
1246 route->input = state->aud_input; 1265 struct i2c_client *client = v4l2_get_subdevdata(sd);
1247 route->output = 0;
1248 break;
1249 1266
1250 case VIDIOC_INT_S_AUDIO_ROUTING: 1267 if (!state->is_cx25836)
1251 if (state->is_cx25836) 1268 input_change(client);
1252 return -EINVAL; 1269 return 0;
1253 return set_input(client, state->vid_input, route->input); 1270}
1254 1271
1255 case VIDIOC_S_FREQUENCY: 1272static int cx25840_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
1256 if (!state->is_cx25836) { 1273{
1257 input_change(client); 1274 struct cx25840_state *state = to_state(sd);
1258 } 1275 struct i2c_client *client = v4l2_get_subdevdata(sd);
1259 break; 1276 u8 vpres = cx25840_read(client, 0x40e) & 0x20;
1277 u8 mode;
1278 int val = 0;
1260 1279
1261 case VIDIOC_G_TUNER: 1280 if (state->radio)
1262 { 1281 return 0;
1263 u8 vpres = cx25840_read(client, 0x40e) & 0x20;
1264 u8 mode;
1265 int val = 0;
1266 1282
1267 if (state->radio) 1283 vt->signal = vpres ? 0xffff : 0x0;
1268 break; 1284 if (state->is_cx25836)
1285 return 0;
1269 1286
1270 vt->signal = vpres ? 0xffff : 0x0; 1287 vt->capability |=
1271 if (state->is_cx25836) 1288 V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LANG1 |
1272 break; 1289 V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP;
1273 1290
1274 vt->capability |= 1291 mode = cx25840_read(client, 0x804);
1275 V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LANG1 |
1276 V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP;
1277 1292
1278 mode = cx25840_read(client, 0x804); 1293 /* get rxsubchans and audmode */
1294 if ((mode & 0xf) == 1)
1295 val |= V4L2_TUNER_SUB_STEREO;
1296 else
1297 val |= V4L2_TUNER_SUB_MONO;
1279 1298
1280 /* get rxsubchans and audmode */ 1299 if (mode == 2 || mode == 4)
1281 if ((mode & 0xf) == 1) 1300 val = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
1282 val |= V4L2_TUNER_SUB_STEREO;
1283 else
1284 val |= V4L2_TUNER_SUB_MONO;
1285 1301
1286 if (mode == 2 || mode == 4) 1302 if (mode & 0x10)
1287 val = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2; 1303 val |= V4L2_TUNER_SUB_SAP;
1288 1304
1289 if (mode & 0x10) 1305 vt->rxsubchans = val;
1290 val |= V4L2_TUNER_SUB_SAP; 1306 vt->audmode = state->audmode;
1307 return 0;
1308}
1291 1309
1292 vt->rxsubchans = val; 1310static int cx25840_s_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
1293 vt->audmode = state->audmode; 1311{
1294 break; 1312 struct cx25840_state *state = to_state(sd);
1295 } 1313 struct i2c_client *client = v4l2_get_subdevdata(sd);
1296 1314
1297 case VIDIOC_S_TUNER: 1315 if (state->radio || state->is_cx25836)
1298 if (state->radio || state->is_cx25836) 1316 return 0;
1299 break;
1300 1317
1301 switch (vt->audmode) { 1318 switch (vt->audmode) {
1302 case V4L2_TUNER_MODE_MONO: 1319 case V4L2_TUNER_MODE_MONO:
1303 /* mono -> mono 1320 /* mono -> mono
1304 stereo -> mono 1321 stereo -> mono
@@ -1326,41 +1343,100 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd,
1326 break; 1343 break;
1327 default: 1344 default:
1328 return -EINVAL; 1345 return -EINVAL;
1329 } 1346 }
1330 state->audmode = vt->audmode; 1347 state->audmode = vt->audmode;
1331 break; 1348 return 0;
1349}
1332 1350
1333 case VIDIOC_G_FMT: 1351static int cx25840_reset(struct v4l2_subdev *sd, u32 val)
1334 return get_v4lfmt(client, (struct v4l2_format *)arg); 1352{
1353 struct cx25840_state *state = to_state(sd);
1354 struct i2c_client *client = v4l2_get_subdevdata(sd);
1335 1355
1336 case VIDIOC_S_FMT: 1356 if (state->is_cx25836)
1337 return set_v4lfmt(client, (struct v4l2_format *)arg); 1357 cx25836_initialize(client);
1358 else if (state->is_cx23885)
1359 cx23885_initialize(client);
1360 else
1361 cx25840_initialize(client);
1362 return 0;
1363}
1338 1364
1339 case VIDIOC_INT_RESET: 1365static int cx25840_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_chip_ident *chip)
1340 if (state->is_cx25836) 1366{
1341 cx25836_initialize(client); 1367 struct cx25840_state *state = to_state(sd);
1342 else if (state->is_cx23885) 1368 struct i2c_client *client = v4l2_get_subdevdata(sd);
1343 cx23885_initialize(client);
1344 else
1345 cx25840_initialize(client);
1346 break;
1347 1369
1348 case VIDIOC_G_CHIP_IDENT: 1370 return v4l2_chip_ident_i2c_client(client, chip, state->id, state->rev);
1349 return v4l2_chip_ident_i2c_client(client, arg, state->id, state->rev); 1371}
1350 1372
1351 default: 1373static int cx25840_log_status(struct v4l2_subdev *sd)
1352 return -EINVAL; 1374{
1353 } 1375 struct cx25840_state *state = to_state(sd);
1376 struct i2c_client *client = v4l2_get_subdevdata(sd);
1354 1377
1378 log_video_status(client);
1379 if (!state->is_cx25836)
1380 log_audio_status(client);
1355 return 0; 1381 return 0;
1356} 1382}
1357 1383
1384static int cx25840_command(struct i2c_client *client, unsigned cmd, void *arg)
1385{
1386 return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
1387}
1388
1389/* ----------------------------------------------------------------------- */
1390
1391static const struct v4l2_subdev_core_ops cx25840_core_ops = {
1392 .log_status = cx25840_log_status,
1393 .g_chip_ident = cx25840_g_chip_ident,
1394 .g_ctrl = cx25840_g_ctrl,
1395 .s_ctrl = cx25840_s_ctrl,
1396 .queryctrl = cx25840_queryctrl,
1397 .reset = cx25840_reset,
1398 .init = cx25840_init,
1399#ifdef CONFIG_VIDEO_ADV_DEBUG
1400 .g_register = cx25840_g_register,
1401 .s_register = cx25840_s_register,
1402#endif
1403};
1404
1405static const struct v4l2_subdev_tuner_ops cx25840_tuner_ops = {
1406 .s_frequency = cx25840_s_frequency,
1407 .s_std = cx25840_s_std,
1408 .s_radio = cx25840_s_radio,
1409 .g_tuner = cx25840_g_tuner,
1410 .s_tuner = cx25840_s_tuner,
1411};
1412
1413static const struct v4l2_subdev_audio_ops cx25840_audio_ops = {
1414 .s_clock_freq = cx25840_s_clock_freq,
1415 .s_routing = cx25840_s_audio_routing,
1416};
1417
1418static const struct v4l2_subdev_video_ops cx25840_video_ops = {
1419 .s_routing = cx25840_s_video_routing,
1420 .g_fmt = cx25840_g_fmt,
1421 .s_fmt = cx25840_s_fmt,
1422 .decode_vbi_line = cx25840_decode_vbi_line,
1423 .s_stream = cx25840_s_stream,
1424};
1425
1426static const struct v4l2_subdev_ops cx25840_ops = {
1427 .core = &cx25840_core_ops,
1428 .tuner = &cx25840_tuner_ops,
1429 .audio = &cx25840_audio_ops,
1430 .video = &cx25840_video_ops,
1431};
1432
1358/* ----------------------------------------------------------------------- */ 1433/* ----------------------------------------------------------------------- */
1359 1434
1360static int cx25840_probe(struct i2c_client *client, 1435static int cx25840_probe(struct i2c_client *client,
1361 const struct i2c_device_id *did) 1436 const struct i2c_device_id *did)
1362{ 1437{
1363 struct cx25840_state *state; 1438 struct cx25840_state *state;
1439 struct v4l2_subdev *sd;
1364 u32 id; 1440 u32 id;
1365 u16 device_id; 1441 u16 device_id;
1366 1442
@@ -1392,10 +1468,11 @@ static int cx25840_probe(struct i2c_client *client,
1392 } 1468 }
1393 1469
1394 state = kzalloc(sizeof(struct cx25840_state), GFP_KERNEL); 1470 state = kzalloc(sizeof(struct cx25840_state), GFP_KERNEL);
1395 if (state == NULL) { 1471 if (state == NULL)
1396 return -ENOMEM; 1472 return -ENOMEM;
1397 }
1398 1473
1474 sd = &state->sd;
1475 v4l2_i2c_subdev_init(sd, client, &cx25840_ops);
1399 /* Note: revision '(device_id & 0x0f) == 2' was never built. The 1476 /* Note: revision '(device_id & 0x0f) == 2' was never built. The
1400 marking skips from 0x1 == 22 to 0x3 == 23. */ 1477 marking skips from 0x1 == 22 to 0x3 == 23. */
1401 v4l_info(client, "cx25%3x-2%x found @ 0x%x (%s)\n", 1478 v4l_info(client, "cx25%3x-2%x found @ 0x%x (%s)\n",
@@ -1403,7 +1480,6 @@ static int cx25840_probe(struct i2c_client *client,
1403 (device_id & 0x0f) < 3 ? (device_id & 0x0f) + 1 : (device_id & 0x0f), 1480 (device_id & 0x0f) < 3 ? (device_id & 0x0f) + 1 : (device_id & 0x0f),
1404 client->addr << 1, client->adapter->name); 1481 client->addr << 1, client->adapter->name);
1405 1482
1406 i2c_set_clientdata(client, state);
1407 state->c = client; 1483 state->c = client;
1408 state->is_cx25836 = ((device_id & 0xff00) == 0x8300); 1484 state->is_cx25836 = ((device_id & 0xff00) == 0x8300);
1409 state->is_cx23885 = (device_id == 0x0000) || (device_id == 0x1313); 1485 state->is_cx23885 = (device_id == 0x0000) || (device_id == 0x1313);
@@ -1430,7 +1506,10 @@ static int cx25840_probe(struct i2c_client *client,
1430 1506
1431static int cx25840_remove(struct i2c_client *client) 1507static int cx25840_remove(struct i2c_client *client)
1432{ 1508{
1433 kfree(i2c_get_clientdata(client)); 1509 struct v4l2_subdev *sd = i2c_get_clientdata(client);
1510
1511 v4l2_device_unregister_subdev(sd);
1512 kfree(to_state(sd));
1434 return 0; 1513 return 0;
1435} 1514}
1436 1515
diff --git a/drivers/media/video/cx25840/cx25840-core.h b/drivers/media/video/cx25840/cx25840-core.h
index b87337e590b4..be0558277ca3 100644
--- a/drivers/media/video/cx25840/cx25840-core.h
+++ b/drivers/media/video/cx25840/cx25840-core.h
@@ -22,6 +22,7 @@
22 22
23 23
24#include <linux/videodev2.h> 24#include <linux/videodev2.h>
25#include <media/v4l2-device.h>
25#include <linux/i2c.h> 26#include <linux/i2c.h>
26 27
27/* ENABLE_PVR150_WORKAROUND activates a workaround for a hardware bug that is 28/* ENABLE_PVR150_WORKAROUND activates a workaround for a hardware bug that is
@@ -34,6 +35,7 @@
34 35
35struct cx25840_state { 36struct cx25840_state {
36 struct i2c_client *c; 37 struct i2c_client *c;
38 struct v4l2_subdev sd;
37 int pvr150_workaround; 39 int pvr150_workaround;
38 int radio; 40 int radio;
39 v4l2_std_id std; 41 v4l2_std_id std;
@@ -53,6 +55,11 @@ struct cx25840_state {
53 struct work_struct fw_work; /* work entry for fw load */ 55 struct work_struct fw_work; /* work entry for fw load */
54}; 56};
55 57
58static inline struct cx25840_state *to_state(struct v4l2_subdev *sd)
59{
60 return container_of(sd, struct cx25840_state, sd);
61}
62
56/* ----------------------------------------------------------------------- */ 63/* ----------------------------------------------------------------------- */
57/* cx25850-core.c */ 64/* cx25850-core.c */
58int cx25840_write(struct i2c_client *client, u16 addr, u8 value); 65int 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 8d489a4b9570..0b2dceb74108 100644
--- a/drivers/media/video/cx25840/cx25840-firmware.c
+++ b/drivers/media/video/cx25840/cx25840-firmware.c
@@ -91,7 +91,7 @@ static int fw_write(struct i2c_client *client, const u8 *data, int size)
91 91
92int cx25840_loadfw(struct i2c_client *client) 92int cx25840_loadfw(struct i2c_client *client)
93{ 93{
94 struct cx25840_state *state = i2c_get_clientdata(client); 94 struct cx25840_state *state = to_state(i2c_get_clientdata(client));
95 const struct firmware *fw = NULL; 95 const struct firmware *fw = NULL;
96 u8 buffer[FWSEND]; 96 u8 buffer[FWSEND];
97 const u8 *ptr; 97 const u8 *ptr;
diff --git a/drivers/media/video/cx25840/cx25840-vbi.c b/drivers/media/video/cx25840/cx25840-vbi.c
index 58e6ef1c28a0..03f09b288eb8 100644
--- a/drivers/media/video/cx25840/cx25840-vbi.c
+++ b/drivers/media/video/cx25840/cx25840-vbi.c
@@ -84,7 +84,7 @@ static int decode_vps(u8 * dst, u8 * p)
84 84
85int cx25840_vbi(struct i2c_client *client, unsigned int cmd, void *arg) 85int cx25840_vbi(struct i2c_client *client, unsigned int cmd, void *arg)
86{ 86{
87 struct cx25840_state *state = i2c_get_clientdata(client); 87 struct cx25840_state *state = to_state(i2c_get_clientdata(client));
88 struct v4l2_format *fmt; 88 struct v4l2_format *fmt;
89 struct v4l2_sliced_vbi_format *svbi; 89 struct v4l2_sliced_vbi_format *svbi;
90 90
diff --git a/drivers/media/video/cx88/cx88-alsa.c b/drivers/media/video/cx88/cx88-alsa.c
index 06f171ab6149..66c755c116dc 100644
--- a/drivers/media/video/cx88/cx88-alsa.c
+++ b/drivers/media/video/cx88/cx88-alsa.c
@@ -742,7 +742,6 @@ static int __devinit snd_cx88_create(struct snd_card *card,
742 core = cx88_core_get(pci); 742 core = cx88_core_get(pci);
743 if (NULL == core) { 743 if (NULL == core) {
744 err = -EINVAL; 744 err = -EINVAL;
745 kfree (chip);
746 return err; 745 return err;
747 } 746 }
748 747
@@ -812,7 +811,7 @@ static int __devinit cx88_audio_initdev(struct pci_dev *pci,
812 811
813 err = snd_cx88_create(card, pci, &chip); 812 err = snd_cx88_create(card, pci, &chip);
814 if (err < 0) 813 if (err < 0)
815 return (err); 814 goto error;
816 815
817 err = snd_cx88_pcm(chip, 0, "CX88 Digital"); 816 err = snd_cx88_pcm(chip, 0, "CX88 Digital");
818 if (err < 0) 817 if (err < 0)
diff --git a/drivers/media/video/cx88/cx88-blackbird.c b/drivers/media/video/cx88/cx88-blackbird.c
index d3ae5b4dfca7..e162a70748c5 100644
--- a/drivers/media/video/cx88/cx88-blackbird.c
+++ b/drivers/media/video/cx88/cx88-blackbird.c
@@ -3,7 +3,7 @@
3 * Support for a cx23416 mpeg encoder via cx2388x host port. 3 * Support for a cx23416 mpeg encoder via cx2388x host port.
4 * "blackbird" reference design. 4 * "blackbird" reference design.
5 * 5 *
6 * (c) 2004 Jelle Foks <jelle@foks.8m.com> 6 * (c) 2004 Jelle Foks <jelle@foks.us>
7 * (c) 2004 Gerd Knorr <kraxel@bytesex.org> 7 * (c) 2004 Gerd Knorr <kraxel@bytesex.org>
8 * 8 *
9 * (c) 2005-2006 Mauro Carvalho Chehab <mchehab@infradead.org> 9 * (c) 2005-2006 Mauro Carvalho Chehab <mchehab@infradead.org>
@@ -39,7 +39,7 @@
39#include "cx88.h" 39#include "cx88.h"
40 40
41MODULE_DESCRIPTION("driver for cx2388x/cx23416 based mpeg encoder cards"); 41MODULE_DESCRIPTION("driver for cx2388x/cx23416 based mpeg encoder cards");
42MODULE_AUTHOR("Jelle Foks <jelle@foks.8m.com>, Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]"); 42MODULE_AUTHOR("Jelle Foks <jelle@foks.us>, Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
43MODULE_LICENSE("GPL"); 43MODULE_LICENSE("GPL");
44 44
45static unsigned int mpegbufs = 32; 45static unsigned int mpegbufs = 32;
@@ -1244,8 +1244,16 @@ static int cx8802_blackbird_advise_acquire(struct cx8802_driver *drv)
1244 * We're being given access to re-arrange the GPIOs. 1244 * We're being given access to re-arrange the GPIOs.
1245 * Take the bus off the cx22702 and put the cx23416 on it. 1245 * Take the bus off the cx22702 and put the cx23416 on it.
1246 */ 1246 */
1247 cx_clear(MO_GP0_IO, 0x00000080); /* cx22702 in reset */ 1247 /* Toggle reset on cx22702 leaving i2c active */
1248 cx_set(MO_GP0_IO, 0x00000004); /* Disable the cx22702 */ 1248 cx_set(MO_GP0_IO, 0x00000080);
1249 udelay(1000);
1250 cx_clear(MO_GP0_IO, 0x00000080);
1251 udelay(50);
1252 cx_set(MO_GP0_IO, 0x00000080);
1253 udelay(1000);
1254 /* tri-state the cx22702 pins */
1255 cx_set(MO_GP0_IO, 0x00000004);
1256 udelay(1000);
1249 break; 1257 break;
1250 default: 1258 default:
1251 err = -ENODEV; 1259 err = -ENODEV;
diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c
index 5bcbb4cc7c2a..733ede34f93a 100644
--- a/drivers/media/video/cx88/cx88-cards.c
+++ b/drivers/media/video/cx88/cx88-cards.c
@@ -1237,7 +1237,6 @@ static const struct cx88_board cx88_boards[] = {
1237 }, 1237 },
1238 }, 1238 },
1239 [CX88_BOARD_WINFAST_DTV2000H] = { 1239 [CX88_BOARD_WINFAST_DTV2000H] = {
1240 /* video inputs and radio still in testing */
1241 .name = "WinFast DTV2000 H", 1240 .name = "WinFast DTV2000 H",
1242 .tuner_type = TUNER_PHILIPS_FMD1216ME_MK3, 1241 .tuner_type = TUNER_PHILIPS_FMD1216ME_MK3,
1243 .radio_type = UNSET, 1242 .radio_type = UNSET,
@@ -1251,7 +1250,35 @@ static const struct cx88_board cx88_boards[] = {
1251 .gpio1 = 0x00008203, 1250 .gpio1 = 0x00008203,
1252 .gpio2 = 0x00017304, 1251 .gpio2 = 0x00017304,
1253 .gpio3 = 0x02000000, 1252 .gpio3 = 0x02000000,
1253 }, {
1254 .type = CX88_VMUX_COMPOSITE1,
1255 .vmux = 1,
1256 .gpio0 = 0x0001d701,
1257 .gpio1 = 0x0000b207,
1258 .gpio2 = 0x0001d701,
1259 .gpio3 = 0x02000000,
1260 }, {
1261 .type = CX88_VMUX_COMPOSITE2,
1262 .vmux = 2,
1263 .gpio0 = 0x0001d503,
1264 .gpio1 = 0x0000b207,
1265 .gpio2 = 0x0001d503,
1266 .gpio3 = 0x02000000,
1267 }, {
1268 .type = CX88_VMUX_SVIDEO,
1269 .vmux = 3,
1270 .gpio0 = 0x0001d701,
1271 .gpio1 = 0x0000b207,
1272 .gpio2 = 0x0001d701,
1273 .gpio3 = 0x02000000,
1254 }}, 1274 }},
1275 .radio = {
1276 .type = CX88_RADIO,
1277 .gpio0 = 0x00015702,
1278 .gpio1 = 0x0000f207,
1279 .gpio2 = 0x00015702,
1280 .gpio3 = 0x02000000,
1281 },
1255 .mpeg = CX88_MPEG_DVB, 1282 .mpeg = CX88_MPEG_DVB,
1256 }, 1283 },
1257 [CX88_BOARD_GENIATECH_DVBS] = { 1284 [CX88_BOARD_GENIATECH_DVBS] = {
@@ -1847,6 +1874,18 @@ static const struct cx88_board cx88_boards[] = {
1847 } }, 1874 } },
1848 .mpeg = CX88_MPEG_DVB, 1875 .mpeg = CX88_MPEG_DVB,
1849 }, 1876 },
1877 [CX88_BOARD_TBS_8910] = {
1878 .name = "TBS 8910 DVB-S",
1879 .tuner_type = UNSET,
1880 .radio_type = UNSET,
1881 .tuner_addr = ADDR_UNSET,
1882 .radio_addr = ADDR_UNSET,
1883 .input = {{
1884 .type = CX88_VMUX_DVB,
1885 .vmux = 0,
1886 } },
1887 .mpeg = CX88_MPEG_DVB,
1888 },
1850 [CX88_BOARD_TBS_8920] = { 1889 [CX88_BOARD_TBS_8920] = {
1851 .name = "TBS 8920 DVB-S/S2", 1890 .name = "TBS 8920 DVB-S/S2",
1852 .tuner_type = TUNER_ABSENT, 1891 .tuner_type = TUNER_ABSENT,
@@ -1859,6 +1898,18 @@ static const struct cx88_board cx88_boards[] = {
1859 } }, 1898 } },
1860 .mpeg = CX88_MPEG_DVB, 1899 .mpeg = CX88_MPEG_DVB,
1861 }, 1900 },
1901 [CX88_BOARD_PROF_6200] = {
1902 .name = "Prof 6200 DVB-S",
1903 .tuner_type = UNSET,
1904 .radio_type = UNSET,
1905 .tuner_addr = ADDR_UNSET,
1906 .radio_addr = ADDR_UNSET,
1907 .input = {{
1908 .type = CX88_VMUX_DVB,
1909 .vmux = 0,
1910 } },
1911 .mpeg = CX88_MPEG_DVB,
1912 },
1862 [CX88_BOARD_PROF_7300] = { 1913 [CX88_BOARD_PROF_7300] = {
1863 .name = "PROF 7300 DVB-S/S2", 1914 .name = "PROF 7300 DVB-S/S2",
1864 .tuner_type = UNSET, 1915 .tuner_type = UNSET,
@@ -1871,6 +1922,18 @@ static const struct cx88_board cx88_boards[] = {
1871 } }, 1922 } },
1872 .mpeg = CX88_MPEG_DVB, 1923 .mpeg = CX88_MPEG_DVB,
1873 }, 1924 },
1925 [CX88_BOARD_SATTRADE_ST4200] = {
1926 .name = "SATTRADE ST4200 DVB-S/S2",
1927 .tuner_type = UNSET,
1928 .radio_type = UNSET,
1929 .tuner_addr = ADDR_UNSET,
1930 .radio_addr = ADDR_UNSET,
1931 .input = {{
1932 .type = CX88_VMUX_DVB,
1933 .vmux = 0,
1934 } },
1935 .mpeg = CX88_MPEG_DVB,
1936 },
1874}; 1937};
1875 1938
1876/* ------------------------------------------------------------------ */ 1939/* ------------------------------------------------------------------ */
@@ -1897,7 +1960,11 @@ static const struct cx88_subid cx88_subids[] = {
1897 .subvendor = PCI_VENDOR_ID_ATI, 1960 .subvendor = PCI_VENDOR_ID_ATI,
1898 .subdevice = 0x00f8, 1961 .subdevice = 0x00f8,
1899 .card = CX88_BOARD_ATI_WONDER_PRO, 1962 .card = CX88_BOARD_ATI_WONDER_PRO,
1900 },{ 1963 }, {
1964 .subvendor = PCI_VENDOR_ID_ATI,
1965 .subdevice = 0x00f9,
1966 .card = CX88_BOARD_ATI_WONDER_PRO,
1967 }, {
1901 .subvendor = 0x107d, 1968 .subvendor = 0x107d,
1902 .subdevice = 0x6611, 1969 .subdevice = 0x6611,
1903 .card = CX88_BOARD_WINFAST2000XP_EXPERT, 1970 .card = CX88_BOARD_WINFAST2000XP_EXPERT,
@@ -2257,13 +2324,25 @@ static const struct cx88_subid cx88_subids[] = {
2257 .subdevice = 0x2011, 2324 .subdevice = 0x2011,
2258 .card = CX88_BOARD_OMICOM_SS4_PCI, 2325 .card = CX88_BOARD_OMICOM_SS4_PCI,
2259 }, { 2326 }, {
2327 .subvendor = 0x8910,
2328 .subdevice = 0x8888,
2329 .card = CX88_BOARD_TBS_8910,
2330 }, {
2260 .subvendor = 0x8920, 2331 .subvendor = 0x8920,
2261 .subdevice = 0x8888, 2332 .subdevice = 0x8888,
2262 .card = CX88_BOARD_TBS_8920, 2333 .card = CX88_BOARD_TBS_8920,
2263 }, { 2334 }, {
2335 .subvendor = 0xb022,
2336 .subdevice = 0x3022,
2337 .card = CX88_BOARD_PROF_6200,
2338 }, {
2264 .subvendor = 0xB033, 2339 .subvendor = 0xB033,
2265 .subdevice = 0x3033, 2340 .subdevice = 0x3033,
2266 .card = CX88_BOARD_PROF_7300, 2341 .card = CX88_BOARD_PROF_7300,
2342 }, {
2343 .subvendor = 0xb200,
2344 .subdevice = 0x4200,
2345 .card = CX88_BOARD_SATTRADE_ST4200,
2267 }, 2346 },
2268}; 2347};
2269 2348
@@ -2874,8 +2953,11 @@ static void cx88_card_setup(struct cx88_core *core)
2874 case CX88_BOARD_TEVII_S420: 2953 case CX88_BOARD_TEVII_S420:
2875 case CX88_BOARD_TEVII_S460: 2954 case CX88_BOARD_TEVII_S460:
2876 case CX88_BOARD_OMICOM_SS4_PCI: 2955 case CX88_BOARD_OMICOM_SS4_PCI:
2956 case CX88_BOARD_TBS_8910:
2877 case CX88_BOARD_TBS_8920: 2957 case CX88_BOARD_TBS_8920:
2958 case CX88_BOARD_PROF_6200:
2878 case CX88_BOARD_PROF_7300: 2959 case CX88_BOARD_PROF_7300:
2960 case CX88_BOARD_SATTRADE_ST4200:
2879 cx_write(MO_SRST_IO, 0); 2961 cx_write(MO_SRST_IO, 0);
2880 msleep(100); 2962 msleep(100);
2881 cx_write(MO_SRST_IO, 1); 2963 cx_write(MO_SRST_IO, 1);
diff --git a/drivers/media/video/cx88/cx88-core.c b/drivers/media/video/cx88/cx88-core.c
index 60705b08bfe8..b045874ad04f 100644
--- a/drivers/media/video/cx88/cx88-core.c
+++ b/drivers/media/video/cx88/cx88-core.c
@@ -844,6 +844,9 @@ static int set_tvaudio(struct cx88_core *core)
844 } else if (V4L2_STD_SECAM_L & norm) { 844 } else if (V4L2_STD_SECAM_L & norm) {
845 core->tvaudio = WW_L; 845 core->tvaudio = WW_L;
846 846
847 } else if ((V4L2_STD_SECAM_B | V4L2_STD_SECAM_G | V4L2_STD_SECAM_H) & norm) {
848 core->tvaudio = WW_BG;
849
847 } else if (V4L2_STD_SECAM_DK & norm) { 850 } else if (V4L2_STD_SECAM_DK & norm) {
848 core->tvaudio = WW_DK; 851 core->tvaudio = WW_DK;
849 852
diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c
index 309ca5e68063..da4dd4913d9f 100644
--- a/drivers/media/video/cx88/cx88-dvb.c
+++ b/drivers/media/video/cx88/cx88-dvb.c
@@ -406,7 +406,7 @@ static int tevii_dvbs_set_voltage(struct dvb_frontend *fe,
406 cx_write(MO_GP0_IO, 0x00006060); 406 cx_write(MO_GP0_IO, 0x00006060);
407 break; 407 break;
408 case SEC_VOLTAGE_OFF: 408 case SEC_VOLTAGE_OFF:
409 printk("LNB Voltage SEC_VOLTAGE_off\n"); 409 printk("LNB Voltage SEC_VOLTAGE_off\n");
410 break; 410 break;
411 } 411 }
412 412
@@ -606,7 +606,7 @@ static int dvb_register(struct cx8802_dev *dev)
606 /* Get the first frontend */ 606 /* Get the first frontend */
607 fe0 = videobuf_dvb_get_frontend(&dev->frontends, 1); 607 fe0 = videobuf_dvb_get_frontend(&dev->frontends, 1);
608 if (!fe0) 608 if (!fe0)
609 return -EINVAL; 609 goto frontend_detach;
610 610
611 /* multi-frontend gate control is undefined or defaults to fe0 */ 611 /* multi-frontend gate control is undefined or defaults to fe0 */
612 dev->frontends.gate = 0; 612 dev->frontends.gate = 0;
@@ -653,38 +653,35 @@ static int dvb_register(struct cx8802_dev *dev)
653 } 653 }
654 break; 654 break;
655 case CX88_BOARD_HAUPPAUGE_HVR3000: 655 case CX88_BOARD_HAUPPAUGE_HVR3000:
656 /* MFE frontend 1 */
657 mfe_shared = 1;
658 dev->frontends.gate = 2;
656 /* DVB-S init */ 659 /* DVB-S init */
657 fe0->dvb.frontend = dvb_attach(cx24123_attach, 660 fe0->dvb.frontend = dvb_attach(cx24123_attach,
658 &hauppauge_novas_config, 661 &hauppauge_novas_config,
659 &dev->core->i2c_adap); 662 &dev->core->i2c_adap);
660 if (fe0->dvb.frontend) { 663 if (fe0->dvb.frontend) {
661 if (!dvb_attach(isl6421_attach, fe0->dvb.frontend, 664 if (!dvb_attach(isl6421_attach,
662 &dev->core->i2c_adap, 0x08, ISL6421_DCL, 0x00)) { 665 fe0->dvb.frontend,
663 dprintk( 1, "%s(): HVR3000 - DVB-S LNB Init: failed\n", __func__); 666 &dev->core->i2c_adap,
664 } 667 0x08, ISL6421_DCL, 0x00))
665 } else { 668 goto frontend_detach;
666 dprintk( 1, "%s(): HVR3000 - DVB-S Init: failed\n", __func__);
667 } 669 }
668 /* DVB-T init */ 670 /* MFE frontend 2 */
669 fe1 = videobuf_dvb_get_frontend(&dev->frontends, 2); 671 fe1 = videobuf_dvb_get_frontend(&dev->frontends, 2);
670 if (fe1) { 672 if (!fe1)
671 dev->frontends.gate = 2; 673 goto frontend_detach;
672 mfe_shared = 1; 674 /* DVB-T init */
673 fe1->dvb.frontend = dvb_attach(cx22702_attach, 675 fe1->dvb.frontend = dvb_attach(cx22702_attach,
674 &hauppauge_hvr_config, 676 &hauppauge_hvr_config,
675 &dev->core->i2c_adap); 677 &dev->core->i2c_adap);
676 if (fe1->dvb.frontend) { 678 if (fe1->dvb.frontend) {
677 fe1->dvb.frontend->id = 1; 679 fe1->dvb.frontend->id = 1;
678 if(!dvb_attach(simple_tuner_attach, fe1->dvb.frontend, 680 if (!dvb_attach(simple_tuner_attach,
679 &dev->core->i2c_adap, 0x61, 681 fe1->dvb.frontend,
680 TUNER_PHILIPS_FMD1216ME_MK3)) { 682 &dev->core->i2c_adap,
681 dprintk( 1, "%s(): HVR3000 - DVB-T misc Init: failed\n", __func__); 683 0x61, TUNER_PHILIPS_FMD1216ME_MK3))
682 } 684 goto frontend_detach;
683 } else {
684 dprintk( 1, "%s(): HVR3000 - DVB-T Init: failed\n", __func__);
685 }
686 } else {
687 dprintk( 1, "%s(): HVR3000 - DVB-T Init: can't find frontend 2.\n", __func__);
688 } 685 }
689 break; 686 break;
690 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS: 687 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS:
@@ -998,50 +995,51 @@ static int dvb_register(struct cx8802_dev *dev)
998 } 995 }
999 break; 996 break;
1000 case CX88_BOARD_HAUPPAUGE_HVR4000: 997 case CX88_BOARD_HAUPPAUGE_HVR4000:
998 /* MFE frontend 1 */
999 mfe_shared = 1;
1000 dev->frontends.gate = 2;
1001 /* DVB-S/S2 Init */ 1001 /* DVB-S/S2 Init */
1002 fe0->dvb.frontend = dvb_attach(cx24116_attach, 1002 fe0->dvb.frontend = dvb_attach(cx24116_attach,
1003 &hauppauge_hvr4000_config, 1003 &hauppauge_hvr4000_config,
1004 &dev->core->i2c_adap); 1004 &dev->core->i2c_adap);
1005 if (fe0->dvb.frontend) { 1005 if (fe0->dvb.frontend) {
1006 if(!dvb_attach(isl6421_attach, fe0->dvb.frontend, 1006 if (!dvb_attach(isl6421_attach,
1007 &dev->core->i2c_adap, 0x08, ISL6421_DCL, 0x00)) { 1007 fe0->dvb.frontend,
1008 dprintk( 1, "%s(): HVR4000 - DVB-S LNB Init: failed\n", __func__); 1008 &dev->core->i2c_adap,
1009 } 1009 0x08, ISL6421_DCL, 0x00))
1010 } else { 1010 goto frontend_detach;
1011 dprintk( 1, "%s(): HVR4000 - DVB-S Init: failed\n", __func__);
1012 } 1011 }
1013 /* DVB-T Init */ 1012 /* MFE frontend 2 */
1014 fe1 = videobuf_dvb_get_frontend(&dev->frontends, 2); 1013 fe1 = videobuf_dvb_get_frontend(&dev->frontends, 2);
1015 if (fe1) { 1014 if (!fe1)
1016 dev->frontends.gate = 2; 1015 goto frontend_detach;
1017 mfe_shared = 1; 1016 /* DVB-T Init */
1018 fe1->dvb.frontend = dvb_attach(cx22702_attach, 1017 fe1->dvb.frontend = dvb_attach(cx22702_attach,
1019 &hauppauge_hvr_config, 1018 &hauppauge_hvr_config,
1020 &dev->core->i2c_adap); 1019 &dev->core->i2c_adap);
1021 if (fe1->dvb.frontend) { 1020 if (fe1->dvb.frontend) {
1022 fe1->dvb.frontend->id = 1; 1021 fe1->dvb.frontend->id = 1;
1023 if(!dvb_attach(simple_tuner_attach, fe1->dvb.frontend, 1022 if (!dvb_attach(simple_tuner_attach,
1024 &dev->core->i2c_adap, 0x61, 1023 fe1->dvb.frontend,
1025 TUNER_PHILIPS_FMD1216ME_MK3)) { 1024 &dev->core->i2c_adap,
1026 dprintk( 1, "%s(): HVR4000 - DVB-T misc Init: failed\n", __func__); 1025 0x61, TUNER_PHILIPS_FMD1216ME_MK3))
1027 } 1026 goto frontend_detach;
1028 } else {
1029 dprintk( 1, "%s(): HVR4000 - DVB-T Init: failed\n", __func__);
1030 }
1031 } else {
1032 dprintk( 1, "%s(): HVR4000 - DVB-T Init: can't find frontend 2.\n", __func__);
1033 } 1027 }
1034 break; 1028 break;
1035 case CX88_BOARD_HAUPPAUGE_HVR4000LITE: 1029 case CX88_BOARD_HAUPPAUGE_HVR4000LITE:
1036 fe0->dvb.frontend = dvb_attach(cx24116_attach, 1030 fe0->dvb.frontend = dvb_attach(cx24116_attach,
1037 &hauppauge_hvr4000_config, 1031 &hauppauge_hvr4000_config,
1038 &dev->core->i2c_adap); 1032 &dev->core->i2c_adap);
1039 if (fe0->dvb.frontend) { 1033 if (fe0->dvb.frontend) {
1040 dvb_attach(isl6421_attach, fe0->dvb.frontend, 1034 if (!dvb_attach(isl6421_attach,
1041 &dev->core->i2c_adap, 1035 fe0->dvb.frontend,
1042 0x08, ISL6421_DCL, 0x00); 1036 &dev->core->i2c_adap,
1037 0x08, ISL6421_DCL, 0x00))
1038 goto frontend_detach;
1043 } 1039 }
1044 break; 1040 break;
1041 case CX88_BOARD_PROF_6200:
1042 case CX88_BOARD_TBS_8910:
1045 case CX88_BOARD_TEVII_S420: 1043 case CX88_BOARD_TEVII_S420:
1046 fe0->dvb.frontend = dvb_attach(stv0299_attach, 1044 fe0->dvb.frontend = dvb_attach(stv0299_attach,
1047 &tevii_tuner_sharp_config, 1045 &tevii_tuner_sharp_config,
@@ -1070,21 +1068,18 @@ static int dvb_register(struct cx8802_dev *dev)
1070 fe0->dvb.frontend = dvb_attach(cx24116_attach, 1068 fe0->dvb.frontend = dvb_attach(cx24116_attach,
1071 &tevii_s460_config, 1069 &tevii_s460_config,
1072 &core->i2c_adap); 1070 &core->i2c_adap);
1073 if (fe0->dvb.frontend != NULL) { 1071 if (fe0->dvb.frontend != NULL)
1074 core->prev_set_voltage = fe0->dvb.frontend->ops.set_voltage;
1075 fe0->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage; 1072 fe0->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage;
1076 }
1077 break; 1073 break;
1078 case CX88_BOARD_OMICOM_SS4_PCI: 1074 case CX88_BOARD_OMICOM_SS4_PCI:
1079 case CX88_BOARD_TBS_8920: 1075 case CX88_BOARD_TBS_8920:
1080 case CX88_BOARD_PROF_7300: 1076 case CX88_BOARD_PROF_7300:
1077 case CX88_BOARD_SATTRADE_ST4200:
1081 fe0->dvb.frontend = dvb_attach(cx24116_attach, 1078 fe0->dvb.frontend = dvb_attach(cx24116_attach,
1082 &hauppauge_hvr4000_config, 1079 &hauppauge_hvr4000_config,
1083 &core->i2c_adap); 1080 &core->i2c_adap);
1084 if (fe0->dvb.frontend != NULL) { 1081 if (fe0->dvb.frontend != NULL)
1085 core->prev_set_voltage = fe0->dvb.frontend->ops.set_voltage;
1086 fe0->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage; 1082 fe0->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage;
1087 }
1088 break; 1083 break;
1089 default: 1084 default:
1090 printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card isn't supported yet\n", 1085 printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card isn't supported yet\n",
@@ -1092,11 +1087,11 @@ static int dvb_register(struct cx8802_dev *dev)
1092 break; 1087 break;
1093 } 1088 }
1094 1089
1095 if ( (NULL == fe0->dvb.frontend) || (fe1 && NULL == fe1->dvb.frontend) ) { 1090 if ( (NULL == fe0->dvb.frontend) || (fe1 && NULL == fe1->dvb.frontend) ) {
1096 printk(KERN_ERR 1091 printk(KERN_ERR
1097 "%s/2: frontend initialization failed\n", 1092 "%s/2: frontend initialization failed\n",
1098 core->name); 1093 core->name);
1099 return -EINVAL; 1094 goto frontend_detach;
1100 } 1095 }
1101 /* define general-purpose callback pointer */ 1096 /* define general-purpose callback pointer */
1102 fe0->dvb.frontend->callback = cx88_tuner_callback; 1097 fe0->dvb.frontend->callback = cx88_tuner_callback;
@@ -1133,40 +1128,44 @@ static int cx8802_dvb_advise_acquire(struct cx8802_driver *drv)
1133 * on the bus. Take the bus from the cx23416 and enable the 1128 * on the bus. Take the bus from the cx23416 and enable the
1134 * cx22702 demod 1129 * cx22702 demod
1135 */ 1130 */
1136 cx_set(MO_GP0_IO, 0x00000080); /* cx22702 out of reset and enable */ 1131 /* Toggle reset on cx22702 leaving i2c active */
1132 cx_set(MO_GP0_IO, 0x00000080);
1133 udelay(1000);
1134 cx_clear(MO_GP0_IO, 0x00000080);
1135 udelay(50);
1136 cx_set(MO_GP0_IO, 0x00000080);
1137 udelay(1000);
1138 /* enable the cx22702 pins */
1137 cx_clear(MO_GP0_IO, 0x00000004); 1139 cx_clear(MO_GP0_IO, 0x00000004);
1138 udelay(1000); 1140 udelay(1000);
1139 break; 1141 break;
1140 1142
1141 case CX88_BOARD_HAUPPAUGE_HVR3000: 1143 case CX88_BOARD_HAUPPAUGE_HVR3000:
1142 case CX88_BOARD_HAUPPAUGE_HVR4000: 1144 case CX88_BOARD_HAUPPAUGE_HVR4000:
1143 if(core->dvbdev->frontends.active_fe_id == 1) { 1145 /* Toggle reset on cx22702 leaving i2c active */
1144 /* DVB-S/S2 Enabled */ 1146 cx_set(MO_GP0_IO, 0x00000080);
1145 1147 udelay(1000);
1146 /* Toggle reset on cx22702 leaving i2c active */ 1148 cx_clear(MO_GP0_IO, 0x00000080);
1147 cx_write(MO_GP0_IO, (core->board.input[0].gpio0 & 0x0000ff00) | 0x00000080); 1149 udelay(50);
1148 udelay(1000); 1150 cx_set(MO_GP0_IO, 0x00000080);
1149 cx_clear(MO_GP0_IO, 0x00000080); 1151 udelay(1000);
1150 udelay(50); 1152 switch (core->dvbdev->frontends.active_fe_id) {
1151 cx_set(MO_GP0_IO, 0x00000080); /* cx22702 out of reset */ 1153 case 1: /* DVB-S/S2 Enabled */
1152 cx_set(MO_GP0_IO, 0x00000004); /* tri-state the cx22702 pins */ 1154 /* tri-state the cx22702 pins */
1153 udelay(1000); 1155 cx_set(MO_GP0_IO, 0x00000004);
1154 1156 /* Take the cx24116/cx24123 out of reset */
1155 cx_write(MO_SRST_IO, 1); /* Take the cx24116/cx24123 out of reset */ 1157 cx_write(MO_SRST_IO, 1);
1156 core->dvbdev->ts_gen_cntrl = 0x02; /* Parallel IO */ 1158 core->dvbdev->ts_gen_cntrl = 0x02; /* Parallel IO */
1157 } else 1159 break;
1158 if (core->dvbdev->frontends.active_fe_id == 2) { 1160 case 2: /* DVB-T Enabled */
1159 /* DVB-T Enabled */
1160
1161 /* Put the cx24116/cx24123 into reset */ 1161 /* Put the cx24116/cx24123 into reset */
1162 cx_write(MO_SRST_IO, 0); 1162 cx_write(MO_SRST_IO, 0);
1163 1163 /* enable the cx22702 pins */
1164 /* cx22702 out of reset and enable it */
1165 cx_set(MO_GP0_IO, 0x00000080);
1166 cx_clear(MO_GP0_IO, 0x00000004); 1164 cx_clear(MO_GP0_IO, 0x00000004);
1167 core->dvbdev->ts_gen_cntrl = 0x0c; /* Serial IO */ 1165 core->dvbdev->ts_gen_cntrl = 0x0c; /* Serial IO */
1168 udelay(1000); 1166 break;
1169 } 1167 }
1168 udelay(1000);
1170 break; 1169 break;
1171 1170
1172 default: 1171 default:
@@ -1199,8 +1198,7 @@ static int cx8802_dvb_probe(struct cx8802_driver *drv)
1199{ 1198{
1200 struct cx88_core *core = drv->core; 1199 struct cx88_core *core = drv->core;
1201 struct cx8802_dev *dev = drv->core->dvbdev; 1200 struct cx8802_dev *dev = drv->core->dvbdev;
1202 int err, i; 1201 int err;
1203 struct videobuf_dvb_frontend *fe;
1204 1202
1205 dprintk( 1, "%s\n", __func__); 1203 dprintk( 1, "%s\n", __func__);
1206 dprintk( 1, " ->being probed by Card=%d Name=%s, PCI %02x:%02x\n", 1204 dprintk( 1, " ->being probed by Card=%d Name=%s, PCI %02x:%02x\n",
@@ -1216,31 +1214,47 @@ static int cx8802_dvb_probe(struct cx8802_driver *drv)
1216 /* If vp3054 isn't enabled, a stub will just return 0 */ 1214 /* If vp3054 isn't enabled, a stub will just return 0 */
1217 err = vp3054_i2c_probe(dev); 1215 err = vp3054_i2c_probe(dev);
1218 if (0 != err) 1216 if (0 != err)
1219 goto fail_core; 1217 goto fail_probe;
1220 1218
1221 /* dvb stuff */ 1219 /* dvb stuff */
1222 printk(KERN_INFO "%s/2: cx2388x based DVB/ATSC card\n", core->name); 1220 printk(KERN_INFO "%s/2: cx2388x based DVB/ATSC card\n", core->name);
1223 dev->ts_gen_cntrl = 0x0c; 1221 dev->ts_gen_cntrl = 0x0c;
1224 1222
1225 for (i = 1; i <= core->board.num_frontends; i++) { 1223 err = -ENODEV;
1226 fe = videobuf_dvb_get_frontend(&core->dvbdev->frontends, i); 1224 if (core->board.num_frontends) {
1227 if (!fe) { 1225 struct videobuf_dvb_frontend *fe;
1228 printk(KERN_ERR "%s() failed to get frontend(%d)\n", __func__, i); 1226 int i;
1229 continue; 1227
1228 for (i = 1; i <= core->board.num_frontends; i++) {
1229 fe = videobuf_dvb_get_frontend(&core->dvbdev->frontends, i);
1230 if (fe == NULL) {
1231 printk(KERN_ERR "%s() failed to get frontend(%d)\n",
1232 __func__, i);
1233 goto fail_probe;
1234 }
1235 videobuf_queue_sg_init(&fe->dvb.dvbq, &dvb_qops,
1236 &dev->pci->dev, &dev->slock,
1237 V4L2_BUF_TYPE_VIDEO_CAPTURE,
1238 V4L2_FIELD_TOP,
1239 sizeof(struct cx88_buffer),
1240 dev);
1241 /* init struct videobuf_dvb */
1242 fe->dvb.name = dev->core->name;
1230 } 1243 }
1231 videobuf_queue_sg_init(&fe->dvb.dvbq, &dvb_qops, 1244 } else {
1232 &dev->pci->dev, &dev->slock, 1245 /* no frontends allocated */
1233 V4L2_BUF_TYPE_VIDEO_CAPTURE, 1246 printk(KERN_ERR "%s/2 .num_frontends should be non-zero\n",
1234 V4L2_FIELD_TOP, 1247 core->name);
1235 sizeof(struct cx88_buffer), 1248 goto fail_core;
1236 dev);
1237 /* init struct videobuf_dvb */
1238 fe->dvb.name = dev->core->name;
1239 } 1249 }
1240 err = dvb_register(dev); 1250 err = dvb_register(dev);
1241 if (err != 0) 1251 if (err)
1252 /* frontends/adapter de-allocated in dvb_register */
1242 printk(KERN_ERR "%s/2: dvb_register failed (err = %d)\n", 1253 printk(KERN_ERR "%s/2: dvb_register failed (err = %d)\n",
1243 core->name, err); 1254 core->name, err);
1255 return err;
1256fail_probe:
1257 videobuf_dvb_dealloc_frontends(&core->dvbdev->frontends);
1244fail_core: 1258fail_core:
1245 return err; 1259 return err;
1246} 1260}
diff --git a/drivers/media/video/cx88/cx88-mpeg.c b/drivers/media/video/cx88/cx88-mpeg.c
index 3ebdcd1d83f8..a04fee235db6 100644
--- a/drivers/media/video/cx88/cx88-mpeg.c
+++ b/drivers/media/video/cx88/cx88-mpeg.c
@@ -3,7 +3,7 @@
3 * Support for the mpeg transport stream transfers 3 * Support for the mpeg transport stream transfers
4 * PCI function #2 of the cx2388x. 4 * PCI function #2 of the cx2388x.
5 * 5 *
6 * (c) 2004 Jelle Foks <jelle@foks.8m.com> 6 * (c) 2004 Jelle Foks <jelle@foks.us>
7 * (c) 2004 Chris Pascoe <c.pascoe@itee.uq.edu.au> 7 * (c) 2004 Chris Pascoe <c.pascoe@itee.uq.edu.au>
8 * (c) 2004 Gerd Knorr <kraxel@bytesex.org> 8 * (c) 2004 Gerd Knorr <kraxel@bytesex.org>
9 * 9 *
@@ -34,7 +34,7 @@
34/* ------------------------------------------------------------------ */ 34/* ------------------------------------------------------------------ */
35 35
36MODULE_DESCRIPTION("mpeg driver for cx2388x based TV cards"); 36MODULE_DESCRIPTION("mpeg driver for cx2388x based TV cards");
37MODULE_AUTHOR("Jelle Foks <jelle@foks.8m.com>"); 37MODULE_AUTHOR("Jelle Foks <jelle@foks.us>");
38MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>"); 38MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>");
39MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]"); 39MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
40MODULE_LICENSE("GPL"); 40MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h
index f4240965be32..20649b25f7ba 100644
--- a/drivers/media/video/cx88/cx88.h
+++ b/drivers/media/video/cx88/cx88.h
@@ -53,12 +53,11 @@
53/* ----------------------------------------------------------- */ 53/* ----------------------------------------------------------- */
54/* defines and enums */ 54/* defines and enums */
55 55
56/* Currently unsupported by the driver: PAL/H, NTSC/Kr, SECAM B/G/H/LC */ 56/* Currently unsupported by the driver: PAL/H, NTSC/Kr, SECAM/LC */
57#define CX88_NORMS (\ 57#define CX88_NORMS (V4L2_STD_ALL \
58 V4L2_STD_NTSC_M| V4L2_STD_NTSC_M_JP| V4L2_STD_NTSC_443 | \ 58 & ~V4L2_STD_PAL_H \
59 V4L2_STD_PAL_BG| V4L2_STD_PAL_DK | V4L2_STD_PAL_I | \ 59 & ~V4L2_STD_NTSC_M_KR \
60 V4L2_STD_PAL_M | V4L2_STD_PAL_N | V4L2_STD_PAL_Nc | \ 60 & ~V4L2_STD_SECAM_LC)
61 V4L2_STD_PAL_60| V4L2_STD_SECAM_L | V4L2_STD_SECAM_DK )
62 61
63#define FORMAT_FLAGS_PACKED 0x01 62#define FORMAT_FLAGS_PACKED 0x01
64#define FORMAT_FLAGS_PLANAR 0x02 63#define FORMAT_FLAGS_PLANAR 0x02
@@ -229,6 +228,9 @@ extern struct sram_channel cx88_sram_channels[];
229#define CX88_BOARD_TEVII_S420 73 228#define CX88_BOARD_TEVII_S420 73
230#define CX88_BOARD_PROLINK_PV_GLOBAL_XTREME 74 229#define CX88_BOARD_PROLINK_PV_GLOBAL_XTREME 74
231#define CX88_BOARD_PROF_7300 75 230#define CX88_BOARD_PROF_7300 75
231#define CX88_BOARD_SATTRADE_ST4200 76
232#define CX88_BOARD_TBS_8910 77
233#define CX88_BOARD_PROF_6200 78
232 234
233enum cx88_itype { 235enum cx88_itype {
234 CX88_VMUX_COMPOSITE1 = 1, 236 CX88_VMUX_COMPOSITE1 = 1,
diff --git a/drivers/media/video/em28xx/em28xx-audio.c b/drivers/media/video/em28xx/em28xx-audio.c
index 7a8d49ef646e..15c03f0e69ad 100644
--- a/drivers/media/video/em28xx/em28xx-audio.c
+++ b/drivers/media/video/em28xx/em28xx-audio.c
@@ -424,11 +424,12 @@ static int em28xx_audio_init(struct em28xx *dev)
424 struct snd_pcm *pcm; 424 struct snd_pcm *pcm;
425 struct snd_card *card; 425 struct snd_card *card;
426 static int devnr; 426 static int devnr;
427 int ret, err; 427 int err;
428 428
429 if (dev->has_audio_class) { 429 if (dev->has_alsa_audio != 1) {
430 /* This device does not support the extension (in this case 430 /* This device does not support the extension (in this case
431 the device is expecting the snd-usb-audio module */ 431 the device is expecting the snd-usb-audio module or
432 doesn't have analog audio support at all) */
432 return 0; 433 return 0;
433 } 434 }
434 435
@@ -449,7 +450,12 @@ static int em28xx_audio_init(struct em28xx *dev)
449 } 450 }
450 451
451 spin_lock_init(&adev->slock); 452 spin_lock_init(&adev->slock);
452 ret = snd_pcm_new(card, "Em28xx Audio", 0, 0, 1, &pcm); 453 err = snd_pcm_new(card, "Em28xx Audio", 0, 0, 1, &pcm);
454 if (err < 0) {
455 snd_card_free(card);
456 return err;
457 }
458
453 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_em28xx_pcm_capture); 459 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_em28xx_pcm_capture);
454 pcm->info_flags = 0; 460 pcm->info_flags = 0;
455 pcm->private_data = dev; 461 pcm->private_data = dev;
@@ -461,7 +467,7 @@ static int em28xx_audio_init(struct em28xx *dev)
461 err = snd_card_register(card); 467 err = snd_card_register(card);
462 if (err < 0) { 468 if (err < 0) {
463 snd_card_free(card); 469 snd_card_free(card);
464 return -ENOMEM; 470 return err;
465 } 471 }
466 adev->sndcard = card; 472 adev->sndcard = card;
467 adev->udev = dev->udev; 473 adev->udev = dev->udev;
@@ -475,9 +481,10 @@ static int em28xx_audio_fini(struct em28xx *dev)
475 if (dev == NULL) 481 if (dev == NULL)
476 return 0; 482 return 0;
477 483
478 if (dev->has_audio_class) { 484 if (dev->has_alsa_audio != 1) {
479 /* This device does not support the extension (in this case 485 /* This device does not support the extension (in this case
480 the device is expecting the snd-usb-audio module */ 486 the device is expecting the snd-usb-audio module or
487 doesn't have analog audio support at all) */
481 return 0; 488 return 0;
482 } 489 }
483 490
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c
index d65d0572403b..e776699b62f9 100644
--- a/drivers/media/video/em28xx/em28xx-cards.c
+++ b/drivers/media/video/em28xx/em28xx-cards.c
@@ -37,6 +37,8 @@
37 37
38#include "em28xx.h" 38#include "em28xx.h"
39 39
40#define DRIVER_NAME "em28xx"
41
40static int tuner = -1; 42static int tuner = -1;
41module_param(tuner, int, 0444); 43module_param(tuner, int, 0444);
42MODULE_PARM_DESC(tuner, "tuner type"); 44MODULE_PARM_DESC(tuner, "tuner type");
@@ -45,122 +47,177 @@ static unsigned int disable_ir;
45module_param(disable_ir, int, 0444); 47module_param(disable_ir, int, 0444);
46MODULE_PARM_DESC(disable_ir, "disable infrared remote support"); 48MODULE_PARM_DESC(disable_ir, "disable infrared remote support");
47 49
50static unsigned int card[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = UNSET };
51module_param_array(card, int, NULL, 0444);
52MODULE_PARM_DESC(card, "card type");
53
54/* Bitmask marking allocated devices from 0 to EM28XX_MAXBOARDS */
55static unsigned long em28xx_devused;
56
48struct em28xx_hash_table { 57struct em28xx_hash_table {
49 unsigned long hash; 58 unsigned long hash;
50 unsigned int model; 59 unsigned int model;
51 unsigned int tuner; 60 unsigned int tuner;
52}; 61};
53 62
63/*
64 * Reset sequences for analog/digital modes
65 */
66
67/* Reset for the most [analog] boards */
68static struct em28xx_reg_seq default_analog[] = {
69 {EM28XX_R08_GPIO, 0x6d, ~EM_GPIO_4, 10},
70 { -1, -1, -1, -1},
71};
72
73/* Reset for the most [digital] boards */
74static struct em28xx_reg_seq default_digital[] = {
75 {EM28XX_R08_GPIO, 0x6e, ~EM_GPIO_4, 10},
76 { -1, -1, -1, -1},
77};
78
79/* Board Hauppauge WinTV HVR 900 analog */
80static struct em28xx_reg_seq hauppauge_wintv_hvr_900_analog[] = {
81 {EM28XX_R08_GPIO, 0x2d, ~EM_GPIO_4, 10},
82 {0x05, 0xff, 0x10, 10},
83 { -1, -1, -1, -1},
84};
85
86/* Board Hauppauge WinTV HVR 900 digital */
87static struct em28xx_reg_seq hauppauge_wintv_hvr_900_digital[] = {
88 {EM28XX_R08_GPIO, 0x2e, ~EM_GPIO_4, 10},
89 {EM2880_R04_GPO, 0x04, 0x0f, 10},
90 {EM2880_R04_GPO, 0x0c, 0x0f, 10},
91 { -1, -1, -1, -1},
92};
93
94/* Boards - EM2880 MSI DIGIVOX AD and EM2880_BOARD_MSI_DIGIVOX_AD_II */
95static struct em28xx_reg_seq em2880_msi_digivox_ad_analog[] = {
96 {EM28XX_R08_GPIO, 0x69, ~EM_GPIO_4, 10},
97 { -1, -1, -1, -1},
98};
99
100/* Boards - EM2880 MSI DIGIVOX AD and EM2880_BOARD_MSI_DIGIVOX_AD_II */
101
102/* Board - EM2870 Kworld 355u
103 Analog - No input analog */
104
105/* Callback for the most boards */
106static struct em28xx_reg_seq default_tuner_gpio[] = {
107 {EM28XX_R08_GPIO, EM_GPIO_4, EM_GPIO_4, 10},
108 {EM28XX_R08_GPIO, 0, EM_GPIO_4, 10},
109 {EM28XX_R08_GPIO, EM_GPIO_4, EM_GPIO_4, 10},
110 { -1, -1, -1, -1},
111};
112
113/*
114 * Board definitions
115 */
54struct em28xx_board em28xx_boards[] = { 116struct em28xx_board em28xx_boards[] = {
55 [EM2750_BOARD_UNKNOWN] = { 117 [EM2750_BOARD_UNKNOWN] = {
56 .name = "Unknown EM2750/EM2751 webcam grabber", 118 .name = "Unknown EM2750/EM2751 webcam grabber",
57 .vchannels = 1, 119 .xclk = EM28XX_XCLK_FREQUENCY_48MHZ,
120 .tuner_type = TUNER_ABSENT, /* This is a webcam */
58 .input = { { 121 .input = { {
59 .type = EM28XX_VMUX_COMPOSITE1, 122 .type = EM28XX_VMUX_COMPOSITE1,
60 .vmux = 0, 123 .vmux = 0,
61 .amux = 0, 124 .amux = EM28XX_AMUX_VIDEO,
62 } }, 125 } },
63 }, 126 },
64 [EM2800_BOARD_UNKNOWN] = { 127 [EM2800_BOARD_UNKNOWN] = {
65 .name = "Unknown EM2800 video grabber", 128 .name = "Unknown EM2800 video grabber",
66 .is_em2800 = 1, 129 .is_em2800 = 1,
67 .vchannels = 2,
68 .tda9887_conf = TDA9887_PRESENT, 130 .tda9887_conf = TDA9887_PRESENT,
69 .decoder = EM28XX_SAA7113, 131 .decoder = EM28XX_SAA711X,
70 .input = { { 132 .tuner_type = TUNER_ABSENT,
133 .input = { {
71 .type = EM28XX_VMUX_COMPOSITE1, 134 .type = EM28XX_VMUX_COMPOSITE1,
72 .vmux = SAA7115_COMPOSITE0, 135 .vmux = SAA7115_COMPOSITE0,
73 .amux = 1, 136 .amux = EM28XX_AMUX_LINE_IN,
74 }, { 137 }, {
75 .type = EM28XX_VMUX_SVIDEO, 138 .type = EM28XX_VMUX_SVIDEO,
76 .vmux = SAA7115_SVIDEO3, 139 .vmux = SAA7115_SVIDEO3,
77 .amux = 1, 140 .amux = EM28XX_AMUX_LINE_IN,
78 } }, 141 } },
79 }, 142 },
80 [EM2820_BOARD_UNKNOWN] = { 143 [EM2820_BOARD_UNKNOWN] = {
81 .name = "Unknown EM2750/28xx video grabber", 144 .name = "Unknown EM2750/28xx video grabber",
82 .is_em2800 = 0, 145 .tuner_type = TUNER_ABSENT,
83 .tuner_type = TUNER_ABSENT,
84 }, 146 },
85 [EM2750_BOARD_DLCW_130] = { 147 [EM2750_BOARD_DLCW_130] = {
86 /* Beijing Huaqi Information Digital Technology Co., Ltd */ 148 /* Beijing Huaqi Information Digital Technology Co., Ltd */
87 .name = "Huaqi DLCW-130", 149 .name = "Huaqi DLCW-130",
88 .valid = EM28XX_BOARD_NOT_VALIDATED, 150 .valid = EM28XX_BOARD_NOT_VALIDATED,
89 .vchannels = 1, 151 .xclk = EM28XX_XCLK_FREQUENCY_48MHZ,
152 .tuner_type = TUNER_ABSENT, /* This is a webcam */
90 .input = { { 153 .input = { {
91 .type = EM28XX_VMUX_COMPOSITE1, 154 .type = EM28XX_VMUX_COMPOSITE1,
92 .vmux = 0, 155 .vmux = 0,
93 .amux = 0, 156 .amux = EM28XX_AMUX_VIDEO,
94 } }, 157 } },
95 }, 158 },
96 [EM2820_BOARD_KWORLD_PVRTV2800RF] = { 159 [EM2820_BOARD_KWORLD_PVRTV2800RF] = {
97 .name = "Kworld PVR TV 2800 RF", 160 .name = "Kworld PVR TV 2800 RF",
98 .is_em2800 = 0,
99 .vchannels = 2,
100 .tuner_type = TUNER_TEMIC_PAL, 161 .tuner_type = TUNER_TEMIC_PAL,
101 .tda9887_conf = TDA9887_PRESENT, 162 .tda9887_conf = TDA9887_PRESENT,
102 .decoder = EM28XX_SAA7113, 163 .decoder = EM28XX_SAA711X,
103 .input = { { 164 .input = { {
104 .type = EM28XX_VMUX_COMPOSITE1, 165 .type = EM28XX_VMUX_COMPOSITE1,
105 .vmux = SAA7115_COMPOSITE0, 166 .vmux = SAA7115_COMPOSITE0,
106 .amux = 1, 167 .amux = EM28XX_AMUX_LINE_IN,
107 }, { 168 }, {
108 .type = EM28XX_VMUX_SVIDEO, 169 .type = EM28XX_VMUX_SVIDEO,
109 .vmux = SAA7115_SVIDEO3, 170 .vmux = SAA7115_SVIDEO3,
110 .amux = 1, 171 .amux = EM28XX_AMUX_LINE_IN,
111 } }, 172 } },
112 }, 173 },
113 [EM2820_BOARD_TERRATEC_CINERGY_250] = { 174 [EM2820_BOARD_TERRATEC_CINERGY_250] = {
114 .name = "Terratec Cinergy 250 USB", 175 .name = "Terratec Cinergy 250 USB",
115 .vchannels = 3,
116 .tuner_type = TUNER_LG_PAL_NEW_TAPC, 176 .tuner_type = TUNER_LG_PAL_NEW_TAPC,
117 .tda9887_conf = TDA9887_PRESENT, 177 .tda9887_conf = TDA9887_PRESENT,
118 .decoder = EM28XX_SAA7113, 178 .decoder = EM28XX_SAA711X,
119 .input = { { 179 .input = { {
120 .type = EM28XX_VMUX_TELEVISION, 180 .type = EM28XX_VMUX_TELEVISION,
121 .vmux = SAA7115_COMPOSITE2, 181 .vmux = SAA7115_COMPOSITE2,
122 .amux = 1, 182 .amux = EM28XX_AMUX_LINE_IN,
123 }, { 183 }, {
124 .type = EM28XX_VMUX_COMPOSITE1, 184 .type = EM28XX_VMUX_COMPOSITE1,
125 .vmux = SAA7115_COMPOSITE0, 185 .vmux = SAA7115_COMPOSITE0,
126 .amux = 1, 186 .amux = EM28XX_AMUX_LINE_IN,
127 }, { 187 }, {
128 .type = EM28XX_VMUX_SVIDEO, 188 .type = EM28XX_VMUX_SVIDEO,
129 .vmux = SAA7115_SVIDEO3, 189 .vmux = SAA7115_SVIDEO3,
130 .amux = 1, 190 .amux = EM28XX_AMUX_LINE_IN,
131 } }, 191 } },
132 }, 192 },
133 [EM2820_BOARD_PINNACLE_USB_2] = { 193 [EM2820_BOARD_PINNACLE_USB_2] = {
134 .name = "Pinnacle PCTV USB 2", 194 .name = "Pinnacle PCTV USB 2",
135 .vchannels = 3,
136 .tuner_type = TUNER_LG_PAL_NEW_TAPC, 195 .tuner_type = TUNER_LG_PAL_NEW_TAPC,
137 .tda9887_conf = TDA9887_PRESENT, 196 .tda9887_conf = TDA9887_PRESENT,
138 .decoder = EM28XX_SAA7113, 197 .decoder = EM28XX_SAA711X,
139 .input = { { 198 .input = { {
140 .type = EM28XX_VMUX_TELEVISION, 199 .type = EM28XX_VMUX_TELEVISION,
141 .vmux = SAA7115_COMPOSITE2, 200 .vmux = SAA7115_COMPOSITE2,
142 .amux = 0, 201 .amux = EM28XX_AMUX_VIDEO,
143 }, { 202 }, {
144 .type = EM28XX_VMUX_COMPOSITE1, 203 .type = EM28XX_VMUX_COMPOSITE1,
145 .vmux = SAA7115_COMPOSITE0, 204 .vmux = SAA7115_COMPOSITE0,
146 .amux = 1, 205 .amux = EM28XX_AMUX_LINE_IN,
147 }, { 206 }, {
148 .type = EM28XX_VMUX_SVIDEO, 207 .type = EM28XX_VMUX_SVIDEO,
149 .vmux = SAA7115_SVIDEO3, 208 .vmux = SAA7115_SVIDEO3,
150 .amux = 1, 209 .amux = EM28XX_AMUX_LINE_IN,
151 } }, 210 } },
152 }, 211 },
153 [EM2820_BOARD_HAUPPAUGE_WINTV_USB_2] = { 212 [EM2820_BOARD_HAUPPAUGE_WINTV_USB_2] = {
154 .name = "Hauppauge WinTV USB 2", 213 .name = "Hauppauge WinTV USB 2",
155 .vchannels = 3,
156 .tuner_type = TUNER_PHILIPS_FM1236_MK3, 214 .tuner_type = TUNER_PHILIPS_FM1236_MK3,
157 .tda9887_conf = TDA9887_PRESENT | 215 .tda9887_conf = TDA9887_PRESENT |
158 TDA9887_PORT1_ACTIVE| 216 TDA9887_PORT1_ACTIVE|
159 TDA9887_PORT2_ACTIVE, 217 TDA9887_PORT2_ACTIVE,
160 .decoder = EM28XX_TVP5150, 218 .decoder = EM28XX_TVP5150,
161 .has_msp34xx = 1, 219 .has_msp34xx = 1,
162 /*FIXME: S-Video not tested */ 220 .input = { {
163 .input = { {
164 .type = EM28XX_VMUX_TELEVISION, 221 .type = EM28XX_VMUX_TELEVISION,
165 .vmux = TVP5150_COMPOSITE0, 222 .vmux = TVP5150_COMPOSITE0,
166 .amux = MSP_INPUT_DEFAULT, 223 .amux = MSP_INPUT_DEFAULT,
@@ -174,327 +231,305 @@ struct em28xx_board em28xx_boards[] = {
174 [EM2820_BOARD_DLINK_USB_TV] = { 231 [EM2820_BOARD_DLINK_USB_TV] = {
175 .name = "D-Link DUB-T210 TV Tuner", 232 .name = "D-Link DUB-T210 TV Tuner",
176 .valid = EM28XX_BOARD_NOT_VALIDATED, 233 .valid = EM28XX_BOARD_NOT_VALIDATED,
177 .vchannels = 3,
178 .is_em2800 = 0,
179 .tuner_type = TUNER_LG_PAL_NEW_TAPC, 234 .tuner_type = TUNER_LG_PAL_NEW_TAPC,
180 .tda9887_conf = TDA9887_PRESENT, 235 .tda9887_conf = TDA9887_PRESENT,
181 .decoder = EM28XX_SAA7113, 236 .decoder = EM28XX_SAA711X,
182 .input = { { 237 .input = { {
183 .type = EM28XX_VMUX_TELEVISION, 238 .type = EM28XX_VMUX_TELEVISION,
184 .vmux = SAA7115_COMPOSITE2, 239 .vmux = SAA7115_COMPOSITE2,
185 .amux = 1, 240 .amux = EM28XX_AMUX_LINE_IN,
186 }, { 241 }, {
187 .type = EM28XX_VMUX_COMPOSITE1, 242 .type = EM28XX_VMUX_COMPOSITE1,
188 .vmux = SAA7115_COMPOSITE0, 243 .vmux = SAA7115_COMPOSITE0,
189 .amux = 1, 244 .amux = EM28XX_AMUX_LINE_IN,
190 }, { 245 }, {
191 .type = EM28XX_VMUX_SVIDEO, 246 .type = EM28XX_VMUX_SVIDEO,
192 .vmux = SAA7115_SVIDEO3, 247 .vmux = SAA7115_SVIDEO3,
193 .amux = 1, 248 .amux = EM28XX_AMUX_LINE_IN,
194 } }, 249 } },
195 }, 250 },
196 [EM2820_BOARD_HERCULES_SMART_TV_USB2] = { 251 [EM2820_BOARD_HERCULES_SMART_TV_USB2] = {
197 .name = "Hercules Smart TV USB 2.0", 252 .name = "Hercules Smart TV USB 2.0",
198 .valid = EM28XX_BOARD_NOT_VALIDATED, 253 .valid = EM28XX_BOARD_NOT_VALIDATED,
199 .vchannels = 3,
200 .tuner_type = TUNER_LG_PAL_NEW_TAPC, 254 .tuner_type = TUNER_LG_PAL_NEW_TAPC,
201 .tda9887_conf = TDA9887_PRESENT, 255 .tda9887_conf = TDA9887_PRESENT,
202 .decoder = EM28XX_SAA7113, 256 .decoder = EM28XX_SAA711X,
203 .input = { { 257 .input = { {
204 .type = EM28XX_VMUX_TELEVISION, 258 .type = EM28XX_VMUX_TELEVISION,
205 .vmux = SAA7115_COMPOSITE2, 259 .vmux = SAA7115_COMPOSITE2,
206 .amux = 1, 260 .amux = EM28XX_AMUX_LINE_IN,
207 }, { 261 }, {
208 .type = EM28XX_VMUX_COMPOSITE1, 262 .type = EM28XX_VMUX_COMPOSITE1,
209 .vmux = SAA7115_COMPOSITE0, 263 .vmux = SAA7115_COMPOSITE0,
210 .amux = 1, 264 .amux = EM28XX_AMUX_LINE_IN,
211 }, { 265 }, {
212 .type = EM28XX_VMUX_SVIDEO, 266 .type = EM28XX_VMUX_SVIDEO,
213 .vmux = SAA7115_SVIDEO3, 267 .vmux = SAA7115_SVIDEO3,
214 .amux = 1, 268 .amux = EM28XX_AMUX_LINE_IN,
215 } }, 269 } },
216 }, 270 },
217 [EM2820_BOARD_PINNACLE_USB_2_FM1216ME] = { 271 [EM2820_BOARD_PINNACLE_USB_2_FM1216ME] = {
218 .name = "Pinnacle PCTV USB 2 (Philips FM1216ME)", 272 .name = "Pinnacle PCTV USB 2 (Philips FM1216ME)",
219 .valid = EM28XX_BOARD_NOT_VALIDATED, 273 .valid = EM28XX_BOARD_NOT_VALIDATED,
220 .vchannels = 3,
221 .is_em2800 = 0,
222 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, 274 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
223 .tda9887_conf = TDA9887_PRESENT, 275 .tda9887_conf = TDA9887_PRESENT,
224 .decoder = EM28XX_SAA7113, 276 .decoder = EM28XX_SAA711X,
225 .input = { { 277 .input = { {
226 .type = EM28XX_VMUX_TELEVISION, 278 .type = EM28XX_VMUX_TELEVISION,
227 .vmux = SAA7115_COMPOSITE2, 279 .vmux = SAA7115_COMPOSITE2,
228 .amux = 0, 280 .amux = EM28XX_AMUX_VIDEO,
229 }, { 281 }, {
230 .type = EM28XX_VMUX_COMPOSITE1, 282 .type = EM28XX_VMUX_COMPOSITE1,
231 .vmux = SAA7115_COMPOSITE0, 283 .vmux = SAA7115_COMPOSITE0,
232 .amux = 1, 284 .amux = EM28XX_AMUX_LINE_IN,
233 }, { 285 }, {
234 .type = EM28XX_VMUX_SVIDEO, 286 .type = EM28XX_VMUX_SVIDEO,
235 .vmux = SAA7115_SVIDEO3, 287 .vmux = SAA7115_SVIDEO3,
236 .amux = 1, 288 .amux = EM28XX_AMUX_LINE_IN,
237 } }, 289 } },
238 }, 290 },
239 [EM2820_BOARD_GADMEI_UTV310] = { 291 [EM2820_BOARD_GADMEI_UTV310] = {
240 .name = "Gadmei UTV310", 292 .name = "Gadmei UTV310",
241 .valid = EM28XX_BOARD_NOT_VALIDATED, 293 .valid = EM28XX_BOARD_NOT_VALIDATED,
242 .vchannels = 3,
243 .tuner_type = TUNER_TNF_5335MF, 294 .tuner_type = TUNER_TNF_5335MF,
244 .tda9887_conf = TDA9887_PRESENT, 295 .tda9887_conf = TDA9887_PRESENT,
245 .decoder = EM28XX_SAA7113, 296 .decoder = EM28XX_SAA711X,
246 .input = { { 297 .input = { {
247 .type = EM28XX_VMUX_TELEVISION, 298 .type = EM28XX_VMUX_TELEVISION,
248 .vmux = SAA7115_COMPOSITE1, 299 .vmux = SAA7115_COMPOSITE1,
249 .amux = 1, 300 .amux = EM28XX_AMUX_LINE_IN,
250 }, { 301 }, {
251 .type = EM28XX_VMUX_COMPOSITE1, 302 .type = EM28XX_VMUX_COMPOSITE1,
252 .vmux = SAA7115_COMPOSITE0, 303 .vmux = SAA7115_COMPOSITE0,
253 .amux = 1, 304 .amux = EM28XX_AMUX_LINE_IN,
254 }, { 305 }, {
255 .type = EM28XX_VMUX_SVIDEO, 306 .type = EM28XX_VMUX_SVIDEO,
256 .vmux = SAA7115_SVIDEO3, 307 .vmux = SAA7115_SVIDEO3,
257 .amux = 1, 308 .amux = EM28XX_AMUX_LINE_IN,
258 } }, 309 } },
259 }, 310 },
260 [EM2820_BOARD_LEADTEK_WINFAST_USBII_DELUXE] = { 311 [EM2820_BOARD_LEADTEK_WINFAST_USBII_DELUXE] = {
261 .name = "Leadtek Winfast USB II Deluxe", 312 .name = "Leadtek Winfast USB II Deluxe",
262 .valid = EM28XX_BOARD_NOT_VALIDATED, 313 .valid = EM28XX_BOARD_NOT_VALIDATED,
263 .vchannels = 3,
264 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, 314 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
265 .tda9887_conf = TDA9887_PRESENT, 315 .tda9887_conf = TDA9887_PRESENT,
266 .decoder = EM28XX_SAA7114, 316 .decoder = EM28XX_SAA711X,
267 .input = { { 317 .input = { {
268 .type = EM28XX_VMUX_TELEVISION, 318 .type = EM28XX_VMUX_TELEVISION,
269 .vmux = 2, 319 .vmux = SAA7115_COMPOSITE2,
270 .amux = 0, 320 .amux = EM28XX_AMUX_VIDEO,
271 }, { 321 }, {
272 .type = EM28XX_VMUX_COMPOSITE1, 322 .type = EM28XX_VMUX_COMPOSITE1,
273 .vmux = 0,
274 .amux = 1,
275 }, {
276 .type = EM28XX_VMUX_SVIDEO,
277 .vmux = 9,
278 .amux = 1,
279 } },
280 },
281 [EM2820_BOARD_PINNACLE_DVC_100] = {
282 .name = "Pinnacle Dazzle DVC 100",
283 .valid = EM28XX_BOARD_NOT_VALIDATED,
284 .vchannels = 3,
285 .decoder = EM28XX_SAA7113,
286 .input = { {
287 .type = EM28XX_VMUX_COMPOSITE1,
288 .vmux = SAA7115_COMPOSITE0, 323 .vmux = SAA7115_COMPOSITE0,
289 .amux = 1, 324 .amux = EM28XX_AMUX_LINE_IN,
290 }, { 325 }, {
291 .type = EM28XX_VMUX_SVIDEO, 326 .type = EM28XX_VMUX_SVIDEO,
292 .vmux = SAA7115_SVIDEO3, 327 .vmux = SAA7115_COMPOSITE0,
293 .amux = 1, 328 .amux = EM28XX_AMUX_LINE_IN,
294 } }, 329 } },
295 }, 330 },
296 [EM2820_BOARD_VIDEOLOGY_20K14XUSB] = { 331 [EM2820_BOARD_VIDEOLOGY_20K14XUSB] = {
297 .name = "Videology 20K14XUSB USB2.0", 332 .name = "Videology 20K14XUSB USB2.0",
298 .valid = EM28XX_BOARD_NOT_VALIDATED, 333 .valid = EM28XX_BOARD_NOT_VALIDATED,
299 .vchannels = 1, 334 .tuner_type = TUNER_ABSENT, /* This is a webcam */
300 .input = { { 335 .input = { {
301 .type = EM28XX_VMUX_COMPOSITE1, 336 .type = EM28XX_VMUX_COMPOSITE1,
302 .vmux = 0, 337 .vmux = 0,
303 .amux = 0, 338 .amux = EM28XX_AMUX_VIDEO,
304 } }, 339 } },
305 }, 340 },
306 [EM2821_BOARD_PROLINK_PLAYTV_USB2] = { 341 [EM2821_BOARD_PROLINK_PLAYTV_USB2] = {
307 .name = "SIIG AVTuner-PVR/Prolink PlayTV USB 2.0", 342 .name = "SIIG AVTuner-PVR/Prolink PlayTV USB 2.0",
308 .valid = EM28XX_BOARD_NOT_VALIDATED, 343 .valid = EM28XX_BOARD_NOT_VALIDATED,
309 .vchannels = 3,
310 .is_em2800 = 0,
311 .tuner_type = TUNER_LG_PAL_NEW_TAPC, /* unknown? */ 344 .tuner_type = TUNER_LG_PAL_NEW_TAPC, /* unknown? */
312 .tda9887_conf = TDA9887_PRESENT, /* unknown? */ 345 .tda9887_conf = TDA9887_PRESENT, /* unknown? */
313 .decoder = EM28XX_SAA7113, 346 .decoder = EM28XX_SAA711X,
314 .input = { { 347 .input = { {
315 .type = EM28XX_VMUX_TELEVISION, 348 .type = EM28XX_VMUX_TELEVISION,
316 .vmux = SAA7115_COMPOSITE2, 349 .vmux = SAA7115_COMPOSITE2,
317 .amux = 1, 350 .amux = EM28XX_AMUX_LINE_IN,
318 }, { 351 }, {
319 .type = EM28XX_VMUX_COMPOSITE1, 352 .type = EM28XX_VMUX_COMPOSITE1,
320 .vmux = SAA7115_COMPOSITE0, 353 .vmux = SAA7115_COMPOSITE0,
321 .amux = 1, 354 .amux = EM28XX_AMUX_LINE_IN,
322 }, { 355 }, {
323 .type = EM28XX_VMUX_SVIDEO, 356 .type = EM28XX_VMUX_SVIDEO,
324 .vmux = SAA7115_SVIDEO3, 357 .vmux = SAA7115_SVIDEO3,
325 .amux = 1, 358 .amux = EM28XX_AMUX_LINE_IN,
326 } }, 359 } },
327 }, 360 },
328 [EM2821_BOARD_SUPERCOMP_USB_2] = { 361 [EM2821_BOARD_SUPERCOMP_USB_2] = {
329 .name = "Supercomp USB 2.0 TV", 362 .name = "Supercomp USB 2.0 TV",
330 .valid = EM28XX_BOARD_NOT_VALIDATED, 363 .valid = EM28XX_BOARD_NOT_VALIDATED,
331 .vchannels = 3,
332 .is_em2800 = 0,
333 .tuner_type = TUNER_PHILIPS_FM1236_MK3, 364 .tuner_type = TUNER_PHILIPS_FM1236_MK3,
334 .tda9887_conf = TDA9887_PRESENT | 365 .tda9887_conf = TDA9887_PRESENT |
335 TDA9887_PORT1_ACTIVE | 366 TDA9887_PORT1_ACTIVE |
336 TDA9887_PORT2_ACTIVE, 367 TDA9887_PORT2_ACTIVE,
337 .decoder = EM28XX_SAA7113, 368 .decoder = EM28XX_SAA711X,
338 .input = { { 369 .input = { {
339 .type = EM28XX_VMUX_TELEVISION, 370 .type = EM28XX_VMUX_TELEVISION,
340 .vmux = SAA7115_COMPOSITE2, 371 .vmux = SAA7115_COMPOSITE2,
341 .amux = 1, 372 .amux = EM28XX_AMUX_LINE_IN,
342 }, { 373 }, {
343 .type = EM28XX_VMUX_COMPOSITE1, 374 .type = EM28XX_VMUX_COMPOSITE1,
344 .vmux = SAA7115_COMPOSITE0, 375 .vmux = SAA7115_COMPOSITE0,
345 .amux = 0, 376 .amux = EM28XX_AMUX_VIDEO,
346 }, { 377 }, {
347 .type = EM28XX_VMUX_SVIDEO, 378 .type = EM28XX_VMUX_SVIDEO,
348 .vmux = SAA7115_SVIDEO3, 379 .vmux = SAA7115_SVIDEO3,
349 .amux = 1, 380 .amux = EM28XX_AMUX_LINE_IN,
350 } }, 381 } },
351 }, 382 },
352 [EM2821_BOARD_USBGEAR_VD204] = { 383 [EM2821_BOARD_USBGEAR_VD204] = {
353 .name = "Usbgear VD204v9", 384 .name = "Usbgear VD204v9",
354 .valid = EM28XX_BOARD_NOT_VALIDATED, 385 .valid = EM28XX_BOARD_NOT_VALIDATED,
355 .vchannels = 2, 386 .tuner_type = TUNER_ABSENT, /* Capture only device */
356 .decoder = EM28XX_SAA7113, 387 .decoder = EM28XX_SAA711X,
357 .input = { { 388 .input = { {
358 .type = EM28XX_VMUX_COMPOSITE1, 389 .type = EM28XX_VMUX_COMPOSITE1,
359 .vmux = SAA7115_COMPOSITE0, 390 .vmux = SAA7115_COMPOSITE0,
360 .amux = 1, 391 .amux = EM28XX_AMUX_LINE_IN,
361 }, { 392 }, {
362 .type = EM28XX_VMUX_SVIDEO, 393 .type = EM28XX_VMUX_SVIDEO,
363 .vmux = SAA7115_SVIDEO3, 394 .vmux = SAA7115_SVIDEO3,
364 .amux = 1, 395 .amux = EM28XX_AMUX_LINE_IN,
365 } }, 396 } },
366 }, 397 },
367 [EM2860_BOARD_NETGMBH_CAM] = { 398 [EM2860_BOARD_NETGMBH_CAM] = {
368 /* Beijing Huaqi Information Digital Technology Co., Ltd */ 399 /* Beijing Huaqi Information Digital Technology Co., Ltd */
369 .name = "NetGMBH Cam", 400 .name = "NetGMBH Cam",
370 .valid = EM28XX_BOARD_NOT_VALIDATED, 401 .valid = EM28XX_BOARD_NOT_VALIDATED,
371 .vchannels = 1, 402 .tuner_type = TUNER_ABSENT, /* This is a webcam */
372 .input = { { 403 .input = { {
373 .type = EM28XX_VMUX_COMPOSITE1, 404 .type = EM28XX_VMUX_COMPOSITE1,
374 .vmux = 0, 405 .vmux = 0,
375 .amux = 0, 406 .amux = EM28XX_AMUX_VIDEO,
376 } }, 407 } },
377 }, 408 },
378 [EM2860_BOARD_TYPHOON_DVD_MAKER] = { 409 [EM2860_BOARD_TYPHOON_DVD_MAKER] = {
379 .name = "Typhoon DVD Maker", 410 .name = "Typhoon DVD Maker",
380 .valid = EM28XX_BOARD_NOT_VALIDATED, 411 .decoder = EM28XX_SAA711X,
381 .vchannels = 2, 412 .tuner_type = TUNER_ABSENT, /* Capture only device */
382 .decoder = EM28XX_SAA7113, 413 .input = { {
383 .input = { {
384 .type = EM28XX_VMUX_COMPOSITE1, 414 .type = EM28XX_VMUX_COMPOSITE1,
385 .vmux = SAA7115_COMPOSITE0, 415 .vmux = SAA7115_COMPOSITE0,
386 .amux = 1, 416 .amux = EM28XX_AMUX_LINE_IN,
387 }, { 417 }, {
388 .type = EM28XX_VMUX_SVIDEO, 418 .type = EM28XX_VMUX_SVIDEO,
389 .vmux = SAA7115_SVIDEO3, 419 .vmux = SAA7115_SVIDEO3,
390 .amux = 1, 420 .amux = EM28XX_AMUX_LINE_IN,
391 } }, 421 } },
392 }, 422 },
393 [EM2860_BOARD_GADMEI_UTV330] = { 423 [EM2860_BOARD_GADMEI_UTV330] = {
394 .name = "Gadmei UTV330", 424 .name = "Gadmei UTV330",
395 .valid = EM28XX_BOARD_NOT_VALIDATED, 425 .valid = EM28XX_BOARD_NOT_VALIDATED,
396 .vchannels = 3,
397 .tuner_type = TUNER_TNF_5335MF, 426 .tuner_type = TUNER_TNF_5335MF,
398 .tda9887_conf = TDA9887_PRESENT, 427 .tda9887_conf = TDA9887_PRESENT,
399 .decoder = EM28XX_SAA7113, 428 .decoder = EM28XX_SAA711X,
400 .input = { { 429 .input = { {
401 .type = EM28XX_VMUX_TELEVISION, 430 .type = EM28XX_VMUX_TELEVISION,
402 .vmux = SAA7115_COMPOSITE2, 431 .vmux = SAA7115_COMPOSITE2,
403 .amux = 0, 432 .amux = EM28XX_AMUX_VIDEO,
404 }, { 433 }, {
405 .type = EM28XX_VMUX_COMPOSITE1, 434 .type = EM28XX_VMUX_COMPOSITE1,
406 .vmux = SAA7115_COMPOSITE0, 435 .vmux = SAA7115_COMPOSITE0,
407 .amux = 1, 436 .amux = EM28XX_AMUX_LINE_IN,
408 }, { 437 }, {
409 .type = EM28XX_VMUX_SVIDEO, 438 .type = EM28XX_VMUX_SVIDEO,
410 .vmux = SAA7115_SVIDEO3, 439 .vmux = SAA7115_SVIDEO3,
411 .amux = 1, 440 .amux = EM28XX_AMUX_LINE_IN,
412 } }, 441 } },
413 }, 442 },
414 [EM2860_BOARD_TERRATEC_HYBRID_XS] = { 443 [EM2860_BOARD_TERRATEC_HYBRID_XS] = {
415 .name = "Terratec Cinergy A Hybrid XS", 444 .name = "Terratec Cinergy A Hybrid XS",
416 .valid = EM28XX_BOARD_NOT_VALIDATED, 445 .valid = EM28XX_BOARD_NOT_VALIDATED,
417 .vchannels = 3,
418 .tuner_type = TUNER_XC2028, 446 .tuner_type = TUNER_XC2028,
447 .tuner_gpio = default_tuner_gpio,
419 .decoder = EM28XX_TVP5150, 448 .decoder = EM28XX_TVP5150,
420 .input = { { 449
450 .input = { {
421 .type = EM28XX_VMUX_TELEVISION, 451 .type = EM28XX_VMUX_TELEVISION,
422 .vmux = TVP5150_COMPOSITE0, 452 .vmux = TVP5150_COMPOSITE0,
423 .amux = 0, 453 .amux = EM28XX_AMUX_VIDEO,
454 .gpio = hauppauge_wintv_hvr_900_analog,
424 }, { 455 }, {
425 .type = EM28XX_VMUX_COMPOSITE1, 456 .type = EM28XX_VMUX_COMPOSITE1,
426 .vmux = TVP5150_COMPOSITE1, 457 .vmux = TVP5150_COMPOSITE1,
427 .amux = 1, 458 .amux = EM28XX_AMUX_LINE_IN,
459 .gpio = hauppauge_wintv_hvr_900_analog,
428 }, { 460 }, {
429 .type = EM28XX_VMUX_SVIDEO, 461 .type = EM28XX_VMUX_SVIDEO,
430 .vmux = TVP5150_SVIDEO, 462 .vmux = TVP5150_SVIDEO,
431 .amux = 1, 463 .amux = EM28XX_AMUX_LINE_IN,
464 .gpio = hauppauge_wintv_hvr_900_analog,
432 } }, 465 } },
433 }, 466 },
434 [EM2861_BOARD_KWORLD_PVRTV_300U] = { 467 [EM2861_BOARD_KWORLD_PVRTV_300U] = {
435 .name = "KWorld PVRTV 300U", 468 .name = "KWorld PVRTV 300U",
436 .valid = EM28XX_BOARD_NOT_VALIDATED, 469 .valid = EM28XX_BOARD_NOT_VALIDATED,
437 .vchannels = 3,
438 .tuner_type = TUNER_XC2028, 470 .tuner_type = TUNER_XC2028,
471 .tuner_gpio = default_tuner_gpio,
439 .decoder = EM28XX_TVP5150, 472 .decoder = EM28XX_TVP5150,
440 .input = { { 473 .input = { {
441 .type = EM28XX_VMUX_TELEVISION, 474 .type = EM28XX_VMUX_TELEVISION,
442 .vmux = TVP5150_COMPOSITE0, 475 .vmux = TVP5150_COMPOSITE0,
443 .amux = 0, 476 .amux = EM28XX_AMUX_VIDEO,
444 }, { 477 }, {
445 .type = EM28XX_VMUX_COMPOSITE1, 478 .type = EM28XX_VMUX_COMPOSITE1,
446 .vmux = TVP5150_COMPOSITE1, 479 .vmux = TVP5150_COMPOSITE1,
447 .amux = 1, 480 .amux = EM28XX_AMUX_LINE_IN,
448 }, { 481 }, {
449 .type = EM28XX_VMUX_SVIDEO, 482 .type = EM28XX_VMUX_SVIDEO,
450 .vmux = TVP5150_SVIDEO, 483 .vmux = TVP5150_SVIDEO,
451 .amux = 1, 484 .amux = EM28XX_AMUX_LINE_IN,
452 } }, 485 } },
453 }, 486 },
454 [EM2861_BOARD_YAKUMO_MOVIE_MIXER] = { 487 [EM2861_BOARD_YAKUMO_MOVIE_MIXER] = {
455 .name = "Yakumo MovieMixer", 488 .name = "Yakumo MovieMixer",
456 .valid = EM28XX_BOARD_NOT_VALIDATED, 489 .tuner_type = TUNER_ABSENT, /* Capture only device */
457 .vchannels = 1,
458 .decoder = EM28XX_TVP5150, 490 .decoder = EM28XX_TVP5150,
459 .input = { { 491 .input = { {
460 .type = EM28XX_VMUX_TELEVISION, 492 .type = EM28XX_VMUX_TELEVISION,
461 .vmux = TVP5150_COMPOSITE0, 493 .vmux = TVP5150_COMPOSITE0,
462 .amux = 0, 494 .amux = EM28XX_AMUX_VIDEO,
463 }, { 495 }, {
464 .type = EM28XX_VMUX_COMPOSITE1, 496 .type = EM28XX_VMUX_COMPOSITE1,
465 .vmux = TVP5150_COMPOSITE1, 497 .vmux = TVP5150_COMPOSITE1,
466 .amux = 1, 498 .amux = EM28XX_AMUX_LINE_IN,
467 }, { 499 }, {
468 .type = EM28XX_VMUX_SVIDEO, 500 .type = EM28XX_VMUX_SVIDEO,
469 .vmux = TVP5150_SVIDEO, 501 .vmux = TVP5150_SVIDEO,
470 .amux = 1, 502 .amux = EM28XX_AMUX_LINE_IN,
471 } }, 503 } },
472 }, 504 },
473 [EM2861_BOARD_PLEXTOR_PX_TV100U] = { 505 [EM2861_BOARD_PLEXTOR_PX_TV100U] = {
474 .name = "Plextor ConvertX PX-TV100U", 506 .name = "Plextor ConvertX PX-TV100U",
475 .valid = EM28XX_BOARD_NOT_VALIDATED, 507 .valid = EM28XX_BOARD_NOT_VALIDATED,
476 .vchannels = 3,
477 .tuner_type = TUNER_TNF_5335MF, 508 .tuner_type = TUNER_TNF_5335MF,
478 .tda9887_conf = TDA9887_PRESENT, 509 .tda9887_conf = TDA9887_PRESENT,
479 .decoder = EM28XX_TVP5150, 510 .decoder = EM28XX_TVP5150,
480 .input = { { 511 .input = { {
481 .type = EM28XX_VMUX_TELEVISION, 512 .type = EM28XX_VMUX_TELEVISION,
482 .vmux = TVP5150_COMPOSITE0, 513 .vmux = TVP5150_COMPOSITE0,
483 .amux = 1, 514 .amux = EM28XX_AMUX_LINE_IN,
484 }, { 515 }, {
485 .type = EM28XX_VMUX_COMPOSITE1, 516 .type = EM28XX_VMUX_COMPOSITE1,
486 .vmux = TVP5150_COMPOSITE1, 517 .vmux = TVP5150_COMPOSITE1,
487 .amux = 1, 518 .amux = EM28XX_AMUX_LINE_IN,
488 }, { 519 }, {
489 .type = EM28XX_VMUX_SVIDEO, 520 .type = EM28XX_VMUX_SVIDEO,
490 .vmux = TVP5150_SVIDEO, 521 .vmux = TVP5150_SVIDEO,
491 .amux = 1, 522 .amux = EM28XX_AMUX_LINE_IN,
492 } }, 523 } },
493 }, 524 },
525
526 /* Those boards with em2870 are DVB Only*/
527
494 [EM2870_BOARD_TERRATEC_XS] = { 528 [EM2870_BOARD_TERRATEC_XS] = {
495 .name = "Terratec Cinergy T XS", 529 .name = "Terratec Cinergy T XS",
496 .valid = EM28XX_BOARD_NOT_VALIDATED, 530 .valid = EM28XX_BOARD_NOT_VALIDATED,
497 .tuner_type = TUNER_XC2028, 531 .tuner_type = TUNER_XC2028,
532 .tuner_gpio = default_tuner_gpio,
498 }, 533 },
499 [EM2870_BOARD_TERRATEC_XS_MT2060] = { 534 [EM2870_BOARD_TERRATEC_XS_MT2060] = {
500 .name = "Terratec Cinergy T XS (MT2060)", 535 .name = "Terratec Cinergy T XS (MT2060)",
@@ -505,6 +540,7 @@ struct em28xx_board em28xx_boards[] = {
505 .name = "Kworld 350 U DVB-T", 540 .name = "Kworld 350 U DVB-T",
506 .valid = EM28XX_BOARD_NOT_VALIDATED, 541 .valid = EM28XX_BOARD_NOT_VALIDATED,
507 .tuner_type = TUNER_XC2028, 542 .tuner_type = TUNER_XC2028,
543 .tuner_gpio = default_tuner_gpio,
508 }, 544 },
509 [EM2870_BOARD_KWORLD_355U] = { 545 [EM2870_BOARD_KWORLD_355U] = {
510 .name = "Kworld 355 U DVB-T", 546 .name = "Kworld 355 U DVB-T",
@@ -514,164 +550,216 @@ struct em28xx_board em28xx_boards[] = {
514 .name = "Pinnacle PCTV DVB-T", 550 .name = "Pinnacle PCTV DVB-T",
515 .valid = EM28XX_BOARD_NOT_VALIDATED, 551 .valid = EM28XX_BOARD_NOT_VALIDATED,
516 .tuner_type = TUNER_ABSENT, /* MT2060 */ 552 .tuner_type = TUNER_ABSENT, /* MT2060 */
553 /* djh - I have serious doubts this is right... */
554 .xclk = EM28XX_XCLK_IR_RC5_MODE |
555 EM28XX_XCLK_FREQUENCY_10MHZ,
517 }, 556 },
518 [EM2870_BOARD_COMPRO_VIDEOMATE] = { 557 [EM2870_BOARD_COMPRO_VIDEOMATE] = {
519 .name = "Compro, VideoMate U3", 558 .name = "Compro, VideoMate U3",
520 .valid = EM28XX_BOARD_NOT_VALIDATED, 559 .valid = EM28XX_BOARD_NOT_VALIDATED,
521 .tuner_type = TUNER_ABSENT, /* MT2060 */ 560 .tuner_type = TUNER_ABSENT, /* MT2060 */
522 }, 561 },
562
523 [EM2880_BOARD_TERRATEC_HYBRID_XS_FR] = { 563 [EM2880_BOARD_TERRATEC_HYBRID_XS_FR] = {
524 .name = "Terratec Hybrid XS Secam", 564 .name = "Terratec Hybrid XS Secam",
525 .valid = EM28XX_BOARD_NOT_VALIDATED, 565 .valid = EM28XX_BOARD_NOT_VALIDATED,
526 .vchannels = 3,
527 .has_msp34xx = 1, 566 .has_msp34xx = 1,
528 .tuner_type = TUNER_XC2028, 567 .tuner_type = TUNER_XC2028,
568 .tuner_gpio = default_tuner_gpio,
529 .decoder = EM28XX_TVP5150, 569 .decoder = EM28XX_TVP5150,
530 .input = { { 570 .input = { {
531 .type = EM28XX_VMUX_TELEVISION, 571 .type = EM28XX_VMUX_TELEVISION,
532 .vmux = TVP5150_COMPOSITE0, 572 .vmux = TVP5150_COMPOSITE0,
533 .amux = 0, 573 .amux = EM28XX_AMUX_VIDEO,
574 .gpio = default_analog,
534 }, { 575 }, {
535 .type = EM28XX_VMUX_COMPOSITE1, 576 .type = EM28XX_VMUX_COMPOSITE1,
536 .vmux = TVP5150_COMPOSITE1, 577 .vmux = TVP5150_COMPOSITE1,
537 .amux = 1, 578 .amux = EM28XX_AMUX_LINE_IN,
579 .gpio = default_analog,
538 }, { 580 }, {
539 .type = EM28XX_VMUX_SVIDEO, 581 .type = EM28XX_VMUX_SVIDEO,
540 .vmux = TVP5150_SVIDEO, 582 .vmux = TVP5150_SVIDEO,
541 .amux = 1, 583 .amux = EM28XX_AMUX_LINE_IN,
584 .gpio = default_analog,
542 } }, 585 } },
543 }, 586 },
544 [EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900] = { 587 [EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900] = {
545 .name = "Hauppauge WinTV HVR 900", 588 .name = "Hauppauge WinTV HVR 900",
546 .vchannels = 3,
547 .tda9887_conf = TDA9887_PRESENT, 589 .tda9887_conf = TDA9887_PRESENT,
548 .tuner_type = TUNER_XC2028, 590 .tuner_type = TUNER_XC2028,
591 .tuner_gpio = default_tuner_gpio,
549 .mts_firmware = 1, 592 .mts_firmware = 1,
550 .has_dvb = 1, 593 .has_dvb = 1,
594 .dvb_gpio = hauppauge_wintv_hvr_900_digital,
551 .decoder = EM28XX_TVP5150, 595 .decoder = EM28XX_TVP5150,
552 .input = { { 596 .input = { {
553 .type = EM28XX_VMUX_TELEVISION, 597 .type = EM28XX_VMUX_TELEVISION,
554 .vmux = TVP5150_COMPOSITE0, 598 .vmux = TVP5150_COMPOSITE0,
555 .amux = 0, 599 .amux = EM28XX_AMUX_VIDEO,
600 .gpio = hauppauge_wintv_hvr_900_analog,
556 }, { 601 }, {
557 .type = EM28XX_VMUX_COMPOSITE1, 602 .type = EM28XX_VMUX_COMPOSITE1,
558 .vmux = TVP5150_COMPOSITE1, 603 .vmux = TVP5150_COMPOSITE1,
559 .amux = 1, 604 .amux = EM28XX_AMUX_LINE_IN,
605 .gpio = hauppauge_wintv_hvr_900_analog,
560 }, { 606 }, {
561 .type = EM28XX_VMUX_SVIDEO, 607 .type = EM28XX_VMUX_SVIDEO,
562 .vmux = TVP5150_SVIDEO, 608 .vmux = TVP5150_SVIDEO,
563 .amux = 1, 609 .amux = EM28XX_AMUX_LINE_IN,
610 .gpio = hauppauge_wintv_hvr_900_analog,
564 } }, 611 } },
565 }, 612 },
566 [EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2] = { 613 [EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2] = {
567 .name = "Hauppauge WinTV HVR 900 (R2)", 614 .name = "Hauppauge WinTV HVR 900 (R2)",
568 .vchannels = 3,
569 .tda9887_conf = TDA9887_PRESENT, 615 .tda9887_conf = TDA9887_PRESENT,
570 .tuner_type = TUNER_XC2028, 616 .tuner_type = TUNER_XC2028,
617 .tuner_gpio = default_tuner_gpio,
571 .mts_firmware = 1, 618 .mts_firmware = 1,
572 .decoder = EM28XX_TVP5150, 619 .decoder = EM28XX_TVP5150,
620 .input = { {
621 .type = EM28XX_VMUX_TELEVISION,
622 .vmux = TVP5150_COMPOSITE0,
623 .amux = EM28XX_AMUX_VIDEO,
624 .gpio = hauppauge_wintv_hvr_900_analog,
625 }, {
626 .type = EM28XX_VMUX_COMPOSITE1,
627 .vmux = TVP5150_COMPOSITE1,
628 .amux = EM28XX_AMUX_LINE_IN,
629 .gpio = hauppauge_wintv_hvr_900_analog,
630 }, {
631 .type = EM28XX_VMUX_SVIDEO,
632 .vmux = TVP5150_SVIDEO,
633 .amux = EM28XX_AMUX_LINE_IN,
634 .gpio = hauppauge_wintv_hvr_900_analog,
635 } },
636 },
637 [EM2883_BOARD_HAUPPAUGE_WINTV_HVR_850] = {
638 .name = "Hauppauge WinTV HVR 850",
639 .tuner_type = TUNER_XC2028,
640 .tuner_gpio = default_tuner_gpio,
641 .mts_firmware = 1,
642 .has_dvb = 1,
643 .dvb_gpio = hauppauge_wintv_hvr_900_digital,
644 .ir_codes = ir_codes_hauppauge_new,
645 .decoder = EM28XX_TVP5150,
573 .input = { { 646 .input = { {
574 .type = EM28XX_VMUX_TELEVISION, 647 .type = EM28XX_VMUX_TELEVISION,
575 .vmux = TVP5150_COMPOSITE0, 648 .vmux = TVP5150_COMPOSITE0,
576 .amux = 0, 649 .amux = EM28XX_AMUX_VIDEO,
650 .gpio = hauppauge_wintv_hvr_900_analog,
577 }, { 651 }, {
578 .type = EM28XX_VMUX_COMPOSITE1, 652 .type = EM28XX_VMUX_COMPOSITE1,
579 .vmux = TVP5150_COMPOSITE1, 653 .vmux = TVP5150_COMPOSITE1,
580 .amux = 3, 654 .amux = EM28XX_AMUX_LINE_IN,
655 .gpio = hauppauge_wintv_hvr_900_analog,
581 }, { 656 }, {
582 .type = EM28XX_VMUX_SVIDEO, 657 .type = EM28XX_VMUX_SVIDEO,
583 .vmux = TVP5150_SVIDEO, 658 .vmux = TVP5150_SVIDEO,
584 .amux = 1, 659 .amux = EM28XX_AMUX_LINE_IN,
660 .gpio = hauppauge_wintv_hvr_900_analog,
585 } }, 661 } },
586 }, 662 },
587 [EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950] = { 663 [EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950] = {
588 .name = "Hauppauge WinTV HVR 950", 664 .name = "Hauppauge WinTV HVR 950",
589 .vchannels = 3,
590 .tda9887_conf = TDA9887_PRESENT,
591 .tuner_type = TUNER_XC2028, 665 .tuner_type = TUNER_XC2028,
666 .tuner_gpio = default_tuner_gpio,
592 .mts_firmware = 1, 667 .mts_firmware = 1,
593 .has_12mhz_i2s = 1,
594 .has_dvb = 1, 668 .has_dvb = 1,
669 .dvb_gpio = hauppauge_wintv_hvr_900_digital,
670 .ir_codes = ir_codes_hauppauge_new,
595 .decoder = EM28XX_TVP5150, 671 .decoder = EM28XX_TVP5150,
596 .input = { { 672 .input = { {
597 .type = EM28XX_VMUX_TELEVISION, 673 .type = EM28XX_VMUX_TELEVISION,
598 .vmux = TVP5150_COMPOSITE0, 674 .vmux = TVP5150_COMPOSITE0,
599 .amux = 0, 675 .amux = EM28XX_AMUX_VIDEO,
676 .gpio = hauppauge_wintv_hvr_900_analog,
600 }, { 677 }, {
601 .type = EM28XX_VMUX_COMPOSITE1, 678 .type = EM28XX_VMUX_COMPOSITE1,
602 .vmux = TVP5150_COMPOSITE1, 679 .vmux = TVP5150_COMPOSITE1,
603 .amux = 1, 680 .amux = EM28XX_AMUX_LINE_IN,
681 .gpio = hauppauge_wintv_hvr_900_analog,
604 }, { 682 }, {
605 .type = EM28XX_VMUX_SVIDEO, 683 .type = EM28XX_VMUX_SVIDEO,
606 .vmux = TVP5150_SVIDEO, 684 .vmux = TVP5150_SVIDEO,
607 .amux = 1, 685 .amux = EM28XX_AMUX_LINE_IN,
686 .gpio = hauppauge_wintv_hvr_900_analog,
608 } }, 687 } },
609 }, 688 },
610 [EM2880_BOARD_PINNACLE_PCTV_HD_PRO] = { 689 [EM2880_BOARD_PINNACLE_PCTV_HD_PRO] = {
611 .name = "Pinnacle PCTV HD Pro Stick", 690 .name = "Pinnacle PCTV HD Pro Stick",
612 .vchannels = 3,
613 .tda9887_conf = TDA9887_PRESENT,
614 .tuner_type = TUNER_XC2028, 691 .tuner_type = TUNER_XC2028,
692 .tuner_gpio = default_tuner_gpio,
615 .mts_firmware = 1, 693 .mts_firmware = 1,
616 .has_12mhz_i2s = 1,
617 .has_dvb = 1, 694 .has_dvb = 1,
695 .dvb_gpio = hauppauge_wintv_hvr_900_digital,
696 .ir_codes = ir_codes_pinnacle_pctv_hd,
618 .decoder = EM28XX_TVP5150, 697 .decoder = EM28XX_TVP5150,
619 .input = { { 698 .input = { {
620 .type = EM28XX_VMUX_TELEVISION, 699 .type = EM28XX_VMUX_TELEVISION,
621 .vmux = TVP5150_COMPOSITE0, 700 .vmux = TVP5150_COMPOSITE0,
622 .amux = 0, 701 .amux = EM28XX_AMUX_VIDEO,
702 .gpio = hauppauge_wintv_hvr_900_analog,
623 }, { 703 }, {
624 .type = EM28XX_VMUX_COMPOSITE1, 704 .type = EM28XX_VMUX_COMPOSITE1,
625 .vmux = TVP5150_COMPOSITE1, 705 .vmux = TVP5150_COMPOSITE1,
626 .amux = 1, 706 .amux = EM28XX_AMUX_LINE_IN,
707 .gpio = hauppauge_wintv_hvr_900_analog,
627 }, { 708 }, {
628 .type = EM28XX_VMUX_SVIDEO, 709 .type = EM28XX_VMUX_SVIDEO,
629 .vmux = TVP5150_SVIDEO, 710 .vmux = TVP5150_SVIDEO,
630 .amux = 1, 711 .amux = EM28XX_AMUX_LINE_IN,
712 .gpio = hauppauge_wintv_hvr_900_analog,
631 } }, 713 } },
632 }, 714 },
633 [EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600] = { 715 [EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600] = {
634 .name = "AMD ATI TV Wonder HD 600", 716 .name = "AMD ATI TV Wonder HD 600",
635 .vchannels = 3,
636 .tda9887_conf = TDA9887_PRESENT,
637 .tuner_type = TUNER_XC2028, 717 .tuner_type = TUNER_XC2028,
718 .tuner_gpio = default_tuner_gpio,
638 .mts_firmware = 1, 719 .mts_firmware = 1,
639 .has_12mhz_i2s = 1,
640 .has_dvb = 1, 720 .has_dvb = 1,
721 .dvb_gpio = hauppauge_wintv_hvr_900_digital,
722 .ir_codes = ir_codes_ati_tv_wonder_hd_600,
641 .decoder = EM28XX_TVP5150, 723 .decoder = EM28XX_TVP5150,
642 .input = { { 724 .input = { {
643 .type = EM28XX_VMUX_TELEVISION, 725 .type = EM28XX_VMUX_TELEVISION,
644 .vmux = TVP5150_COMPOSITE0, 726 .vmux = TVP5150_COMPOSITE0,
645 .amux = 0, 727 .amux = EM28XX_AMUX_VIDEO,
728 .gpio = hauppauge_wintv_hvr_900_analog,
646 }, { 729 }, {
647 .type = EM28XX_VMUX_COMPOSITE1, 730 .type = EM28XX_VMUX_COMPOSITE1,
648 .vmux = TVP5150_COMPOSITE1, 731 .vmux = TVP5150_COMPOSITE1,
649 .amux = 1, 732 .amux = EM28XX_AMUX_LINE_IN,
733 .gpio = hauppauge_wintv_hvr_900_analog,
650 }, { 734 }, {
651 .type = EM28XX_VMUX_SVIDEO, 735 .type = EM28XX_VMUX_SVIDEO,
652 .vmux = TVP5150_SVIDEO, 736 .vmux = TVP5150_SVIDEO,
653 .amux = 1, 737 .amux = EM28XX_AMUX_LINE_IN,
738 .gpio = hauppauge_wintv_hvr_900_analog,
654 } }, 739 } },
655 }, 740 },
656 [EM2880_BOARD_TERRATEC_HYBRID_XS] = { 741 [EM2880_BOARD_TERRATEC_HYBRID_XS] = {
657 .name = "Terratec Hybrid XS", 742 .name = "Terratec Hybrid XS",
658 .vchannels = 3, 743 .tuner_type = TUNER_XC2028,
659 .tda9887_conf = TDA9887_PRESENT, 744 .tuner_gpio = default_tuner_gpio,
660 .tuner_type = TUNER_XC2028, 745 .decoder = EM28XX_TVP5150,
661 .decoder = EM28XX_TVP5150,
662 .has_dvb = 1, 746 .has_dvb = 1,
747 .dvb_gpio = default_analog,
663 .input = { { 748 .input = { {
664 .type = EM28XX_VMUX_TELEVISION, 749 .type = EM28XX_VMUX_TELEVISION,
665 .vmux = TVP5150_COMPOSITE0, 750 .vmux = TVP5150_COMPOSITE0,
666 .amux = 0, 751 .amux = EM28XX_AMUX_VIDEO,
752 .gpio = default_analog,
667 }, { 753 }, {
668 .type = EM28XX_VMUX_COMPOSITE1, 754 .type = EM28XX_VMUX_COMPOSITE1,
669 .vmux = TVP5150_COMPOSITE1, 755 .vmux = TVP5150_COMPOSITE1,
670 .amux = 1, 756 .amux = EM28XX_AMUX_LINE_IN,
757 .gpio = default_analog,
671 }, { 758 }, {
672 .type = EM28XX_VMUX_SVIDEO, 759 .type = EM28XX_VMUX_SVIDEO,
673 .vmux = TVP5150_SVIDEO, 760 .vmux = TVP5150_SVIDEO,
674 .amux = 1, 761 .amux = EM28XX_AMUX_LINE_IN,
762 .gpio = default_analog,
675 } }, 763 } },
676 }, 764 },
677 /* maybe there's a reason behind it why Terratec sells the Hybrid XS 765 /* maybe there's a reason behind it why Terratec sells the Hybrid XS
@@ -679,172 +767,190 @@ struct em28xx_board em28xx_boards[] = {
679 maybe we'll need it lateron */ 767 maybe we'll need it lateron */
680 [EM2880_BOARD_TERRATEC_PRODIGY_XS] = { 768 [EM2880_BOARD_TERRATEC_PRODIGY_XS] = {
681 .name = "Terratec Prodigy XS", 769 .name = "Terratec Prodigy XS",
682 .vchannels = 3,
683 .tda9887_conf = TDA9887_PRESENT,
684 .tuner_type = TUNER_XC2028, 770 .tuner_type = TUNER_XC2028,
771 .tuner_gpio = default_tuner_gpio,
685 .decoder = EM28XX_TVP5150, 772 .decoder = EM28XX_TVP5150,
686 .input = { { 773 .input = { {
687 .type = EM28XX_VMUX_TELEVISION, 774 .type = EM28XX_VMUX_TELEVISION,
688 .vmux = TVP5150_COMPOSITE0, 775 .vmux = TVP5150_COMPOSITE0,
689 .amux = 0, 776 .amux = EM28XX_AMUX_VIDEO,
777 .gpio = hauppauge_wintv_hvr_900_analog,
690 }, { 778 }, {
691 .type = EM28XX_VMUX_COMPOSITE1, 779 .type = EM28XX_VMUX_COMPOSITE1,
692 .vmux = TVP5150_COMPOSITE1, 780 .vmux = TVP5150_COMPOSITE1,
693 .amux = 1, 781 .amux = EM28XX_AMUX_LINE_IN,
782 .gpio = hauppauge_wintv_hvr_900_analog,
694 }, { 783 }, {
695 .type = EM28XX_VMUX_SVIDEO, 784 .type = EM28XX_VMUX_SVIDEO,
696 .vmux = TVP5150_SVIDEO, 785 .vmux = TVP5150_SVIDEO,
697 .amux = 1, 786 .amux = EM28XX_AMUX_LINE_IN,
787 .gpio = hauppauge_wintv_hvr_900_analog,
698 } }, 788 } },
699 }, 789 },
700 [EM2820_BOARD_MSI_VOX_USB_2] = { 790 [EM2820_BOARD_MSI_VOX_USB_2] = {
701 .name = "MSI VOX USB 2.0", 791 .name = "MSI VOX USB 2.0",
702 .vchannels = 3,
703 .tuner_type = TUNER_LG_PAL_NEW_TAPC, 792 .tuner_type = TUNER_LG_PAL_NEW_TAPC,
704 .tda9887_conf = TDA9887_PRESENT | 793 .tda9887_conf = TDA9887_PRESENT |
705 TDA9887_PORT1_ACTIVE | 794 TDA9887_PORT1_ACTIVE |
706 TDA9887_PORT2_ACTIVE, 795 TDA9887_PORT2_ACTIVE,
707 .max_range_640_480 = 1, 796 .max_range_640_480 = 1,
708 797 .decoder = EM28XX_SAA711X,
709 .decoder = EM28XX_SAA7114,
710 .input = { { 798 .input = { {
711 .type = EM28XX_VMUX_TELEVISION, 799 .type = EM28XX_VMUX_TELEVISION,
712 .vmux = SAA7115_COMPOSITE4, 800 .vmux = SAA7115_COMPOSITE4,
713 .amux = 0, 801 .amux = EM28XX_AMUX_VIDEO,
714 }, { 802 }, {
715 .type = EM28XX_VMUX_COMPOSITE1, 803 .type = EM28XX_VMUX_COMPOSITE1,
716 .vmux = SAA7115_COMPOSITE0, 804 .vmux = SAA7115_COMPOSITE0,
717 .amux = 1, 805 .amux = EM28XX_AMUX_LINE_IN,
718 }, { 806 }, {
719 .type = EM28XX_VMUX_SVIDEO, 807 .type = EM28XX_VMUX_SVIDEO,
720 .vmux = SAA7115_SVIDEO3, 808 .vmux = SAA7115_SVIDEO3,
721 .amux = 1, 809 .amux = EM28XX_AMUX_LINE_IN,
722 } }, 810 } },
723 }, 811 },
724 [EM2800_BOARD_TERRATEC_CINERGY_200] = { 812 [EM2800_BOARD_TERRATEC_CINERGY_200] = {
725 .name = "Terratec Cinergy 200 USB", 813 .name = "Terratec Cinergy 200 USB",
726 .is_em2800 = 1, 814 .is_em2800 = 1,
727 .vchannels = 3,
728 .tuner_type = TUNER_LG_PAL_NEW_TAPC, 815 .tuner_type = TUNER_LG_PAL_NEW_TAPC,
729 .tda9887_conf = TDA9887_PRESENT, 816 .tda9887_conf = TDA9887_PRESENT,
730 .decoder = EM28XX_SAA7113, 817 .decoder = EM28XX_SAA711X,
731 .input = { { 818 .input = { {
732 .type = EM28XX_VMUX_TELEVISION, 819 .type = EM28XX_VMUX_TELEVISION,
733 .vmux = SAA7115_COMPOSITE2, 820 .vmux = SAA7115_COMPOSITE2,
734 .amux = 0, 821 .amux = EM28XX_AMUX_VIDEO,
735 }, { 822 }, {
736 .type = EM28XX_VMUX_COMPOSITE1, 823 .type = EM28XX_VMUX_COMPOSITE1,
737 .vmux = SAA7115_COMPOSITE0, 824 .vmux = SAA7115_COMPOSITE0,
738 .amux = 1, 825 .amux = EM28XX_AMUX_LINE_IN,
739 }, { 826 }, {
740 .type = EM28XX_VMUX_SVIDEO, 827 .type = EM28XX_VMUX_SVIDEO,
741 .vmux = SAA7115_SVIDEO3, 828 .vmux = SAA7115_SVIDEO3,
742 .amux = 1, 829 .amux = EM28XX_AMUX_LINE_IN,
743 } }, 830 } },
744 }, 831 },
745 [EM2800_BOARD_GRABBEEX_USB2800] = { 832 [EM2800_BOARD_GRABBEEX_USB2800] = {
746 .name = "eMPIA Technology, Inc. GrabBeeX+ Video Encoder", 833 .name = "eMPIA Technology, Inc. GrabBeeX+ Video Encoder",
747 .is_em2800 = 1, 834 .is_em2800 = 1,
748 .vchannels = 2, 835 .decoder = EM28XX_SAA711X,
749 .decoder = EM28XX_SAA7113, 836 .tuner_type = TUNER_ABSENT, /* capture only board */
750 .input = { { 837 .input = { {
751 .type = EM28XX_VMUX_COMPOSITE1, 838 .type = EM28XX_VMUX_COMPOSITE1,
752 .vmux = SAA7115_COMPOSITE0, 839 .vmux = SAA7115_COMPOSITE0,
753 .amux = 1, 840 .amux = EM28XX_AMUX_LINE_IN,
754 }, { 841 }, {
755 .type = EM28XX_VMUX_SVIDEO, 842 .type = EM28XX_VMUX_SVIDEO,
756 .vmux = SAA7115_SVIDEO3, 843 .vmux = SAA7115_SVIDEO3,
757 .amux = 1, 844 .amux = EM28XX_AMUX_LINE_IN,
758 } }, 845 } },
759 }, 846 },
760 [EM2800_BOARD_LEADTEK_WINFAST_USBII] = { 847 [EM2800_BOARD_LEADTEK_WINFAST_USBII] = {
761 .name = "Leadtek Winfast USB II", 848 .name = "Leadtek Winfast USB II",
762 .is_em2800 = 1, 849 .is_em2800 = 1,
763 .vchannels = 3,
764 .tuner_type = TUNER_LG_PAL_NEW_TAPC, 850 .tuner_type = TUNER_LG_PAL_NEW_TAPC,
765 .tda9887_conf = TDA9887_PRESENT, 851 .tda9887_conf = TDA9887_PRESENT,
766 .decoder = EM28XX_SAA7113, 852 .decoder = EM28XX_SAA711X,
767 .input = { { 853 .input = { {
768 .type = EM28XX_VMUX_TELEVISION, 854 .type = EM28XX_VMUX_TELEVISION,
769 .vmux = SAA7115_COMPOSITE2, 855 .vmux = SAA7115_COMPOSITE2,
770 .amux = 0, 856 .amux = EM28XX_AMUX_VIDEO,
771 }, { 857 }, {
772 .type = EM28XX_VMUX_COMPOSITE1, 858 .type = EM28XX_VMUX_COMPOSITE1,
773 .vmux = SAA7115_COMPOSITE0, 859 .vmux = SAA7115_COMPOSITE0,
774 .amux = 1, 860 .amux = EM28XX_AMUX_LINE_IN,
775 }, { 861 }, {
776 .type = EM28XX_VMUX_SVIDEO, 862 .type = EM28XX_VMUX_SVIDEO,
777 .vmux = SAA7115_SVIDEO3, 863 .vmux = SAA7115_SVIDEO3,
778 .amux = 1, 864 .amux = EM28XX_AMUX_LINE_IN,
779 } }, 865 } },
780 }, 866 },
781 [EM2800_BOARD_KWORLD_USB2800] = { 867 [EM2800_BOARD_KWORLD_USB2800] = {
782 .name = "Kworld USB2800", 868 .name = "Kworld USB2800",
783 .is_em2800 = 1, 869 .is_em2800 = 1,
784 .vchannels = 3,
785 .tuner_type = TUNER_PHILIPS_FCV1236D, 870 .tuner_type = TUNER_PHILIPS_FCV1236D,
786 .tda9887_conf = TDA9887_PRESENT, 871 .tda9887_conf = TDA9887_PRESENT,
787 .decoder = EM28XX_SAA7113, 872 .decoder = EM28XX_SAA711X,
788 .input = { { 873 .input = { {
789 .type = EM28XX_VMUX_TELEVISION, 874 .type = EM28XX_VMUX_TELEVISION,
790 .vmux = SAA7115_COMPOSITE2, 875 .vmux = SAA7115_COMPOSITE2,
791 .amux = 0, 876 .amux = EM28XX_AMUX_VIDEO,
792 }, { 877 }, {
793 .type = EM28XX_VMUX_COMPOSITE1, 878 .type = EM28XX_VMUX_COMPOSITE1,
794 .vmux = SAA7115_COMPOSITE0, 879 .vmux = SAA7115_COMPOSITE0,
795 .amux = 1, 880 .amux = EM28XX_AMUX_LINE_IN,
796 }, { 881 }, {
797 .type = EM28XX_VMUX_SVIDEO, 882 .type = EM28XX_VMUX_SVIDEO,
798 .vmux = SAA7115_SVIDEO3, 883 .vmux = SAA7115_SVIDEO3,
799 .amux = 1, 884 .amux = EM28XX_AMUX_LINE_IN,
800 } }, 885 } },
801 }, 886 },
802 [EM2820_BOARD_PINNACLE_DVC_90] = { 887 [EM2820_BOARD_PINNACLE_DVC_90] = {
803 .name = "Pinnacle Dazzle DVC 90/DVC 100", 888 .name = "Pinnacle Dazzle DVC 90/DVC 100",
804 .vchannels = 3, 889 .tuner_type = TUNER_ABSENT, /* capture only board */
805 .tuner_type = TUNER_ABSENT, 890 .decoder = EM28XX_SAA711X,
806 .decoder = EM28XX_SAA7113, 891 .input = { {
807 .input = { {
808 .type = EM28XX_VMUX_COMPOSITE1, 892 .type = EM28XX_VMUX_COMPOSITE1,
809 .vmux = SAA7115_COMPOSITE0, 893 .vmux = SAA7115_COMPOSITE0,
810 .amux = 1, 894 .amux = EM28XX_AMUX_LINE_IN,
811 }, { 895 }, {
812 .type = EM28XX_VMUX_SVIDEO, 896 .type = EM28XX_VMUX_SVIDEO,
813 .vmux = SAA7115_SVIDEO3, 897 .vmux = SAA7115_SVIDEO3,
814 .amux = 1, 898 .amux = EM28XX_AMUX_LINE_IN,
815 } }, 899 } },
816 }, 900 },
817 [EM2800_BOARD_VGEAR_POCKETTV] = { 901 [EM2800_BOARD_VGEAR_POCKETTV] = {
818 .name = "V-Gear PocketTV", 902 .name = "V-Gear PocketTV",
819 .is_em2800 = 1, 903 .is_em2800 = 1,
820 .vchannels = 3,
821 .tuner_type = TUNER_LG_PAL_NEW_TAPC, 904 .tuner_type = TUNER_LG_PAL_NEW_TAPC,
822 .tda9887_conf = TDA9887_PRESENT, 905 .tda9887_conf = TDA9887_PRESENT,
823 .decoder = EM28XX_SAA7113, 906 .decoder = EM28XX_SAA711X,
824 .input = { { 907 .input = { {
825 .type = EM28XX_VMUX_TELEVISION, 908 .type = EM28XX_VMUX_TELEVISION,
826 .vmux = SAA7115_COMPOSITE2, 909 .vmux = SAA7115_COMPOSITE2,
827 .amux = 0, 910 .amux = EM28XX_AMUX_VIDEO,
828 }, { 911 }, {
829 .type = EM28XX_VMUX_COMPOSITE1, 912 .type = EM28XX_VMUX_COMPOSITE1,
830 .vmux = SAA7115_COMPOSITE0, 913 .vmux = SAA7115_COMPOSITE0,
831 .amux = 1, 914 .amux = EM28XX_AMUX_LINE_IN,
915 }, {
916 .type = EM28XX_VMUX_SVIDEO,
917 .vmux = SAA7115_SVIDEO3,
918 .amux = EM28XX_AMUX_LINE_IN,
919 } },
920 },
921 [EM2820_BOARD_PROLINK_PLAYTV_BOX4_USB2] = {
922 .name = "Pixelview PlayTV Box 4 USB 2.0",
923 .tda9887_conf = TDA9887_PRESENT,
924 .tuner_type = TUNER_YMEC_TVF_5533MF,
925 .decoder = EM28XX_SAA711X,
926 .input = { {
927 .type = EM28XX_VMUX_TELEVISION,
928 .vmux = SAA7115_COMPOSITE2,
929 .amux = EM28XX_AMUX_VIDEO,
930 .aout = EM28XX_AOUT_MONO | /* I2S */
931 EM28XX_AOUT_MASTER, /* Line out pin */
932 }, {
933 .type = EM28XX_VMUX_COMPOSITE1,
934 .vmux = SAA7115_COMPOSITE0,
935 .amux = EM28XX_AMUX_LINE_IN,
832 }, { 936 }, {
833 .type = EM28XX_VMUX_SVIDEO, 937 .type = EM28XX_VMUX_SVIDEO,
834 .vmux = SAA7115_SVIDEO3, 938 .vmux = SAA7115_SVIDEO3,
835 .amux = 1, 939 .amux = EM28XX_AMUX_LINE_IN,
836 } }, 940 } },
837 }, 941 },
838 [EM2820_BOARD_PROLINK_PLAYTV_USB2] = { 942 [EM2820_BOARD_PROLINK_PLAYTV_USB2] = {
839 .name = "Pixelview Prolink PlayTV USB 2.0", 943 .name = "Pixelview Prolink PlayTV USB 2.0",
840 .vchannels = 3, 944 .has_snapshot_button = 1,
841 .tda9887_conf = TDA9887_PRESENT, 945 .tda9887_conf = TDA9887_PRESENT,
842 .tuner_type = TUNER_YMEC_TVF_5533MF, 946 .tuner_type = TUNER_YMEC_TVF_5533MF,
843 .decoder = EM28XX_SAA7113, 947 .decoder = EM28XX_SAA711X,
844 .input = { { 948 .input = { {
845 .type = EM28XX_VMUX_TELEVISION, 949 .type = EM28XX_VMUX_TELEVISION,
846 .vmux = SAA7115_COMPOSITE2, 950 .vmux = SAA7115_COMPOSITE2,
847 .amux = EM28XX_AMUX_LINE_IN, 951 .amux = EM28XX_AMUX_VIDEO,
952 .aout = EM28XX_AOUT_MONO | /* I2S */
953 EM28XX_AOUT_MASTER, /* Line out pin */
848 }, { 954 }, {
849 .type = EM28XX_VMUX_COMPOSITE1, 955 .type = EM28XX_VMUX_COMPOSITE1,
850 .vmux = SAA7115_COMPOSITE0, 956 .vmux = SAA7115_COMPOSITE0,
@@ -856,228 +962,252 @@ struct em28xx_board em28xx_boards[] = {
856 } }, 962 } },
857 }, 963 },
858 [EM2860_BOARD_POINTNIX_INTRAORAL_CAMERA] = { 964 [EM2860_BOARD_POINTNIX_INTRAORAL_CAMERA] = {
859 .name = "PointNix Intra-Oral Camera", 965 .name = "PointNix Intra-Oral Camera",
860 .has_snapshot_button = 1, 966 .has_snapshot_button = 1,
861 .vchannels = 1, 967 .tda9887_conf = TDA9887_PRESENT,
862 .tda9887_conf = TDA9887_PRESENT, 968 .tuner_type = TUNER_ABSENT,
863 .tuner_type = TUNER_ABSENT, 969 .decoder = EM28XX_SAA711X,
864 .decoder = EM28XX_SAA7113, 970 .input = { {
865 .input = { {
866 .type = EM28XX_VMUX_SVIDEO, 971 .type = EM28XX_VMUX_SVIDEO,
867 .vmux = SAA7115_SVIDEO3, 972 .vmux = SAA7115_SVIDEO3,
868 .amux = 0, 973 .amux = EM28XX_AMUX_VIDEO,
869 } }, 974 } },
870 }, 975 },
871 [EM2880_BOARD_MSI_DIGIVOX_AD] = { 976 [EM2880_BOARD_MSI_DIGIVOX_AD] = {
872 .name = "MSI DigiVox A/D", 977 .name = "MSI DigiVox A/D",
873 .valid = EM28XX_BOARD_NOT_VALIDATED, 978 .valid = EM28XX_BOARD_NOT_VALIDATED,
874 .vchannels = 3,
875 .tuner_type = TUNER_XC2028, 979 .tuner_type = TUNER_XC2028,
980 .tuner_gpio = default_tuner_gpio,
876 .decoder = EM28XX_TVP5150, 981 .decoder = EM28XX_TVP5150,
877 .input = { { 982 .input = { {
878 .type = EM28XX_VMUX_TELEVISION, 983 .type = EM28XX_VMUX_TELEVISION,
879 .vmux = TVP5150_COMPOSITE0, 984 .vmux = TVP5150_COMPOSITE0,
880 .amux = 0, 985 .amux = EM28XX_AMUX_VIDEO,
986 .gpio = em2880_msi_digivox_ad_analog,
881 }, { 987 }, {
882 .type = EM28XX_VMUX_COMPOSITE1, 988 .type = EM28XX_VMUX_COMPOSITE1,
883 .vmux = TVP5150_COMPOSITE1, 989 .vmux = TVP5150_COMPOSITE1,
884 .amux = 1, 990 .amux = EM28XX_AMUX_LINE_IN,
991 .gpio = em2880_msi_digivox_ad_analog,
885 }, { 992 }, {
886 .type = EM28XX_VMUX_SVIDEO, 993 .type = EM28XX_VMUX_SVIDEO,
887 .vmux = TVP5150_SVIDEO, 994 .vmux = TVP5150_SVIDEO,
888 .amux = 1, 995 .amux = EM28XX_AMUX_LINE_IN,
996 .gpio = em2880_msi_digivox_ad_analog,
889 } }, 997 } },
890 }, 998 },
891 [EM2880_BOARD_MSI_DIGIVOX_AD_II] = { 999 [EM2880_BOARD_MSI_DIGIVOX_AD_II] = {
892 .name = "MSI DigiVox A/D II", 1000 .name = "MSI DigiVox A/D II",
893 .valid = EM28XX_BOARD_NOT_VALIDATED, 1001 .valid = EM28XX_BOARD_NOT_VALIDATED,
894 .vchannels = 3,
895 .tuner_type = TUNER_XC2028, 1002 .tuner_type = TUNER_XC2028,
1003 .tuner_gpio = default_tuner_gpio,
896 .decoder = EM28XX_TVP5150, 1004 .decoder = EM28XX_TVP5150,
897 .input = { { 1005 .input = { {
898 .type = EM28XX_VMUX_TELEVISION, 1006 .type = EM28XX_VMUX_TELEVISION,
899 .vmux = TVP5150_COMPOSITE0, 1007 .vmux = TVP5150_COMPOSITE0,
900 .amux = 0, 1008 .amux = EM28XX_AMUX_VIDEO,
1009 .gpio = em2880_msi_digivox_ad_analog,
901 }, { 1010 }, {
902 .type = EM28XX_VMUX_COMPOSITE1, 1011 .type = EM28XX_VMUX_COMPOSITE1,
903 .vmux = TVP5150_COMPOSITE1, 1012 .vmux = TVP5150_COMPOSITE1,
904 .amux = 1, 1013 .amux = EM28XX_AMUX_LINE_IN,
1014 .gpio = em2880_msi_digivox_ad_analog,
905 }, { 1015 }, {
906 .type = EM28XX_VMUX_SVIDEO, 1016 .type = EM28XX_VMUX_SVIDEO,
907 .vmux = TVP5150_SVIDEO, 1017 .vmux = TVP5150_SVIDEO,
908 .amux = 1, 1018 .amux = EM28XX_AMUX_LINE_IN,
1019 .gpio = em2880_msi_digivox_ad_analog,
909 } }, 1020 } },
910 }, 1021 },
911 [EM2880_BOARD_KWORLD_DVB_305U] = { 1022 [EM2880_BOARD_KWORLD_DVB_305U] = {
912 .name = "KWorld DVB-T 305U", 1023 .name = "KWorld DVB-T 305U",
913 .valid = EM28XX_BOARD_NOT_VALIDATED, 1024 .valid = EM28XX_BOARD_NOT_VALIDATED,
914 .vchannels = 3,
915 .tuner_type = TUNER_XC2028, 1025 .tuner_type = TUNER_XC2028,
1026 .tuner_gpio = default_tuner_gpio,
916 .decoder = EM28XX_TVP5150, 1027 .decoder = EM28XX_TVP5150,
917 .input = { { 1028 .input = { {
918 .type = EM28XX_VMUX_TELEVISION, 1029 .type = EM28XX_VMUX_TELEVISION,
919 .vmux = TVP5150_COMPOSITE0, 1030 .vmux = TVP5150_COMPOSITE0,
920 .amux = 0, 1031 .amux = EM28XX_AMUX_VIDEO,
921 }, { 1032 }, {
922 .type = EM28XX_VMUX_COMPOSITE1, 1033 .type = EM28XX_VMUX_COMPOSITE1,
923 .vmux = TVP5150_COMPOSITE1, 1034 .vmux = TVP5150_COMPOSITE1,
924 .amux = 1, 1035 .amux = EM28XX_AMUX_LINE_IN,
925 }, { 1036 }, {
926 .type = EM28XX_VMUX_SVIDEO, 1037 .type = EM28XX_VMUX_SVIDEO,
927 .vmux = TVP5150_SVIDEO, 1038 .vmux = TVP5150_SVIDEO,
928 .amux = 1, 1039 .amux = EM28XX_AMUX_LINE_IN,
929 } }, 1040 } },
930 }, 1041 },
931 [EM2880_BOARD_KWORLD_DVB_310U] = { 1042 [EM2880_BOARD_KWORLD_DVB_310U] = {
932 .name = "KWorld DVB-T 310U", 1043 .name = "KWorld DVB-T 310U",
933 .vchannels = 3,
934 .tuner_type = TUNER_XC2028, 1044 .tuner_type = TUNER_XC2028,
1045 .tuner_gpio = default_tuner_gpio,
935 .has_dvb = 1, 1046 .has_dvb = 1,
1047 .dvb_gpio = default_digital,
936 .mts_firmware = 1, 1048 .mts_firmware = 1,
937 .decoder = EM28XX_TVP5150, 1049 .decoder = EM28XX_TVP5150,
938 .input = { { 1050 .input = { {
939 .type = EM28XX_VMUX_TELEVISION, 1051 .type = EM28XX_VMUX_TELEVISION,
940 .vmux = TVP5150_COMPOSITE0, 1052 .vmux = TVP5150_COMPOSITE0,
941 .amux = EM28XX_AMUX_VIDEO, 1053 .amux = EM28XX_AMUX_VIDEO,
1054 .gpio = default_analog,
942 }, { 1055 }, {
943 .type = EM28XX_VMUX_COMPOSITE1, 1056 .type = EM28XX_VMUX_COMPOSITE1,
944 .vmux = TVP5150_COMPOSITE1, 1057 .vmux = TVP5150_COMPOSITE1,
945 .amux = EM28XX_AMUX_AC97_LINE_IN, 1058 .amux = EM28XX_AMUX_LINE_IN,
1059 .gpio = default_analog,
946 }, { /* S-video has not been tested yet */ 1060 }, { /* S-video has not been tested yet */
947 .type = EM28XX_VMUX_SVIDEO, 1061 .type = EM28XX_VMUX_SVIDEO,
948 .vmux = TVP5150_SVIDEO, 1062 .vmux = TVP5150_SVIDEO,
949 .amux = EM28XX_AMUX_AC97_LINE_IN, 1063 .amux = EM28XX_AMUX_LINE_IN,
1064 .gpio = default_analog,
950 } }, 1065 } },
951 }, 1066 },
952 [EM2881_BOARD_DNT_DA2_HYBRID] = { 1067 [EM2881_BOARD_DNT_DA2_HYBRID] = {
953 .name = "DNT DA2 Hybrid", 1068 .name = "DNT DA2 Hybrid",
954 .valid = EM28XX_BOARD_NOT_VALIDATED, 1069 .valid = EM28XX_BOARD_NOT_VALIDATED,
955 .vchannels = 3,
956 .tuner_type = TUNER_XC2028, 1070 .tuner_type = TUNER_XC2028,
1071 .tuner_gpio = default_tuner_gpio,
957 .decoder = EM28XX_TVP5150, 1072 .decoder = EM28XX_TVP5150,
958 .input = { { 1073 .input = { {
959 .type = EM28XX_VMUX_TELEVISION, 1074 .type = EM28XX_VMUX_TELEVISION,
960 .vmux = TVP5150_COMPOSITE0, 1075 .vmux = TVP5150_COMPOSITE0,
961 .amux = 0, 1076 .amux = EM28XX_AMUX_VIDEO,
1077 .gpio = default_analog,
962 }, { 1078 }, {
963 .type = EM28XX_VMUX_COMPOSITE1, 1079 .type = EM28XX_VMUX_COMPOSITE1,
964 .vmux = TVP5150_COMPOSITE1, 1080 .vmux = TVP5150_COMPOSITE1,
965 .amux = 1, 1081 .amux = EM28XX_AMUX_LINE_IN,
1082 .gpio = default_analog,
966 }, { 1083 }, {
967 .type = EM28XX_VMUX_SVIDEO, 1084 .type = EM28XX_VMUX_SVIDEO,
968 .vmux = TVP5150_SVIDEO, 1085 .vmux = TVP5150_SVIDEO,
969 .amux = 1, 1086 .amux = EM28XX_AMUX_LINE_IN,
1087 .gpio = default_analog,
970 } }, 1088 } },
971 }, 1089 },
972 [EM2881_BOARD_PINNACLE_HYBRID_PRO] = { 1090 [EM2881_BOARD_PINNACLE_HYBRID_PRO] = {
973 .name = "Pinnacle Hybrid Pro", 1091 .name = "Pinnacle Hybrid Pro",
974 .valid = EM28XX_BOARD_NOT_VALIDATED, 1092 .valid = EM28XX_BOARD_NOT_VALIDATED,
975 .vchannels = 3,
976 .tuner_type = TUNER_XC2028, 1093 .tuner_type = TUNER_XC2028,
1094 .tuner_gpio = default_tuner_gpio,
977 .decoder = EM28XX_TVP5150, 1095 .decoder = EM28XX_TVP5150,
978 .input = { { 1096 .input = { {
979 .type = EM28XX_VMUX_TELEVISION, 1097 .type = EM28XX_VMUX_TELEVISION,
980 .vmux = TVP5150_COMPOSITE0, 1098 .vmux = TVP5150_COMPOSITE0,
981 .amux = 0, 1099 .amux = EM28XX_AMUX_VIDEO,
1100 .gpio = default_analog,
982 }, { 1101 }, {
983 .type = EM28XX_VMUX_COMPOSITE1, 1102 .type = EM28XX_VMUX_COMPOSITE1,
984 .vmux = TVP5150_COMPOSITE1, 1103 .vmux = TVP5150_COMPOSITE1,
985 .amux = 1, 1104 .amux = EM28XX_AMUX_LINE_IN,
1105 .gpio = default_analog,
986 }, { 1106 }, {
987 .type = EM28XX_VMUX_SVIDEO, 1107 .type = EM28XX_VMUX_SVIDEO,
988 .vmux = TVP5150_SVIDEO, 1108 .vmux = TVP5150_SVIDEO,
989 .amux = 1, 1109 .amux = EM28XX_AMUX_LINE_IN,
1110 .gpio = default_analog,
990 } }, 1111 } },
991 }, 1112 },
992 [EM2882_BOARD_PINNACLE_HYBRID_PRO] = { 1113 [EM2882_BOARD_PINNACLE_HYBRID_PRO] = {
993 .name = "Pinnacle Hybrid Pro (2)", 1114 .name = "Pinnacle Hybrid Pro (2)",
994 .valid = EM28XX_BOARD_NOT_VALIDATED, 1115 .valid = EM28XX_BOARD_NOT_VALIDATED,
995 .vchannels = 3,
996 .tuner_type = TUNER_XC2028, 1116 .tuner_type = TUNER_XC2028,
1117 .tuner_gpio = default_tuner_gpio,
997 .mts_firmware = 1, 1118 .mts_firmware = 1,
998 .decoder = EM28XX_TVP5150, 1119 .decoder = EM28XX_TVP5150,
999 .input = { { 1120 .input = { {
1000 .type = EM28XX_VMUX_TELEVISION, 1121 .type = EM28XX_VMUX_TELEVISION,
1001 .vmux = TVP5150_COMPOSITE0, 1122 .vmux = TVP5150_COMPOSITE0,
1002 .amux = 0, 1123 .amux = EM28XX_AMUX_VIDEO,
1124 .gpio = hauppauge_wintv_hvr_900_analog,
1003 }, { 1125 }, {
1004 .type = EM28XX_VMUX_COMPOSITE1, 1126 .type = EM28XX_VMUX_COMPOSITE1,
1005 .vmux = TVP5150_COMPOSITE1, 1127 .vmux = TVP5150_COMPOSITE1,
1006 .amux = 1, 1128 .amux = EM28XX_AMUX_LINE_IN,
1129 .gpio = hauppauge_wintv_hvr_900_analog,
1007 }, { 1130 }, {
1008 .type = EM28XX_VMUX_SVIDEO, 1131 .type = EM28XX_VMUX_SVIDEO,
1009 .vmux = TVP5150_SVIDEO, 1132 .vmux = TVP5150_SVIDEO,
1010 .amux = 1, 1133 .amux = EM28XX_AMUX_LINE_IN,
1134 .gpio = hauppauge_wintv_hvr_900_analog,
1011 } }, 1135 } },
1012 }, 1136 },
1013 [EM2882_BOARD_KWORLD_VS_DVBT] = { 1137 [EM2882_BOARD_KWORLD_VS_DVBT] = {
1014 .name = "Kworld VS-DVB-T 323UR", 1138 .name = "Kworld VS-DVB-T 323UR",
1015 .valid = EM28XX_BOARD_NOT_VALIDATED, 1139 .valid = EM28XX_BOARD_NOT_VALIDATED,
1016 .vchannels = 3,
1017 .tuner_type = TUNER_XC2028, 1140 .tuner_type = TUNER_XC2028,
1141 .tuner_gpio = default_tuner_gpio,
1018 .decoder = EM28XX_TVP5150, 1142 .decoder = EM28XX_TVP5150,
1019 .input = { { 1143 .input = { {
1020 .type = EM28XX_VMUX_TELEVISION, 1144 .type = EM28XX_VMUX_TELEVISION,
1021 .vmux = TVP5150_COMPOSITE0, 1145 .vmux = TVP5150_COMPOSITE0,
1022 .amux = 0, 1146 .amux = EM28XX_AMUX_VIDEO,
1023 }, { 1147 }, {
1024 .type = EM28XX_VMUX_COMPOSITE1, 1148 .type = EM28XX_VMUX_COMPOSITE1,
1025 .vmux = TVP5150_COMPOSITE1, 1149 .vmux = TVP5150_COMPOSITE1,
1026 .amux = 1, 1150 .amux = EM28XX_AMUX_LINE_IN,
1027 }, { 1151 }, {
1028 .type = EM28XX_VMUX_SVIDEO, 1152 .type = EM28XX_VMUX_SVIDEO,
1029 .vmux = TVP5150_SVIDEO, 1153 .vmux = TVP5150_SVIDEO,
1030 .amux = 1, 1154 .amux = EM28XX_AMUX_LINE_IN,
1031 } }, 1155 } },
1032 }, 1156 },
1033 [EM2882_BOARD_TERRATEC_HYBRID_XS] = { 1157 [EM2882_BOARD_TERRATEC_HYBRID_XS] = {
1034 .name = "Terratec Hybrid XS (em2882)", 1158 .name = "Terratec Hybrid XS (em2882)",
1035 .valid = EM28XX_BOARD_NOT_VALIDATED, 1159 .valid = EM28XX_BOARD_NOT_VALIDATED,
1036 .vchannels = 3,
1037 .tuner_type = TUNER_XC2028, 1160 .tuner_type = TUNER_XC2028,
1161 .tuner_gpio = default_tuner_gpio,
1038 .decoder = EM28XX_TVP5150, 1162 .decoder = EM28XX_TVP5150,
1039 .input = { { 1163 .input = { {
1040 .type = EM28XX_VMUX_TELEVISION, 1164 .type = EM28XX_VMUX_TELEVISION,
1041 .vmux = TVP5150_COMPOSITE0, 1165 .vmux = TVP5150_COMPOSITE0,
1042 .amux = 0, 1166 .amux = EM28XX_AMUX_VIDEO,
1167 .gpio = hauppauge_wintv_hvr_900_analog,
1043 }, { 1168 }, {
1044 .type = EM28XX_VMUX_COMPOSITE1, 1169 .type = EM28XX_VMUX_COMPOSITE1,
1045 .vmux = TVP5150_COMPOSITE1, 1170 .vmux = TVP5150_COMPOSITE1,
1046 .amux = 1, 1171 .amux = EM28XX_AMUX_LINE_IN,
1172 .gpio = hauppauge_wintv_hvr_900_analog,
1047 }, { 1173 }, {
1048 .type = EM28XX_VMUX_SVIDEO, 1174 .type = EM28XX_VMUX_SVIDEO,
1049 .vmux = TVP5150_SVIDEO, 1175 .vmux = TVP5150_SVIDEO,
1050 .amux = 1, 1176 .amux = EM28XX_AMUX_LINE_IN,
1177 .gpio = hauppauge_wintv_hvr_900_analog,
1051 } }, 1178 } },
1052 }, 1179 },
1053 [EM2883_BOARD_KWORLD_HYBRID_A316] = { 1180 [EM2883_BOARD_KWORLD_HYBRID_A316] = {
1054 .name = "Kworld PlusTV HD Hybrid 330", 1181 .name = "Kworld PlusTV HD Hybrid 330",
1055 .valid = EM28XX_BOARD_NOT_VALIDATED,
1056 .vchannels = 3,
1057 .is_em2800 = 0,
1058 .tuner_type = TUNER_XC2028, 1182 .tuner_type = TUNER_XC2028,
1183 .tuner_gpio = default_tuner_gpio,
1059 .decoder = EM28XX_TVP5150, 1184 .decoder = EM28XX_TVP5150,
1060 .input = { { 1185 .mts_firmware = 1,
1186 .has_dvb = 1,
1187 .dvb_gpio = default_digital,
1188 .input = { {
1061 .type = EM28XX_VMUX_TELEVISION, 1189 .type = EM28XX_VMUX_TELEVISION,
1062 .vmux = TVP5150_COMPOSITE0, 1190 .vmux = TVP5150_COMPOSITE0,
1063 .amux = 0, 1191 .amux = EM28XX_AMUX_VIDEO,
1192 .gpio = default_analog,
1064 }, { 1193 }, {
1065 .type = EM28XX_VMUX_COMPOSITE1, 1194 .type = EM28XX_VMUX_COMPOSITE1,
1066 .vmux = TVP5150_COMPOSITE1, 1195 .vmux = TVP5150_COMPOSITE1,
1067 .amux = 1, 1196 .amux = EM28XX_AMUX_LINE_IN,
1197 .gpio = hauppauge_wintv_hvr_900_analog,
1068 }, { 1198 }, {
1069 .type = EM28XX_VMUX_SVIDEO, 1199 .type = EM28XX_VMUX_SVIDEO,
1070 .vmux = TVP5150_SVIDEO, 1200 .vmux = TVP5150_SVIDEO,
1071 .amux = 1, 1201 .amux = EM28XX_AMUX_LINE_IN,
1202 .gpio = hauppauge_wintv_hvr_900_analog,
1072 } }, 1203 } },
1073 }, 1204 },
1074 [EM2820_BOARD_COMPRO_VIDEOMATE_FORYOU] = { 1205 [EM2820_BOARD_COMPRO_VIDEOMATE_FORYOU] = {
1075 .name = "Compro VideoMate ForYou/Stereo", 1206 .name = "Compro VideoMate ForYou/Stereo",
1076 .vchannels = 2,
1077 .tuner_type = TUNER_LG_PAL_NEW_TAPC, 1207 .tuner_type = TUNER_LG_PAL_NEW_TAPC,
1078 .tda9887_conf = TDA9887_PRESENT, 1208 .tda9887_conf = TDA9887_PRESENT,
1079 .decoder = EM28XX_TVP5150, 1209 .decoder = EM28XX_TVP5150,
1080 .input = { { 1210 .input = { {
1081 .type = EM28XX_VMUX_TELEVISION, 1211 .type = EM28XX_VMUX_TELEVISION,
1082 .vmux = TVP5150_COMPOSITE0, 1212 .vmux = TVP5150_COMPOSITE0,
1083 .amux = EM28XX_AMUX_LINE_IN, 1213 .amux = EM28XX_AMUX_LINE_IN,
@@ -1101,7 +1231,7 @@ struct usb_device_id em28xx_id_table [] = {
1101 { USB_DEVICE(0xeb1a, 0x2820), 1231 { USB_DEVICE(0xeb1a, 0x2820),
1102 .driver_info = EM2820_BOARD_UNKNOWN }, 1232 .driver_info = EM2820_BOARD_UNKNOWN },
1103 { USB_DEVICE(0xeb1a, 0x2821), 1233 { USB_DEVICE(0xeb1a, 0x2821),
1104 .driver_info = EM2820_BOARD_PROLINK_PLAYTV_USB2 }, 1234 .driver_info = EM2820_BOARD_UNKNOWN },
1105 { USB_DEVICE(0xeb1a, 0x2860), 1235 { USB_DEVICE(0xeb1a, 0x2860),
1106 .driver_info = EM2820_BOARD_UNKNOWN }, 1236 .driver_info = EM2820_BOARD_UNKNOWN },
1107 { USB_DEVICE(0xeb1a, 0x2861), 1237 { USB_DEVICE(0xeb1a, 0x2861),
@@ -1164,8 +1294,8 @@ struct usb_device_id em28xx_id_table [] = {
1164 .driver_info = EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950 }, 1294 .driver_info = EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950 },
1165 { USB_DEVICE(0x2040, 0x651b), /* RP HVR-950 */ 1295 { USB_DEVICE(0x2040, 0x651b), /* RP HVR-950 */
1166 .driver_info = EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950 }, 1296 .driver_info = EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950 },
1167 { USB_DEVICE(0x2040, 0x651f), /* HCW HVR-850 */ 1297 { USB_DEVICE(0x2040, 0x651f),
1168 .driver_info = EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950 }, 1298 .driver_info = EM2883_BOARD_HAUPPAUGE_WINTV_HVR_850 },
1169 { USB_DEVICE(0x0438, 0xb002), 1299 { USB_DEVICE(0x0438, 0xb002),
1170 .driver_info = EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600 }, 1300 .driver_info = EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600 },
1171 { USB_DEVICE(0x2001, 0xf112), 1301 { USB_DEVICE(0x2001, 0xf112),
@@ -1189,78 +1319,12 @@ struct usb_device_id em28xx_id_table [] = {
1189MODULE_DEVICE_TABLE(usb, em28xx_id_table); 1319MODULE_DEVICE_TABLE(usb, em28xx_id_table);
1190 1320
1191/* 1321/*
1192 * Reset sequences for analog/digital modes
1193 */
1194
1195/* Reset for the most [analog] boards */
1196static struct em28xx_reg_seq default_analog[] = {
1197 {EM28XX_R08_GPIO, 0x6d, ~EM_GPIO_4, 10},
1198 { -1, -1, -1, -1},
1199};
1200
1201/* Reset for the most [digital] boards */
1202static struct em28xx_reg_seq default_digital[] = {
1203 {EM28XX_R08_GPIO, 0x6e, ~EM_GPIO_4, 10},
1204 { -1, -1, -1, -1},
1205};
1206
1207/* Board Hauppauge WinTV HVR 900 analog */
1208static struct em28xx_reg_seq hauppauge_wintv_hvr_900_analog[] = {
1209 {EM28XX_R08_GPIO, 0x2d, ~EM_GPIO_4, 10},
1210 {0x05, 0xff, 0x10, 10},
1211 { -1, -1, -1, -1},
1212};
1213
1214/* Board Hauppauge WinTV HVR 900 digital */
1215static struct em28xx_reg_seq hauppauge_wintv_hvr_900_digital[] = {
1216 {EM28XX_R08_GPIO, 0x2e, ~EM_GPIO_4, 10},
1217 {EM2880_R04_GPO, 0x04, 0x0f, 10},
1218 {EM2880_R04_GPO, 0x0c, 0x0f, 10},
1219 { -1, -1, -1, -1},
1220};
1221
1222/* Boards - EM2880 MSI DIGIVOX AD and EM2880_BOARD_MSI_DIGIVOX_AD_II */
1223static struct em28xx_reg_seq em2880_msi_digivox_ad_analog[] = {
1224 {EM28XX_R08_GPIO, 0x69, ~EM_GPIO_4, 10},
1225 { -1, -1, -1, -1},
1226};
1227
1228/* Boards - EM2880 MSI DIGIVOX AD and EM2880_BOARD_MSI_DIGIVOX_AD_II */
1229static struct em28xx_reg_seq em2880_msi_digivox_ad_digital[] = {
1230 {EM28XX_R08_GPIO, 0x6a, ~EM_GPIO_4, 10},
1231 { -1, -1, -1, -1},
1232};
1233
1234/* Board - EM2870 Kworld 355u
1235 Analog - No input analog */
1236static struct em28xx_reg_seq em2870_kworld_355u_digital[] = {
1237 {EM2880_R04_GPO, 0x01, 0xff, 10},
1238 { -1, -1, -1, -1},
1239};
1240
1241/* Callback for the most boards */
1242static struct em28xx_reg_seq default_callback[] = {
1243 {EM28XX_R08_GPIO, EM_GPIO_4, EM_GPIO_4, 10},
1244 {EM28XX_R08_GPIO, 0, EM_GPIO_4, 10},
1245 {EM28XX_R08_GPIO, EM_GPIO_4, EM_GPIO_4, 10},
1246 { -1, -1, -1, -1},
1247};
1248
1249/* Callback for EM2882 TERRATEC HYBRID XS */
1250static struct em28xx_reg_seq em2882_terratec_hybrid_xs_digital[] = {
1251 {EM28XX_R08_GPIO, 0x2e, 0xff, 6},
1252 {EM28XX_R08_GPIO, 0x3e, ~EM_GPIO_4, 6},
1253 {EM2880_R04_GPO, 0x04, 0xff, 10},
1254 {EM2880_R04_GPO, 0x0c, 0xff, 10},
1255 { -1, -1, -1, -1},
1256};
1257
1258/*
1259 * EEPROM hash table for devices with generic USB IDs 1322 * EEPROM hash table for devices with generic USB IDs
1260 */ 1323 */
1261static struct em28xx_hash_table em28xx_eeprom_hash [] = { 1324static struct em28xx_hash_table em28xx_eeprom_hash [] = {
1262 /* P/N: SA 60002070465 Tuner: TVF7533-MF */ 1325 /* P/N: SA 60002070465 Tuner: TVF7533-MF */
1263 {0x6ce05a8f, EM2820_BOARD_PROLINK_PLAYTV_USB2, TUNER_YMEC_TVF_5533MF}, 1326 {0x6ce05a8f, EM2820_BOARD_PROLINK_PLAYTV_USB2, TUNER_YMEC_TVF_5533MF},
1327 {0x72cc5a8b, EM2820_BOARD_PROLINK_PLAYTV_BOX4_USB2, TUNER_YMEC_TVF_5533MF},
1264 {0x966a0441, EM2880_BOARD_KWORLD_DVB_310U, TUNER_XC2028}, 1328 {0x966a0441, EM2880_BOARD_KWORLD_DVB_310U, TUNER_XC2028},
1265}; 1329};
1266 1330
@@ -1282,27 +1346,26 @@ int em28xx_tuner_callback(void *ptr, int component, int command, int arg)
1282 if (command != XC2028_TUNER_RESET) 1346 if (command != XC2028_TUNER_RESET)
1283 return 0; 1347 return 0;
1284 1348
1285 if (dev->mode == EM28XX_ANALOG_MODE) 1349 rc = em28xx_gpio_set(dev, dev->board.tuner_gpio);
1286 rc = em28xx_gpio_set(dev, dev->tun_analog_gpio);
1287 else
1288 rc = em28xx_gpio_set(dev, dev->tun_digital_gpio);
1289 1350
1290 return rc; 1351 return rc;
1291} 1352}
1292EXPORT_SYMBOL_GPL(em28xx_tuner_callback); 1353EXPORT_SYMBOL_GPL(em28xx_tuner_callback);
1293 1354
1294static void em28xx_set_model(struct em28xx *dev) 1355static void inline em28xx_set_model(struct em28xx *dev)
1295{ 1356{
1296 dev->is_em2800 = em28xx_boards[dev->model].is_em2800; 1357 memcpy(&dev->board, &em28xx_boards[dev->model], sizeof(dev->board));
1297 dev->has_msp34xx = em28xx_boards[dev->model].has_msp34xx; 1358
1298 dev->tda9887_conf = em28xx_boards[dev->model].tda9887_conf; 1359 /* Those are the default values for the majority of boards
1299 dev->decoder = em28xx_boards[dev->model].decoder; 1360 Use those values if not specified otherwise at boards entry
1300 dev->video_inputs = em28xx_boards[dev->model].vchannels; 1361 */
1301 dev->has_12mhz_i2s = em28xx_boards[dev->model].has_12mhz_i2s; 1362 if (!dev->board.xclk)
1302 dev->max_range_640_480 = em28xx_boards[dev->model].max_range_640_480; 1363 dev->board.xclk = EM28XX_XCLK_IR_RC5_MODE |
1303 dev->has_dvb = em28xx_boards[dev->model].has_dvb; 1364 EM28XX_XCLK_FREQUENCY_12MHZ;
1304 dev->has_snapshot_button = em28xx_boards[dev->model].has_snapshot_button; 1365
1305 dev->valid = em28xx_boards[dev->model].valid; 1366 if (!dev->board.i2c_speed)
1367 dev->board.i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE |
1368 EM28XX_I2C_FREQ_100_KHZ;
1306} 1369}
1307 1370
1308/* Since em28xx_pre_card_setup() requires a proper dev->model, 1371/* Since em28xx_pre_card_setup() requires a proper dev->model,
@@ -1312,205 +1375,126 @@ void em28xx_pre_card_setup(struct em28xx *dev)
1312{ 1375{
1313 int rc; 1376 int rc;
1314 1377
1315 rc = em28xx_read_reg(dev, EM2880_R04_GPO); 1378 em28xx_set_model(dev);
1316 if (rc >= 0) 1379
1317 dev->reg_gpo = rc; 1380 em28xx_info("Identified as %s (card=%d)\n",
1381 dev->board.name, dev->model);
1382
1383 /* Set the default GPO/GPIO for legacy devices */
1384 dev->reg_gpo_num = EM2880_R04_GPO;
1385 dev->reg_gpio_num = EM28XX_R08_GPIO;
1318 1386
1319 dev->wait_after_write = 5; 1387 dev->wait_after_write = 5;
1388
1389 /* Based on the Chip ID, set the device configuration */
1320 rc = em28xx_read_reg(dev, EM28XX_R0A_CHIPID); 1390 rc = em28xx_read_reg(dev, EM28XX_R0A_CHIPID);
1321 if (rc > 0) { 1391 if (rc > 0) {
1322 switch (rc) { 1392 dev->chip_id = rc;
1393
1394 switch (dev->chip_id) {
1395 case CHIP_ID_EM2750:
1396 em28xx_info("chip ID is em2750\n");
1397 break;
1398 case CHIP_ID_EM2820:
1399 em28xx_info("chip ID is em2820\n");
1400 break;
1401 case CHIP_ID_EM2840:
1402 em28xx_info("chip ID is em2840\n");
1403 break;
1323 case CHIP_ID_EM2860: 1404 case CHIP_ID_EM2860:
1324 em28xx_info("chip ID is em2860\n"); 1405 em28xx_info("chip ID is em2860\n");
1325 break; 1406 break;
1407 case CHIP_ID_EM2870:
1408 em28xx_info("chip ID is em2870\n");
1409 dev->wait_after_write = 0;
1410 break;
1411 case CHIP_ID_EM2874:
1412 em28xx_info("chip ID is em2874\n");
1413 dev->reg_gpio_num = EM2874_R80_GPIO;
1414 dev->wait_after_write = 0;
1415 break;
1326 case CHIP_ID_EM2883: 1416 case CHIP_ID_EM2883:
1327 em28xx_info("chip ID is em2882/em2883\n"); 1417 em28xx_info("chip ID is em2882/em2883\n");
1328 dev->wait_after_write = 0; 1418 dev->wait_after_write = 0;
1329 break; 1419 break;
1330 default: 1420 default:
1331 em28xx_info("em28xx chip ID = %d\n", rc); 1421 em28xx_info("em28xx chip ID = %d\n", dev->chip_id);
1332 } 1422 }
1333 } 1423 }
1334 em28xx_set_model(dev);
1335
1336 /* request some modules */
1337 switch (dev->model) {
1338 case EM2880_BOARD_TERRATEC_PRODIGY_XS:
1339 case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900:
1340 case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2:
1341 case EM2860_BOARD_TERRATEC_HYBRID_XS:
1342 case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950:
1343 case EM2880_BOARD_PINNACLE_PCTV_HD_PRO:
1344 case EM2882_BOARD_PINNACLE_HYBRID_PRO:
1345 case EM2883_BOARD_KWORLD_HYBRID_A316:
1346 case EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600:
1347 em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x27", 1);
1348 em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1);
1349 msleep(50);
1350
1351 /* Sets GPO/GPIO sequences for this device */
1352 dev->analog_gpio = hauppauge_wintv_hvr_900_analog;
1353 dev->digital_gpio = hauppauge_wintv_hvr_900_digital;
1354 dev->tun_analog_gpio = default_callback;
1355 dev->tun_digital_gpio = default_callback;
1356 break;
1357
1358 case EM2882_BOARD_TERRATEC_HYBRID_XS:
1359 em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x27", 1);
1360 em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1);
1361 msleep(50);
1362
1363 /* should be added ir_codes here */
1364
1365 /* Sets GPO/GPIO sequences for this device */
1366 dev->analog_gpio = hauppauge_wintv_hvr_900_analog;
1367 dev->digital_gpio = hauppauge_wintv_hvr_900_digital;
1368 dev->tun_analog_gpio = default_callback;
1369 dev->tun_digital_gpio = em2882_terratec_hybrid_xs_digital;
1370 break;
1371
1372 case EM2880_BOARD_TERRATEC_HYBRID_XS_FR:
1373 case EM2880_BOARD_TERRATEC_HYBRID_XS:
1374 case EM2870_BOARD_TERRATEC_XS:
1375 case EM2881_BOARD_PINNACLE_HYBRID_PRO:
1376 case EM2880_BOARD_KWORLD_DVB_310U:
1377 case EM2870_BOARD_KWORLD_350U:
1378 case EM2881_BOARD_DNT_DA2_HYBRID:
1379 em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x27", 1);
1380 em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1);
1381 msleep(50);
1382
1383 /* NOTE: EM2881_DNT_DA2_HYBRID spend 140 msleep for digital
1384 and analog commands. If this commands doesn't work,
1385 add this timer. */
1386
1387 /* Sets GPO/GPIO sequences for this device */
1388 dev->analog_gpio = default_analog;
1389 dev->digital_gpio = default_digital;
1390 dev->tun_analog_gpio = default_callback;
1391 dev->tun_digital_gpio = default_callback;
1392 break;
1393 1424
1394 case EM2880_BOARD_MSI_DIGIVOX_AD: 1425 /* Prepopulate cached GPO register content */
1395 case EM2880_BOARD_MSI_DIGIVOX_AD_II: 1426 rc = em28xx_read_reg(dev, dev->reg_gpo_num);
1396 em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x27", 1); 1427 if (rc >= 0)
1397 em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1); 1428 dev->reg_gpo = rc;
1398 msleep(50);
1399
1400 /* Sets GPO/GPIO sequences for this device */
1401 dev->analog_gpio = em2880_msi_digivox_ad_analog;
1402 dev->digital_gpio = em2880_msi_digivox_ad_digital;
1403 dev->tun_analog_gpio = default_callback;
1404 dev->tun_digital_gpio = default_callback;
1405 break;
1406 1429
1407 case EM2750_BOARD_UNKNOWN: 1430 /* Set the initial XCLK and I2C clock values based on the board
1408 case EM2750_BOARD_DLCW_130: 1431 definition */
1409 em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x0a", 1); 1432 em28xx_write_reg(dev, EM28XX_R0F_XCLK, dev->board.xclk & 0x7f);
1410 break; 1433 em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, dev->board.i2c_speed);
1434 msleep(50);
1411 1435
1436 /* request some modules */
1437 switch (dev->model) {
1412 case EM2861_BOARD_PLEXTOR_PX_TV100U: 1438 case EM2861_BOARD_PLEXTOR_PX_TV100U:
1413 em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x27", 1);
1414 em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1);
1415 /* FIXME guess */ 1439 /* FIXME guess */
1416 /* Turn on analog audio output */ 1440 /* Turn on analog audio output */
1417 em28xx_write_regs_req(dev, 0x00, 0x08, "\xfd", 1); 1441 em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfd);
1418 break; 1442 break;
1419
1420 case EM2861_BOARD_KWORLD_PVRTV_300U: 1443 case EM2861_BOARD_KWORLD_PVRTV_300U:
1421 case EM2880_BOARD_KWORLD_DVB_305U: 1444 case EM2880_BOARD_KWORLD_DVB_305U:
1422 em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x27", 1); 1445 em28xx_write_reg(dev, EM28XX_R08_GPIO, 0x6d);
1423 em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x4c", 1);
1424 msleep(10);
1425 em28xx_write_regs(dev, 0x08, "\x6d", 1);
1426 msleep(10); 1446 msleep(10);
1427 em28xx_write_regs(dev, 0x08, "\x7d", 1); 1447 em28xx_write_reg(dev, EM28XX_R08_GPIO, 0x7d);
1428 msleep(10); 1448 msleep(10);
1429 break; 1449 break;
1430
1431 case EM2870_BOARD_KWORLD_355U:
1432 em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x27", 1);
1433 em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1);
1434 msleep(50);
1435
1436 /* Sets GPO/GPIO sequences for this device */
1437 dev->digital_gpio = em2870_kworld_355u_digital;
1438 break;
1439
1440 case EM2870_BOARD_COMPRO_VIDEOMATE: 1450 case EM2870_BOARD_COMPRO_VIDEOMATE:
1441 em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x27", 1);
1442 em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1);
1443 /* TODO: someone can do some cleanup here... 1451 /* TODO: someone can do some cleanup here...
1444 not everything's needed */ 1452 not everything's needed */
1445 em28xx_write_regs(dev, 0x04, "\x00", 1); 1453 em28xx_write_reg(dev, EM2880_R04_GPO, 0x00);
1446 msleep(10); 1454 msleep(10);
1447 em28xx_write_regs(dev, 0x04, "\x01", 1); 1455 em28xx_write_reg(dev, EM2880_R04_GPO, 0x01);
1448 msleep(10); 1456 msleep(10);
1449 em28xx_write_regs(dev, 0x08, "\xfd", 1); 1457 em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfd);
1450 mdelay(70); 1458 mdelay(70);
1451 em28xx_write_regs(dev, 0x08, "\xfc", 1); 1459 em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfc);
1452 mdelay(70); 1460 mdelay(70);
1453 em28xx_write_regs(dev, 0x08, "\xdc", 1); 1461 em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xdc);
1454 mdelay(70); 1462 mdelay(70);
1455 em28xx_write_regs(dev, 0x08, "\xfc", 1); 1463 em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfc);
1456 mdelay(70); 1464 mdelay(70);
1457 break; 1465 break;
1458
1459 case EM2870_BOARD_TERRATEC_XS_MT2060: 1466 case EM2870_BOARD_TERRATEC_XS_MT2060:
1460 em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x27", 1);
1461 em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1);
1462 /* this device needs some gpio writes to get the DVB-T 1467 /* this device needs some gpio writes to get the DVB-T
1463 demod work */ 1468 demod work */
1464 em28xx_write_regs(dev, 0x08, "\xfe", 1); 1469 em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfe);
1465 mdelay(70); 1470 mdelay(70);
1466 em28xx_write_regs(dev, 0x08, "\xde", 1); 1471 em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xde);
1467 mdelay(70); 1472 mdelay(70);
1468 dev->em28xx_write_regs(dev, 0x08, "\xfe", 1); 1473 em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfe);
1469 mdelay(70); 1474 mdelay(70);
1470 break; 1475 break;
1471
1472 case EM2870_BOARD_PINNACLE_PCTV_DVB: 1476 case EM2870_BOARD_PINNACLE_PCTV_DVB:
1473 em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1);
1474 /* this device needs some gpio writes to get the 1477 /* this device needs some gpio writes to get the
1475 DVB-T demod work */ 1478 DVB-T demod work */
1476 em28xx_write_regs(dev, 0x08, "\xfe", 1); 1479 em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfe);
1477 mdelay(70); 1480 mdelay(70);
1478 em28xx_write_regs(dev, 0x08, "\xde", 1); 1481 em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xde);
1479 mdelay(70); 1482 mdelay(70);
1480 em28xx_write_regs(dev, 0x08, "\xfe", 1); 1483 em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfe);
1481 mdelay(70); 1484 mdelay(70);
1482 /* switch em2880 rc protocol */
1483 em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x22", 1);
1484 /* should be added ir_codes here */
1485 break; 1485 break;
1486
1487 case EM2820_BOARD_GADMEI_UTV310: 1486 case EM2820_BOARD_GADMEI_UTV310:
1488 em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x27", 1);
1489 em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1);
1490 /* Turn on analog audio output */
1491 em28xx_write_regs_req(dev, 0x00, 0x08, "\xfd", 1);
1492 break;
1493
1494 case EM2860_BOARD_GADMEI_UTV330:
1495 /* Turn on IR */
1496 em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x07", 1);
1497 em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1);
1498 /* should be added ir_codes here */
1499 break;
1500
1501 case EM2820_BOARD_MSI_VOX_USB_2: 1487 case EM2820_BOARD_MSI_VOX_USB_2:
1502 em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x27", 1); 1488 /* enables audio for that devices */
1503 em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1); 1489 em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfd);
1504 /* enables audio for that device */
1505 em28xx_write_regs_req(dev, 0x00, 0x08, "\xfd", 1);
1506 break; 1490 break;
1507 } 1491 }
1508 1492
1509 em28xx_gpio_set(dev, dev->tun_analog_gpio); 1493 em28xx_gpio_set(dev, dev->board.tuner_gpio);
1510 em28xx_set_mode(dev, EM28XX_ANALOG_MODE); 1494 em28xx_set_mode(dev, EM28XX_ANALOG_MODE);
1511 1495
1512 /* Unlock device */ 1496 /* Unlock device */
1513 em28xx_set_mode(dev, EM28XX_MODE_UNDEFINED); 1497 em28xx_set_mode(dev, EM28XX_SUSPEND);
1514} 1498}
1515 1499
1516static void em28xx_setup_xc3028(struct em28xx *dev, struct xc2028_ctrl *ctl) 1500static void em28xx_setup_xc3028(struct em28xx *dev, struct xc2028_ctrl *ctl)
@@ -1536,6 +1520,7 @@ static void em28xx_setup_xc3028(struct em28xx *dev, struct xc2028_ctrl *ctl)
1536 ctl->demod = XC3028_FE_DEFAULT; 1520 ctl->demod = XC3028_FE_DEFAULT;
1537 ctl->fname = XC3028L_DEFAULT_FIRMWARE; 1521 ctl->fname = XC3028L_DEFAULT_FIRMWARE;
1538 break; 1522 break;
1523 case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_850:
1539 case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950: 1524 case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950:
1540 case EM2880_BOARD_PINNACLE_PCTV_HD_PRO: 1525 case EM2880_BOARD_PINNACLE_PCTV_HD_PRO:
1541 /* FIXME: Better to specify the needed IF */ 1526 /* FIXME: Better to specify the needed IF */
@@ -1712,12 +1697,15 @@ void em28xx_card_setup(struct em28xx *dev)
1712 em28xx_set_model(dev); 1697 em28xx_set_model(dev);
1713 1698
1714 dev->tuner_type = em28xx_boards[dev->model].tuner_type; 1699 dev->tuner_type = em28xx_boards[dev->model].tuner_type;
1700 if (em28xx_boards[dev->model].tuner_addr)
1701 dev->tuner_addr = em28xx_boards[dev->model].tuner_addr;
1715 1702
1716 /* request some modules */ 1703 /* request some modules */
1717 switch (dev->model) { 1704 switch (dev->model) {
1718 case EM2820_BOARD_HAUPPAUGE_WINTV_USB_2: 1705 case EM2820_BOARD_HAUPPAUGE_WINTV_USB_2:
1719 case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900: 1706 case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900:
1720 case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2: 1707 case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2:
1708 case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_850:
1721 case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950: 1709 case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950:
1722 { 1710 {
1723 struct tveeprom tv; 1711 struct tveeprom tv;
@@ -1733,7 +1721,7 @@ void em28xx_card_setup(struct em28xx *dev)
1733 1721
1734 if (tv.audio_processor == V4L2_IDENT_MSPX4XX) { 1722 if (tv.audio_processor == V4L2_IDENT_MSPX4XX) {
1735 dev->i2s_speed = 2048000; 1723 dev->i2s_speed = 2048000;
1736 dev->has_msp34xx = 1; 1724 dev->board.has_msp34xx = 1;
1737 } 1725 }
1738#ifdef CONFIG_MODULES 1726#ifdef CONFIG_MODULES
1739 if (tv.has_ir) 1727 if (tv.has_ir)
@@ -1743,7 +1731,7 @@ void em28xx_card_setup(struct em28xx *dev)
1743 } 1731 }
1744 case EM2820_BOARD_KWORLD_PVRTV2800RF: 1732 case EM2820_BOARD_KWORLD_PVRTV2800RF:
1745 /* GPIO enables sound on KWORLD PVR TV 2800RF */ 1733 /* GPIO enables sound on KWORLD PVR TV 2800RF */
1746 em28xx_write_regs_req(dev, 0x00, 0x08, "\xf9", 1); 1734 em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xf9);
1747 break; 1735 break;
1748 case EM2820_BOARD_UNKNOWN: 1736 case EM2820_BOARD_UNKNOWN:
1749 case EM2800_BOARD_UNKNOWN: 1737 case EM2800_BOARD_UNKNOWN:
@@ -1766,10 +1754,10 @@ void em28xx_card_setup(struct em28xx *dev)
1766 break; 1754 break;
1767 } 1755 }
1768 1756
1769 if (dev->has_snapshot_button) 1757 if (dev->board.has_snapshot_button)
1770 em28xx_register_snapshot_button(dev); 1758 em28xx_register_snapshot_button(dev);
1771 1759
1772 if (dev->valid == EM28XX_BOARD_NOT_VALIDATED) { 1760 if (dev->board.valid == EM28XX_BOARD_NOT_VALIDATED) {
1773 em28xx_errdev("\n\n"); 1761 em28xx_errdev("\n\n");
1774 em28xx_errdev("The support for this board weren't " 1762 em28xx_errdev("The support for this board weren't "
1775 "valid yet.\n"); 1763 "valid yet.\n");
@@ -1784,15 +1772,433 @@ void em28xx_card_setup(struct em28xx *dev)
1784 1772
1785#ifdef CONFIG_MODULES 1773#ifdef CONFIG_MODULES
1786 /* request some modules */ 1774 /* request some modules */
1787 if (dev->has_msp34xx) 1775 if (dev->board.has_msp34xx)
1788 request_module("msp3400"); 1776 request_module("msp3400");
1789 if (dev->decoder == EM28XX_SAA7113 || dev->decoder == EM28XX_SAA7114) 1777 if (dev->board.decoder == EM28XX_SAA711X)
1790 request_module("saa7115"); 1778 request_module("saa7115");
1791 if (dev->decoder == EM28XX_TVP5150) 1779 if (dev->board.decoder == EM28XX_TVP5150)
1792 request_module("tvp5150"); 1780 request_module("tvp5150");
1793 if (dev->tuner_type != TUNER_ABSENT) 1781 if (dev->board.tuner_type != TUNER_ABSENT)
1794 request_module("tuner"); 1782 request_module("tuner");
1795#endif 1783#endif
1796 1784
1797 em28xx_config_tuner(dev); 1785 em28xx_config_tuner(dev);
1786
1787 em28xx_ir_init(dev);
1788}
1789
1790
1791#if defined(CONFIG_MODULES) && defined(MODULE)
1792static void request_module_async(struct work_struct *work)
1793{
1794 struct em28xx *dev = container_of(work,
1795 struct em28xx, request_module_wk);
1796
1797 if (dev->has_audio_class)
1798 request_module("snd-usb-audio");
1799 else if (dev->has_alsa_audio)
1800 request_module("em28xx-alsa");
1801
1802 if (dev->board.has_dvb)
1803 request_module("em28xx-dvb");
1804}
1805
1806static void request_modules(struct em28xx *dev)
1807{
1808 INIT_WORK(&dev->request_module_wk, request_module_async);
1809 schedule_work(&dev->request_module_wk);
1810}
1811#else
1812#define request_modules(dev)
1813#endif /* CONFIG_MODULES */
1814
1815/*
1816 * em28xx_realease_resources()
1817 * unregisters the v4l2,i2c and usb devices
1818 * called when the device gets disconected or at module unload
1819*/
1820void em28xx_release_resources(struct em28xx *dev)
1821{
1822 if (dev->sbutton_input_dev)
1823 em28xx_deregister_snapshot_button(dev);
1824
1825 if (dev->ir)
1826 em28xx_ir_fini(dev);
1827
1828 /*FIXME: I2C IR should be disconnected */
1829
1830 em28xx_release_analog_resources(dev);
1831
1832 em28xx_remove_from_devlist(dev);
1833
1834 em28xx_i2c_unregister(dev);
1835 usb_put_dev(dev->udev);
1836
1837 /* Mark device as unused */
1838 em28xx_devused &= ~(1 << dev->devno);
1839};
1840
1841/*
1842 * em28xx_init_dev()
1843 * allocates and inits the device structs, registers i2c bus and v4l device
1844 */
1845int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
1846 int minor)
1847{
1848 struct em28xx *dev = *devhandle;
1849 int retval = -ENOMEM;
1850 int errCode;
1851
1852 dev->udev = udev;
1853 mutex_init(&dev->ctrl_urb_lock);
1854 spin_lock_init(&dev->slock);
1855 init_waitqueue_head(&dev->open);
1856 init_waitqueue_head(&dev->wait_frame);
1857 init_waitqueue_head(&dev->wait_stream);
1858
1859 dev->em28xx_write_regs = em28xx_write_regs;
1860 dev->em28xx_read_reg = em28xx_read_reg;
1861 dev->em28xx_read_reg_req_len = em28xx_read_reg_req_len;
1862 dev->em28xx_write_regs_req = em28xx_write_regs_req;
1863 dev->em28xx_read_reg_req = em28xx_read_reg_req;
1864 dev->board.is_em2800 = em28xx_boards[dev->model].is_em2800;
1865
1866 em28xx_pre_card_setup(dev);
1867
1868 if (!dev->board.is_em2800) {
1869 /* Sets I2C speed to 100 KHz */
1870 retval = em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x40);
1871 if (retval < 0) {
1872 em28xx_errdev("%s: em28xx_write_regs_req failed!"
1873 " retval [%d]\n",
1874 __func__, retval);
1875 return retval;
1876 }
1877 }
1878
1879 /* register i2c bus */
1880 errCode = em28xx_i2c_register(dev);
1881 if (errCode < 0) {
1882 em28xx_errdev("%s: em28xx_i2c_register - errCode [%d]!\n",
1883 __func__, errCode);
1884 return errCode;
1885 }
1886
1887 /* Do board specific init and eeprom reading */
1888 em28xx_card_setup(dev);
1889
1890 /* Configure audio */
1891 errCode = em28xx_audio_setup(dev);
1892 if (errCode < 0) {
1893 em28xx_errdev("%s: Error while setting audio - errCode [%d]!\n",
1894 __func__, errCode);
1895 }
1896
1897 /* wake i2c devices */
1898 em28xx_wake_i2c(dev);
1899
1900 /* init video dma queues */
1901 INIT_LIST_HEAD(&dev->vidq.active);
1902 INIT_LIST_HEAD(&dev->vidq.queued);
1903
1904
1905 if (dev->board.has_msp34xx) {
1906 /* Send a reset to other chips via gpio */
1907 errCode = em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xf7);
1908 if (errCode < 0) {
1909 em28xx_errdev("%s: em28xx_write_regs_req - "
1910 "msp34xx(1) failed! errCode [%d]\n",
1911 __func__, errCode);
1912 return errCode;
1913 }
1914 msleep(3);
1915
1916 errCode = em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xff);
1917 if (errCode < 0) {
1918 em28xx_errdev("%s: em28xx_write_regs_req - "
1919 "msp34xx(2) failed! errCode [%d]\n",
1920 __func__, errCode);
1921 return errCode;
1922 }
1923 msleep(3);
1924 }
1925
1926 em28xx_add_into_devlist(dev);
1927
1928 retval = em28xx_register_analog_devices(dev);
1929 if (retval < 0) {
1930 em28xx_release_resources(dev);
1931 goto fail_reg_devices;
1932 }
1933
1934 em28xx_init_extension(dev);
1935
1936 /* Save some power by putting tuner to sleep */
1937 em28xx_i2c_call_clients(dev, TUNER_SET_STANDBY, NULL);
1938
1939 return 0;
1940
1941fail_reg_devices:
1942 return retval;
1943}
1944
1945/*
1946 * em28xx_usb_probe()
1947 * checks for supported devices
1948 */
1949static int em28xx_usb_probe(struct usb_interface *interface,
1950 const struct usb_device_id *id)
1951{
1952 const struct usb_endpoint_descriptor *endpoint;
1953 struct usb_device *udev;
1954 struct usb_interface *uif;
1955 struct em28xx *dev = NULL;
1956 int retval = -ENODEV;
1957 int i, nr, ifnum, isoc_pipe;
1958 char *speed;
1959 char descr[255] = "";
1960
1961 udev = usb_get_dev(interface_to_usbdev(interface));
1962 ifnum = interface->altsetting[0].desc.bInterfaceNumber;
1963
1964 /* Check to see next free device and mark as used */
1965 nr = find_first_zero_bit(&em28xx_devused, EM28XX_MAXBOARDS);
1966 em28xx_devused |= 1<<nr;
1967
1968 /* Don't register audio interfaces */
1969 if (interface->altsetting[0].desc.bInterfaceClass == USB_CLASS_AUDIO) {
1970 em28xx_err(DRIVER_NAME " audio device (%04x:%04x): "
1971 "interface %i, class %i\n",
1972 le16_to_cpu(udev->descriptor.idVendor),
1973 le16_to_cpu(udev->descriptor.idProduct),
1974 ifnum,
1975 interface->altsetting[0].desc.bInterfaceClass);
1976
1977 em28xx_devused &= ~(1<<nr);
1978 return -ENODEV;
1979 }
1980
1981 endpoint = &interface->cur_altsetting->endpoint[0].desc;
1982
1983 /* check if the device has the iso in endpoint at the correct place */
1984 if (usb_endpoint_xfer_isoc(endpoint)
1985 &&
1986 (interface->altsetting[1].endpoint[0].desc.wMaxPacketSize == 940)) {
1987 /* It's a newer em2874/em2875 device */
1988 isoc_pipe = 0;
1989 } else {
1990 int check_interface = 1;
1991 isoc_pipe = 1;
1992 endpoint = &interface->cur_altsetting->endpoint[1].desc;
1993 if (usb_endpoint_type(endpoint) !=
1994 USB_ENDPOINT_XFER_ISOC)
1995 check_interface = 0;
1996
1997 if (usb_endpoint_dir_out(endpoint))
1998 check_interface = 0;
1999
2000 if (!check_interface) {
2001 em28xx_err(DRIVER_NAME " video device (%04x:%04x): "
2002 "interface %i, class %i found.\n",
2003 le16_to_cpu(udev->descriptor.idVendor),
2004 le16_to_cpu(udev->descriptor.idProduct),
2005 ifnum,
2006 interface->altsetting[0].desc.bInterfaceClass);
2007
2008 em28xx_err(DRIVER_NAME " This is an anciliary "
2009 "interface not used by the driver\n");
2010
2011 em28xx_devused &= ~(1<<nr);
2012 return -ENODEV;
2013 }
2014 }
2015
2016 switch (udev->speed) {
2017 case USB_SPEED_LOW:
2018 speed = "1.5";
2019 break;
2020 case USB_SPEED_UNKNOWN:
2021 case USB_SPEED_FULL:
2022 speed = "12";
2023 break;
2024 case USB_SPEED_HIGH:
2025 speed = "480";
2026 break;
2027 default:
2028 speed = "unknown";
2029 }
2030
2031 if (udev->manufacturer)
2032 strlcpy(descr, udev->manufacturer, sizeof(descr));
2033
2034 if (udev->product) {
2035 if (*descr)
2036 strlcat(descr, " ", sizeof(descr));
2037 strlcat(descr, udev->product, sizeof(descr));
2038 }
2039 if (*descr)
2040 strlcat(descr, " ", sizeof(descr));
2041
2042 printk(DRIVER_NAME ": New device %s@ %s Mbps "
2043 "(%04x:%04x, interface %d, class %d)\n",
2044 descr,
2045 speed,
2046 le16_to_cpu(udev->descriptor.idVendor),
2047 le16_to_cpu(udev->descriptor.idProduct),
2048 ifnum,
2049 interface->altsetting->desc.bInterfaceNumber);
2050
2051 if (nr >= EM28XX_MAXBOARDS) {
2052 printk(DRIVER_NAME ": Supports only %i em28xx boards.\n",
2053 EM28XX_MAXBOARDS);
2054 em28xx_devused &= ~(1<<nr);
2055 return -ENOMEM;
2056 }
2057
2058 /* allocate memory for our device state and initialize it */
2059 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
2060 if (dev == NULL) {
2061 em28xx_err(DRIVER_NAME ": out of memory!\n");
2062 em28xx_devused &= ~(1<<nr);
2063 return -ENOMEM;
2064 }
2065
2066 snprintf(dev->name, 29, "em28xx #%d", nr);
2067 dev->devno = nr;
2068 dev->model = id->driver_info;
2069 dev->alt = -1;
2070
2071 /* Checks if audio is provided by some interface */
2072 for (i = 0; i < udev->config->desc.bNumInterfaces; i++) {
2073 uif = udev->config->interface[i];
2074 if (uif->altsetting[0].desc.bInterfaceClass == USB_CLASS_AUDIO) {
2075 dev->has_audio_class = 1;
2076 break;
2077 }
2078 }
2079
2080 /* compute alternate max packet sizes */
2081 uif = udev->actconfig->interface[0];
2082
2083 dev->num_alt = uif->num_altsetting;
2084 dev->alt_max_pkt_size = kmalloc(32 * dev->num_alt, GFP_KERNEL);
2085
2086 if (dev->alt_max_pkt_size == NULL) {
2087 em28xx_errdev("out of memory!\n");
2088 em28xx_devused &= ~(1<<nr);
2089 kfree(dev);
2090 return -ENOMEM;
2091 }
2092
2093 for (i = 0; i < dev->num_alt ; i++) {
2094 u16 tmp = le16_to_cpu(uif->altsetting[i].endpoint[isoc_pipe].desc.wMaxPacketSize);
2095 dev->alt_max_pkt_size[i] =
2096 (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1);
2097 }
2098
2099 if ((card[nr] >= 0) && (card[nr] < em28xx_bcount))
2100 dev->model = card[nr];
2101
2102 /* allocate device struct */
2103 mutex_init(&dev->lock);
2104 mutex_lock(&dev->lock);
2105 retval = em28xx_init_dev(&dev, udev, nr);
2106 if (retval) {
2107 em28xx_devused &= ~(1<<dev->devno);
2108 kfree(dev);
2109
2110 return retval;
2111 }
2112
2113 /* save our data pointer in this interface device */
2114 usb_set_intfdata(interface, dev);
2115
2116 request_modules(dev);
2117
2118 /* Should be the last thing to do, to avoid newer udev's to
2119 open the device before fully initializing it
2120 */
2121 mutex_unlock(&dev->lock);
2122
2123 return 0;
2124}
2125
2126/*
2127 * em28xx_usb_disconnect()
2128 * called when the device gets diconencted
2129 * video device will be unregistered on v4l2_close in case it is still open
2130 */
2131static void em28xx_usb_disconnect(struct usb_interface *interface)
2132{
2133 struct em28xx *dev;
2134
2135 dev = usb_get_intfdata(interface);
2136 usb_set_intfdata(interface, NULL);
2137
2138 if (!dev)
2139 return;
2140
2141 em28xx_info("disconnecting %s\n", dev->vdev->name);
2142
2143 /* wait until all current v4l2 io is finished then deallocate
2144 resources */
2145 mutex_lock(&dev->lock);
2146
2147 wake_up_interruptible_all(&dev->open);
2148
2149 if (dev->users) {
2150 em28xx_warn
2151 ("device /dev/video%d is open! Deregistration and memory "
2152 "deallocation are deferred on close.\n",
2153 dev->vdev->num);
2154
2155 dev->state |= DEV_MISCONFIGURED;
2156 em28xx_uninit_isoc(dev);
2157 dev->state |= DEV_DISCONNECTED;
2158 wake_up_interruptible(&dev->wait_frame);
2159 wake_up_interruptible(&dev->wait_stream);
2160 } else {
2161 dev->state |= DEV_DISCONNECTED;
2162 em28xx_release_resources(dev);
2163 }
2164
2165 em28xx_close_extension(dev);
2166
2167 mutex_unlock(&dev->lock);
2168
2169 if (!dev->users) {
2170 kfree(dev->alt_max_pkt_size);
2171 kfree(dev);
2172 }
1798} 2173}
2174
2175static struct usb_driver em28xx_usb_driver = {
2176 .name = "em28xx",
2177 .probe = em28xx_usb_probe,
2178 .disconnect = em28xx_usb_disconnect,
2179 .id_table = em28xx_id_table,
2180};
2181
2182static int __init em28xx_module_init(void)
2183{
2184 int result;
2185
2186 /* register this driver with the USB subsystem */
2187 result = usb_register(&em28xx_usb_driver);
2188 if (result)
2189 em28xx_err(DRIVER_NAME
2190 " usb_register failed. Error number %d.\n", result);
2191
2192 printk(KERN_INFO DRIVER_NAME " driver loaded\n");
2193
2194 return result;
2195}
2196
2197static void __exit em28xx_module_exit(void)
2198{
2199 /* deregister this driver with the USB subsystem */
2200 usb_deregister(&em28xx_usb_driver);
2201}
2202
2203module_init(em28xx_module_init);
2204module_exit(em28xx_module_exit);
diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c
index 15e2b525310d..f8504518586a 100644
--- a/drivers/media/video/em28xx/em28xx-core.c
+++ b/drivers/media/video/em28xx/em28xx-core.c
@@ -26,6 +26,7 @@
26#include <linux/module.h> 26#include <linux/module.h>
27#include <linux/usb.h> 27#include <linux/usb.h>
28#include <linux/vmalloc.h> 28#include <linux/vmalloc.h>
29#include <media/v4l2-common.h>
29 30
30#include "em28xx.h" 31#include "em28xx.h"
31 32
@@ -66,7 +67,8 @@ MODULE_PARM_DESC(alt, "alternate setting to use for video endpoint");
66int em28xx_read_reg_req_len(struct em28xx *dev, u8 req, u16 reg, 67int em28xx_read_reg_req_len(struct em28xx *dev, u8 req, u16 reg,
67 char *buf, int len) 68 char *buf, int len)
68{ 69{
69 int ret, byte; 70 int ret;
71 int pipe = usb_rcvctrlpipe(dev->udev, 0);
70 72
71 if (dev->state & DEV_DISCONNECTED) 73 if (dev->state & DEV_DISCONNECTED)
72 return -ENODEV; 74 return -ENODEV;
@@ -74,10 +76,18 @@ int em28xx_read_reg_req_len(struct em28xx *dev, u8 req, u16 reg,
74 if (len > URB_MAX_CTRL_SIZE) 76 if (len > URB_MAX_CTRL_SIZE)
75 return -EINVAL; 77 return -EINVAL;
76 78
77 em28xx_regdbg("req=%02x, reg=%02x ", req, reg); 79 if (reg_debug) {
80 printk( KERN_DEBUG "(pipe 0x%08x): "
81 "IN: %02x %02x %02x %02x %02x %02x %02x %02x ",
82 pipe,
83 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
84 req, 0, 0,
85 reg & 0xff, reg >> 8,
86 len & 0xff, len >> 8);
87 }
78 88
79 mutex_lock(&dev->ctrl_urb_lock); 89 mutex_lock(&dev->ctrl_urb_lock);
80 ret = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0), req, 90 ret = usb_control_msg(dev->udev, pipe, req,
81 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 91 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
82 0x0000, reg, dev->urb_buf, len, HZ); 92 0x0000, reg, dev->urb_buf, len, HZ);
83 if (ret < 0) { 93 if (ret < 0) {
@@ -93,7 +103,9 @@ int em28xx_read_reg_req_len(struct em28xx *dev, u8 req, u16 reg,
93 mutex_unlock(&dev->ctrl_urb_lock); 103 mutex_unlock(&dev->ctrl_urb_lock);
94 104
95 if (reg_debug) { 105 if (reg_debug) {
96 printk("%02x values: ", ret); 106 int byte;
107
108 printk("<<<");
97 for (byte = 0; byte < len; byte++) 109 for (byte = 0; byte < len; byte++)
98 printk(" %02x", (unsigned char)buf[byte]); 110 printk(" %02x", (unsigned char)buf[byte]);
99 printk("\n"); 111 printk("\n");
@@ -108,28 +120,12 @@ int em28xx_read_reg_req_len(struct em28xx *dev, u8 req, u16 reg,
108 */ 120 */
109int em28xx_read_reg_req(struct em28xx *dev, u8 req, u16 reg) 121int em28xx_read_reg_req(struct em28xx *dev, u8 req, u16 reg)
110{ 122{
111 u8 val;
112 int ret; 123 int ret;
124 u8 val;
113 125
114 if (dev->state & DEV_DISCONNECTED) 126 ret = em28xx_read_reg_req_len(dev, req, reg, &val, 1);
115 return(-ENODEV); 127 if (ret < 0)
116
117 em28xx_regdbg("req=%02x, reg=%02x:", req, reg);
118
119 mutex_lock(&dev->ctrl_urb_lock);
120 ret = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0), req,
121 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
122 0x0000, reg, dev->urb_buf, 1, HZ);
123 val = dev->urb_buf[0];
124 mutex_unlock(&dev->ctrl_urb_lock);
125
126 if (ret < 0) {
127 printk(" failed!\n");
128 return ret; 128 return ret;
129 }
130
131 if (reg_debug)
132 printk("%02x\n", (unsigned char) val);
133 129
134 return val; 130 return val;
135} 131}
@@ -147,6 +143,7 @@ int em28xx_write_regs_req(struct em28xx *dev, u8 req, u16 reg, char *buf,
147 int len) 143 int len)
148{ 144{
149 int ret; 145 int ret;
146 int pipe = usb_sndctrlpipe(dev->udev, 0);
150 147
151 if (dev->state & DEV_DISCONNECTED) 148 if (dev->state & DEV_DISCONNECTED)
152 return -ENODEV; 149 return -ENODEV;
@@ -154,17 +151,25 @@ int em28xx_write_regs_req(struct em28xx *dev, u8 req, u16 reg, char *buf,
154 if ((len < 1) || (len > URB_MAX_CTRL_SIZE)) 151 if ((len < 1) || (len > URB_MAX_CTRL_SIZE))
155 return -EINVAL; 152 return -EINVAL;
156 153
157 em28xx_regdbg("req=%02x reg=%02x:", req, reg);
158 if (reg_debug) { 154 if (reg_debug) {
159 int i; 155 int byte;
160 for (i = 0; i < len; ++i) 156
161 printk(" %02x", (unsigned char)buf[i]); 157 printk( KERN_DEBUG "(pipe 0x%08x): "
158 "OUT: %02x %02x %02x %02x %02x %02x %02x %02x >>>",
159 pipe,
160 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
161 req, 0, 0,
162 reg & 0xff, reg >> 8,
163 len & 0xff, len >> 8);
164
165 for (byte = 0; byte < len; byte++)
166 printk(" %02x", (unsigned char)buf[byte]);
162 printk("\n"); 167 printk("\n");
163 } 168 }
164 169
165 mutex_lock(&dev->ctrl_urb_lock); 170 mutex_lock(&dev->ctrl_urb_lock);
166 memcpy(dev->urb_buf, buf, len); 171 memcpy(dev->urb_buf, buf, len);
167 ret = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0), req, 172 ret = usb_control_msg(dev->udev, pipe, req,
168 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 173 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
169 0x0000, reg, dev->urb_buf, len, HZ); 174 0x0000, reg, dev->urb_buf, len, HZ);
170 mutex_unlock(&dev->ctrl_urb_lock); 175 mutex_unlock(&dev->ctrl_urb_lock);
@@ -187,15 +192,21 @@ int em28xx_write_regs(struct em28xx *dev, u16 reg, char *buf, int len)
187 Not sure what happens on reading GPO register. 192 Not sure what happens on reading GPO register.
188 */ 193 */
189 if (rc >= 0) { 194 if (rc >= 0) {
190 if (reg == EM2880_R04_GPO) 195 if (reg == dev->reg_gpo_num)
191 dev->reg_gpo = buf[0]; 196 dev->reg_gpo = buf[0];
192 else if (reg == EM28XX_R08_GPIO) 197 else if (reg == dev->reg_gpio_num)
193 dev->reg_gpio = buf[0]; 198 dev->reg_gpio = buf[0];
194 } 199 }
195 200
196 return rc; 201 return rc;
197} 202}
198 203
204/* Write a single register */
205int em28xx_write_reg(struct em28xx *dev, u16 reg, u8 val)
206{
207 return em28xx_write_regs(dev, reg, &val, 1);
208}
209
199/* 210/*
200 * em28xx_write_reg_bits() 211 * em28xx_write_reg_bits()
201 * sets only some bits (specified by bitmask) of a register, by first reading 212 * sets only some bits (specified by bitmask) of a register, by first reading
@@ -208,9 +219,9 @@ static int em28xx_write_reg_bits(struct em28xx *dev, u16 reg, u8 val,
208 u8 newval; 219 u8 newval;
209 220
210 /* Uses cache for gpo/gpio registers */ 221 /* Uses cache for gpo/gpio registers */
211 if (reg == EM2880_R04_GPO) 222 if (reg == dev->reg_gpo_num)
212 oldval = dev->reg_gpo; 223 oldval = dev->reg_gpo;
213 else if (reg == EM28XX_R08_GPIO) 224 else if (reg == dev->reg_gpio_num)
214 oldval = dev->reg_gpio; 225 oldval = dev->reg_gpio;
215 else 226 else
216 oldval = em28xx_read_reg(dev, reg); 227 oldval = em28xx_read_reg(dev, reg);
@@ -224,15 +235,70 @@ static int em28xx_write_reg_bits(struct em28xx *dev, u16 reg, u8 val,
224} 235}
225 236
226/* 237/*
238 * em28xx_is_ac97_ready()
239 * Checks if ac97 is ready
240 */
241static int em28xx_is_ac97_ready(struct em28xx *dev)
242{
243 int ret, i;
244
245 /* Wait up to 50 ms for AC97 command to complete */
246 for (i = 0; i < 10; i++, msleep(5)) {
247 ret = em28xx_read_reg(dev, EM28XX_R43_AC97BUSY);
248 if (ret < 0)
249 return ret;
250
251 if (!(ret & 0x01))
252 return 0;
253 }
254
255 em28xx_warn("AC97 command still being executed: not handled properly!\n");
256 return -EBUSY;
257}
258
259/*
260 * em28xx_read_ac97()
261 * write a 16 bit value to the specified AC97 address (LSB first!)
262 */
263int em28xx_read_ac97(struct em28xx *dev, u8 reg)
264{
265 int ret;
266 u8 addr = (reg & 0x7f) | 0x80;
267 u16 val;
268
269 ret = em28xx_is_ac97_ready(dev);
270 if (ret < 0)
271 return ret;
272
273 ret = em28xx_write_regs(dev, EM28XX_R42_AC97ADDR, &addr, 1);
274 if (ret < 0)
275 return ret;
276
277 ret = dev->em28xx_read_reg_req_len(dev, 0, EM28XX_R40_AC97LSB,
278 (u8 *)&val, sizeof(val));
279
280 if (ret < 0)
281 return ret;
282 return le16_to_cpu(val);
283}
284
285/*
227 * em28xx_write_ac97() 286 * em28xx_write_ac97()
228 * write a 16 bit value to the specified AC97 address (LSB first!) 287 * write a 16 bit value to the specified AC97 address (LSB first!)
229 */ 288 */
230static int em28xx_write_ac97(struct em28xx *dev, u8 reg, u8 *val) 289int em28xx_write_ac97(struct em28xx *dev, u8 reg, u16 val)
231{ 290{
232 int ret, i; 291 int ret;
233 u8 addr = reg & 0x7f; 292 u8 addr = reg & 0x7f;
293 __le16 value;
234 294
235 ret = em28xx_write_regs(dev, EM28XX_R40_AC97LSB, val, 2); 295 value = cpu_to_le16(val);
296
297 ret = em28xx_is_ac97_ready(dev);
298 if (ret < 0)
299 return ret;
300
301 ret = em28xx_write_regs(dev, EM28XX_R40_AC97LSB, (u8 *) &value, 2);
236 if (ret < 0) 302 if (ret < 0)
237 return ret; 303 return ret;
238 304
@@ -240,58 +306,74 @@ static int em28xx_write_ac97(struct em28xx *dev, u8 reg, u8 *val)
240 if (ret < 0) 306 if (ret < 0)
241 return ret; 307 return ret;
242 308
243 /* Wait up to 50 ms for AC97 command to complete */ 309 return 0;
244 for (i = 0; i < 10; i++) { 310}
245 ret = em28xx_read_reg(dev, EM28XX_R43_AC97BUSY);
246 if (ret < 0)
247 return ret;
248 311
249 if (!(ret & 0x01)) 312struct em28xx_vol_table {
250 return 0; 313 enum em28xx_amux mux;
251 msleep(5); 314 u8 reg;
315};
316
317static struct em28xx_vol_table inputs[] = {
318 { EM28XX_AMUX_VIDEO, AC97_VIDEO_VOL },
319 { EM28XX_AMUX_LINE_IN, AC97_LINEIN_VOL },
320 { EM28XX_AMUX_PHONE, AC97_PHONE_VOL },
321 { EM28XX_AMUX_MIC, AC97_MIC_VOL },
322 { EM28XX_AMUX_CD, AC97_CD_VOL },
323 { EM28XX_AMUX_AUX, AC97_AUX_VOL },
324 { EM28XX_AMUX_PCM_OUT, AC97_PCM_OUT_VOL },
325};
326
327static int set_ac97_input(struct em28xx *dev)
328{
329 int ret, i;
330 enum em28xx_amux amux = dev->ctl_ainput;
331
332 /* EM28XX_AMUX_VIDEO2 is a special case used to indicate that
333 em28xx should point to LINE IN, while AC97 should use VIDEO
334 */
335 if (amux == EM28XX_AMUX_VIDEO2)
336 amux = EM28XX_AMUX_VIDEO;
337
338 /* Mute all entres but the one that were selected */
339 for (i = 0; i < ARRAY_SIZE(inputs); i++) {
340 if (amux == inputs[i].mux)
341 ret = em28xx_write_ac97(dev, inputs[i].reg, 0x0808);
342 else
343 ret = em28xx_write_ac97(dev, inputs[i].reg, 0x8000);
344
345 if (ret < 0)
346 em28xx_warn("couldn't setup AC97 register %d\n",
347 inputs[i].reg);
252 } 348 }
253 em28xx_warn("AC97 command still being executed: not handled properly!\n");
254 return 0; 349 return 0;
255} 350}
256 351
257static int em28xx_set_audio_source(struct em28xx *dev) 352static int em28xx_set_audio_source(struct em28xx *dev)
258{ 353{
259 static char *enable = "\x08\x08";
260 static char *disable = "\x08\x88";
261 char *video = enable, *line = disable;
262 int ret; 354 int ret;
263 u8 input; 355 u8 input;
264 356
265 if (dev->is_em2800) { 357 if (dev->board.is_em2800) {
266 if (dev->ctl_ainput) 358 if (dev->ctl_ainput == EM28XX_AMUX_VIDEO)
267 input = EM2800_AUDIO_SRC_LINE;
268 else
269 input = EM2800_AUDIO_SRC_TUNER; 359 input = EM2800_AUDIO_SRC_TUNER;
360 else
361 input = EM2800_AUDIO_SRC_LINE;
270 362
271 ret = em28xx_write_regs(dev, EM2800_R08_AUDIOSRC, &input, 1); 363 ret = em28xx_write_regs(dev, EM2800_R08_AUDIOSRC, &input, 1);
272 if (ret < 0) 364 if (ret < 0)
273 return ret; 365 return ret;
274 } 366 }
275 367
276 if (dev->has_msp34xx) 368 if (dev->board.has_msp34xx)
277 input = EM28XX_AUDIO_SRC_TUNER; 369 input = EM28XX_AUDIO_SRC_TUNER;
278 else { 370 else {
279 switch (dev->ctl_ainput) { 371 switch (dev->ctl_ainput) {
280 case EM28XX_AMUX_VIDEO: 372 case EM28XX_AMUX_VIDEO:
281 input = EM28XX_AUDIO_SRC_TUNER; 373 input = EM28XX_AUDIO_SRC_TUNER;
282 break; 374 break;
283 case EM28XX_AMUX_LINE_IN: 375 default:
284 input = EM28XX_AUDIO_SRC_LINE; 376 input = EM28XX_AUDIO_SRC_LINE;
285 video = disable;
286 line = enable;
287 break;
288 case EM28XX_AMUX_AC97_VIDEO:
289 input = EM28XX_AUDIO_SRC_LINE;
290 break;
291 case EM28XX_AMUX_AC97_LINE_IN:
292 input = EM28XX_AUDIO_SRC_LINE;
293 video = disable;
294 line = enable;
295 break; 377 break;
296 } 378 }
297 } 379 }
@@ -301,41 +383,50 @@ static int em28xx_set_audio_source(struct em28xx *dev)
301 return ret; 383 return ret;
302 msleep(5); 384 msleep(5);
303 385
304 /* Sets AC97 mixer registers 386 switch (dev->audio_mode.ac97) {
305 This is seems to be needed, even for non-ac97 configs 387 case EM28XX_NO_AC97:
306 */ 388 break;
307 ret = em28xx_write_ac97(dev, EM28XX_R14_VIDEO_AC97, video); 389 default:
308 if (ret < 0) 390 ret = set_ac97_input(dev);
309 return ret; 391 }
310
311 ret = em28xx_write_ac97(dev, EM28XX_R10_LINE_IN_AC97, line);
312 392
313 return ret; 393 return ret;
314} 394}
315 395
396struct em28xx_vol_table outputs[] = {
397 { EM28XX_AOUT_MASTER, AC97_MASTER_VOL },
398 { EM28XX_AOUT_LINE, AC97_LINE_LEVEL_VOL },
399 { EM28XX_AOUT_MONO, AC97_MASTER_MONO_VOL },
400 { EM28XX_AOUT_LFE, AC97_LFE_MASTER_VOL },
401 { EM28XX_AOUT_SURR, AC97_SURR_MASTER_VOL },
402};
403
316int em28xx_audio_analog_set(struct em28xx *dev) 404int em28xx_audio_analog_set(struct em28xx *dev)
317{ 405{
318 int ret; 406 int ret, i;
319 char s[2] = { 0x00, 0x00 }; 407 u8 xclk;
320 u8 xclk = 0x07;
321
322 s[0] |= 0x1f - dev->volume;
323 s[1] |= 0x1f - dev->volume;
324
325 /* Mute */
326 s[1] |= 0x80;
327 ret = em28xx_write_ac97(dev, EM28XX_R02_MASTER_AC97, s);
328 408
329 if (ret < 0) 409 if (!dev->audio_mode.has_audio)
330 return ret; 410 return 0;
331 411
332 if (dev->has_12mhz_i2s) 412 /* It is assumed that all devices use master volume for output.
333 xclk |= 0x20; 413 It would be possible to use also line output.
414 */
415 if (dev->audio_mode.ac97 != EM28XX_NO_AC97) {
416 /* Mute all outputs */
417 for (i = 0; i < ARRAY_SIZE(outputs); i++) {
418 ret = em28xx_write_ac97(dev, outputs[i].reg, 0x8000);
419 if (ret < 0)
420 em28xx_warn("couldn't setup AC97 register %d\n",
421 outputs[i].reg);
422 }
423 }
334 424
425 xclk = dev->board.xclk & 0x7f;
335 if (!dev->mute) 426 if (!dev->mute)
336 xclk |= 0x80; 427 xclk |= 0x80;
337 428
338 ret = em28xx_write_reg_bits(dev, EM28XX_R0F_XCLK, xclk, 0xa7); 429 ret = em28xx_write_reg(dev, EM28XX_R0F_XCLK, xclk);
339 if (ret < 0) 430 if (ret < 0)
340 return ret; 431 return ret;
341 msleep(10); 432 msleep(10);
@@ -343,36 +434,169 @@ int em28xx_audio_analog_set(struct em28xx *dev)
343 /* Selects the proper audio input */ 434 /* Selects the proper audio input */
344 ret = em28xx_set_audio_source(dev); 435 ret = em28xx_set_audio_source(dev);
345 436
346 /* Unmute device */ 437 /* Sets volume */
347 if (!dev->mute) 438 if (dev->audio_mode.ac97 != EM28XX_NO_AC97) {
348 s[1] &= ~0x80; 439 int vol;
349 ret = em28xx_write_ac97(dev, EM28XX_R02_MASTER_AC97, s); 440
441 /* LSB: left channel - both channels with the same level */
442 vol = (0x1f - dev->volume) | ((0x1f - dev->volume) << 8);
443
444 /* Mute device, if needed */
445 if (dev->mute)
446 vol |= 0x8000;
447
448 /* Sets volume */
449 for (i = 0; i < ARRAY_SIZE(outputs); i++) {
450 if (dev->ctl_aoutput & outputs[i].mux)
451 ret = em28xx_write_ac97(dev, outputs[i].reg,
452 vol);
453 if (ret < 0)
454 em28xx_warn("couldn't setup AC97 register %d\n",
455 outputs[i].reg);
456 }
457 }
350 458
351 return ret; 459 return ret;
352} 460}
353EXPORT_SYMBOL_GPL(em28xx_audio_analog_set); 461EXPORT_SYMBOL_GPL(em28xx_audio_analog_set);
354 462
355int em28xx_colorlevels_set_default(struct em28xx *dev) 463int em28xx_audio_setup(struct em28xx *dev)
356{ 464{
357 em28xx_write_regs(dev, EM28XX_R20_YGAIN, "\x10", 1); /* contrast */ 465 int vid1, vid2, feat, cfg;
358 em28xx_write_regs(dev, EM28XX_R21_YOFFSET, "\x00", 1); /* brightness */ 466 u32 vid;
359 em28xx_write_regs(dev, EM28XX_R22_UVGAIN, "\x10", 1); /* saturation */ 467
360 em28xx_write_regs(dev, EM28XX_R23_UOFFSET, "\x00", 1); 468 if (dev->chip_id == CHIP_ID_EM2870 || dev->chip_id == CHIP_ID_EM2874) {
361 em28xx_write_regs(dev, EM28XX_R24_VOFFSET, "\x00", 1); 469 /* Digital only device - don't load any alsa module */
362 em28xx_write_regs(dev, EM28XX_R25_SHARPNESS, "\x00", 1); 470 dev->audio_mode.has_audio = 0;
471 dev->has_audio_class = 0;
472 dev->has_alsa_audio = 0;
473 return 0;
474 }
475
476 /* If device doesn't support Usb Audio Class, use vendor class */
477 if (!dev->has_audio_class)
478 dev->has_alsa_audio = 1;
479
480 dev->audio_mode.has_audio = 1;
363 481
364 em28xx_write_regs(dev, EM28XX_R14_GAMMA, "\x20", 1); 482 /* See how this device is configured */
365 em28xx_write_regs(dev, EM28XX_R15_RGAIN, "\x20", 1); 483 cfg = em28xx_read_reg(dev, EM28XX_R00_CHIPCFG);
366 em28xx_write_regs(dev, EM28XX_R16_GGAIN, "\x20", 1); 484 if (cfg < 0)
367 em28xx_write_regs(dev, EM28XX_R17_BGAIN, "\x20", 1); 485 cfg = EM28XX_CHIPCFG_AC97; /* Be conservative */
368 em28xx_write_regs(dev, EM28XX_R18_ROFFSET, "\x00", 1); 486 else
369 em28xx_write_regs(dev, EM28XX_R19_GOFFSET, "\x00", 1); 487 em28xx_info("Config register raw data: 0x%02x\n", cfg);
370 return em28xx_write_regs(dev, EM28XX_R1A_BOFFSET, "\x00", 1); 488
489 if ((cfg & EM28XX_CHIPCFG_AUDIOMASK) ==
490 EM28XX_CHIPCFG_I2S_3_SAMPRATES) {
491 em28xx_info("I2S Audio (3 sample rates)\n");
492 dev->audio_mode.i2s_3rates = 1;
493 }
494 if ((cfg & EM28XX_CHIPCFG_AUDIOMASK) ==
495 EM28XX_CHIPCFG_I2S_5_SAMPRATES) {
496 em28xx_info("I2S Audio (5 sample rates)\n");
497 dev->audio_mode.i2s_5rates = 1;
498 }
499
500 if ((cfg & EM28XX_CHIPCFG_AUDIOMASK) != EM28XX_CHIPCFG_AC97) {
501 /* Skip the code that does AC97 vendor detection */
502 dev->audio_mode.ac97 = EM28XX_NO_AC97;
503 goto init_audio;
504 }
505
506 dev->audio_mode.ac97 = EM28XX_AC97_OTHER;
507
508 vid1 = em28xx_read_ac97(dev, AC97_VENDOR_ID1);
509 if (vid1 < 0) {
510 /* Device likely doesn't support AC97 */
511 em28xx_warn("AC97 chip type couldn't be determined\n");
512 goto init_audio;
513 }
514
515 vid2 = em28xx_read_ac97(dev, AC97_VENDOR_ID2);
516 if (vid2 < 0)
517 goto init_audio;
518
519 vid = vid1 << 16 | vid2;
520
521 dev->audio_mode.ac97_vendor_id = vid;
522 em28xx_warn("AC97 vendor ID = 0x%08x\n", vid);
523
524 feat = em28xx_read_ac97(dev, AC97_RESET);
525 if (feat < 0)
526 goto init_audio;
527
528 dev->audio_mode.ac97_feat = feat;
529 em28xx_warn("AC97 features = 0x%04x\n", feat);
530
531 /* Try to identify what audio processor we have */
532 if ((vid == 0xffffffff) && (feat == 0x6a90))
533 dev->audio_mode.ac97 = EM28XX_AC97_EM202;
534 else if ((vid >> 8) == 0x838476)
535 dev->audio_mode.ac97 = EM28XX_AC97_SIGMATEL;
536
537init_audio:
538 /* Reports detected AC97 processor */
539 switch (dev->audio_mode.ac97) {
540 case EM28XX_NO_AC97:
541 em28xx_info("No AC97 audio processor\n");
542 break;
543 case EM28XX_AC97_EM202:
544 em28xx_info("Empia 202 AC97 audio processor detected\n");
545 break;
546 case EM28XX_AC97_SIGMATEL:
547 em28xx_info("Sigmatel audio processor detected(stac 97%02x)\n",
548 dev->audio_mode.ac97_vendor_id & 0xff);
549 break;
550 case EM28XX_AC97_OTHER:
551 em28xx_warn("Unknown AC97 audio processor detected!\n");
552 break;
553 default:
554 break;
555 }
556
557 return em28xx_audio_analog_set(dev);
558}
559EXPORT_SYMBOL_GPL(em28xx_audio_setup);
560
561int em28xx_colorlevels_set_default(struct em28xx *dev)
562{
563 em28xx_write_reg(dev, EM28XX_R20_YGAIN, 0x10); /* contrast */
564 em28xx_write_reg(dev, EM28XX_R21_YOFFSET, 0x00); /* brightness */
565 em28xx_write_reg(dev, EM28XX_R22_UVGAIN, 0x10); /* saturation */
566 em28xx_write_reg(dev, EM28XX_R23_UOFFSET, 0x00);
567 em28xx_write_reg(dev, EM28XX_R24_VOFFSET, 0x00);
568 em28xx_write_reg(dev, EM28XX_R25_SHARPNESS, 0x00);
569
570 em28xx_write_reg(dev, EM28XX_R14_GAMMA, 0x20);
571 em28xx_write_reg(dev, EM28XX_R15_RGAIN, 0x20);
572 em28xx_write_reg(dev, EM28XX_R16_GGAIN, 0x20);
573 em28xx_write_reg(dev, EM28XX_R17_BGAIN, 0x20);
574 em28xx_write_reg(dev, EM28XX_R18_ROFFSET, 0x00);
575 em28xx_write_reg(dev, EM28XX_R19_GOFFSET, 0x00);
576 return em28xx_write_reg(dev, EM28XX_R1A_BOFFSET, 0x00);
371} 577}
372 578
373int em28xx_capture_start(struct em28xx *dev, int start) 579int em28xx_capture_start(struct em28xx *dev, int start)
374{ 580{
375 int rc; 581 int rc;
582
583 if (dev->chip_id == CHIP_ID_EM2874) {
584 /* The Transport Stream Enable Register moved in em2874 */
585 if (!start) {
586 rc = em28xx_write_reg_bits(dev, EM2874_R5F_TS_ENABLE,
587 0x00,
588 EM2874_TS1_CAPTURE_ENABLE);
589 return rc;
590 }
591
592 /* Enable Transport Stream */
593 rc = em28xx_write_reg_bits(dev, EM2874_R5F_TS_ENABLE,
594 EM2874_TS1_CAPTURE_ENABLE,
595 EM2874_TS1_CAPTURE_ENABLE);
596 return rc;
597 }
598
599
376 /* FIXME: which is the best order? */ 600 /* FIXME: which is the best order? */
377 /* video registers are sampled by VREF */ 601 /* video registers are sampled by VREF */
378 rc = em28xx_write_reg_bits(dev, EM28XX_R0C_USBSUSP, 602 rc = em28xx_write_reg_bits(dev, EM28XX_R0C_USBSUSP,
@@ -382,28 +606,37 @@ int em28xx_capture_start(struct em28xx *dev, int start)
382 606
383 if (!start) { 607 if (!start) {
384 /* disable video capture */ 608 /* disable video capture */
385 rc = em28xx_write_regs(dev, EM28XX_R12_VINENABLE, "\x27", 1); 609 rc = em28xx_write_reg(dev, EM28XX_R12_VINENABLE, 0x27);
386 return rc; 610 return rc;
387 } 611 }
388 612
389 /* enable video capture */ 613 /* enable video capture */
390 rc = em28xx_write_regs_req(dev, 0x00, 0x48, "\x00", 1); 614 rc = em28xx_write_reg(dev, 0x48, 0x00);
391 615
392 if (dev->mode == EM28XX_ANALOG_MODE) 616 if (dev->mode == EM28XX_ANALOG_MODE)
393 rc = em28xx_write_regs(dev, EM28XX_R12_VINENABLE, "\x67", 1); 617 rc = em28xx_write_reg(dev, EM28XX_R12_VINENABLE, 0x67);
394 else 618 else
395 rc = em28xx_write_regs(dev, EM28XX_R12_VINENABLE, "\x37", 1); 619 rc = em28xx_write_reg(dev, EM28XX_R12_VINENABLE, 0x37);
396 620
397 msleep(6); 621 msleep(6);
398 622
399 return rc; 623 return rc;
400} 624}
401 625
402int em28xx_outfmt_set_yuv422(struct em28xx *dev) 626int em28xx_set_outfmt(struct em28xx *dev)
403{ 627{
404 em28xx_write_regs(dev, EM28XX_R27_OUTFMT, "\x34", 1); 628 int ret;
405 em28xx_write_regs(dev, EM28XX_R10_VINMODE, "\x10", 1); 629
406 return em28xx_write_regs(dev, EM28XX_R11_VINCTRL, "\x11", 1); 630 ret = em28xx_write_reg_bits(dev, EM28XX_R27_OUTFMT,
631 dev->format->reg | 0x20, 0x3f);
632 if (ret < 0)
633 return ret;
634
635 ret = em28xx_write_reg(dev, EM28XX_R10_VINMODE, 0x10);
636 if (ret < 0)
637 return ret;
638
639 return em28xx_write_reg(dev, EM28XX_R11_VINCTRL, 0x11);
407} 640}
408 641
409static int em28xx_accumulator_set(struct em28xx *dev, u8 xmin, u8 xmax, 642static int em28xx_accumulator_set(struct em28xx *dev, u8 xmin, u8 xmax,
@@ -440,7 +673,7 @@ static int em28xx_scaler_set(struct em28xx *dev, u16 h, u16 v)
440{ 673{
441 u8 mode; 674 u8 mode;
442 /* the em2800 scaler only supports scaling down to 50% */ 675 /* the em2800 scaler only supports scaling down to 50% */
443 if (dev->is_em2800) 676 if (dev->board.is_em2800)
444 mode = (v ? 0x20 : 0x00) | (h ? 0x10 : 0x00); 677 mode = (v ? 0x20 : 0x00) | (h ? 0x10 : 0x00);
445 else { 678 else {
446 u8 buf[2]; 679 u8 buf[2];
@@ -464,7 +697,7 @@ int em28xx_resolution_set(struct em28xx *dev)
464 width = norm_maxw(dev); 697 width = norm_maxw(dev);
465 height = norm_maxh(dev) >> 1; 698 height = norm_maxh(dev) >> 1;
466 699
467 em28xx_outfmt_set_yuv422(dev); 700 em28xx_set_outfmt(dev);
468 em28xx_accumulator_set(dev, 1, (width - 4) >> 2, 1, (height - 4) >> 2); 701 em28xx_accumulator_set(dev, 1, (width - 4) >> 2, 1, (height - 4) >> 2);
469 em28xx_capture_area_set(dev, 0, 0, width >> 2, height >> 2); 702 em28xx_capture_area_set(dev, 0, 0, width >> 2, height >> 2);
470 return em28xx_scaler_set(dev, dev->hscale, dev->vscale); 703 return em28xx_scaler_set(dev, dev->hscale, dev->vscale);
@@ -519,12 +752,14 @@ int em28xx_gpio_set(struct em28xx *dev, struct em28xx_reg_seq *gpio)
519 if (!gpio) 752 if (!gpio)
520 return rc; 753 return rc;
521 754
522 dev->em28xx_write_regs_req(dev, 0x00, 0x48, "\x00", 1); 755 if (dev->mode != EM28XX_SUSPEND) {
523 if (dev->mode == EM28XX_ANALOG_MODE) 756 em28xx_write_reg(dev, 0x48, 0x00);
524 dev->em28xx_write_regs_req(dev, 0x00, 0x12, "\x67", 1); 757 if (dev->mode == EM28XX_ANALOG_MODE)
525 else 758 em28xx_write_reg(dev, EM28XX_R12_VINENABLE, 0x67);
526 dev->em28xx_write_regs_req(dev, 0x00, 0x12, "\x37", 1); 759 else
527 msleep(6); 760 em28xx_write_reg(dev, EM28XX_R12_VINENABLE, 0x37);
761 msleep(6);
762 }
528 763
529 /* Send GPIO reset sequences specified at board entry */ 764 /* Send GPIO reset sequences specified at board entry */
530 while (gpio->sleep >= 0) { 765 while (gpio->sleep >= 0) {
@@ -549,17 +784,20 @@ int em28xx_set_mode(struct em28xx *dev, enum em28xx_mode set_mode)
549 if (dev->mode == set_mode) 784 if (dev->mode == set_mode)
550 return 0; 785 return 0;
551 786
552 if (set_mode == EM28XX_MODE_UNDEFINED) { 787 if (set_mode == EM28XX_SUSPEND) {
553 dev->mode = set_mode; 788 dev->mode = set_mode;
554 return 0; 789
790 /* FIXME: add suspend support for ac97 */
791
792 return em28xx_gpio_set(dev, dev->board.suspend_gpio);
555 } 793 }
556 794
557 dev->mode = set_mode; 795 dev->mode = set_mode;
558 796
559 if (dev->mode == EM28XX_DIGITAL_MODE) 797 if (dev->mode == EM28XX_DIGITAL_MODE)
560 return em28xx_gpio_set(dev, dev->digital_gpio); 798 return em28xx_gpio_set(dev, dev->board.dvb_gpio);
561 else 799 else
562 return em28xx_gpio_set(dev, dev->analog_gpio); 800 return em28xx_gpio_set(dev, INPUT(dev->ctl_input)->gpio);
563} 801}
564EXPORT_SYMBOL_GPL(em28xx_set_mode); 802EXPORT_SYMBOL_GPL(em28xx_set_mode);
565 803
@@ -738,3 +976,145 @@ int em28xx_init_isoc(struct em28xx *dev, int max_packets,
738 return 0; 976 return 0;
739} 977}
740EXPORT_SYMBOL_GPL(em28xx_init_isoc); 978EXPORT_SYMBOL_GPL(em28xx_init_isoc);
979
980/*
981 * em28xx_wake_i2c()
982 * configure i2c attached devices
983 */
984void em28xx_wake_i2c(struct em28xx *dev)
985{
986 struct v4l2_routing route;
987 int zero = 0;
988
989 route.input = INPUT(dev->ctl_input)->vmux;
990 route.output = 0;
991 em28xx_i2c_call_clients(dev, VIDIOC_INT_RESET, &zero);
992 em28xx_i2c_call_clients(dev, VIDIOC_INT_S_VIDEO_ROUTING, &route);
993 em28xx_i2c_call_clients(dev, VIDIOC_STREAMON, NULL);
994}
995
996/*
997 * Device control list
998 */
999
1000static LIST_HEAD(em28xx_devlist);
1001static DEFINE_MUTEX(em28xx_devlist_mutex);
1002
1003struct em28xx *em28xx_get_device(struct inode *inode,
1004 enum v4l2_buf_type *fh_type,
1005 int *has_radio)
1006{
1007 struct em28xx *h, *dev = NULL;
1008 int minor = iminor(inode);
1009
1010 *fh_type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1011 *has_radio = 0;
1012
1013 mutex_lock(&em28xx_devlist_mutex);
1014 list_for_each_entry(h, &em28xx_devlist, devlist) {
1015 if (h->vdev->minor == minor)
1016 dev = h;
1017 if (h->vbi_dev->minor == minor) {
1018 dev = h;
1019 *fh_type = V4L2_BUF_TYPE_VBI_CAPTURE;
1020 }
1021 if (h->radio_dev &&
1022 h->radio_dev->minor == minor) {
1023 dev = h;
1024 *has_radio = 1;
1025 }
1026 }
1027 mutex_unlock(&em28xx_devlist_mutex);
1028
1029 return dev;
1030}
1031
1032/*
1033 * em28xx_realease_resources()
1034 * unregisters the v4l2,i2c and usb devices
1035 * called when the device gets disconected or at module unload
1036*/
1037void em28xx_remove_from_devlist(struct em28xx *dev)
1038{
1039 mutex_lock(&em28xx_devlist_mutex);
1040 list_del(&dev->devlist);
1041 mutex_unlock(&em28xx_devlist_mutex);
1042};
1043
1044void em28xx_add_into_devlist(struct em28xx *dev)
1045{
1046 mutex_lock(&em28xx_devlist_mutex);
1047 list_add_tail(&dev->devlist, &em28xx_devlist);
1048 mutex_unlock(&em28xx_devlist_mutex);
1049};
1050
1051/*
1052 * Extension interface
1053 */
1054
1055static LIST_HEAD(em28xx_extension_devlist);
1056static DEFINE_MUTEX(em28xx_extension_devlist_lock);
1057
1058int em28xx_register_extension(struct em28xx_ops *ops)
1059{
1060 struct em28xx *dev = NULL;
1061
1062 mutex_lock(&em28xx_devlist_mutex);
1063 mutex_lock(&em28xx_extension_devlist_lock);
1064 list_add_tail(&ops->next, &em28xx_extension_devlist);
1065 list_for_each_entry(dev, &em28xx_devlist, devlist) {
1066 if (dev)
1067 ops->init(dev);
1068 }
1069 printk(KERN_INFO "Em28xx: Initialized (%s) extension\n", ops->name);
1070 mutex_unlock(&em28xx_extension_devlist_lock);
1071 mutex_unlock(&em28xx_devlist_mutex);
1072 return 0;
1073}
1074EXPORT_SYMBOL(em28xx_register_extension);
1075
1076void em28xx_unregister_extension(struct em28xx_ops *ops)
1077{
1078 struct em28xx *dev = NULL;
1079
1080 mutex_lock(&em28xx_devlist_mutex);
1081 list_for_each_entry(dev, &em28xx_devlist, devlist) {
1082 if (dev)
1083 ops->fini(dev);
1084 }
1085
1086 mutex_lock(&em28xx_extension_devlist_lock);
1087 printk(KERN_INFO "Em28xx: Removed (%s) extension\n", ops->name);
1088 list_del(&ops->next);
1089 mutex_unlock(&em28xx_extension_devlist_lock);
1090 mutex_unlock(&em28xx_devlist_mutex);
1091}
1092EXPORT_SYMBOL(em28xx_unregister_extension);
1093
1094void em28xx_init_extension(struct em28xx *dev)
1095{
1096 struct em28xx_ops *ops = NULL;
1097
1098 mutex_lock(&em28xx_extension_devlist_lock);
1099 if (!list_empty(&em28xx_extension_devlist)) {
1100 list_for_each_entry(ops, &em28xx_extension_devlist, next) {
1101 if (ops->init)
1102 ops->init(dev);
1103 }
1104 }
1105 mutex_unlock(&em28xx_extension_devlist_lock);
1106}
1107
1108void em28xx_close_extension(struct em28xx *dev)
1109{
1110 struct em28xx_ops *ops = NULL;
1111
1112 mutex_lock(&em28xx_extension_devlist_lock);
1113 if (!list_empty(&em28xx_extension_devlist)) {
1114 list_for_each_entry(ops, &em28xx_extension_devlist, next) {
1115 if (ops->fini)
1116 ops->fini(dev);
1117 }
1118 }
1119 mutex_unlock(&em28xx_extension_devlist_lock);
1120}
diff --git a/drivers/media/video/em28xx/em28xx-dvb.c b/drivers/media/video/em28xx/em28xx-dvb.c
index c99e2383b7ec..d38cb21834d9 100644
--- a/drivers/media/video/em28xx/em28xx-dvb.c
+++ b/drivers/media/video/em28xx/em28xx-dvb.c
@@ -161,7 +161,7 @@ static int stop_streaming(struct em28xx_dvb *dvb)
161 161
162 em28xx_uninit_isoc(dev); 162 em28xx_uninit_isoc(dev);
163 163
164 em28xx_set_mode(dev, EM28XX_MODE_UNDEFINED); 164 em28xx_set_mode(dev, EM28XX_SUSPEND);
165 165
166 return 0; 166 return 0;
167} 167}
@@ -215,7 +215,7 @@ static int em28xx_dvb_bus_ctrl(struct dvb_frontend *fe, int acquire)
215 if (acquire) 215 if (acquire)
216 return em28xx_set_mode(dev, EM28XX_DIGITAL_MODE); 216 return em28xx_set_mode(dev, EM28XX_DIGITAL_MODE);
217 else 217 else
218 return em28xx_set_mode(dev, EM28XX_MODE_UNDEFINED); 218 return em28xx_set_mode(dev, EM28XX_SUSPEND);
219} 219}
220 220
221/* ------------------------------------------------------------------ */ 221/* ------------------------------------------------------------------ */
@@ -393,7 +393,7 @@ static int dvb_init(struct em28xx *dev)
393 int result = 0; 393 int result = 0;
394 struct em28xx_dvb *dvb; 394 struct em28xx_dvb *dvb;
395 395
396 if (!dev->has_dvb) { 396 if (!dev->board.has_dvb) {
397 /* This device does not support the extension */ 397 /* This device does not support the extension */
398 return 0; 398 return 0;
399 } 399 }
@@ -409,8 +409,10 @@ static int dvb_init(struct em28xx *dev)
409 em28xx_set_mode(dev, EM28XX_DIGITAL_MODE); 409 em28xx_set_mode(dev, EM28XX_DIGITAL_MODE);
410 /* init frontend */ 410 /* init frontend */
411 switch (dev->model) { 411 switch (dev->model) {
412 case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_850:
412 case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950: 413 case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950:
413 case EM2880_BOARD_PINNACLE_PCTV_HD_PRO: 414 case EM2880_BOARD_PINNACLE_PCTV_HD_PRO:
415 case EM2883_BOARD_KWORLD_HYBRID_A316:
414 case EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600: 416 case EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600:
415 dvb->frontend = dvb_attach(lgdt330x_attach, 417 dvb->frontend = dvb_attach(lgdt330x_attach,
416 &em2880_lgdt3303_dev, 418 &em2880_lgdt3303_dev,
@@ -466,12 +468,12 @@ static int dvb_init(struct em28xx *dev)
466 if (result < 0) 468 if (result < 0)
467 goto out_free; 469 goto out_free;
468 470
469 em28xx_set_mode(dev, EM28XX_MODE_UNDEFINED); 471 em28xx_set_mode(dev, EM28XX_SUSPEND);
470 printk(KERN_INFO "Successfully loaded em28xx-dvb\n"); 472 printk(KERN_INFO "Successfully loaded em28xx-dvb\n");
471 return 0; 473 return 0;
472 474
473out_free: 475out_free:
474 em28xx_set_mode(dev, EM28XX_MODE_UNDEFINED); 476 em28xx_set_mode(dev, EM28XX_SUSPEND);
475 kfree(dvb); 477 kfree(dvb);
476 dev->dvb = NULL; 478 dev->dvb = NULL;
477 return result; 479 return result;
@@ -479,7 +481,7 @@ out_free:
479 481
480static int dvb_fini(struct em28xx *dev) 482static int dvb_fini(struct em28xx *dev)
481{ 483{
482 if (!dev->has_dvb) { 484 if (!dev->board.has_dvb) {
483 /* This device does not support the extension */ 485 /* This device does not support the extension */
484 return 0; 486 return 0;
485 } 487 }
diff --git a/drivers/media/video/em28xx/em28xx-i2c.c b/drivers/media/video/em28xx/em28xx-i2c.c
index 2360c61ddca9..d69f0efcc9aa 100644
--- a/drivers/media/video/em28xx/em28xx-i2c.c
+++ b/drivers/media/video/em28xx/em28xx-i2c.c
@@ -250,7 +250,7 @@ static int em28xx_i2c_xfer(struct i2c_adapter *i2c_adap,
250 (msgs[i].flags & I2C_M_RD) ? "read" : "write", 250 (msgs[i].flags & I2C_M_RD) ? "read" : "write",
251 i == num - 1 ? "stop" : "nonstop", addr, msgs[i].len); 251 i == num - 1 ? "stop" : "nonstop", addr, msgs[i].len);
252 if (!msgs[i].len) { /* no len: check only for device presence */ 252 if (!msgs[i].len) { /* no len: check only for device presence */
253 if (dev->is_em2800) 253 if (dev->board.is_em2800)
254 rc = em2800_i2c_check_for_device(dev, addr); 254 rc = em2800_i2c_check_for_device(dev, addr);
255 else 255 else
256 rc = em28xx_i2c_check_for_device(dev, addr); 256 rc = em28xx_i2c_check_for_device(dev, addr);
@@ -261,7 +261,7 @@ static int em28xx_i2c_xfer(struct i2c_adapter *i2c_adap,
261 261
262 } else if (msgs[i].flags & I2C_M_RD) { 262 } else if (msgs[i].flags & I2C_M_RD) {
263 /* read bytes */ 263 /* read bytes */
264 if (dev->is_em2800) 264 if (dev->board.is_em2800)
265 rc = em2800_i2c_recv_bytes(dev, addr, 265 rc = em2800_i2c_recv_bytes(dev, addr,
266 msgs[i].buf, 266 msgs[i].buf,
267 msgs[i].len); 267 msgs[i].len);
@@ -279,7 +279,7 @@ static int em28xx_i2c_xfer(struct i2c_adapter *i2c_adap,
279 for (byte = 0; byte < msgs[i].len; byte++) 279 for (byte = 0; byte < msgs[i].len; byte++)
280 printk(" %02x", msgs[i].buf[byte]); 280 printk(" %02x", msgs[i].buf[byte]);
281 } 281 }
282 if (dev->is_em2800) 282 if (dev->board.is_em2800)
283 rc = em2800_i2c_send_bytes(dev, addr, 283 rc = em2800_i2c_send_bytes(dev, addr,
284 msgs[i].buf, 284 msgs[i].buf,
285 msgs[i].len); 285 msgs[i].len);
@@ -332,6 +332,17 @@ static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned char *eedata, int len)
332 struct em28xx_eeprom *em_eeprom = (void *)eedata; 332 struct em28xx_eeprom *em_eeprom = (void *)eedata;
333 int i, err, size = len, block; 333 int i, err, size = len, block;
334 334
335 if (dev->chip_id == CHIP_ID_EM2874) {
336 /* Empia switched to a 16-bit addressable eeprom in newer
337 devices. While we could certainly write a routine to read
338 the eeprom, there is nothing of use in there that cannot be
339 accessed through registers, and there is the risk that we
340 could corrupt the eeprom (since a 16-bit read call is
341 interpreted as a write call by 8-bit eeproms).
342 */
343 return 0;
344 }
345
335 dev->i2c_client.addr = 0xa0 >> 1; 346 dev->i2c_client.addr = 0xa0 >> 1;
336 347
337 /* Check if board has eeprom */ 348 /* Check if board has eeprom */
@@ -377,47 +388,49 @@ static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned char *eedata, int len)
377 if (em_eeprom->id == 0x9567eb1a) 388 if (em_eeprom->id == 0x9567eb1a)
378 dev->hash = em28xx_hash_mem(eedata, len, 32); 389 dev->hash = em28xx_hash_mem(eedata, len, 32);
379 390
380 printk(KERN_INFO "EEPROM ID= 0x%08x, hash = 0x%08lx\n", 391 printk(KERN_INFO "%s: EEPROM ID= 0x%08x, EEPROM hash = 0x%08lx\n",
381 em_eeprom->id, dev->hash); 392 dev->name, em_eeprom->id, dev->hash);
382 printk(KERN_INFO "Vendor/Product ID= %04x:%04x\n", em_eeprom->vendor_ID, 393
383 em_eeprom->product_ID); 394 printk(KERN_INFO "%s: EEPROM info:\n", dev->name);
384 395
385 switch (em_eeprom->chip_conf >> 4 & 0x3) { 396 switch (em_eeprom->chip_conf >> 4 & 0x3) {
386 case 0: 397 case 0:
387 printk(KERN_INFO "No audio on board.\n"); 398 printk(KERN_INFO "%s:\tNo audio on board.\n", dev->name);
388 break; 399 break;
389 case 1: 400 case 1:
390 printk(KERN_INFO "AC97 audio (5 sample rates)\n"); 401 printk(KERN_INFO "%s:\tAC97 audio (5 sample rates)\n",
402 dev->name);
391 break; 403 break;
392 case 2: 404 case 2:
393 printk(KERN_INFO "I2S audio, sample rate=32k\n"); 405 printk(KERN_INFO "%s:\tI2S audio, sample rate=32k\n", dev->name);
394 break; 406 break;
395 case 3: 407 case 3:
396 printk(KERN_INFO "I2S audio, 3 sample rates\n"); 408 printk(KERN_INFO "%s:\tI2S audio, 3 sample rates\n", dev->name);
397 break; 409 break;
398 } 410 }
399 411
400 if (em_eeprom->chip_conf & 1 << 3) 412 if (em_eeprom->chip_conf & 1 << 3)
401 printk(KERN_INFO "USB Remote wakeup capable\n"); 413 printk(KERN_INFO "%s:\tUSB Remote wakeup capable\n", dev->name);
402 414
403 if (em_eeprom->chip_conf & 1 << 2) 415 if (em_eeprom->chip_conf & 1 << 2)
404 printk(KERN_INFO "USB Self power capable\n"); 416 printk(KERN_INFO "%s:\tUSB Self power capable\n", dev->name);
405 417
406 switch (em_eeprom->chip_conf & 0x3) { 418 switch (em_eeprom->chip_conf & 0x3) {
407 case 0: 419 case 0:
408 printk(KERN_INFO "500mA max power\n"); 420 printk(KERN_INFO "%s:\t500mA max power\n", dev->name);
409 break; 421 break;
410 case 1: 422 case 1:
411 printk(KERN_INFO "400mA max power\n"); 423 printk(KERN_INFO "%s:\t400mA max power\n", dev->name);
412 break; 424 break;
413 case 2: 425 case 2:
414 printk(KERN_INFO "300mA max power\n"); 426 printk(KERN_INFO "%s:\t300mA max power\n", dev->name);
415 break; 427 break;
416 case 3: 428 case 3:
417 printk(KERN_INFO "200mA max power\n"); 429 printk(KERN_INFO "%s:\t200mA max power\n", dev->name);
418 break; 430 break;
419 } 431 }
420 printk(KERN_INFO "Table at 0x%02x, strings=0x%04x, 0x%04x, 0x%04x\n", 432 printk(KERN_INFO "%s:\tTable at 0x%02x, strings=0x%04x, 0x%04x, 0x%04x\n",
433 dev->name,
421 em_eeprom->string_idx_table, 434 em_eeprom->string_idx_table,
422 em_eeprom->string1, 435 em_eeprom->string1,
423 em_eeprom->string2, 436 em_eeprom->string2,
diff --git a/drivers/media/video/em28xx/em28xx-input.c b/drivers/media/video/em28xx/em28xx-input.c
index eab3d9511af3..42bbaf64aceb 100644
--- a/drivers/media/video/em28xx/em28xx-input.c
+++ b/drivers/media/video/em28xx/em28xx-input.c
@@ -38,12 +38,48 @@ static unsigned int ir_debug;
38module_param(ir_debug, int, 0644); 38module_param(ir_debug, int, 0644);
39MODULE_PARM_DESC(ir_debug, "enable debug messages [IR]"); 39MODULE_PARM_DESC(ir_debug, "enable debug messages [IR]");
40 40
41#define dprintk(fmt, arg...) \ 41#define i2cdprintk(fmt, arg...) \
42 if (ir_debug) { \ 42 if (ir_debug) { \
43 printk(KERN_DEBUG "%s/ir: " fmt, ir->c.name , ## arg); \ 43 printk(KERN_DEBUG "%s/ir: " fmt, ir->c.name , ## arg); \
44 } 44 }
45 45
46/* ----------------------------------------------------------------------- */ 46#define dprintk(fmt, arg...) \
47 if (ir_debug) { \
48 printk(KERN_DEBUG "%s/ir: " fmt, ir->name , ## arg); \
49 }
50
51/**********************************************************
52 Polling structure used by em28xx IR's
53 **********************************************************/
54
55struct em28xx_ir_poll_result {
56 unsigned int toggle_bit:1;
57 unsigned int read_count:7;
58 u8 rc_address;
59 u8 rc_data[4]; /* 1 byte on em2860/2880, 4 on em2874 */
60};
61
62struct em28xx_IR {
63 struct em28xx *dev;
64 struct input_dev *input;
65 struct ir_input_state ir;
66 char name[32];
67 char phys[32];
68
69 /* poll external decoder */
70 int polling;
71 struct work_struct work;
72 struct timer_list timer;
73 unsigned int last_toggle:1;
74 unsigned int last_readcount;
75 unsigned int repeat_interval;
76
77 int (*get_key)(struct em28xx_IR *, struct em28xx_ir_poll_result *);
78};
79
80/**********************************************************
81 I2C IR based get keycodes - should be used with ir-kbd-i2c
82 **********************************************************/
47 83
48int em28xx_get_key_terratec(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) 84int em28xx_get_key_terratec(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
49{ 85{
@@ -51,7 +87,7 @@ int em28xx_get_key_terratec(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
51 87
52 /* poll IR chip */ 88 /* poll IR chip */
53 if (1 != i2c_master_recv(&ir->c, &b, 1)) { 89 if (1 != i2c_master_recv(&ir->c, &b, 1)) {
54 dprintk("read error\n"); 90 i2cdprintk("read error\n");
55 return -EIO; 91 return -EIO;
56 } 92 }
57 93
@@ -59,7 +95,7 @@ int em28xx_get_key_terratec(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
59 down, while 0xff indicates that no button is hold 95 down, while 0xff indicates that no button is hold
60 down. 0xfe sequences are sometimes interrupted by 0xFF */ 96 down. 0xfe sequences are sometimes interrupted by 0xFF */
61 97
62 dprintk("key %02x\n", b); 98 i2cdprintk("key %02x\n", b);
63 99
64 if (b == 0xff) 100 if (b == 0xff)
65 return 0; 101 return 0;
@@ -73,7 +109,6 @@ int em28xx_get_key_terratec(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
73 return 1; 109 return 1;
74} 110}
75 111
76
77int em28xx_get_key_em_haup(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) 112int em28xx_get_key_em_haup(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
78{ 113{
79 unsigned char buf[2]; 114 unsigned char buf[2];
@@ -97,7 +132,7 @@ int em28xx_get_key_em_haup(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
97 ((buf[0]&0x10)>>3) | /* 0000 0010 */ 132 ((buf[0]&0x10)>>3) | /* 0000 0010 */
98 ((buf[0]&0x20)>>5); /* 0000 0001 */ 133 ((buf[0]&0x20)>>5); /* 0000 0001 */
99 134
100 dprintk("ir hauppauge (em2840): code=0x%02x (rcv=0x%02x)\n", 135 i2cdprintk("ir hauppauge (em2840): code=0x%02x (rcv=0x%02x)\n",
101 code, buf[0]); 136 code, buf[0]);
102 137
103 /* return key */ 138 /* return key */
@@ -114,11 +149,11 @@ int em28xx_get_key_pinnacle_usb_grey(struct IR_i2c *ir, u32 *ir_key,
114 /* poll IR chip */ 149 /* poll IR chip */
115 150
116 if (3 != i2c_master_recv(&ir->c, buf, 3)) { 151 if (3 != i2c_master_recv(&ir->c, buf, 3)) {
117 dprintk("read error\n"); 152 i2cdprintk("read error\n");
118 return -EIO; 153 return -EIO;
119 } 154 }
120 155
121 dprintk("key %02x\n", buf[2]&0x3f); 156 i2cdprintk("key %02x\n", buf[2]&0x3f);
122 if (buf[0] != 0x00) 157 if (buf[0] != 0x00)
123 return 0; 158 return 0;
124 159
@@ -128,6 +163,260 @@ int em28xx_get_key_pinnacle_usb_grey(struct IR_i2c *ir, u32 *ir_key,
128 return 1; 163 return 1;
129} 164}
130 165
166/**********************************************************
167 Poll based get keycode functions
168 **********************************************************/
169
170/* This is for the em2860/em2880 */
171static int default_polling_getkey(struct em28xx_IR *ir,
172 struct em28xx_ir_poll_result *poll_result)
173{
174 struct em28xx *dev = ir->dev;
175 int rc;
176 u8 msg[3] = { 0, 0, 0 };
177
178 /* Read key toggle, brand, and key code
179 on registers 0x45, 0x46 and 0x47
180 */
181 rc = dev->em28xx_read_reg_req_len(dev, 0, EM28XX_R45_IR,
182 msg, sizeof(msg));
183 if (rc < 0)
184 return rc;
185
186 /* Infrared toggle (Reg 0x45[7]) */
187 poll_result->toggle_bit = (msg[0] >> 7);
188
189 /* Infrared read count (Reg 0x45[6:0] */
190 poll_result->read_count = (msg[0] & 0x7f);
191
192 /* Remote Control Address (Reg 0x46) */
193 poll_result->rc_address = msg[1];
194
195 /* Remote Control Data (Reg 0x47) */
196 poll_result->rc_data[0] = msg[2];
197
198 return 0;
199}
200
201static int em2874_polling_getkey(struct em28xx_IR *ir,
202 struct em28xx_ir_poll_result *poll_result)
203{
204 struct em28xx *dev = ir->dev;
205 int rc;
206 u8 msg[5] = { 0, 0, 0, 0, 0 };
207
208 /* Read key toggle, brand, and key code
209 on registers 0x51-55
210 */
211 rc = dev->em28xx_read_reg_req_len(dev, 0, EM2874_R51_IR,
212 msg, sizeof(msg));
213 if (rc < 0)
214 return rc;
215
216 /* Infrared toggle (Reg 0x51[7]) */
217 poll_result->toggle_bit = (msg[0] >> 7);
218
219 /* Infrared read count (Reg 0x51[6:0] */
220 poll_result->read_count = (msg[0] & 0x7f);
221
222 /* Remote Control Address (Reg 0x52) */
223 poll_result->rc_address = msg[1];
224
225 /* Remote Control Data (Reg 0x53-55) */
226 poll_result->rc_data[0] = msg[2];
227 poll_result->rc_data[1] = msg[3];
228 poll_result->rc_data[2] = msg[4];
229
230 return 0;
231}
232
233/**********************************************************
234 Polling code for em28xx
235 **********************************************************/
236
237static void em28xx_ir_handle_key(struct em28xx_IR *ir)
238{
239 int result;
240 int do_sendkey = 0;
241 struct em28xx_ir_poll_result poll_result;
242
243 /* read the registers containing the IR status */
244 result = ir->get_key(ir, &poll_result);
245 if (result < 0) {
246 dprintk("ir->get_key() failed %d\n", result);
247 return;
248 }
249
250 dprintk("ir->get_key result tb=%02x rc=%02x lr=%02x data=%02x\n",
251 poll_result.toggle_bit, poll_result.read_count,
252 ir->last_readcount, poll_result.rc_data[0]);
253
254 if (ir->dev->chip_id == CHIP_ID_EM2874) {
255 /* The em2874 clears the readcount field every time the
256 register is read. The em2860/2880 datasheet says that it
257 is supposed to clear the readcount, but it doesn't. So with
258 the em2874, we are looking for a non-zero read count as
259 opposed to a readcount that is incrementing */
260 ir->last_readcount = 0;
261 }
262
263 if (poll_result.read_count == 0) {
264 /* The button has not been pressed since the last read */
265 } else if (ir->last_toggle != poll_result.toggle_bit) {
266 /* A button has been pressed */
267 dprintk("button has been pressed\n");
268 ir->last_toggle = poll_result.toggle_bit;
269 ir->repeat_interval = 0;
270 do_sendkey = 1;
271 } else if (poll_result.toggle_bit == ir->last_toggle &&
272 poll_result.read_count > 0 &&
273 poll_result.read_count != ir->last_readcount) {
274 /* The button is still being held down */
275 dprintk("button being held down\n");
276
277 /* Debouncer for first keypress */
278 if (ir->repeat_interval++ > 9) {
279 /* Start repeating after 1 second */
280 do_sendkey = 1;
281 }
282 }
283
284 if (do_sendkey) {
285 dprintk("sending keypress\n");
286 ir_input_keydown(ir->input, &ir->ir, poll_result.rc_data[0],
287 poll_result.rc_data[0]);
288 ir_input_nokey(ir->input, &ir->ir);
289 }
290
291 ir->last_readcount = poll_result.read_count;
292 return;
293}
294
295static void ir_timer(unsigned long data)
296{
297 struct em28xx_IR *ir = (struct em28xx_IR *)data;
298
299 schedule_work(&ir->work);
300}
301
302static void em28xx_ir_work(struct work_struct *work)
303{
304 struct em28xx_IR *ir = container_of(work, struct em28xx_IR, work);
305
306 em28xx_ir_handle_key(ir);
307 mod_timer(&ir->timer, jiffies + msecs_to_jiffies(ir->polling));
308}
309
310void em28xx_ir_start(struct em28xx_IR *ir)
311{
312 setup_timer(&ir->timer, ir_timer, (unsigned long)ir);
313 INIT_WORK(&ir->work, em28xx_ir_work);
314 schedule_work(&ir->work);
315}
316
317static void em28xx_ir_stop(struct em28xx_IR *ir)
318{
319 del_timer_sync(&ir->timer);
320 flush_scheduled_work();
321}
322
323int em28xx_ir_init(struct em28xx *dev)
324{
325 struct em28xx_IR *ir;
326 struct input_dev *input_dev;
327 u8 ir_config;
328 int err = -ENOMEM;
329
330 if (dev->board.ir_codes == NULL) {
331 /* No remote control support */
332 return 0;
333 }
334
335 ir = kzalloc(sizeof(*ir), GFP_KERNEL);
336 input_dev = input_allocate_device();
337 if (!ir || !input_dev)
338 goto err_out_free;
339
340 ir->input = input_dev;
341
342 /* Setup the proper handler based on the chip */
343 switch (dev->chip_id) {
344 case CHIP_ID_EM2860:
345 case CHIP_ID_EM2883:
346 ir->get_key = default_polling_getkey;
347 break;
348 case CHIP_ID_EM2874:
349 ir->get_key = em2874_polling_getkey;
350 /* For now we only support RC5, so enable it */
351 ir_config = EM2874_IR_RC5;
352 em28xx_write_regs(dev, EM2874_R50_IR_CONFIG, &ir_config, 1);
353 break;
354 default:
355 printk("Unrecognized em28xx chip id: IR not supported\n");
356 goto err_out_free;
357 }
358
359 /* This is how often we ask the chip for IR information */
360 ir->polling = 100; /* ms */
361
362 /* init input device */
363 snprintf(ir->name, sizeof(ir->name), "em28xx IR (%s)",
364 dev->name);
365
366 usb_make_path(dev->udev, ir->phys, sizeof(ir->phys));
367 strlcat(ir->phys, "/input0", sizeof(ir->phys));
368
369 ir_input_init(input_dev, &ir->ir, IR_TYPE_OTHER, dev->board.ir_codes);
370 input_dev->name = ir->name;
371 input_dev->phys = ir->phys;
372 input_dev->id.bustype = BUS_USB;
373 input_dev->id.version = 1;
374 input_dev->id.vendor = le16_to_cpu(dev->udev->descriptor.idVendor);
375 input_dev->id.product = le16_to_cpu(dev->udev->descriptor.idProduct);
376
377 input_dev->dev.parent = &dev->udev->dev;
378 /* record handles to ourself */
379 ir->dev = dev;
380 dev->ir = ir;
381
382 em28xx_ir_start(ir);
383
384 /* all done */
385 err = input_register_device(ir->input);
386 if (err)
387 goto err_out_stop;
388
389 return 0;
390 err_out_stop:
391 em28xx_ir_stop(ir);
392 dev->ir = NULL;
393 err_out_free:
394 input_free_device(input_dev);
395 kfree(ir);
396 return err;
397}
398
399int em28xx_ir_fini(struct em28xx *dev)
400{
401 struct em28xx_IR *ir = dev->ir;
402
403 /* skip detach on non attached boards */
404 if (!ir)
405 return 0;
406
407 em28xx_ir_stop(ir);
408 input_unregister_device(ir->input);
409 kfree(ir);
410
411 /* done */
412 dev->ir = NULL;
413 return 0;
414}
415
416/**********************************************************
417 Handle Webcam snapshot button
418 **********************************************************/
419
131static void em28xx_query_sbutton(struct work_struct *work) 420static void em28xx_query_sbutton(struct work_struct *work)
132{ 421{
133 /* Poll the register and see if the button is depressed */ 422 /* Poll the register and see if the button is depressed */
@@ -210,9 +499,3 @@ void em28xx_deregister_snapshot_button(struct em28xx *dev)
210 } 499 }
211 return; 500 return;
212} 501}
213
214/* ----------------------------------------------------------------------
215 * Local variables:
216 * c-basic-offset: 8
217 * End:
218 */
diff --git a/drivers/media/video/em28xx/em28xx-reg.h b/drivers/media/video/em28xx/em28xx-reg.h
index fac1ab23f621..65dcb91bdcc2 100644
--- a/drivers/media/video/em28xx/em28xx-reg.h
+++ b/drivers/media/video/em28xx/em28xx-reg.h
@@ -17,17 +17,58 @@
17 17
18/* em28xx registers */ 18/* em28xx registers */
19 19
20#define EM28XX_R00_CHIPCFG 0x00
21
22/* em28xx Chip Configuration 0x00 */
23#define EM28XX_CHIPCFG_VENDOR_AUDIO 0x80
24#define EM28XX_CHIPCFG_I2S_VOLUME_CAPABLE 0x40
25#define EM28XX_CHIPCFG_I2S_5_SAMPRATES 0x30
26#define EM28XX_CHIPCFG_I2S_3_SAMPRATES 0x20
27#define EM28XX_CHIPCFG_AC97 0x10
28#define EM28XX_CHIPCFG_AUDIOMASK 0x30
29
20 /* GPIO/GPO registers */ 30 /* GPIO/GPO registers */
21#define EM2880_R04_GPO 0x04 /* em2880-em2883 only */ 31#define EM2880_R04_GPO 0x04 /* em2880-em2883 only */
22#define EM28XX_R08_GPIO 0x08 /* em2820 or upper */ 32#define EM28XX_R08_GPIO 0x08 /* em2820 or upper */
23 33
24#define EM28XX_R06_I2C_CLK 0x06 34#define EM28XX_R06_I2C_CLK 0x06
35
36/* em28xx I2C Clock Register (0x06) */
37#define EM28XX_I2C_CLK_ACK_LAST_READ 0x80
38#define EM28XX_I2C_CLK_WAIT_ENABLE 0x40
39#define EM28XX_I2C_EEPROM_ON_BOARD 0x08
40#define EM28XX_I2C_EEPROM_KEY_VALID 0x04
41#define EM2874_I2C_SECONDARY_BUS_SELECT 0x04 /* em2874 has two i2c busses */
42#define EM28XX_I2C_FREQ_1_5_MHZ 0x03 /* bus frequency (bits [1-0]) */
43#define EM28XX_I2C_FREQ_25_KHZ 0x02
44#define EM28XX_I2C_FREQ_400_KHZ 0x01
45#define EM28XX_I2C_FREQ_100_KHZ 0x00
46
47
25#define EM28XX_R0A_CHIPID 0x0a 48#define EM28XX_R0A_CHIPID 0x0a
26#define EM28XX_R0C_USBSUSP 0x0c /* */ 49#define EM28XX_R0C_USBSUSP 0x0c /* */
27 50
28#define EM28XX_R0E_AUDIOSRC 0x0e 51#define EM28XX_R0E_AUDIOSRC 0x0e
29#define EM28XX_R0F_XCLK 0x0f 52#define EM28XX_R0F_XCLK 0x0f
30 53
54/* em28xx XCLK Register (0x0f) */
55#define EM28XX_XCLK_AUDIO_UNMUTE 0x80 /* otherwise audio muted */
56#define EM28XX_XCLK_I2S_MSB_TIMING 0x40 /* otherwise standard timing */
57#define EM28XX_XCLK_IR_RC5_MODE 0x20 /* otherwise NEC mode */
58#define EM28XX_XCLK_IR_NEC_CHK_PARITY 0x10
59#define EM28XX_XCLK_FREQUENCY_30MHZ 0x00 /* Freq. select (bits [3-0]) */
60#define EM28XX_XCLK_FREQUENCY_15MHZ 0x01
61#define EM28XX_XCLK_FREQUENCY_10MHZ 0x02
62#define EM28XX_XCLK_FREQUENCY_7_5MHZ 0x03
63#define EM28XX_XCLK_FREQUENCY_6MHZ 0x04
64#define EM28XX_XCLK_FREQUENCY_5MHZ 0x05
65#define EM28XX_XCLK_FREQUENCY_4_3MHZ 0x06
66#define EM28XX_XCLK_FREQUENCY_12MHZ 0x07
67#define EM28XX_XCLK_FREQUENCY_20MHZ 0x08
68#define EM28XX_XCLK_FREQUENCY_20MHZ_2 0x09
69#define EM28XX_XCLK_FREQUENCY_48MHZ 0x0a
70#define EM28XX_XCLK_FREQUENCY_24MHZ 0x0b
71
31#define EM28XX_R10_VINMODE 0x10 72#define EM28XX_R10_VINMODE 0x10
32#define EM28XX_R11_VINCTRL 0x11 73#define EM28XX_R11_VINCTRL 0x11
33#define EM28XX_R12_VINENABLE 0x12 /* */ 74#define EM28XX_R12_VINENABLE 0x12 /* */
@@ -56,6 +97,19 @@
56#define EM28XX_R26_COMPR 0x26 97#define EM28XX_R26_COMPR 0x26
57#define EM28XX_R27_OUTFMT 0x27 98#define EM28XX_R27_OUTFMT 0x27
58 99
100/* em28xx Output Format Register (0x27) */
101#define EM28XX_OUTFMT_RGB_8_RGRG 0x00
102#define EM28XX_OUTFMT_RGB_8_GRGR 0x01
103#define EM28XX_OUTFMT_RGB_8_GBGB 0x02
104#define EM28XX_OUTFMT_RGB_8_BGBG 0x03
105#define EM28XX_OUTFMT_RGB_16_656 0x04
106#define EM28XX_OUTFMT_RGB_8_BAYER 0x08 /* Pattern in Reg 0x10[1-0] */
107#define EM28XX_OUTFMT_YUV211 0x10
108#define EM28XX_OUTFMT_YUV422_Y0UY1V 0x14
109#define EM28XX_OUTFMT_YUV422_Y1UY0V 0x15
110#define EM28XX_OUTFMT_YUV411 0x18
111
112
59#define EM28XX_R28_XMIN 0x28 113#define EM28XX_R28_XMIN 0x28
60#define EM28XX_R29_XMAX 0x29 114#define EM28XX_R29_XMAX 0x29
61#define EM28XX_R2A_YMIN 0x2a 115#define EM28XX_R2A_YMIN 0x2a
@@ -71,10 +125,32 @@
71#define EM28XX_R42_AC97ADDR 0x42 125#define EM28XX_R42_AC97ADDR 0x42
72#define EM28XX_R43_AC97BUSY 0x43 126#define EM28XX_R43_AC97BUSY 0x43
73 127
74/* em202 registers */ 128#define EM28XX_R45_IR 0x45
75#define EM28XX_R02_MASTER_AC97 0x02 129 /* 0x45 bit 7 - parity bit
76#define EM28XX_R10_LINE_IN_AC97 0x10 130 bits 6-0 - count
77#define EM28XX_R14_VIDEO_AC97 0x14 131 0x46 IR brand
132 0x47 IR data
133 */
134
135/* em2874 registers */
136#define EM2874_R50_IR_CONFIG 0x50
137#define EM2874_R51_IR 0x51
138#define EM2874_R5F_TS_ENABLE 0x5f
139#define EM2874_R80_GPIO 0x80
140
141/* em2874 IR config register (0x50) */
142#define EM2874_IR_NEC 0x00
143#define EM2874_IR_RC5 0x04
144#define EM2874_IR_RC5_MODE_0 0x08
145#define EM2874_IR_RC5_MODE_6A 0x0b
146
147/* em2874 Transport Stream Enable Register (0x5f) */
148#define EM2874_TS1_CAPTURE_ENABLE (1 << 0)
149#define EM2874_TS1_FILTER_ENABLE (1 << 1)
150#define EM2874_TS1_NULL_DISCARD (1 << 2)
151#define EM2874_TS2_CAPTURE_ENABLE (1 << 4)
152#define EM2874_TS2_FILTER_ENABLE (1 << 5)
153#define EM2874_TS2_NULL_DISCARD (1 << 6)
78 154
79/* register settings */ 155/* register settings */
80#define EM2800_AUDIO_SRC_TUNER 0x0d 156#define EM2800_AUDIO_SRC_TUNER 0x0d
@@ -84,6 +160,75 @@
84 160
85/* FIXME: Need to be populated with the other chip ID's */ 161/* FIXME: Need to be populated with the other chip ID's */
86enum em28xx_chip_id { 162enum em28xx_chip_id {
163 CHIP_ID_EM2820 = 18,
164 CHIP_ID_EM2840 = 20,
165 CHIP_ID_EM2750 = 33,
87 CHIP_ID_EM2860 = 34, 166 CHIP_ID_EM2860 = 34,
167 CHIP_ID_EM2870 = 35,
88 CHIP_ID_EM2883 = 36, 168 CHIP_ID_EM2883 = 36,
169 CHIP_ID_EM2874 = 65,
89}; 170};
171
172/*
173 * Registers used by em202 and other AC97 chips
174 */
175
176/* Standard AC97 registers */
177#define AC97_RESET 0x00
178
179 /* Output volumes */
180#define AC97_MASTER_VOL 0x02
181#define AC97_LINE_LEVEL_VOL 0x04 /* Some devices use for headphones */
182#define AC97_MASTER_MONO_VOL 0x06
183
184 /* Input volumes */
185#define AC97_PC_BEEP_VOL 0x0a
186#define AC97_PHONE_VOL 0x0c
187#define AC97_MIC_VOL 0x0e
188#define AC97_LINEIN_VOL 0x10
189#define AC97_CD_VOL 0x12
190#define AC97_VIDEO_VOL 0x14
191#define AC97_AUX_VOL 0x16
192#define AC97_PCM_OUT_VOL 0x18
193
194 /* capture registers */
195#define AC97_RECORD_SELECT 0x1a
196#define AC97_RECORD_GAIN 0x1c
197
198 /* control registers */
199#define AC97_GENERAL_PURPOSE 0x20
200#define AC97_3D_CTRL 0x22
201#define AC97_AUD_INT_AND_PAG 0x24
202#define AC97_POWER_DOWN_CTRL 0x26
203#define AC97_EXT_AUD_ID 0x28
204#define AC97_EXT_AUD_CTRL 0x2a
205
206/* Supported rate varies for each AC97 device
207 if write an unsupported value, it will return the closest one
208 */
209#define AC97_PCM_OUT_FRONT_SRATE 0x2c
210#define AC97_PCM_OUT_SURR_SRATE 0x2e
211#define AC97_PCM_OUT_LFE_SRATE 0x30
212#define AC97_PCM_IN_SRATE 0x32
213
214 /* For devices with more than 2 channels, extra output volumes */
215#define AC97_LFE_MASTER_VOL 0x36
216#define AC97_SURR_MASTER_VOL 0x38
217
218 /* Digital SPDIF output control */
219#define AC97_SPDIF_OUT_CTRL 0x3a
220
221 /* Vendor ID identifier */
222#define AC97_VENDOR_ID1 0x7c
223#define AC97_VENDOR_ID2 0x7e
224
225/* EMP202 vendor registers */
226#define EM202_EXT_MODEM_CTRL 0x3e
227#define EM202_GPIO_CONF 0x4c
228#define EM202_GPIO_POLARITY 0x4e
229#define EM202_GPIO_STICKY 0x50
230#define EM202_GPIO_MASK 0x52
231#define EM202_GPIO_STATUS 0x54
232#define EM202_SPDIF_OUT_SEL 0x6a
233#define EM202_ANTIPOP 0x72
234#define EM202_EAPD_GPIO_ACCESS 0x74
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c
index 4ea1f1e04897..53527536481e 100644
--- a/drivers/media/video/em28xx/em28xx-video.c
+++ b/drivers/media/video/em28xx/em28xx-video.c
@@ -39,6 +39,7 @@
39#include "em28xx.h" 39#include "em28xx.h"
40#include <media/v4l2-common.h> 40#include <media/v4l2-common.h>
41#include <media/v4l2-ioctl.h> 41#include <media/v4l2-ioctl.h>
42#include <media/v4l2-chip-ident.h>
42#include <media/msp3400.h> 43#include <media/msp3400.h>
43#include <media/tuner.h> 44#include <media/tuner.h>
44 45
@@ -47,9 +48,8 @@
47 "Mauro Carvalho Chehab <mchehab@infradead.org>, " \ 48 "Mauro Carvalho Chehab <mchehab@infradead.org>, " \
48 "Sascha Sommer <saschasommer@freenet.de>" 49 "Sascha Sommer <saschasommer@freenet.de>"
49 50
50#define DRIVER_NAME "em28xx"
51#define DRIVER_DESC "Empia em28xx based USB video device driver" 51#define DRIVER_DESC "Empia em28xx based USB video device driver"
52#define EM28XX_VERSION_CODE KERNEL_VERSION(0, 1, 0) 52#define EM28XX_VERSION_CODE KERNEL_VERSION(0, 1, 1)
53 53
54#define em28xx_videodbg(fmt, arg...) do {\ 54#define em28xx_videodbg(fmt, arg...) do {\
55 if (video_debug) \ 55 if (video_debug) \
@@ -72,19 +72,13 @@ MODULE_AUTHOR(DRIVER_AUTHOR);
72MODULE_DESCRIPTION(DRIVER_DESC); 72MODULE_DESCRIPTION(DRIVER_DESC);
73MODULE_LICENSE("GPL"); 73MODULE_LICENSE("GPL");
74 74
75static LIST_HEAD(em28xx_devlist);
76static DEFINE_MUTEX(em28xx_devlist_mutex);
77
78static unsigned int card[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = UNSET };
79static unsigned int video_nr[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = UNSET }; 75static unsigned int video_nr[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = UNSET };
80static unsigned int vbi_nr[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = UNSET }; 76static unsigned int vbi_nr[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = UNSET };
81static unsigned int radio_nr[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = UNSET }; 77static unsigned int radio_nr[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = UNSET };
82 78
83module_param_array(card, int, NULL, 0444);
84module_param_array(video_nr, int, NULL, 0444); 79module_param_array(video_nr, int, NULL, 0444);
85module_param_array(vbi_nr, int, NULL, 0444); 80module_param_array(vbi_nr, int, NULL, 0444);
86module_param_array(radio_nr, int, NULL, 0444); 81module_param_array(radio_nr, int, NULL, 0444);
87MODULE_PARM_DESC(card, "card type");
88MODULE_PARM_DESC(video_nr, "video device numbers"); 82MODULE_PARM_DESC(video_nr, "video device numbers");
89MODULE_PARM_DESC(vbi_nr, "vbi device numbers"); 83MODULE_PARM_DESC(vbi_nr, "vbi device numbers");
90MODULE_PARM_DESC(radio_nr, "radio device numbers"); 84MODULE_PARM_DESC(radio_nr, "radio device numbers");
@@ -93,8 +87,15 @@ static unsigned int video_debug;
93module_param(video_debug, int, 0644); 87module_param(video_debug, int, 0644);
94MODULE_PARM_DESC(video_debug, "enable debug messages [video]"); 88MODULE_PARM_DESC(video_debug, "enable debug messages [video]");
95 89
96/* Bitmask marking allocated devices from 0 to EM28XX_MAXBOARDS */ 90/* supported video standards */
97static unsigned long em28xx_devused; 91static struct em28xx_fmt format[] = {
92 {
93 .name = "16bpp YUY2, 4:2:2, packed",
94 .fourcc = V4L2_PIX_FMT_YUYV,
95 .depth = 16,
96 .reg = EM28XX_OUTFMT_YUV422_Y0UY1V,
97 },
98};
98 99
99/* supported controls */ 100/* supported controls */
100/* Common to all boards */ 101/* Common to all boards */
@@ -120,8 +121,6 @@ static struct v4l2_queryctrl em28xx_qctrl[] = {
120 } 121 }
121}; 122};
122 123
123static struct usb_driver em28xx_usb_driver;
124
125/* ------------------------------------------------------------------ 124/* ------------------------------------------------------------------
126 DMA and thread functions 125 DMA and thread functions
127 ------------------------------------------------------------------*/ 126 ------------------------------------------------------------------*/
@@ -386,16 +385,18 @@ buffer_setup(struct videobuf_queue *vq, unsigned int *count, unsigned int *size)
386 struct em28xx *dev = fh->dev; 385 struct em28xx *dev = fh->dev;
387 struct v4l2_frequency f; 386 struct v4l2_frequency f;
388 387
389 *size = 16 * fh->dev->width * fh->dev->height >> 3; 388 *size = (fh->dev->width * fh->dev->height * dev->format->depth + 7) >> 3;
389
390 if (0 == *count) 390 if (0 == *count)
391 *count = EM28XX_DEF_BUF; 391 *count = EM28XX_DEF_BUF;
392 392
393 if (*count < EM28XX_MIN_BUF) 393 if (*count < EM28XX_MIN_BUF)
394 *count = EM28XX_MIN_BUF; 394 *count = EM28XX_MIN_BUF;
395 395
396 /* Ask tuner to go to analog mode */ 396 /* Ask tuner to go to analog or radio mode */
397 memset(&f, 0, sizeof(f)); 397 memset(&f, 0, sizeof(f));
398 f.frequency = dev->ctl_freq; 398 f.frequency = dev->ctl_freq;
399 f.type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
399 400
400 em28xx_i2c_call_clients(dev, VIDIOC_S_FREQUENCY, &f); 401 em28xx_i2c_call_clients(dev, VIDIOC_S_FREQUENCY, &f);
401 402
@@ -438,9 +439,7 @@ buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb,
438 struct em28xx *dev = fh->dev; 439 struct em28xx *dev = fh->dev;
439 int rc = 0, urb_init = 0; 440 int rc = 0, urb_init = 0;
440 441
441 /* FIXME: It assumes depth = 16 */ 442 buf->vb.size = (fh->dev->width * fh->dev->height * dev->format->depth + 7) >> 3;
442 /* The only currently supported format is 16 bits/pixel */
443 buf->vb.size = 16 * dev->width * dev->height >> 3;
444 443
445 if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size) 444 if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size)
446 return -EINVAL; 445 return -EINVAL;
@@ -508,56 +507,6 @@ static struct videobuf_queue_ops em28xx_video_qops = {
508 507
509/********************* v4l2 interface **************************************/ 508/********************* v4l2 interface **************************************/
510 509
511/*
512 * em28xx_config()
513 * inits registers with sane defaults
514 */
515static int em28xx_config(struct em28xx *dev)
516{
517 int retval;
518
519 /* Sets I2C speed to 100 KHz */
520 if (!dev->is_em2800) {
521 retval = em28xx_write_regs_req(dev, 0x00, 0x06, "\x40", 1);
522 if (retval < 0) {
523 em28xx_errdev("%s: em28xx_write_regs_req failed! retval [%d]\n",
524 __func__, retval);
525 return retval;
526 }
527 }
528
529 /* enable vbi capturing */
530
531/* em28xx_write_regs_req(dev, 0x00, 0x0e, "\xC0", 1); audio register */
532/* em28xx_write_regs_req(dev, 0x00, 0x0f, "\x80", 1); clk register */
533 em28xx_write_regs_req(dev, 0x00, 0x11, "\x51", 1);
534
535 dev->mute = 1; /* maybe not the right place... */
536 dev->volume = 0x1f;
537
538 em28xx_outfmt_set_yuv422(dev);
539 em28xx_colorlevels_set_default(dev);
540 em28xx_compression_disable(dev);
541
542 return 0;
543}
544
545/*
546 * em28xx_config_i2c()
547 * configure i2c attached devices
548 */
549static void em28xx_config_i2c(struct em28xx *dev)
550{
551 struct v4l2_routing route;
552 int zero = 0;
553
554 route.input = INPUT(dev->ctl_input)->vmux;
555 route.output = 0;
556 em28xx_i2c_call_clients(dev, VIDIOC_INT_RESET, &zero);
557 em28xx_i2c_call_clients(dev, VIDIOC_INT_S_VIDEO_ROUTING, &route);
558 em28xx_i2c_call_clients(dev, VIDIOC_STREAMON, NULL);
559}
560
561static void video_mux(struct em28xx *dev, int index) 510static void video_mux(struct em28xx *dev, int index)
562{ 511{
563 struct v4l2_routing route; 512 struct v4l2_routing route;
@@ -566,10 +515,14 @@ static void video_mux(struct em28xx *dev, int index)
566 route.output = 0; 515 route.output = 0;
567 dev->ctl_input = index; 516 dev->ctl_input = index;
568 dev->ctl_ainput = INPUT(index)->amux; 517 dev->ctl_ainput = INPUT(index)->amux;
518 dev->ctl_aoutput = INPUT(index)->aout;
519
520 if (!dev->ctl_aoutput)
521 dev->ctl_aoutput = EM28XX_AOUT_MASTER;
569 522
570 em28xx_i2c_call_clients(dev, VIDIOC_INT_S_VIDEO_ROUTING, &route); 523 em28xx_i2c_call_clients(dev, VIDIOC_INT_S_VIDEO_ROUTING, &route);
571 524
572 if (dev->has_msp34xx) { 525 if (dev->board.has_msp34xx) {
573 if (dev->i2s_speed) { 526 if (dev->i2s_speed) {
574 em28xx_i2c_call_clients(dev, VIDIOC_INT_I2S_CLOCK_FREQ, 527 em28xx_i2c_call_clients(dev, VIDIOC_INT_I2S_CLOCK_FREQ,
575 &dev->i2s_speed); 528 &dev->i2s_speed);
@@ -595,12 +548,10 @@ static int res_get(struct em28xx_fh *fh)
595 return rc; 548 return rc;
596 549
597 if (dev->stream_on) 550 if (dev->stream_on)
598 return -EINVAL; 551 return -EBUSY;
599 552
600 mutex_lock(&dev->lock);
601 dev->stream_on = 1; 553 dev->stream_on = 1;
602 fh->stream_on = 1; 554 fh->stream_on = 1;
603 mutex_unlock(&dev->lock);
604 return rc; 555 return rc;
605} 556}
606 557
@@ -613,10 +564,8 @@ static void res_free(struct em28xx_fh *fh)
613{ 564{
614 struct em28xx *dev = fh->dev; 565 struct em28xx *dev = fh->dev;
615 566
616 mutex_lock(&dev->lock);
617 fh->stream_on = 0; 567 fh->stream_on = 0;
618 dev->stream_on = 0; 568 dev->stream_on = 0;
619 mutex_unlock(&dev->lock);
620} 569}
621 570
622/* 571/*
@@ -703,8 +652,8 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
703 652
704 f->fmt.pix.width = dev->width; 653 f->fmt.pix.width = dev->width;
705 f->fmt.pix.height = dev->height; 654 f->fmt.pix.height = dev->height;
706 f->fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV; 655 f->fmt.pix.pixelformat = dev->format->fourcc;
707 f->fmt.pix.bytesperline = dev->width * 2; 656 f->fmt.pix.bytesperline = (dev->width * dev->format->depth + 7) >> 3;
708 f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * dev->height; 657 f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * dev->height;
709 f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; 658 f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
710 659
@@ -716,6 +665,17 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
716 return 0; 665 return 0;
717} 666}
718 667
668static struct em28xx_fmt *format_by_fourcc(unsigned int fourcc)
669{
670 unsigned int i;
671
672 for (i = 0; i < ARRAY_SIZE(format); i++)
673 if (format[i].fourcc == fourcc)
674 return &format[i];
675
676 return NULL;
677}
678
719static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, 679static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
720 struct v4l2_format *f) 680 struct v4l2_format *f)
721{ 681{
@@ -726,24 +686,30 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
726 unsigned int maxw = norm_maxw(dev); 686 unsigned int maxw = norm_maxw(dev);
727 unsigned int maxh = norm_maxh(dev); 687 unsigned int maxh = norm_maxh(dev);
728 unsigned int hscale, vscale; 688 unsigned int hscale, vscale;
689 struct em28xx_fmt *fmt;
690
691 fmt = format_by_fourcc(f->fmt.pix.pixelformat);
692 if (!fmt) {
693 em28xx_videodbg("Fourcc format (%08x) invalid.\n",
694 f->fmt.pix.pixelformat);
695 return -EINVAL;
696 }
729 697
730 /* width must even because of the YUYV format 698 /* width must even because of the YUYV format
731 height must be even because of interlacing */ 699 height must be even because of interlacing */
732 height &= 0xfffe; 700 height &= 0xfffe;
733 width &= 0xfffe; 701 width &= 0xfffe;
734 702
735 if (height < 32) 703 if (unlikely(height < 32))
736 height = 32; 704 height = 32;
737 if (height > maxh) 705 if (unlikely(height > maxh))
738 height = maxh; 706 height = maxh;
739 if (width < 48) 707 if (unlikely(width < 48))
740 width = 48; 708 width = 48;
741 if (width > maxw) 709 if (unlikely(width > maxw))
742 width = maxw; 710 width = maxw;
743 711
744 mutex_lock(&dev->lock); 712 if (dev->board.is_em2800) {
745
746 if (dev->is_em2800) {
747 /* the em2800 can only scale down to 50% */ 713 /* the em2800 can only scale down to 50% */
748 if (height % (maxh / 2)) 714 if (height % (maxh / 2))
749 height = maxh; 715 height = maxh;
@@ -766,13 +732,12 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
766 732
767 f->fmt.pix.width = width; 733 f->fmt.pix.width = width;
768 f->fmt.pix.height = height; 734 f->fmt.pix.height = height;
769 f->fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV; 735 f->fmt.pix.pixelformat = fmt->fourcc;
770 f->fmt.pix.bytesperline = width * 2; 736 f->fmt.pix.bytesperline = (dev->width * fmt->depth + 7) >> 3;
771 f->fmt.pix.sizeimage = width * 2 * height; 737 f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * height;
772 f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; 738 f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
773 f->fmt.pix.field = V4L2_FIELD_INTERLACED; 739 f->fmt.pix.field = V4L2_FIELD_INTERLACED;
774 740
775 mutex_unlock(&dev->lock);
776 return 0; 741 return 0;
777} 742}
778 743
@@ -782,14 +747,21 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
782 struct em28xx_fh *fh = priv; 747 struct em28xx_fh *fh = priv;
783 struct em28xx *dev = fh->dev; 748 struct em28xx *dev = fh->dev;
784 int rc; 749 int rc;
750 struct em28xx_fmt *fmt;
785 751
786 rc = check_dev(dev); 752 rc = check_dev(dev);
787 if (rc < 0) 753 if (rc < 0)
788 return rc; 754 return rc;
789 755
756 mutex_lock(&dev->lock);
757
790 vidioc_try_fmt_vid_cap(file, priv, f); 758 vidioc_try_fmt_vid_cap(file, priv, f);
791 759
792 mutex_lock(&dev->lock); 760 fmt = format_by_fourcc(f->fmt.pix.pixelformat);
761 if (!fmt) {
762 rc = -EINVAL;
763 goto out;
764 }
793 765
794 if (videobuf_queue_is_busy(&fh->vb_vidq)) { 766 if (videobuf_queue_is_busy(&fh->vb_vidq)) {
795 em28xx_errdev("%s queue busy\n", __func__); 767 em28xx_errdev("%s queue busy\n", __func__);
@@ -806,6 +778,7 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
806 /* set new image size */ 778 /* set new image size */
807 dev->width = f->fmt.pix.width; 779 dev->width = f->fmt.pix.width;
808 dev->height = f->fmt.pix.height; 780 dev->height = f->fmt.pix.height;
781 dev->format = fmt;
809 get_scale(dev, dev->width, dev->height, &dev->hscale, &dev->vscale); 782 get_scale(dev, dev->width, dev->height, &dev->hscale, &dev->vscale);
810 783
811 em28xx_set_alternate(dev); 784 em28xx_set_alternate(dev);
@@ -831,15 +804,12 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id * norm)
831 804
832 mutex_lock(&dev->lock); 805 mutex_lock(&dev->lock);
833 dev->norm = *norm; 806 dev->norm = *norm;
834 mutex_unlock(&dev->lock);
835 807
836 /* Adjusts width/height, if needed */ 808 /* Adjusts width/height, if needed */
837 f.fmt.pix.width = dev->width; 809 f.fmt.pix.width = dev->width;
838 f.fmt.pix.height = dev->height; 810 f.fmt.pix.height = dev->height;
839 vidioc_try_fmt_vid_cap(file, priv, &f); 811 vidioc_try_fmt_vid_cap(file, priv, &f);
840 812
841 mutex_lock(&dev->lock);
842
843 /* set new image size */ 813 /* set new image size */
844 dev->width = f.fmt.pix.width; 814 dev->width = f.fmt.pix.width;
845 dev->height = f.fmt.pix.height; 815 dev->height = f.fmt.pix.height;
@@ -928,20 +898,38 @@ static int vidioc_g_audio(struct file *file, void *priv, struct v4l2_audio *a)
928{ 898{
929 struct em28xx_fh *fh = priv; 899 struct em28xx_fh *fh = priv;
930 struct em28xx *dev = fh->dev; 900 struct em28xx *dev = fh->dev;
931 unsigned int index = a->index;
932
933 if (a->index > 1)
934 return -EINVAL;
935
936 index = dev->ctl_ainput;
937 901
938 if (index == 0) 902 switch (a->index) {
903 case EM28XX_AMUX_VIDEO:
939 strcpy(a->name, "Television"); 904 strcpy(a->name, "Television");
940 else 905 break;
906 case EM28XX_AMUX_LINE_IN:
941 strcpy(a->name, "Line In"); 907 strcpy(a->name, "Line In");
908 break;
909 case EM28XX_AMUX_VIDEO2:
910 strcpy(a->name, "Television alt");
911 break;
912 case EM28XX_AMUX_PHONE:
913 strcpy(a->name, "Phone");
914 break;
915 case EM28XX_AMUX_MIC:
916 strcpy(a->name, "Mic");
917 break;
918 case EM28XX_AMUX_CD:
919 strcpy(a->name, "CD");
920 break;
921 case EM28XX_AMUX_AUX:
922 strcpy(a->name, "Aux");
923 break;
924 case EM28XX_AMUX_PCM_OUT:
925 strcpy(a->name, "PCM");
926 break;
927 default:
928 return -EINVAL;
929 }
942 930
931 a->index = dev->ctl_ainput;
943 a->capability = V4L2_AUDCAP_STEREO; 932 a->capability = V4L2_AUDCAP_STEREO;
944 a->index = index;
945 933
946 return 0; 934 return 0;
947} 935}
@@ -951,9 +939,15 @@ static int vidioc_s_audio(struct file *file, void *priv, struct v4l2_audio *a)
951 struct em28xx_fh *fh = priv; 939 struct em28xx_fh *fh = priv;
952 struct em28xx *dev = fh->dev; 940 struct em28xx *dev = fh->dev;
953 941
954 if (a->index != dev->ctl_ainput) 942 mutex_lock(&dev->lock);
955 return -EINVAL; 943
944 dev->ctl_ainput = INPUT(a->index)->amux;
945 dev->ctl_aoutput = INPUT(a->index)->aout;
956 946
947 if (!dev->ctl_aoutput)
948 dev->ctl_aoutput = EM28XX_AOUT_MASTER;
949
950 mutex_unlock(&dev->lock);
957 return 0; 951 return 0;
958} 952}
959 953
@@ -974,7 +968,7 @@ static int vidioc_queryctrl(struct file *file, void *priv,
974 968
975 qc->id = id; 969 qc->id = id;
976 970
977 if (!dev->has_msp34xx) { 971 if (!dev->board.has_msp34xx) {
978 for (i = 0; i < ARRAY_SIZE(em28xx_qctrl); i++) { 972 for (i = 0; i < ARRAY_SIZE(em28xx_qctrl); i++) {
979 if (qc->id && qc->id == em28xx_qctrl[i].id) { 973 if (qc->id && qc->id == em28xx_qctrl[i].id) {
980 memcpy(qc, &(em28xx_qctrl[i]), sizeof(*qc)); 974 memcpy(qc, &(em28xx_qctrl[i]), sizeof(*qc));
@@ -1002,17 +996,14 @@ static int vidioc_g_ctrl(struct file *file, void *priv,
1002 rc = check_dev(dev); 996 rc = check_dev(dev);
1003 if (rc < 0) 997 if (rc < 0)
1004 return rc; 998 return rc;
1005 mutex_lock(&dev->lock); 999 rc = 0;
1006 1000
1007 if (!dev->has_msp34xx) 1001 mutex_lock(&dev->lock);
1008 rc = em28xx_get_ctrl(dev, ctrl);
1009 else
1010 rc = -EINVAL;
1011 1002
1012 if (rc == -EINVAL) { 1003 if (dev->board.has_msp34xx)
1013 em28xx_i2c_call_clients(dev, VIDIOC_G_CTRL, ctrl); 1004 em28xx_i2c_call_clients(dev, VIDIOC_G_CTRL, ctrl);
1014 rc = 0; 1005 else
1015 } 1006 rc = em28xx_get_ctrl(dev, ctrl);
1016 1007
1017 mutex_unlock(&dev->lock); 1008 mutex_unlock(&dev->lock);
1018 return rc; 1009 return rc;
@@ -1032,7 +1023,7 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
1032 1023
1033 mutex_lock(&dev->lock); 1024 mutex_lock(&dev->lock);
1034 1025
1035 if (dev->has_msp34xx) 1026 if (dev->board.has_msp34xx)
1036 em28xx_i2c_call_clients(dev, VIDIOC_S_CTRL, ctrl); 1027 em28xx_i2c_call_clients(dev, VIDIOC_S_CTRL, ctrl);
1037 else { 1028 else {
1038 rc = 1; 1029 rc = 1;
@@ -1112,8 +1103,10 @@ static int vidioc_g_frequency(struct file *file, void *priv,
1112 struct em28xx_fh *fh = priv; 1103 struct em28xx_fh *fh = priv;
1113 struct em28xx *dev = fh->dev; 1104 struct em28xx *dev = fh->dev;
1114 1105
1106 mutex_lock(&dev->lock);
1115 f->type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; 1107 f->type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
1116 f->frequency = dev->ctl_freq; 1108 f->frequency = dev->ctl_freq;
1109 mutex_unlock(&dev->lock);
1117 1110
1118 return 0; 1111 return 0;
1119} 1112}
@@ -1143,6 +1136,7 @@ static int vidioc_s_frequency(struct file *file, void *priv,
1143 em28xx_i2c_call_clients(dev, VIDIOC_S_FREQUENCY, f); 1136 em28xx_i2c_call_clients(dev, VIDIOC_S_FREQUENCY, f);
1144 1137
1145 mutex_unlock(&dev->lock); 1138 mutex_unlock(&dev->lock);
1139
1146 return 0; 1140 return 0;
1147} 1141}
1148 1142
@@ -1159,6 +1153,21 @@ static int em28xx_reg_len(int reg)
1159 } 1153 }
1160} 1154}
1161 1155
1156static int vidioc_g_chip_ident(struct file *file, void *priv,
1157 struct v4l2_chip_ident *chip)
1158{
1159 struct em28xx_fh *fh = priv;
1160 struct em28xx *dev = fh->dev;
1161
1162 chip->ident = V4L2_IDENT_NONE;
1163 chip->revision = 0;
1164
1165 em28xx_i2c_call_clients(dev, VIDIOC_G_CHIP_IDENT, chip);
1166
1167 return 0;
1168}
1169
1170
1162static int vidioc_g_register(struct file *file, void *priv, 1171static int vidioc_g_register(struct file *file, void *priv,
1163 struct v4l2_register *reg) 1172 struct v4l2_register *reg)
1164{ 1173{
@@ -1166,19 +1175,43 @@ static int vidioc_g_register(struct file *file, void *priv,
1166 struct em28xx *dev = fh->dev; 1175 struct em28xx *dev = fh->dev;
1167 int ret; 1176 int ret;
1168 1177
1169 if (!v4l2_chip_match_host(reg->match_type, reg->match_chip)) 1178 switch (reg->match_type) {
1179 case V4L2_CHIP_MATCH_AC97:
1180 mutex_lock(&dev->lock);
1181 ret = em28xx_read_ac97(dev, reg->reg);
1182 mutex_unlock(&dev->lock);
1183 if (ret < 0)
1184 return ret;
1185
1186 reg->val = ret;
1187 return 0;
1188 case V4L2_CHIP_MATCH_I2C_DRIVER:
1189 em28xx_i2c_call_clients(dev, VIDIOC_DBG_G_REGISTER, reg);
1190 return 0;
1191 case V4L2_CHIP_MATCH_I2C_ADDR:
1192 /* Not supported yet */
1170 return -EINVAL; 1193 return -EINVAL;
1194 default:
1195 if (!v4l2_chip_match_host(reg->match_type, reg->match_chip))
1196 return -EINVAL;
1197 }
1171 1198
1199 /* Match host */
1172 if (em28xx_reg_len(reg->reg) == 1) { 1200 if (em28xx_reg_len(reg->reg) == 1) {
1201 mutex_lock(&dev->lock);
1173 ret = em28xx_read_reg(dev, reg->reg); 1202 ret = em28xx_read_reg(dev, reg->reg);
1203 mutex_unlock(&dev->lock);
1204
1174 if (ret < 0) 1205 if (ret < 0)
1175 return ret; 1206 return ret;
1176 1207
1177 reg->val = ret; 1208 reg->val = ret;
1178 } else { 1209 } else {
1179 __le64 val = 0; 1210 __le64 val = 0;
1211 mutex_lock(&dev->lock);
1180 ret = em28xx_read_reg_req_len(dev, USB_REQ_GET_STATUS, 1212 ret = em28xx_read_reg_req_len(dev, USB_REQ_GET_STATUS,
1181 reg->reg, (char *)&val, 2); 1213 reg->reg, (char *)&val, 2);
1214 mutex_unlock(&dev->lock);
1182 if (ret < 0) 1215 if (ret < 0)
1183 return ret; 1216 return ret;
1184 1217
@@ -1194,11 +1227,35 @@ static int vidioc_s_register(struct file *file, void *priv,
1194 struct em28xx_fh *fh = priv; 1227 struct em28xx_fh *fh = priv;
1195 struct em28xx *dev = fh->dev; 1228 struct em28xx *dev = fh->dev;
1196 __le64 buf; 1229 __le64 buf;
1230 int rc;
1197 1231
1232 switch (reg->match_type) {
1233 case V4L2_CHIP_MATCH_AC97:
1234 mutex_lock(&dev->lock);
1235 rc = em28xx_write_ac97(dev, reg->reg, reg->val);
1236 mutex_unlock(&dev->lock);
1237
1238 return rc;
1239 case V4L2_CHIP_MATCH_I2C_DRIVER:
1240 em28xx_i2c_call_clients(dev, VIDIOC_DBG_S_REGISTER, reg);
1241 return 0;
1242 case V4L2_CHIP_MATCH_I2C_ADDR:
1243 /* Not supported yet */
1244 return -EINVAL;
1245 default:
1246 if (!v4l2_chip_match_host(reg->match_type, reg->match_chip))
1247 return -EINVAL;
1248 }
1249
1250 /* Match host */
1198 buf = cpu_to_le64(reg->val); 1251 buf = cpu_to_le64(reg->val);
1199 1252
1200 return em28xx_write_regs(dev, reg->reg, (char *)&buf, 1253 mutex_lock(&dev->lock);
1201 em28xx_reg_len(reg->reg)); 1254 rc = em28xx_write_regs(dev, reg->reg, (char *)&buf,
1255 em28xx_reg_len(reg->reg));
1256 mutex_unlock(&dev->lock);
1257
1258 return rc;
1202} 1259}
1203#endif 1260#endif
1204 1261
@@ -1235,10 +1292,15 @@ static int vidioc_streamon(struct file *file, void *priv,
1235 return rc; 1292 return rc;
1236 1293
1237 1294
1238 if (unlikely(res_get(fh) < 0)) 1295 mutex_lock(&dev->lock);
1239 return -EBUSY; 1296 rc = res_get(fh);
1297
1298 if (likely(rc >= 0))
1299 rc = videobuf_streamon(&fh->vb_vidq);
1240 1300
1241 return (videobuf_streamon(&fh->vb_vidq)); 1301 mutex_unlock(&dev->lock);
1302
1303 return rc;
1242} 1304}
1243 1305
1244static int vidioc_streamoff(struct file *file, void *priv, 1306static int vidioc_streamoff(struct file *file, void *priv,
@@ -1257,9 +1319,13 @@ static int vidioc_streamoff(struct file *file, void *priv,
1257 if (type != fh->type) 1319 if (type != fh->type)
1258 return -EINVAL; 1320 return -EINVAL;
1259 1321
1322 mutex_lock(&dev->lock);
1323
1260 videobuf_streamoff(&fh->vb_vidq); 1324 videobuf_streamoff(&fh->vb_vidq);
1261 res_free(fh); 1325 res_free(fh);
1262 1326
1327 mutex_unlock(&dev->lock);
1328
1263 return 0; 1329 return 0;
1264} 1330}
1265 1331
@@ -1271,7 +1337,7 @@ static int vidioc_querycap(struct file *file, void *priv,
1271 1337
1272 strlcpy(cap->driver, "em28xx", sizeof(cap->driver)); 1338 strlcpy(cap->driver, "em28xx", sizeof(cap->driver));
1273 strlcpy(cap->card, em28xx_boards[dev->model].name, sizeof(cap->card)); 1339 strlcpy(cap->card, em28xx_boards[dev->model].name, sizeof(cap->card));
1274 strlcpy(cap->bus_info, dev->udev->dev.bus_id, sizeof(cap->bus_info)); 1340 strlcpy(cap->bus_info, dev_name(&dev->udev->dev), sizeof(cap->bus_info));
1275 1341
1276 cap->version = EM28XX_VERSION_CODE; 1342 cap->version = EM28XX_VERSION_CODE;
1277 1343
@@ -1288,15 +1354,13 @@ static int vidioc_querycap(struct file *file, void *priv,
1288} 1354}
1289 1355
1290static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, 1356static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
1291 struct v4l2_fmtdesc *fmtd) 1357 struct v4l2_fmtdesc *f)
1292{ 1358{
1293 if (fmtd->index != 0) 1359 if (unlikely(f->index >= ARRAY_SIZE(format)))
1294 return -EINVAL; 1360 return -EINVAL;
1295 1361
1296 fmtd->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 1362 strlcpy(f->description, format[f->index].name, sizeof(f->description));
1297 strcpy(fmtd->description, "Packed YUY2"); 1363 f->pixelformat = format[f->index].fourcc;
1298 fmtd->pixelformat = V4L2_PIX_FMT_YUYV;
1299 memset(fmtd->reserved, 0, sizeof(fmtd->reserved));
1300 1364
1301 return 0; 1365 return 0;
1302} 1366}
@@ -1424,7 +1488,7 @@ static int radio_querycap(struct file *file, void *priv,
1424 1488
1425 strlcpy(cap->driver, "em28xx", sizeof(cap->driver)); 1489 strlcpy(cap->driver, "em28xx", sizeof(cap->driver));
1426 strlcpy(cap->card, em28xx_boards[dev->model].name, sizeof(cap->card)); 1490 strlcpy(cap->card, em28xx_boards[dev->model].name, sizeof(cap->card));
1427 strlcpy(cap->bus_info, dev->udev->dev.bus_id, sizeof(cap->bus_info)); 1491 strlcpy(cap->bus_info, dev_name(&dev->udev->dev), sizeof(cap->bus_info));
1428 1492
1429 cap->version = EM28XX_VERSION_CODE; 1493 cap->version = EM28XX_VERSION_CODE;
1430 cap->capabilities = V4L2_CAP_TUNER; 1494 cap->capabilities = V4L2_CAP_TUNER;
@@ -1442,7 +1506,10 @@ static int radio_g_tuner(struct file *file, void *priv,
1442 strcpy(t->name, "Radio"); 1506 strcpy(t->name, "Radio");
1443 t->type = V4L2_TUNER_RADIO; 1507 t->type = V4L2_TUNER_RADIO;
1444 1508
1509 mutex_lock(&dev->lock);
1445 em28xx_i2c_call_clients(dev, VIDIOC_G_TUNER, t); 1510 em28xx_i2c_call_clients(dev, VIDIOC_G_TUNER, t);
1511 mutex_unlock(&dev->lock);
1512
1446 return 0; 1513 return 0;
1447} 1514}
1448 1515
@@ -1474,7 +1541,9 @@ static int radio_s_tuner(struct file *file, void *priv,
1474 if (0 != t->index) 1541 if (0 != t->index)
1475 return -EINVAL; 1542 return -EINVAL;
1476 1543
1544 mutex_lock(&dev->lock);
1477 em28xx_i2c_call_clients(dev, VIDIOC_S_TUNER, t); 1545 em28xx_i2c_call_clients(dev, VIDIOC_S_TUNER, t);
1546 mutex_unlock(&dev->lock);
1478 1547
1479 return 0; 1548 return 0;
1480} 1549}
@@ -1516,28 +1585,13 @@ static int radio_queryctrl(struct file *file, void *priv,
1516static int em28xx_v4l2_open(struct inode *inode, struct file *filp) 1585static int em28xx_v4l2_open(struct inode *inode, struct file *filp)
1517{ 1586{
1518 int minor = iminor(inode); 1587 int minor = iminor(inode);
1519 int errCode = 0, radio = 0; 1588 int errCode = 0, radio;
1520 struct em28xx *h, *dev = NULL; 1589 struct em28xx *dev;
1590 enum v4l2_buf_type fh_type;
1521 struct em28xx_fh *fh; 1591 struct em28xx_fh *fh;
1522 enum v4l2_buf_type fh_type = 0;
1523 1592
1524 mutex_lock(&em28xx_devlist_mutex); 1593 dev = em28xx_get_device(inode, &fh_type, &radio);
1525 list_for_each_entry(h, &em28xx_devlist, devlist) { 1594
1526 if (h->vdev->minor == minor) {
1527 dev = h;
1528 fh_type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1529 }
1530 if (h->vbi_dev->minor == minor) {
1531 dev = h;
1532 fh_type = V4L2_BUF_TYPE_VBI_CAPTURE;
1533 }
1534 if (h->radio_dev &&
1535 h->radio_dev->minor == minor) {
1536 radio = 1;
1537 dev = h;
1538 }
1539 }
1540 mutex_unlock(&em28xx_devlist_mutex);
1541 if (NULL == dev) 1595 if (NULL == dev)
1542 return -ENODEV; 1596 return -ENODEV;
1543 1597
@@ -1571,7 +1625,7 @@ static int em28xx_v4l2_open(struct inode *inode, struct file *filp)
1571 /* Needed, since GPIO might have disabled power of 1625 /* Needed, since GPIO might have disabled power of
1572 some i2c device 1626 some i2c device
1573 */ 1627 */
1574 em28xx_config_i2c(dev); 1628 em28xx_wake_i2c(dev);
1575 1629
1576 } 1630 }
1577 if (fh->radio) { 1631 if (fh->radio) {
@@ -1595,16 +1649,11 @@ static int em28xx_v4l2_open(struct inode *inode, struct file *filp)
1595 * unregisters the v4l2,i2c and usb devices 1649 * unregisters the v4l2,i2c and usb devices
1596 * called when the device gets disconected or at module unload 1650 * called when the device gets disconected or at module unload
1597*/ 1651*/
1598static void em28xx_release_resources(struct em28xx *dev) 1652void em28xx_release_analog_resources(struct em28xx *dev)
1599{ 1653{
1600 1654
1601 /*FIXME: I2C IR should be disconnected */ 1655 /*FIXME: I2C IR should be disconnected */
1602 1656
1603 em28xx_info("V4L2 devices /dev/video%d and /dev/vbi%d deregistered\n",
1604 dev->vdev->num, dev->vbi_dev->num);
1605 list_del(&dev->devlist);
1606 if (dev->sbutton_input_dev)
1607 em28xx_deregister_snapshot_button(dev);
1608 if (dev->radio_dev) { 1657 if (dev->radio_dev) {
1609 if (-1 != dev->radio_dev->minor) 1658 if (-1 != dev->radio_dev->minor)
1610 video_unregister_device(dev->radio_dev); 1659 video_unregister_device(dev->radio_dev);
@@ -1613,6 +1662,8 @@ static void em28xx_release_resources(struct em28xx *dev)
1613 dev->radio_dev = NULL; 1662 dev->radio_dev = NULL;
1614 } 1663 }
1615 if (dev->vbi_dev) { 1664 if (dev->vbi_dev) {
1665 em28xx_info("V4L2 device /dev/vbi%d deregistered\n",
1666 dev->vbi_dev->num);
1616 if (-1 != dev->vbi_dev->minor) 1667 if (-1 != dev->vbi_dev->minor)
1617 video_unregister_device(dev->vbi_dev); 1668 video_unregister_device(dev->vbi_dev);
1618 else 1669 else
@@ -1620,17 +1671,14 @@ static void em28xx_release_resources(struct em28xx *dev)
1620 dev->vbi_dev = NULL; 1671 dev->vbi_dev = NULL;
1621 } 1672 }
1622 if (dev->vdev) { 1673 if (dev->vdev) {
1674 em28xx_info("V4L2 device /dev/video%d deregistered\n",
1675 dev->vdev->num);
1623 if (-1 != dev->vdev->minor) 1676 if (-1 != dev->vdev->minor)
1624 video_unregister_device(dev->vdev); 1677 video_unregister_device(dev->vdev);
1625 else 1678 else
1626 video_device_release(dev->vdev); 1679 video_device_release(dev->vdev);
1627 dev->vdev = NULL; 1680 dev->vdev = NULL;
1628 } 1681 }
1629 em28xx_i2c_unregister(dev);
1630 usb_put_dev(dev->udev);
1631
1632 /* Mark device as unused */
1633 em28xx_devused &= ~(1<<dev->devno);
1634} 1682}
1635 1683
1636/* 1684/*
@@ -1647,11 +1695,10 @@ static int em28xx_v4l2_close(struct inode *inode, struct file *filp)
1647 em28xx_videodbg("users=%d\n", dev->users); 1695 em28xx_videodbg("users=%d\n", dev->users);
1648 1696
1649 1697
1698 mutex_lock(&dev->lock);
1650 if (res_check(fh)) 1699 if (res_check(fh))
1651 res_free(fh); 1700 res_free(fh);
1652 1701
1653 mutex_lock(&dev->lock);
1654
1655 if (dev->users == 1) { 1702 if (dev->users == 1) {
1656 videobuf_stop(&fh->vb_vidq); 1703 videobuf_stop(&fh->vb_vidq);
1657 videobuf_mmap_free(&fh->vb_vidq); 1704 videobuf_mmap_free(&fh->vb_vidq);
@@ -1665,9 +1712,12 @@ static int em28xx_v4l2_close(struct inode *inode, struct file *filp)
1665 return 0; 1712 return 0;
1666 } 1713 }
1667 1714
1715 /* Save some power by putting tuner to sleep */
1716 em28xx_i2c_call_clients(dev, TUNER_SET_STANDBY, NULL);
1717
1668 /* do this before setting alternate! */ 1718 /* do this before setting alternate! */
1669 em28xx_uninit_isoc(dev); 1719 em28xx_uninit_isoc(dev);
1670 em28xx_set_mode(dev, EM28XX_MODE_UNDEFINED); 1720 em28xx_set_mode(dev, EM28XX_SUSPEND);
1671 1721
1672 /* set alternate 0 */ 1722 /* set alternate 0 */
1673 dev->alt = 0; 1723 dev->alt = 0;
@@ -1706,8 +1756,12 @@ em28xx_v4l2_read(struct file *filp, char __user *buf, size_t count,
1706 */ 1756 */
1707 1757
1708 if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { 1758 if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1709 if (unlikely(res_get(fh))) 1759 mutex_lock(&dev->lock);
1710 return -EBUSY; 1760 rc = res_get(fh);
1761 mutex_unlock(&dev->lock);
1762
1763 if (unlikely(rc < 0))
1764 return rc;
1711 1765
1712 return videobuf_read_stream(&fh->vb_vidq, buf, count, pos, 0, 1766 return videobuf_read_stream(&fh->vb_vidq, buf, count, pos, 0,
1713 filp->f_flags & O_NONBLOCK); 1767 filp->f_flags & O_NONBLOCK);
@@ -1729,7 +1783,11 @@ static unsigned int em28xx_v4l2_poll(struct file *filp, poll_table * wait)
1729 if (rc < 0) 1783 if (rc < 0)
1730 return rc; 1784 return rc;
1731 1785
1732 if (unlikely(res_get(fh) < 0)) 1786 mutex_lock(&dev->lock);
1787 rc = res_get(fh);
1788 mutex_unlock(&dev->lock);
1789
1790 if (unlikely(rc < 0))
1733 return POLLERR; 1791 return POLLERR;
1734 1792
1735 if (V4L2_BUF_TYPE_VIDEO_CAPTURE != fh->type) 1793 if (V4L2_BUF_TYPE_VIDEO_CAPTURE != fh->type)
@@ -1747,13 +1805,17 @@ static int em28xx_v4l2_mmap(struct file *filp, struct vm_area_struct *vma)
1747 struct em28xx *dev = fh->dev; 1805 struct em28xx *dev = fh->dev;
1748 int rc; 1806 int rc;
1749 1807
1750 if (unlikely(res_get(fh) < 0))
1751 return -EBUSY;
1752
1753 rc = check_dev(dev); 1808 rc = check_dev(dev);
1754 if (rc < 0) 1809 if (rc < 0)
1755 return rc; 1810 return rc;
1756 1811
1812 mutex_lock(&dev->lock);
1813 rc = res_get(fh);
1814 mutex_unlock(&dev->lock);
1815
1816 if (unlikely(rc < 0))
1817 return rc;
1818
1757 rc = videobuf_mmap_mapper(&fh->vb_vidq, vma); 1819 rc = videobuf_mmap_mapper(&fh->vb_vidq, vma);
1758 1820
1759 em28xx_videodbg("vma start=0x%08lx, size=%ld, ret=%d\n", 1821 em28xx_videodbg("vma start=0x%08lx, size=%ld, ret=%d\n",
@@ -1810,6 +1872,7 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = {
1810#ifdef CONFIG_VIDEO_ADV_DEBUG 1872#ifdef CONFIG_VIDEO_ADV_DEBUG
1811 .vidioc_g_register = vidioc_g_register, 1873 .vidioc_g_register = vidioc_g_register,
1812 .vidioc_s_register = vidioc_s_register, 1874 .vidioc_s_register = vidioc_s_register,
1875 .vidioc_g_chip_ident = vidioc_g_chip_ident,
1813#endif 1876#endif
1814#ifdef CONFIG_VIDEO_V4L1_COMPAT 1877#ifdef CONFIG_VIDEO_V4L1_COMPAT
1815 .vidiocgmbuf = vidiocgmbuf, 1878 .vidiocgmbuf = vidiocgmbuf,
@@ -1865,44 +1928,6 @@ static struct video_device em28xx_radio_template = {
1865/******************************** usb interface ******************************/ 1928/******************************** usb interface ******************************/
1866 1929
1867 1930
1868static LIST_HEAD(em28xx_extension_devlist);
1869static DEFINE_MUTEX(em28xx_extension_devlist_lock);
1870
1871int em28xx_register_extension(struct em28xx_ops *ops)
1872{
1873 struct em28xx *dev = NULL;
1874
1875 mutex_lock(&em28xx_devlist_mutex);
1876 mutex_lock(&em28xx_extension_devlist_lock);
1877 list_add_tail(&ops->next, &em28xx_extension_devlist);
1878 list_for_each_entry(dev, &em28xx_devlist, devlist) {
1879 if (dev)
1880 ops->init(dev);
1881 }
1882 printk(KERN_INFO "Em28xx: Initialized (%s) extension\n", ops->name);
1883 mutex_unlock(&em28xx_extension_devlist_lock);
1884 mutex_unlock(&em28xx_devlist_mutex);
1885 return 0;
1886}
1887EXPORT_SYMBOL(em28xx_register_extension);
1888
1889void em28xx_unregister_extension(struct em28xx_ops *ops)
1890{
1891 struct em28xx *dev = NULL;
1892
1893 mutex_lock(&em28xx_devlist_mutex);
1894 list_for_each_entry(dev, &em28xx_devlist, devlist) {
1895 if (dev)
1896 ops->fini(dev);
1897 }
1898
1899 mutex_lock(&em28xx_extension_devlist_lock);
1900 printk(KERN_INFO "Em28xx: Removed (%s) extension\n", ops->name);
1901 list_del(&ops->next);
1902 mutex_unlock(&em28xx_extension_devlist_lock);
1903 mutex_unlock(&em28xx_devlist_mutex);
1904}
1905EXPORT_SYMBOL(em28xx_unregister_extension);
1906 1931
1907static struct video_device *em28xx_vdev_init(struct em28xx *dev, 1932static struct video_device *em28xx_vdev_init(struct em28xx *dev,
1908 const struct video_device *template, 1933 const struct video_device *template,
@@ -1925,11 +1950,43 @@ static struct video_device *em28xx_vdev_init(struct em28xx *dev,
1925 return vfd; 1950 return vfd;
1926} 1951}
1927 1952
1928 1953int em28xx_register_analog_devices(struct em28xx *dev)
1929static int register_analog_devices(struct em28xx *dev)
1930{ 1954{
1931 int ret; 1955 int ret;
1932 1956
1957 printk(KERN_INFO "%s: v4l2 driver version %d.%d.%d\n",
1958 dev->name,
1959 (EM28XX_VERSION_CODE >> 16) & 0xff,
1960 (EM28XX_VERSION_CODE >> 8) & 0xff, EM28XX_VERSION_CODE & 0xff);
1961
1962 /* Analog specific initialization */
1963 dev->format = &format[0];
1964 video_mux(dev, 0);
1965
1966 /* enable vbi capturing */
1967
1968/* em28xx_write_reg(dev, EM28XX_R0E_AUDIOSRC, 0xc0); audio register */
1969/* em28xx_write_reg(dev, EM28XX_R0F_XCLK, 0x80); clk register */
1970 em28xx_write_reg(dev, EM28XX_R11_VINCTRL, 0x51);
1971
1972 dev->mute = 1; /* maybe not the right place... */
1973 dev->volume = 0x1f;
1974
1975 em28xx_set_outfmt(dev);
1976 em28xx_colorlevels_set_default(dev);
1977 em28xx_compression_disable(dev);
1978
1979 /* set default norm */
1980 dev->norm = em28xx_video_template.current_norm;
1981 dev->width = norm_maxw(dev);
1982 dev->height = norm_maxh(dev);
1983 dev->interlaced = EM28XX_INTERLACED_DEFAULT;
1984 dev->hscale = 0;
1985 dev->vscale = 0;
1986
1987 /* FIXME: This is a very bad hack! Not all devices have TV on input 2 */
1988 dev->ctl_input = 2;
1989
1933 /* allocate and fill video video_device struct */ 1990 /* allocate and fill video video_device struct */
1934 dev->vdev = em28xx_vdev_init(dev, &em28xx_video_template, "video"); 1991 dev->vdev = em28xx_vdev_init(dev, &em28xx_video_template, "video");
1935 if (!dev->vdev) { 1992 if (!dev->vdev) {
@@ -1978,383 +2035,3 @@ static int register_analog_devices(struct em28xx *dev)
1978 2035
1979 return 0; 2036 return 0;
1980} 2037}
1981
1982
1983/*
1984 * em28xx_init_dev()
1985 * allocates and inits the device structs, registers i2c bus and v4l device
1986 */
1987static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
1988 int minor)
1989{
1990 struct em28xx_ops *ops = NULL;
1991 struct em28xx *dev = *devhandle;
1992 int retval = -ENOMEM;
1993 int errCode;
1994 unsigned int maxh, maxw;
1995
1996 dev->udev = udev;
1997 mutex_init(&dev->lock);
1998 mutex_init(&dev->ctrl_urb_lock);
1999 spin_lock_init(&dev->slock);
2000 init_waitqueue_head(&dev->open);
2001 init_waitqueue_head(&dev->wait_frame);
2002 init_waitqueue_head(&dev->wait_stream);
2003
2004 dev->em28xx_write_regs = em28xx_write_regs;
2005 dev->em28xx_read_reg = em28xx_read_reg;
2006 dev->em28xx_read_reg_req_len = em28xx_read_reg_req_len;
2007 dev->em28xx_write_regs_req = em28xx_write_regs_req;
2008 dev->em28xx_read_reg_req = em28xx_read_reg_req;
2009 dev->is_em2800 = em28xx_boards[dev->model].is_em2800;
2010
2011 em28xx_pre_card_setup(dev);
2012
2013 errCode = em28xx_config(dev);
2014 if (errCode) {
2015 em28xx_errdev("error configuring device\n");
2016 return -ENOMEM;
2017 }
2018
2019 /* register i2c bus */
2020 errCode = em28xx_i2c_register(dev);
2021 if (errCode < 0) {
2022 em28xx_errdev("%s: em28xx_i2c_register - errCode [%d]!\n",
2023 __func__, errCode);
2024 return errCode;
2025 }
2026
2027 /* Do board specific init and eeprom reading */
2028 em28xx_card_setup(dev);
2029
2030 /* Configure audio */
2031 errCode = em28xx_audio_analog_set(dev);
2032 if (errCode < 0) {
2033 em28xx_errdev("%s: em28xx_audio_analog_set - errCode [%d]!\n",
2034 __func__, errCode);
2035 return errCode;
2036 }
2037
2038 /* configure the device */
2039 em28xx_config_i2c(dev);
2040
2041 /* set default norm */
2042 dev->norm = em28xx_video_template.current_norm;
2043
2044 maxw = norm_maxw(dev);
2045 maxh = norm_maxh(dev);
2046
2047 /* set default image size */
2048 dev->width = maxw;
2049 dev->height = maxh;
2050 dev->interlaced = EM28XX_INTERLACED_DEFAULT;
2051 dev->hscale = 0;
2052 dev->vscale = 0;
2053 dev->ctl_input = 2;
2054
2055 errCode = em28xx_config(dev);
2056 if (errCode < 0) {
2057 em28xx_errdev("%s: em28xx_config - errCode [%d]!\n",
2058 __func__, errCode);
2059 return errCode;
2060 }
2061
2062 /* init video dma queues */
2063 INIT_LIST_HEAD(&dev->vidq.active);
2064 INIT_LIST_HEAD(&dev->vidq.queued);
2065
2066
2067 if (dev->has_msp34xx) {
2068 /* Send a reset to other chips via gpio */
2069 errCode = em28xx_write_regs_req(dev, 0x00, 0x08, "\xf7", 1);
2070 if (errCode < 0) {
2071 em28xx_errdev("%s: em28xx_write_regs_req - msp34xx(1) failed! errCode [%d]\n",
2072 __func__, errCode);
2073 return errCode;
2074 }
2075 msleep(3);
2076
2077 errCode = em28xx_write_regs_req(dev, 0x00, 0x08, "\xff", 1);
2078 if (errCode < 0) {
2079 em28xx_errdev("%s: em28xx_write_regs_req - msp34xx(2) failed! errCode [%d]\n",
2080 __func__, errCode);
2081 return errCode;
2082 }
2083 msleep(3);
2084 }
2085
2086 video_mux(dev, 0);
2087
2088 mutex_lock(&em28xx_devlist_mutex);
2089 list_add_tail(&dev->devlist, &em28xx_devlist);
2090 retval = register_analog_devices(dev);
2091 if (retval < 0) {
2092 em28xx_release_resources(dev);
2093 mutex_unlock(&em28xx_devlist_mutex);
2094 goto fail_reg_devices;
2095 }
2096
2097 mutex_lock(&em28xx_extension_devlist_lock);
2098 if (!list_empty(&em28xx_extension_devlist)) {
2099 list_for_each_entry(ops, &em28xx_extension_devlist, next) {
2100 if (ops->id)
2101 ops->init(dev);
2102 }
2103 }
2104 mutex_unlock(&em28xx_extension_devlist_lock);
2105 mutex_unlock(&em28xx_devlist_mutex);
2106
2107 return 0;
2108
2109fail_reg_devices:
2110 mutex_unlock(&dev->lock);
2111 return retval;
2112}
2113
2114#if defined(CONFIG_MODULES) && defined(MODULE)
2115static void request_module_async(struct work_struct *work)
2116{
2117 struct em28xx *dev = container_of(work,
2118 struct em28xx, request_module_wk);
2119
2120 if (dev->has_audio_class)
2121 request_module("snd-usb-audio");
2122 else
2123 request_module("em28xx-alsa");
2124
2125 if (dev->has_dvb)
2126 request_module("em28xx-dvb");
2127}
2128
2129static void request_modules(struct em28xx *dev)
2130{
2131 INIT_WORK(&dev->request_module_wk, request_module_async);
2132 schedule_work(&dev->request_module_wk);
2133}
2134#else
2135#define request_modules(dev)
2136#endif /* CONFIG_MODULES */
2137
2138/*
2139 * em28xx_usb_probe()
2140 * checks for supported devices
2141 */
2142static int em28xx_usb_probe(struct usb_interface *interface,
2143 const struct usb_device_id *id)
2144{
2145 const struct usb_endpoint_descriptor *endpoint;
2146 struct usb_device *udev;
2147 struct usb_interface *uif;
2148 struct em28xx *dev = NULL;
2149 int retval = -ENODEV;
2150 int i, nr, ifnum;
2151
2152 udev = usb_get_dev(interface_to_usbdev(interface));
2153 ifnum = interface->altsetting[0].desc.bInterfaceNumber;
2154
2155 /* Check to see next free device and mark as used */
2156 nr = find_first_zero_bit(&em28xx_devused, EM28XX_MAXBOARDS);
2157 em28xx_devused |= 1<<nr;
2158
2159 /* Don't register audio interfaces */
2160 if (interface->altsetting[0].desc.bInterfaceClass == USB_CLASS_AUDIO) {
2161 em28xx_err(DRIVER_NAME " audio device (%04x:%04x): interface %i, class %i\n",
2162 udev->descriptor.idVendor,
2163 udev->descriptor.idProduct,
2164 ifnum,
2165 interface->altsetting[0].desc.bInterfaceClass);
2166
2167 em28xx_devused &= ~(1<<nr);
2168 return -ENODEV;
2169 }
2170
2171 em28xx_err(DRIVER_NAME " new video device (%04x:%04x): interface %i, class %i\n",
2172 udev->descriptor.idVendor,
2173 udev->descriptor.idProduct,
2174 ifnum,
2175 interface->altsetting[0].desc.bInterfaceClass);
2176
2177 endpoint = &interface->cur_altsetting->endpoint[1].desc;
2178
2179 /* check if the device has the iso in endpoint at the correct place */
2180 if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) !=
2181 USB_ENDPOINT_XFER_ISOC) {
2182 em28xx_err(DRIVER_NAME " probing error: endpoint is non-ISO endpoint!\n");
2183 em28xx_devused &= ~(1<<nr);
2184 return -ENODEV;
2185 }
2186 if ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT) {
2187 em28xx_err(DRIVER_NAME " probing error: endpoint is ISO OUT endpoint!\n");
2188 em28xx_devused &= ~(1<<nr);
2189 return -ENODEV;
2190 }
2191
2192 if (nr >= EM28XX_MAXBOARDS) {
2193 printk(DRIVER_NAME ": Supports only %i em28xx boards.\n",
2194 EM28XX_MAXBOARDS);
2195 em28xx_devused &= ~(1<<nr);
2196 return -ENOMEM;
2197 }
2198
2199 /* allocate memory for our device state and initialize it */
2200 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
2201 if (dev == NULL) {
2202 em28xx_err(DRIVER_NAME ": out of memory!\n");
2203 em28xx_devused &= ~(1<<nr);
2204 return -ENOMEM;
2205 }
2206
2207 snprintf(dev->name, 29, "em28xx #%d", nr);
2208 dev->devno = nr;
2209 dev->model = id->driver_info;
2210 dev->alt = -1;
2211
2212 /* Checks if audio is provided by some interface */
2213 for (i = 0; i < udev->config->desc.bNumInterfaces; i++) {
2214 uif = udev->config->interface[i];
2215 if (uif->altsetting[0].desc.bInterfaceClass == USB_CLASS_AUDIO) {
2216 dev->has_audio_class = 1;
2217 break;
2218 }
2219 }
2220
2221 printk(KERN_INFO DRIVER_NAME " %s usb audio class\n",
2222 dev->has_audio_class ? "Has" : "Doesn't have");
2223
2224 /* compute alternate max packet sizes */
2225 uif = udev->actconfig->interface[0];
2226
2227 dev->num_alt = uif->num_altsetting;
2228 em28xx_info("Alternate settings: %i\n", dev->num_alt);
2229/* dev->alt_max_pkt_size = kmalloc(sizeof(*dev->alt_max_pkt_size)* */
2230 dev->alt_max_pkt_size = kmalloc(32 * dev->num_alt, GFP_KERNEL);
2231
2232 if (dev->alt_max_pkt_size == NULL) {
2233 em28xx_errdev("out of memory!\n");
2234 em28xx_devused &= ~(1<<nr);
2235 kfree(dev);
2236 return -ENOMEM;
2237 }
2238
2239 for (i = 0; i < dev->num_alt ; i++) {
2240 u16 tmp = le16_to_cpu(uif->altsetting[i].endpoint[1].desc.
2241 wMaxPacketSize);
2242 dev->alt_max_pkt_size[i] =
2243 (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1);
2244 em28xx_info("Alternate setting %i, max size= %i\n", i,
2245 dev->alt_max_pkt_size[i]);
2246 }
2247
2248 if ((card[nr] >= 0) && (card[nr] < em28xx_bcount))
2249 dev->model = card[nr];
2250
2251 /* allocate device struct */
2252 retval = em28xx_init_dev(&dev, udev, nr);
2253 if (retval) {
2254 em28xx_devused &= ~(1<<dev->devno);
2255 kfree(dev);
2256
2257 return retval;
2258 }
2259
2260 em28xx_info("Found %s\n", em28xx_boards[dev->model].name);
2261
2262 /* save our data pointer in this interface device */
2263 usb_set_intfdata(interface, dev);
2264
2265 request_modules(dev);
2266
2267 return 0;
2268}
2269
2270/*
2271 * em28xx_usb_disconnect()
2272 * called when the device gets diconencted
2273 * video device will be unregistered on v4l2_close in case it is still open
2274 */
2275static void em28xx_usb_disconnect(struct usb_interface *interface)
2276{
2277 struct em28xx *dev;
2278 struct em28xx_ops *ops = NULL;
2279
2280 dev = usb_get_intfdata(interface);
2281 usb_set_intfdata(interface, NULL);
2282
2283 if (!dev)
2284 return;
2285
2286 em28xx_info("disconnecting %s\n", dev->vdev->name);
2287
2288 /* wait until all current v4l2 io is finished then deallocate
2289 resources */
2290 mutex_lock(&dev->lock);
2291
2292 wake_up_interruptible_all(&dev->open);
2293
2294 if (dev->users) {
2295 em28xx_warn
2296 ("device /dev/video%d is open! Deregistration and memory "
2297 "deallocation are deferred on close.\n",
2298 dev->vdev->num);
2299
2300 dev->state |= DEV_MISCONFIGURED;
2301 em28xx_uninit_isoc(dev);
2302 dev->state |= DEV_DISCONNECTED;
2303 wake_up_interruptible(&dev->wait_frame);
2304 wake_up_interruptible(&dev->wait_stream);
2305 } else {
2306 dev->state |= DEV_DISCONNECTED;
2307 em28xx_release_resources(dev);
2308 }
2309 mutex_unlock(&dev->lock);
2310
2311 mutex_lock(&em28xx_extension_devlist_lock);
2312 if (!list_empty(&em28xx_extension_devlist)) {
2313 list_for_each_entry(ops, &em28xx_extension_devlist, next) {
2314 ops->fini(dev);
2315 }
2316 }
2317 mutex_unlock(&em28xx_extension_devlist_lock);
2318
2319 if (!dev->users) {
2320 kfree(dev->alt_max_pkt_size);
2321 kfree(dev);
2322 }
2323}
2324
2325static struct usb_driver em28xx_usb_driver = {
2326 .name = "em28xx",
2327 .probe = em28xx_usb_probe,
2328 .disconnect = em28xx_usb_disconnect,
2329 .id_table = em28xx_id_table,
2330};
2331
2332static int __init em28xx_module_init(void)
2333{
2334 int result;
2335
2336 printk(KERN_INFO DRIVER_NAME " v4l2 driver version %d.%d.%d loaded\n",
2337 (EM28XX_VERSION_CODE >> 16) & 0xff,
2338 (EM28XX_VERSION_CODE >> 8) & 0xff, EM28XX_VERSION_CODE & 0xff);
2339#ifdef SNAPSHOT
2340 printk(KERN_INFO DRIVER_NAME " snapshot date %04d-%02d-%02d\n",
2341 SNAPSHOT / 10000, (SNAPSHOT / 100) % 100, SNAPSHOT % 100);
2342#endif
2343
2344 /* register this driver with the USB subsystem */
2345 result = usb_register(&em28xx_usb_driver);
2346 if (result)
2347 em28xx_err(DRIVER_NAME
2348 " usb_register failed. Error number %d.\n", result);
2349
2350 return result;
2351}
2352
2353static void __exit em28xx_module_exit(void)
2354{
2355 /* deregister this driver with the USB subsystem */
2356 usb_deregister(&em28xx_usb_driver);
2357}
2358
2359module_init(em28xx_module_init);
2360module_exit(em28xx_module_exit);
diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h
index 5956e9b3062f..b5eddc26388e 100644
--- a/drivers/media/video/em28xx/em28xx.h
+++ b/drivers/media/video/em28xx/em28xx.h
@@ -67,7 +67,6 @@
67#define EM2820_BOARD_HERCULES_SMART_TV_USB2 26 67#define EM2820_BOARD_HERCULES_SMART_TV_USB2 26
68#define EM2820_BOARD_PINNACLE_USB_2_FM1216ME 27 68#define EM2820_BOARD_PINNACLE_USB_2_FM1216ME 27
69#define EM2820_BOARD_LEADTEK_WINFAST_USBII_DELUXE 28 69#define EM2820_BOARD_LEADTEK_WINFAST_USBII_DELUXE 28
70#define EM2820_BOARD_PINNACLE_DVC_100 29
71#define EM2820_BOARD_VIDEOLOGY_20K14XUSB 30 70#define EM2820_BOARD_VIDEOLOGY_20K14XUSB 30
72#define EM2821_BOARD_USBGEAR_VD204 31 71#define EM2821_BOARD_USBGEAR_VD204 31
73#define EM2821_BOARD_SUPERCOMP_USB_2 32 72#define EM2821_BOARD_SUPERCOMP_USB_2 32
@@ -97,6 +96,8 @@
97#define EM2882_BOARD_PINNACLE_HYBRID_PRO 56 96#define EM2882_BOARD_PINNACLE_HYBRID_PRO 56
98#define EM2883_BOARD_KWORLD_HYBRID_A316 57 97#define EM2883_BOARD_KWORLD_HYBRID_A316 57
99#define EM2820_BOARD_COMPRO_VIDEOMATE_FORYOU 58 98#define EM2820_BOARD_COMPRO_VIDEOMATE_FORYOU 58
99#define EM2883_BOARD_HAUPPAUGE_WINTV_HVR_850 60
100#define EM2820_BOARD_PROLINK_PLAYTV_BOX4_USB2 61
100 101
101/* Limits minimum and default number of buffers */ 102/* Limits minimum and default number of buffers */
102#define EM28XX_MIN_BUF 4 103#define EM28XX_MIN_BUF 4
@@ -159,7 +160,7 @@
159#define EM2800_I2C_WRITE_TIMEOUT 20 160#define EM2800_I2C_WRITE_TIMEOUT 20
160 161
161enum em28xx_mode { 162enum em28xx_mode {
162 EM28XX_MODE_UNDEFINED, 163 EM28XX_SUSPEND,
163 EM28XX_ANALOG_MODE, 164 EM28XX_ANALOG_MODE,
164 EM28XX_DIGITAL_MODE, 165 EM28XX_DIGITAL_MODE,
165}; 166};
@@ -207,9 +208,12 @@ struct em28xx_usb_isoc_ctl {
207 208
208}; 209};
209 210
211/* Struct to enumberate video formats */
210struct em28xx_fmt { 212struct em28xx_fmt {
211 char *name; 213 char *name;
212 u32 fourcc; /* v4l2 format id */ 214 u32 fourcc; /* v4l2 format id */
215 int depth;
216 int reg;
213}; 217};
214 218
215/* buffer for one video frame */ 219/* buffer for one video frame */
@@ -255,54 +259,105 @@ enum enum28xx_itype {
255 EM28XX_RADIO, 259 EM28XX_RADIO,
256}; 260};
257 261
262enum em28xx_ac97_mode {
263 EM28XX_NO_AC97 = 0,
264 EM28XX_AC97_EM202,
265 EM28XX_AC97_SIGMATEL,
266 EM28XX_AC97_OTHER,
267};
268
269struct em28xx_audio_mode {
270 enum em28xx_ac97_mode ac97;
271
272 u16 ac97_feat;
273 u32 ac97_vendor_id;
274
275 unsigned int has_audio:1;
276
277 unsigned int i2s_3rates:1;
278 unsigned int i2s_5rates:1;
279};
280
281/* em28xx has two audio inputs: tuner and line in.
282 However, on most devices, an auxiliary AC97 codec device is used.
283 The AC97 device may have several different inputs and outputs,
284 depending on their model. So, it is possible to use AC97 mixer to
285 address more than two different entries.
286 */
258enum em28xx_amux { 287enum em28xx_amux {
259 EM28XX_AMUX_VIDEO, 288 /* This is the only entry for em28xx tuner input */
260 EM28XX_AMUX_LINE_IN, 289 EM28XX_AMUX_VIDEO, /* em28xx tuner, AC97 mixer Video */
261 EM28XX_AMUX_AC97_VIDEO, 290
262 EM28XX_AMUX_AC97_LINE_IN, 291 EM28XX_AMUX_LINE_IN, /* AC97 mixer Line In */
292
293 /* Some less-common mixer setups */
294 EM28XX_AMUX_VIDEO2, /* em28xx Line in, AC97 mixer Video */
295 EM28XX_AMUX_PHONE,
296 EM28XX_AMUX_MIC,
297 EM28XX_AMUX_CD,
298 EM28XX_AMUX_AUX,
299 EM28XX_AMUX_PCM_OUT,
300};
301
302enum em28xx_aout {
303 EM28XX_AOUT_MASTER = 1 << 0,
304 EM28XX_AOUT_LINE = 1 << 1,
305 EM28XX_AOUT_MONO = 1 << 2,
306 EM28XX_AOUT_LFE = 1 << 3,
307 EM28XX_AOUT_SURR = 1 << 4,
308};
309
310struct em28xx_reg_seq {
311 int reg;
312 unsigned char val, mask;
313 int sleep;
263}; 314};
264 315
265struct em28xx_input { 316struct em28xx_input {
266 enum enum28xx_itype type; 317 enum enum28xx_itype type;
267 unsigned int vmux; 318 unsigned int vmux;
268 enum em28xx_amux amux; 319 enum em28xx_amux amux;
320 enum em28xx_aout aout;
321 struct em28xx_reg_seq *gpio;
269}; 322};
270 323
271#define INPUT(nr) (&em28xx_boards[dev->model].input[nr]) 324#define INPUT(nr) (&em28xx_boards[dev->model].input[nr])
272 325
273enum em28xx_decoder { 326enum em28xx_decoder {
327 EM28XX_NODECODER,
274 EM28XX_TVP5150, 328 EM28XX_TVP5150,
275 EM28XX_SAA7113, 329 EM28XX_SAA711X,
276 EM28XX_SAA7114
277};
278
279struct em28xx_reg_seq {
280 int reg;
281 unsigned char val, mask;
282 int sleep;
283}; 330};
284 331
285struct em28xx_board { 332struct em28xx_board {
286 char *name; 333 char *name;
287 int vchannels; 334 int vchannels;
288 int tuner_type; 335 int tuner_type;
336 int tuner_addr;
289 337
290 /* i2c flags */ 338 /* i2c flags */
291 unsigned int tda9887_conf; 339 unsigned int tda9887_conf;
292 340
341 /* GPIO sequences */
342 struct em28xx_reg_seq *dvb_gpio;
343 struct em28xx_reg_seq *suspend_gpio;
344 struct em28xx_reg_seq *tuner_gpio;
345
293 unsigned int is_em2800:1; 346 unsigned int is_em2800:1;
294 unsigned int has_msp34xx:1; 347 unsigned int has_msp34xx:1;
295 unsigned int mts_firmware:1; 348 unsigned int mts_firmware:1;
296 unsigned int has_12mhz_i2s:1;
297 unsigned int max_range_640_480:1; 349 unsigned int max_range_640_480:1;
298 unsigned int has_dvb:1; 350 unsigned int has_dvb:1;
299 unsigned int has_snapshot_button:1; 351 unsigned int has_snapshot_button:1;
300 unsigned int valid:1; 352 unsigned int valid:1;
301 353
354 unsigned char xclk, i2c_speed;
355
302 enum em28xx_decoder decoder; 356 enum em28xx_decoder decoder;
303 357
304 struct em28xx_input input[MAX_EM28XX_INPUT]; 358 struct em28xx_input input[MAX_EM28XX_INPUT];
305 struct em28xx_input radio; 359 struct em28xx_input radio;
360 IR_KEYTAB_TYPE *ir_codes;
306}; 361};
307 362
308struct em28xx_eeprom { 363struct em28xx_eeprom {
@@ -369,32 +424,26 @@ struct em28xx {
369 char name[30]; /* name (including minor) of the device */ 424 char name[30]; /* name (including minor) of the device */
370 int model; /* index in the device_data struct */ 425 int model; /* index in the device_data struct */
371 int devno; /* marks the number of this device */ 426 int devno; /* marks the number of this device */
372 unsigned int is_em2800:1; 427 enum em28xx_chip_id chip_id;
373 unsigned int has_msp34xx:1; 428
374 unsigned int has_tda9887:1; 429 struct em28xx_board board;
430
375 unsigned int stream_on:1; /* Locks streams */ 431 unsigned int stream_on:1; /* Locks streams */
376 unsigned int has_audio_class:1; 432 unsigned int has_audio_class:1;
377 unsigned int has_12mhz_i2s:1; 433 unsigned int has_alsa_audio:1;
378 unsigned int max_range_640_480:1;
379 unsigned int has_dvb:1;
380 unsigned int has_snapshot_button:1;
381 unsigned int valid:1; /* report for validated boards */
382 434
383 /* Some older em28xx chips needs a waiting time after writing */ 435 struct em28xx_fmt *format;
384 unsigned int wait_after_write;
385 436
386 /* GPIO sequences for analog and digital mode */ 437 struct em28xx_IR *ir;
387 struct em28xx_reg_seq *analog_gpio, *digital_gpio;
388 438
389 /* GPIO sequences for tuner callbacks */ 439 /* Some older em28xx chips needs a waiting time after writing */
390 struct em28xx_reg_seq *tun_analog_gpio, *tun_digital_gpio; 440 unsigned int wait_after_write;
391 441
392 int video_inputs; /* number of video inputs */
393 struct list_head devlist; 442 struct list_head devlist;
394 443
395 u32 i2s_speed; /* I2S speed for audio digital stream */ 444 u32 i2s_speed; /* I2S speed for audio digital stream */
396 445
397 enum em28xx_decoder decoder; 446 struct em28xx_audio_mode audio_mode;
398 447
399 int tuner_type; /* type of the tuner */ 448 int tuner_type; /* type of the tuner */
400 int tuner_addr; /* tuner address */ 449 int tuner_addr; /* tuner address */
@@ -409,6 +458,7 @@ struct em28xx {
409 int ctl_freq; /* selected frequency */ 458 int ctl_freq; /* selected frequency */
410 unsigned int ctl_input; /* selected input */ 459 unsigned int ctl_input; /* selected input */
411 unsigned int ctl_ainput;/* selected audio input */ 460 unsigned int ctl_ainput;/* selected audio input */
461 unsigned int ctl_aoutput;/* selected audio output */
412 int mute; 462 int mute;
413 int volume; 463 int volume;
414 /* frame properties */ 464 /* frame properties */
@@ -469,6 +519,9 @@ struct em28xx {
469 519
470 enum em28xx_mode mode; 520 enum em28xx_mode mode;
471 521
522 /* register numbers for GPO/GPIO registers */
523 u16 reg_gpo_num, reg_gpio_num;
524
472 /* Caches GPO and GPIO registers */ 525 /* Caches GPO and GPIO registers */
473 unsigned char reg_gpo, reg_gpio; 526 unsigned char reg_gpo, reg_gpio;
474 527
@@ -508,11 +561,17 @@ int em28xx_read_reg(struct em28xx *dev, u16 reg);
508int em28xx_write_regs_req(struct em28xx *dev, u8 req, u16 reg, char *buf, 561int em28xx_write_regs_req(struct em28xx *dev, u8 req, u16 reg, char *buf,
509 int len); 562 int len);
510int em28xx_write_regs(struct em28xx *dev, u16 reg, char *buf, int len); 563int em28xx_write_regs(struct em28xx *dev, u16 reg, char *buf, int len);
564int em28xx_write_reg(struct em28xx *dev, u16 reg, u8 val);
565
566int em28xx_read_ac97(struct em28xx *dev, u8 reg);
567int em28xx_write_ac97(struct em28xx *dev, u8 reg, u16 val);
568
511int em28xx_audio_analog_set(struct em28xx *dev); 569int em28xx_audio_analog_set(struct em28xx *dev);
570int em28xx_audio_setup(struct em28xx *dev);
512 571
513int em28xx_colorlevels_set_default(struct em28xx *dev); 572int em28xx_colorlevels_set_default(struct em28xx *dev);
514int em28xx_capture_start(struct em28xx *dev, int start); 573int em28xx_capture_start(struct em28xx *dev, int start);
515int em28xx_outfmt_set_yuv422(struct em28xx *dev); 574int em28xx_set_outfmt(struct em28xx *dev);
516int em28xx_resolution_set(struct em28xx *dev); 575int em28xx_resolution_set(struct em28xx *dev);
517int em28xx_set_alternate(struct em28xx *dev); 576int em28xx_set_alternate(struct em28xx *dev);
518int em28xx_init_isoc(struct em28xx *dev, int max_packets, 577int em28xx_init_isoc(struct em28xx *dev, int max_packets,
@@ -521,10 +580,20 @@ int em28xx_init_isoc(struct em28xx *dev, int max_packets,
521void em28xx_uninit_isoc(struct em28xx *dev); 580void em28xx_uninit_isoc(struct em28xx *dev);
522int em28xx_set_mode(struct em28xx *dev, enum em28xx_mode set_mode); 581int em28xx_set_mode(struct em28xx *dev, enum em28xx_mode set_mode);
523int em28xx_gpio_set(struct em28xx *dev, struct em28xx_reg_seq *gpio); 582int em28xx_gpio_set(struct em28xx *dev, struct em28xx_reg_seq *gpio);
524 583void em28xx_wake_i2c(struct em28xx *dev);
525/* Provided by em28xx-video.c */ 584void em28xx_remove_from_devlist(struct em28xx *dev);
585void em28xx_add_into_devlist(struct em28xx *dev);
586struct em28xx *em28xx_get_device(struct inode *inode,
587 enum v4l2_buf_type *fh_type,
588 int *has_radio);
526int em28xx_register_extension(struct em28xx_ops *dev); 589int em28xx_register_extension(struct em28xx_ops *dev);
527void em28xx_unregister_extension(struct em28xx_ops *dev); 590void em28xx_unregister_extension(struct em28xx_ops *dev);
591void em28xx_init_extension(struct em28xx *dev);
592void em28xx_close_extension(struct em28xx *dev);
593
594/* Provided by em28xx-video.c */
595int em28xx_register_analog_devices(struct em28xx *dev);
596void em28xx_release_analog_resources(struct em28xx *dev);
528 597
529/* Provided by em28xx-cards.c */ 598/* Provided by em28xx-cards.c */
530extern int em2800_variant_detect(struct usb_device *udev, int model); 599extern int em2800_variant_detect(struct usb_device *udev, int model);
@@ -535,9 +604,9 @@ extern struct usb_device_id em28xx_id_table[];
535extern const unsigned int em28xx_bcount; 604extern const unsigned int em28xx_bcount;
536void em28xx_set_ir(struct em28xx *dev, struct IR_i2c *ir); 605void em28xx_set_ir(struct em28xx *dev, struct IR_i2c *ir);
537int em28xx_tuner_callback(void *ptr, int component, int command, int arg); 606int em28xx_tuner_callback(void *ptr, int component, int command, int arg);
607void em28xx_release_resources(struct em28xx *dev);
538 608
539/* Provided by em28xx-input.c */ 609/* Provided by em28xx-input.c */
540/* TODO: Check if the standard get_key handlers on ir-common can be used */
541int em28xx_get_key_terratec(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw); 610int em28xx_get_key_terratec(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw);
542int em28xx_get_key_em_haup(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw); 611int em28xx_get_key_em_haup(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw);
543int em28xx_get_key_pinnacle_usb_grey(struct IR_i2c *ir, u32 *ir_key, 612int em28xx_get_key_pinnacle_usb_grey(struct IR_i2c *ir, u32 *ir_key,
@@ -545,6 +614,9 @@ int em28xx_get_key_pinnacle_usb_grey(struct IR_i2c *ir, u32 *ir_key,
545void em28xx_register_snapshot_button(struct em28xx *dev); 614void em28xx_register_snapshot_button(struct em28xx *dev);
546void em28xx_deregister_snapshot_button(struct em28xx *dev); 615void em28xx_deregister_snapshot_button(struct em28xx *dev);
547 616
617int em28xx_ir_init(struct em28xx *dev);
618int em28xx_ir_fini(struct em28xx *dev);
619
548/* printk macros */ 620/* printk macros */
549 621
550#define em28xx_err(fmt, arg...) do {\ 622#define em28xx_err(fmt, arg...) do {\
@@ -564,7 +636,7 @@ void em28xx_deregister_snapshot_button(struct em28xx *dev);
564static inline int em28xx_compression_disable(struct em28xx *dev) 636static inline int em28xx_compression_disable(struct em28xx *dev)
565{ 637{
566 /* side effect of disabling scaler and mixer */ 638 /* side effect of disabling scaler and mixer */
567 return em28xx_write_regs(dev, EM28XX_R26_COMPR, "\x00", 1); 639 return em28xx_write_reg(dev, EM28XX_R26_COMPR, 0x00);
568} 640}
569 641
570static inline int em28xx_contrast_get(struct em28xx *dev) 642static inline int em28xx_contrast_get(struct em28xx *dev)
@@ -636,7 +708,7 @@ static inline int em28xx_gamma_set(struct em28xx *dev, s32 val)
636/*FIXME: maxw should be dependent of alt mode */ 708/*FIXME: maxw should be dependent of alt mode */
637static inline unsigned int norm_maxw(struct em28xx *dev) 709static inline unsigned int norm_maxw(struct em28xx *dev)
638{ 710{
639 if (dev->max_range_640_480) 711 if (dev->board.max_range_640_480)
640 return 640; 712 return 640;
641 else 713 else
642 return 720; 714 return 720;
@@ -644,7 +716,7 @@ static inline unsigned int norm_maxw(struct em28xx *dev)
644 716
645static inline unsigned int norm_maxh(struct em28xx *dev) 717static inline unsigned int norm_maxh(struct em28xx *dev)
646{ 718{
647 if (dev->max_range_640_480) 719 if (dev->board.max_range_640_480)
648 return 480; 720 return 480;
649 else 721 else
650 return (dev->norm & V4L2_STD_625_50) ? 576 : 480; 722 return (dev->norm & V4L2_STD_625_50) ? 576 : 480;
diff --git a/drivers/media/video/et61x251/et61x251_core.c b/drivers/media/video/et61x251/et61x251_core.c
index 9d0ef96c23ff..83c07112c59d 100644
--- a/drivers/media/video/et61x251/et61x251_core.c
+++ b/drivers/media/video/et61x251/et61x251_core.c
@@ -1581,7 +1581,7 @@ et61x251_vidioc_querycap(struct et61x251_device* cam, void __user * arg)
1581 1581
1582 strlcpy(cap.card, cam->v4ldev->name, sizeof(cap.card)); 1582 strlcpy(cap.card, cam->v4ldev->name, sizeof(cap.card));
1583 if (usb_make_path(cam->usbdev, cap.bus_info, sizeof(cap.bus_info)) < 0) 1583 if (usb_make_path(cam->usbdev, cap.bus_info, sizeof(cap.bus_info)) < 0)
1584 strlcpy(cap.bus_info, cam->usbdev->dev.bus_id, 1584 strlcpy(cap.bus_info, dev_name(&cam->usbdev->dev),
1585 sizeof(cap.bus_info)); 1585 sizeof(cap.bus_info));
1586 1586
1587 if (copy_to_user(arg, &cap, sizeof(cap))) 1587 if (copy_to_user(arg, &cap, sizeof(cap)))
diff --git a/drivers/media/video/gspca/Kconfig b/drivers/media/video/gspca/Kconfig
index 6b557c057fac..ee6a691dff22 100644
--- a/drivers/media/video/gspca/Kconfig
+++ b/drivers/media/video/gspca/Kconfig
@@ -12,12 +12,13 @@ menuconfig USB_GSPCA
12 "Video For Linux" to use this driver. 12 "Video For Linux" to use this driver.
13 13
14 To compile this driver as modules, choose M here: the 14 To compile this driver as modules, choose M here: the
15 modules will be called gspca_main. 15 module will be called gspca_main.
16 16
17 17
18if USB_GSPCA && VIDEO_V4L2 18if USB_GSPCA && VIDEO_V4L2
19 19
20source "drivers/media/video/gspca/m5602/Kconfig" 20source "drivers/media/video/gspca/m5602/Kconfig"
21source "drivers/media/video/gspca/stv06xx/Kconfig"
21 22
22config USB_GSPCA_CONEX 23config USB_GSPCA_CONEX
23 tristate "Conexant Camera Driver" 24 tristate "Conexant Camera Driver"
@@ -64,6 +65,16 @@ config USB_GSPCA_OV519
64 To compile this driver as a module, choose M here: the 65 To compile this driver as a module, choose M here: the
65 module will be called gspca_ov519. 66 module will be called gspca_ov519.
66 67
68config USB_GSPCA_OV534
69 tristate "OV534 USB Camera Driver"
70 depends on VIDEO_V4L2 && USB_GSPCA
71 help
72 Say Y here if you want support for cameras based on the OV534 chip.
73 (e.g. Sony Playstation EYE)
74
75 To compile this driver as a module, choose M here: the
76 module will be called gspca_ov534.
77
67config USB_GSPCA_PAC207 78config USB_GSPCA_PAC207
68 tristate "Pixart PAC207 USB Camera Driver" 79 tristate "Pixart PAC207 USB Camera Driver"
69 depends on VIDEO_V4L2 && USB_GSPCA 80 depends on VIDEO_V4L2 && USB_GSPCA
@@ -83,10 +94,11 @@ config USB_GSPCA_PAC7311
83 module will be called gspca_pac7311. 94 module will be called gspca_pac7311.
84 95
85config USB_GSPCA_SONIXB 96config USB_GSPCA_SONIXB
86 tristate "SN9C102 USB Camera Driver" 97 tristate "SONIX Bayer USB Camera Driver"
87 depends on VIDEO_V4L2 && USB_GSPCA 98 depends on VIDEO_V4L2 && USB_GSPCA
88 help 99 help
89 Say Y here if you want support for cameras based on the SONIXB chip. 100 Say Y here if you want support for cameras based on the Sonix
101 chips with Bayer format (SN9C101, SN9C102 and SN9C103).
90 102
91 To compile this driver as a module, choose M here: the 103 To compile this driver as a module, choose M here: the
92 module will be called gspca_sonixb. 104 module will be called gspca_sonixb.
@@ -95,7 +107,8 @@ config USB_GSPCA_SONIXJ
95 tristate "SONIX JPEG USB Camera Driver" 107 tristate "SONIX JPEG USB Camera Driver"
96 depends on VIDEO_V4L2 && USB_GSPCA 108 depends on VIDEO_V4L2 && USB_GSPCA
97 help 109 help
98 Say Y here if you want support for cameras based on the SONIXJ chip. 110 Say Y here if you want support for cameras based on the Sonix
111 chips with JPEG format (SN9C102P, SN9C105 and >= SN9C110).
99 112
100 To compile this driver as a module, choose M here: the 113 To compile this driver as a module, choose M here: the
101 module will be called gspca_sonixj 114 module will be called gspca_sonixj
@@ -171,7 +184,7 @@ config USB_GSPCA_SUNPLUS
171 SPCA504(abc) SPCA533 SPCA536 chips. 184 SPCA504(abc) SPCA533 SPCA536 chips.
172 185
173 To compile this driver as a module, choose M here: the 186 To compile this driver as a module, choose M here: the
174 module will be called gspca_spca5xx. 187 module will be called gspca_sunplus.
175 188
176config USB_GSPCA_T613 189config USB_GSPCA_T613
177 tristate "T613 (JPEG Compliance) USB Camera Driver" 190 tristate "T613 (JPEG Compliance) USB Camera Driver"
diff --git a/drivers/media/video/gspca/Makefile b/drivers/media/video/gspca/Makefile
index 22734f5a6c32..bd8d9ee40504 100644
--- a/drivers/media/video/gspca/Makefile
+++ b/drivers/media/video/gspca/Makefile
@@ -4,6 +4,7 @@ obj-$(CONFIG_USB_GSPCA_ETOMS) += gspca_etoms.o
4obj-$(CONFIG_USB_GSPCA_FINEPIX) += gspca_finepix.o 4obj-$(CONFIG_USB_GSPCA_FINEPIX) += gspca_finepix.o
5obj-$(CONFIG_USB_GSPCA_MARS) += gspca_mars.o 5obj-$(CONFIG_USB_GSPCA_MARS) += gspca_mars.o
6obj-$(CONFIG_USB_GSPCA_OV519) += gspca_ov519.o 6obj-$(CONFIG_USB_GSPCA_OV519) += gspca_ov519.o
7obj-$(CONFIG_USB_GSPCA_OV534) += gspca_ov534.o
7obj-$(CONFIG_USB_GSPCA_PAC207) += gspca_pac207.o 8obj-$(CONFIG_USB_GSPCA_PAC207) += gspca_pac207.o
8obj-$(CONFIG_USB_GSPCA_PAC7311) += gspca_pac7311.o 9obj-$(CONFIG_USB_GSPCA_PAC7311) += gspca_pac7311.o
9obj-$(CONFIG_USB_GSPCA_SONIXB) += gspca_sonixb.o 10obj-$(CONFIG_USB_GSPCA_SONIXB) += gspca_sonixb.o
@@ -27,6 +28,7 @@ gspca_etoms-objs := etoms.o
27gspca_finepix-objs := finepix.o 28gspca_finepix-objs := finepix.o
28gspca_mars-objs := mars.o 29gspca_mars-objs := mars.o
29gspca_ov519-objs := ov519.o 30gspca_ov519-objs := ov519.o
31gspca_ov534-objs := ov534.o
30gspca_pac207-objs := pac207.o 32gspca_pac207-objs := pac207.o
31gspca_pac7311-objs := pac7311.o 33gspca_pac7311-objs := pac7311.o
32gspca_sonixb-objs := sonixb.o 34gspca_sonixb-objs := sonixb.o
@@ -45,4 +47,4 @@ gspca_vc032x-objs := vc032x.o
45gspca_zc3xx-objs := zc3xx.o 47gspca_zc3xx-objs := zc3xx.o
46 48
47obj-$(CONFIG_USB_M5602) += m5602/ 49obj-$(CONFIG_USB_M5602) += m5602/
48 50obj-$(CONFIG_USB_STV06XX) += stv06xx/
diff --git a/drivers/media/video/gspca/conex.c b/drivers/media/video/gspca/conex.c
index de28354ea5ba..1753f5bb3544 100644
--- a/drivers/media/video/gspca/conex.c
+++ b/drivers/media/video/gspca/conex.c
@@ -93,7 +93,7 @@ static struct ctrl sd_ctrls[] = {
93 }, 93 },
94}; 94};
95 95
96static struct v4l2_pix_format vga_mode[] = { 96static const struct v4l2_pix_format vga_mode[] = {
97 {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 97 {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
98 .bytesperline = 176, 98 .bytesperline = 176,
99 .sizeimage = 176 * 144 * 3 / 8 + 590, 99 .sizeimage = 176 * 144 * 3 / 8 + 590,
diff --git a/drivers/media/video/gspca/etoms.c b/drivers/media/video/gspca/etoms.c
index 3be30b420a26..f3cd8ff5cc92 100644
--- a/drivers/media/video/gspca/etoms.c
+++ b/drivers/media/video/gspca/etoms.c
@@ -112,7 +112,7 @@ static struct ctrl sd_ctrls[] = {
112 }, 112 },
113}; 113};
114 114
115static struct v4l2_pix_format vga_mode[] = { 115static const struct v4l2_pix_format vga_mode[] = {
116 {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, 116 {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
117 .bytesperline = 320, 117 .bytesperline = 320,
118 .sizeimage = 320 * 240, 118 .sizeimage = 320 * 240,
@@ -125,7 +125,7 @@ static struct v4l2_pix_format vga_mode[] = {
125 .priv = 0}, */ 125 .priv = 0}, */
126}; 126};
127 127
128static struct v4l2_pix_format sif_mode[] = { 128static const struct v4l2_pix_format sif_mode[] = {
129 {176, 144, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, 129 {176, 144, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
130 .bytesperline = 176, 130 .bytesperline = 176,
131 .sizeimage = 176 * 144, 131 .sizeimage = 176 * 144,
diff --git a/drivers/media/video/gspca/finepix.c b/drivers/media/video/gspca/finepix.c
index 607942fd7970..afc8b2dd307b 100644
--- a/drivers/media/video/gspca/finepix.c
+++ b/drivers/media/video/gspca/finepix.c
@@ -72,7 +72,7 @@ struct usb_fpix {
72} 72}
73 73
74/* These cameras only support 320x200. */ 74/* These cameras only support 320x200. */
75static struct v4l2_pix_format fpix_mode[1] = { 75static const struct v4l2_pix_format fpix_mode[1] = {
76 { 320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 76 { 320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
77 .bytesperline = 320, 77 .bytesperline = 320,
78 .sizeimage = 320 * 240 * 3 / 8 + 590, 78 .sizeimage = 320 * 240 * 3 / 8 + 590,
@@ -314,9 +314,6 @@ static int sd_start(struct gspca_dev *gspca_dev)
314 int ret; 314 int ret;
315 int size_ret; 315 int size_ret;
316 316
317 /* Reset bulk in endpoint */
318 usb_clear_halt(gspca_dev->dev, gspca_dev->cam.epaddr);
319
320 /* Init the device */ 317 /* Init the device */
321 memset(gspca_dev->usb_buf, 0, 12); 318 memset(gspca_dev->usb_buf, 0, 12);
322 gspca_dev->usb_buf[0] = 0xc6; 319 gspca_dev->usb_buf[0] = 0xc6;
diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c
index 02a6e9ef0337..8b9f3bde5740 100644
--- a/drivers/media/video/gspca/gspca.c
+++ b/drivers/media/video/gspca/gspca.c
@@ -30,7 +30,6 @@
30#include <linux/string.h> 30#include <linux/string.h>
31#include <linux/pagemap.h> 31#include <linux/pagemap.h>
32#include <linux/io.h> 32#include <linux/io.h>
33#include <linux/kref.h>
34#include <asm/page.h> 33#include <asm/page.h>
35#include <linux/uaccess.h> 34#include <linux/uaccess.h>
36#include <linux/jiffies.h> 35#include <linux/jiffies.h>
@@ -45,7 +44,7 @@ MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>");
45MODULE_DESCRIPTION("GSPCA USB Camera Driver"); 44MODULE_DESCRIPTION("GSPCA USB Camera Driver");
46MODULE_LICENSE("GPL"); 45MODULE_LICENSE("GPL");
47 46
48#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 3, 0) 47#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 4, 0)
49 48
50static int video_nr = -1; 49static int video_nr = -1;
51 50
@@ -150,8 +149,11 @@ static void fill_frame(struct gspca_dev *gspca_dev,
150 149
151 /* check the packet status and length */ 150 /* check the packet status and length */
152 len = urb->iso_frame_desc[i].actual_length; 151 len = urb->iso_frame_desc[i].actual_length;
153 if (len == 0) 152 if (len == 0) {
153 if (gspca_dev->empty_packet == 0)
154 gspca_dev->empty_packet = 1;
154 continue; 155 continue;
156 }
155 st = urb->iso_frame_desc[i].status; 157 st = urb->iso_frame_desc[i].status;
156 if (st) { 158 if (st) {
157 PDEBUG(D_ERR, 159 PDEBUG(D_ERR,
@@ -170,7 +172,6 @@ static void fill_frame(struct gspca_dev *gspca_dev,
170 } 172 }
171 173
172 /* resubmit the URB */ 174 /* resubmit the URB */
173 urb->status = 0;
174 st = usb_submit_urb(urb, GFP_ATOMIC); 175 st = usb_submit_urb(urb, GFP_ATOMIC);
175 if (st < 0) 176 if (st < 0)
176 PDEBUG(D_ERR|D_PACK, "usb_submit_urb() ret %d", st); 177 PDEBUG(D_ERR|D_PACK, "usb_submit_urb() ret %d", st);
@@ -200,11 +201,18 @@ static void bulk_irq(struct urb *urb
200{ 201{
201 struct gspca_dev *gspca_dev = (struct gspca_dev *) urb->context; 202 struct gspca_dev *gspca_dev = (struct gspca_dev *) urb->context;
202 struct gspca_frame *frame; 203 struct gspca_frame *frame;
204 int st;
203 205
204 PDEBUG(D_PACK, "bulk irq"); 206 PDEBUG(D_PACK, "bulk irq");
205 if (!gspca_dev->streaming) 207 if (!gspca_dev->streaming)
206 return; 208 return;
207 if (urb->status != 0 && urb->status != -ECONNRESET) { 209 switch (urb->status) {
210 case 0:
211 break;
212 case -ECONNRESET:
213 urb->status = 0;
214 break;
215 default:
208#ifdef CONFIG_PM 216#ifdef CONFIG_PM
209 if (!gspca_dev->frozen) 217 if (!gspca_dev->frozen)
210#endif 218#endif
@@ -223,6 +231,13 @@ static void bulk_irq(struct urb *urb
223 urb->transfer_buffer, 231 urb->transfer_buffer,
224 urb->actual_length); 232 urb->actual_length);
225 } 233 }
234
235 /* resubmit the URB */
236 if (gspca_dev->cam.bulk_nurbs != 0) {
237 st = usb_submit_urb(urb, GFP_ATOMIC);
238 if (st < 0)
239 PDEBUG(D_ERR|D_PACK, "usb_submit_urb() ret %d", st);
240 }
226} 241}
227 242
228/* 243/*
@@ -285,7 +300,6 @@ struct gspca_frame *gspca_frame_add(struct gspca_dev *gspca_dev,
285 frame->v4l2_buf.bytesused = frame->data_end - frame->data; 300 frame->v4l2_buf.bytesused = frame->data_end - frame->data;
286 frame->v4l2_buf.flags &= ~V4L2_BUF_FLAG_QUEUED; 301 frame->v4l2_buf.flags &= ~V4L2_BUF_FLAG_QUEUED;
287 frame->v4l2_buf.flags |= V4L2_BUF_FLAG_DONE; 302 frame->v4l2_buf.flags |= V4L2_BUF_FLAG_DONE;
288 atomic_inc(&gspca_dev->nevent);
289 wake_up_interruptible(&gspca_dev->wq); /* event = new frame */ 303 wake_up_interruptible(&gspca_dev->wq); /* event = new frame */
290 i = (gspca_dev->fr_i + 1) % gspca_dev->nframes; 304 i = (gspca_dev->fr_i + 1) % gspca_dev->nframes;
291 gspca_dev->fr_i = i; 305 gspca_dev->fr_i = i;
@@ -379,7 +393,6 @@ static int frame_alloc(struct gspca_dev *gspca_dev,
379 gspca_dev->fr_i = gspca_dev->fr_o = gspca_dev->fr_q = 0; 393 gspca_dev->fr_i = gspca_dev->fr_o = gspca_dev->fr_q = 0;
380 gspca_dev->last_packet_type = DISCARD_PACKET; 394 gspca_dev->last_packet_type = DISCARD_PACKET;
381 gspca_dev->sequence = 0; 395 gspca_dev->sequence = 0;
382 atomic_set(&gspca_dev->nevent, 0);
383 return 0; 396 return 0;
384} 397}
385 398
@@ -520,11 +533,14 @@ static int create_urbs(struct gspca_dev *gspca_dev,
520 nurbs = DEF_NURBS; 533 nurbs = DEF_NURBS;
521 } else { /* bulk */ 534 } else { /* bulk */
522 npkt = 0; 535 npkt = 0;
523 bsize = gspca_dev->cam. bulk_size; 536 bsize = gspca_dev->cam.bulk_size;
524 if (bsize == 0) 537 if (bsize == 0)
525 bsize = psize; 538 bsize = psize;
526 PDEBUG(D_STREAM, "bulk bsize:%d", bsize); 539 PDEBUG(D_STREAM, "bulk bsize:%d", bsize);
527 nurbs = 1; 540 if (gspca_dev->cam.bulk_nurbs != 0)
541 nurbs = gspca_dev->cam.bulk_nurbs;
542 else
543 nurbs = 1;
528 } 544 }
529 545
530 gspca_dev->nurbs = nurbs; 546 gspca_dev->nurbs = nurbs;
@@ -597,6 +613,12 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev)
597 if (ret < 0) 613 if (ret < 0)
598 goto out; 614 goto out;
599 615
616 /* clear the bulk endpoint */
617 if (gspca_dev->alt == 0) /* if bulk transfer */
618 usb_clear_halt(gspca_dev->dev,
619 usb_rcvintpipe(gspca_dev->dev,
620 gspca_dev->cam.epaddr));
621
600 /* start the cam */ 622 /* start the cam */
601 ret = gspca_dev->sd_desc->start(gspca_dev); 623 ret = gspca_dev->sd_desc->start(gspca_dev);
602 if (ret < 0) { 624 if (ret < 0) {
@@ -604,10 +626,9 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev)
604 goto out; 626 goto out;
605 } 627 }
606 gspca_dev->streaming = 1; 628 gspca_dev->streaming = 1;
607 atomic_set(&gspca_dev->nevent, 0);
608 629
609 /* bulk transfers are started by the subdriver */ 630 /* some bulk transfers are started by the subdriver */
610 if (gspca_dev->alt == 0) 631 if (gspca_dev->alt == 0 && gspca_dev->cam.bulk_nurbs == 0)
611 break; 632 break;
612 633
613 /* submit the URBs */ 634 /* submit the URBs */
@@ -618,8 +639,11 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev)
618 "usb_submit_urb [%d] err %d", n, ret); 639 "usb_submit_urb [%d] err %d", n, ret);
619 gspca_dev->streaming = 0; 640 gspca_dev->streaming = 0;
620 destroy_urbs(gspca_dev); 641 destroy_urbs(gspca_dev);
621 if (ret == -ENOSPC) 642 if (ret == -ENOSPC) {
643 msleep(20); /* wait for kill
644 * complete */
622 break; /* try the previous alt */ 645 break; /* try the previous alt */
646 }
623 goto out; 647 goto out;
624 } 648 }
625 } 649 }
@@ -637,7 +661,7 @@ static int gspca_set_alt0(struct gspca_dev *gspca_dev)
637 661
638 ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, 0); 662 ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, 0);
639 if (ret < 0) 663 if (ret < 0)
640 PDEBUG(D_ERR|D_STREAM, "set interface 0 err %d", ret); 664 PDEBUG(D_ERR|D_STREAM, "set alt 0 err %d", ret);
641 return ret; 665 return ret;
642} 666}
643 667
@@ -645,7 +669,6 @@ static int gspca_set_alt0(struct gspca_dev *gspca_dev)
645static void gspca_stream_off(struct gspca_dev *gspca_dev) 669static void gspca_stream_off(struct gspca_dev *gspca_dev)
646{ 670{
647 gspca_dev->streaming = 0; 671 gspca_dev->streaming = 0;
648 atomic_set(&gspca_dev->nevent, 0);
649 if (gspca_dev->present 672 if (gspca_dev->present
650 && gspca_dev->sd_desc->stopN) 673 && gspca_dev->sd_desc->stopN)
651 gspca_dev->sd_desc->stopN(gspca_dev); 674 gspca_dev->sd_desc->stopN(gspca_dev);
@@ -727,7 +750,7 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
727 if (fmtdesc->index == index) 750 if (fmtdesc->index == index)
728 break; /* new format */ 751 break; /* new format */
729 index++; 752 index++;
730 if (index >= sizeof fmt_tb / sizeof fmt_tb[0]) 753 if (index >= ARRAY_SIZE(fmt_tb))
731 return -EINVAL; 754 return -EINVAL;
732 } 755 }
733 } 756 }
@@ -752,8 +775,6 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
752 struct gspca_dev *gspca_dev = priv; 775 struct gspca_dev *gspca_dev = priv;
753 int mode; 776 int mode;
754 777
755 if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
756 return -EINVAL;
757 mode = gspca_dev->curr_mode; 778 mode = gspca_dev->curr_mode;
758 memcpy(&fmt->fmt.pix, &gspca_dev->cam.cam_mode[mode], 779 memcpy(&fmt->fmt.pix, &gspca_dev->cam.cam_mode[mode],
759 sizeof fmt->fmt.pix); 780 sizeof fmt->fmt.pix);
@@ -765,8 +786,6 @@ static int try_fmt_vid_cap(struct gspca_dev *gspca_dev,
765{ 786{
766 int w, h, mode, mode2; 787 int w, h, mode, mode2;
767 788
768 if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
769 return -EINVAL;
770 w = fmt->fmt.pix.width; 789 w = fmt->fmt.pix.width;
771 h = fmt->fmt.pix.height; 790 h = fmt->fmt.pix.height;
772 791
@@ -846,11 +865,11 @@ out:
846 return ret; 865 return ret;
847} 866}
848 867
849static void gspca_delete(struct kref *kref) 868static void gspca_release(struct video_device *vfd)
850{ 869{
851 struct gspca_dev *gspca_dev = container_of(kref, struct gspca_dev, kref); 870 struct gspca_dev *gspca_dev = container_of(vfd, struct gspca_dev, vdev);
852 871
853 PDEBUG(D_STREAM, "device deleted"); 872 PDEBUG(D_STREAM, "device released");
854 873
855 kfree(gspca_dev->usb_buf); 874 kfree(gspca_dev->usb_buf);
856 kfree(gspca_dev); 875 kfree(gspca_dev);
@@ -862,7 +881,7 @@ static int dev_open(struct inode *inode, struct file *file)
862 int ret; 881 int ret;
863 882
864 PDEBUG(D_STREAM, "%s open", current->comm); 883 PDEBUG(D_STREAM, "%s open", current->comm);
865 gspca_dev = video_drvdata(file); 884 gspca_dev = (struct gspca_dev *) video_devdata(file);
866 if (mutex_lock_interruptible(&gspca_dev->queue_lock)) 885 if (mutex_lock_interruptible(&gspca_dev->queue_lock))
867 return -ERESTARTSYS; 886 return -ERESTARTSYS;
868 if (!gspca_dev->present) { 887 if (!gspca_dev->present) {
@@ -883,17 +902,14 @@ static int dev_open(struct inode *inode, struct file *file)
883 902
884 gspca_dev->users++; 903 gspca_dev->users++;
885 904
886 /* one more user */
887 kref_get(&gspca_dev->kref);
888
889 file->private_data = gspca_dev; 905 file->private_data = gspca_dev;
890#ifdef GSPCA_DEBUG 906#ifdef GSPCA_DEBUG
891 /* activate the v4l2 debug */ 907 /* activate the v4l2 debug */
892 if (gspca_debug & D_V4L2) 908 if (gspca_debug & D_V4L2)
893 gspca_dev->vdev->debug |= V4L2_DEBUG_IOCTL 909 gspca_dev->vdev.debug |= V4L2_DEBUG_IOCTL
894 | V4L2_DEBUG_IOCTL_ARG; 910 | V4L2_DEBUG_IOCTL_ARG;
895 else 911 else
896 gspca_dev->vdev->debug &= ~(V4L2_DEBUG_IOCTL 912 gspca_dev->vdev.debug &= ~(V4L2_DEBUG_IOCTL
897 | V4L2_DEBUG_IOCTL_ARG); 913 | V4L2_DEBUG_IOCTL_ARG);
898#endif 914#endif
899 ret = 0; 915 ret = 0;
@@ -932,8 +948,6 @@ static int dev_close(struct inode *inode, struct file *file)
932 948
933 PDEBUG(D_STREAM, "close done"); 949 PDEBUG(D_STREAM, "close done");
934 950
935 kref_put(&gspca_dev->kref, gspca_delete);
936
937 return 0; 951 return 0;
938} 952}
939 953
@@ -1053,6 +1067,35 @@ static int vidioc_g_ctrl(struct file *file, void *priv,
1053 return -EINVAL; 1067 return -EINVAL;
1054} 1068}
1055 1069
1070/*fixme: have an audio flag in gspca_dev?*/
1071static int vidioc_s_audio(struct file *file, void *priv,
1072 struct v4l2_audio *audio)
1073{
1074 if (audio->index != 0)
1075 return -EINVAL;
1076 return 0;
1077}
1078
1079static int vidioc_g_audio(struct file *file, void *priv,
1080 struct v4l2_audio *audio)
1081{
1082 memset(audio, 0, sizeof *audio);
1083 strcpy(audio->name, "Microphone");
1084 return 0;
1085}
1086
1087static int vidioc_enumaudio(struct file *file, void *priv,
1088 struct v4l2_audio *audio)
1089{
1090 if (audio->index != 0)
1091 return -EINVAL;
1092
1093 strcpy(audio->name, "Microphone");
1094 audio->capability = 0;
1095 audio->mode = 0;
1096 return 0;
1097}
1098
1056static int vidioc_querymenu(struct file *file, void *priv, 1099static int vidioc_querymenu(struct file *file, void *priv,
1057 struct v4l2_querymenu *qmenu) 1100 struct v4l2_querymenu *qmenu)
1058{ 1101{
@@ -1096,8 +1139,6 @@ static int vidioc_reqbufs(struct file *file, void *priv,
1096 struct gspca_dev *gspca_dev = priv; 1139 struct gspca_dev *gspca_dev = priv;
1097 int i, ret = 0; 1140 int i, ret = 0;
1098 1141
1099 if (rb->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1100 return -EINVAL;
1101 switch (rb->memory) { 1142 switch (rb->memory) {
1102 case GSPCA_MEMORY_READ: /* (internal call) */ 1143 case GSPCA_MEMORY_READ: /* (internal call) */
1103 case V4L2_MEMORY_MMAP: 1144 case V4L2_MEMORY_MMAP:
@@ -1162,8 +1203,7 @@ static int vidioc_querybuf(struct file *file, void *priv,
1162 struct gspca_dev *gspca_dev = priv; 1203 struct gspca_dev *gspca_dev = priv;
1163 struct gspca_frame *frame; 1204 struct gspca_frame *frame;
1164 1205
1165 if (v4l2_buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE 1206 if (v4l2_buf->index < 0
1166 || v4l2_buf->index < 0
1167 || v4l2_buf->index >= gspca_dev->nframes) 1207 || v4l2_buf->index >= gspca_dev->nframes)
1168 return -EINVAL; 1208 return -EINVAL;
1169 1209
@@ -1186,7 +1226,8 @@ static int vidioc_streamon(struct file *file, void *priv,
1186 ret = -ENODEV; 1226 ret = -ENODEV;
1187 goto out; 1227 goto out;
1188 } 1228 }
1189 if (gspca_dev->nframes == 0) { 1229 if (gspca_dev->nframes == 0
1230 || !(gspca_dev->frame[0].v4l2_buf.flags & V4L2_BUF_FLAG_QUEUED)) {
1190 ret = -EINVAL; 1231 ret = -EINVAL;
1191 goto out; 1232 goto out;
1192 } 1233 }
@@ -1236,7 +1277,6 @@ static int vidioc_streamoff(struct file *file, void *priv,
1236 gspca_dev->fr_i = gspca_dev->fr_o = gspca_dev->fr_q = 0; 1277 gspca_dev->fr_i = gspca_dev->fr_o = gspca_dev->fr_q = 0;
1237 gspca_dev->last_packet_type = DISCARD_PACKET; 1278 gspca_dev->last_packet_type = DISCARD_PACKET;
1238 gspca_dev->sequence = 0; 1279 gspca_dev->sequence = 0;
1239 atomic_set(&gspca_dev->nevent, 0);
1240 ret = 0; 1280 ret = 0;
1241out: 1281out:
1242 mutex_unlock(&gspca_dev->queue_lock); 1282 mutex_unlock(&gspca_dev->queue_lock);
@@ -1281,6 +1321,17 @@ static int vidioc_g_parm(struct file *filp, void *priv,
1281 memset(parm, 0, sizeof *parm); 1321 memset(parm, 0, sizeof *parm);
1282 parm->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 1322 parm->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1283 parm->parm.capture.readbuffers = gspca_dev->nbufread; 1323 parm->parm.capture.readbuffers = gspca_dev->nbufread;
1324
1325 if (gspca_dev->sd_desc->get_streamparm) {
1326 int ret;
1327
1328 if (mutex_lock_interruptible(&gspca_dev->usb_lock))
1329 return -ERESTARTSYS;
1330 ret = gspca_dev->sd_desc->get_streamparm(gspca_dev, parm);
1331 mutex_unlock(&gspca_dev->usb_lock);
1332 return ret;
1333 }
1334
1284 return 0; 1335 return 0;
1285} 1336}
1286 1337
@@ -1295,6 +1346,17 @@ static int vidioc_s_parm(struct file *filp, void *priv,
1295 parm->parm.capture.readbuffers = gspca_dev->nbufread; 1346 parm->parm.capture.readbuffers = gspca_dev->nbufread;
1296 else 1347 else
1297 gspca_dev->nbufread = n; 1348 gspca_dev->nbufread = n;
1349
1350 if (gspca_dev->sd_desc->set_streamparm) {
1351 int ret;
1352
1353 if (mutex_lock_interruptible(&gspca_dev->usb_lock))
1354 return -ERESTARTSYS;
1355 ret = gspca_dev->sd_desc->set_streamparm(gspca_dev, parm);
1356 mutex_unlock(&gspca_dev->usb_lock);
1357 return ret;
1358 }
1359
1298 return 0; 1360 return 0;
1299} 1361}
1300 1362
@@ -1440,33 +1502,22 @@ static int frame_wait(struct gspca_dev *gspca_dev,
1440 i = gspca_dev->fr_o; 1502 i = gspca_dev->fr_o;
1441 j = gspca_dev->fr_queue[i]; 1503 j = gspca_dev->fr_queue[i];
1442 frame = &gspca_dev->frame[j]; 1504 frame = &gspca_dev->frame[j];
1443 if (frame->v4l2_buf.flags & V4L2_BUF_FLAG_DONE) {
1444 atomic_dec(&gspca_dev->nevent);
1445 goto ok;
1446 }
1447 if (nonblock_ing) /* no frame yet */
1448 return -EAGAIN;
1449 1505
1450 /* wait till a frame is ready */ 1506 if (!(frame->v4l2_buf.flags & V4L2_BUF_FLAG_DONE)) {
1451 for (;;) { 1507 if (nonblock_ing)
1508 return -EAGAIN;
1509
1510 /* wait till a frame is ready */
1452 ret = wait_event_interruptible_timeout(gspca_dev->wq, 1511 ret = wait_event_interruptible_timeout(gspca_dev->wq,
1453 atomic_read(&gspca_dev->nevent) > 0, 1512 (frame->v4l2_buf.flags & V4L2_BUF_FLAG_DONE) ||
1454 msecs_to_jiffies(3000)); 1513 !gspca_dev->streaming || !gspca_dev->present,
1455 if (ret <= 0) { 1514 msecs_to_jiffies(3000));
1456 if (ret < 0) 1515 if (ret < 0)
1457 return ret; /* interrupt */ 1516 return ret;
1458 return -EIO; /* timeout */ 1517 if (ret == 0 || !gspca_dev->streaming || !gspca_dev->present)
1459 }
1460 atomic_dec(&gspca_dev->nevent);
1461 if (!gspca_dev->streaming || !gspca_dev->present)
1462 return -EIO; 1518 return -EIO;
1463 i = gspca_dev->fr_o;
1464 j = gspca_dev->fr_queue[i];
1465 frame = &gspca_dev->frame[j];
1466 if (frame->v4l2_buf.flags & V4L2_BUF_FLAG_DONE)
1467 break;
1468 } 1519 }
1469ok: 1520
1470 gspca_dev->fr_o = (i + 1) % gspca_dev->nframes; 1521 gspca_dev->fr_o = (i + 1) % gspca_dev->nframes;
1471 PDEBUG(D_FRAM, "frame wait q:%d i:%d o:%d", 1522 PDEBUG(D_FRAM, "frame wait q:%d i:%d o:%d",
1472 gspca_dev->fr_q, 1523 gspca_dev->fr_q,
@@ -1494,8 +1545,6 @@ static int vidioc_dqbuf(struct file *file, void *priv,
1494 int i, ret; 1545 int i, ret;
1495 1546
1496 PDEBUG(D_FRAM, "dqbuf"); 1547 PDEBUG(D_FRAM, "dqbuf");
1497 if (v4l2_buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1498 return -EINVAL;
1499 if (v4l2_buf->memory != gspca_dev->memory) 1548 if (v4l2_buf->memory != gspca_dev->memory)
1500 return -EINVAL; 1549 return -EINVAL;
1501 1550
@@ -1550,8 +1599,6 @@ static int vidioc_qbuf(struct file *file, void *priv,
1550 int i, index, ret; 1599 int i, index, ret;
1551 1600
1552 PDEBUG(D_FRAM, "qbuf %d", v4l2_buf->index); 1601 PDEBUG(D_FRAM, "qbuf %d", v4l2_buf->index);
1553 if (v4l2_buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1554 return -EINVAL;
1555 1602
1556 if (mutex_lock_interruptible(&gspca_dev->queue_lock)) 1603 if (mutex_lock_interruptible(&gspca_dev->queue_lock))
1557 return -ERESTARTSYS; 1604 return -ERESTARTSYS;
@@ -1761,7 +1808,7 @@ static struct file_operations dev_fops = {
1761 .release = dev_close, 1808 .release = dev_close,
1762 .read = dev_read, 1809 .read = dev_read,
1763 .mmap = dev_mmap, 1810 .mmap = dev_mmap,
1764 .ioctl = video_ioctl2, 1811 .unlocked_ioctl = __video_ioctl2,
1765#ifdef CONFIG_COMPAT 1812#ifdef CONFIG_COMPAT
1766 .compat_ioctl = v4l_compat_ioctl32, 1813 .compat_ioctl = v4l_compat_ioctl32,
1767#endif 1814#endif
@@ -1781,6 +1828,9 @@ static const struct v4l2_ioctl_ops dev_ioctl_ops = {
1781 .vidioc_queryctrl = vidioc_queryctrl, 1828 .vidioc_queryctrl = vidioc_queryctrl,
1782 .vidioc_g_ctrl = vidioc_g_ctrl, 1829 .vidioc_g_ctrl = vidioc_g_ctrl,
1783 .vidioc_s_ctrl = vidioc_s_ctrl, 1830 .vidioc_s_ctrl = vidioc_s_ctrl,
1831 .vidioc_g_audio = vidioc_g_audio,
1832 .vidioc_s_audio = vidioc_s_audio,
1833 .vidioc_enumaudio = vidioc_enumaudio,
1784 .vidioc_querymenu = vidioc_querymenu, 1834 .vidioc_querymenu = vidioc_querymenu,
1785 .vidioc_enum_input = vidioc_enum_input, 1835 .vidioc_enum_input = vidioc_enum_input,
1786 .vidioc_g_input = vidioc_g_input, 1836 .vidioc_g_input = vidioc_g_input,
@@ -1802,7 +1852,7 @@ static struct video_device gspca_template = {
1802 .name = "gspca main driver", 1852 .name = "gspca main driver",
1803 .fops = &dev_fops, 1853 .fops = &dev_fops,
1804 .ioctl_ops = &dev_ioctl_ops, 1854 .ioctl_ops = &dev_ioctl_ops,
1805 .release = video_device_release, 1855 .release = gspca_release,
1806 .minor = -1, 1856 .minor = -1,
1807}; 1857};
1808 1858
@@ -1840,7 +1890,6 @@ int gspca_dev_probe(struct usb_interface *intf,
1840 err("couldn't kzalloc gspca struct"); 1890 err("couldn't kzalloc gspca struct");
1841 return -ENOMEM; 1891 return -ENOMEM;
1842 } 1892 }
1843 kref_init(&gspca_dev->kref);
1844 gspca_dev->usb_buf = kmalloc(USB_BUF_SZ, GFP_KERNEL); 1893 gspca_dev->usb_buf = kmalloc(USB_BUF_SZ, GFP_KERNEL);
1845 if (!gspca_dev->usb_buf) { 1894 if (!gspca_dev->usb_buf) {
1846 err("out of memory"); 1895 err("out of memory");
@@ -1852,12 +1901,13 @@ int gspca_dev_probe(struct usb_interface *intf,
1852 gspca_dev->nbalt = intf->num_altsetting; 1901 gspca_dev->nbalt = intf->num_altsetting;
1853 gspca_dev->sd_desc = sd_desc; 1902 gspca_dev->sd_desc = sd_desc;
1854 gspca_dev->nbufread = 2; 1903 gspca_dev->nbufread = 2;
1904 gspca_dev->empty_packet = -1; /* don't check the empty packets */
1855 1905
1856 /* configure the subdriver and initialize the USB device */ 1906 /* configure the subdriver and initialize the USB device */
1857 ret = gspca_dev->sd_desc->config(gspca_dev, id); 1907 ret = sd_desc->config(gspca_dev, id);
1858 if (ret < 0) 1908 if (ret < 0)
1859 goto out; 1909 goto out;
1860 ret = gspca_dev->sd_desc->init(gspca_dev); 1910 ret = sd_desc->init(gspca_dev);
1861 if (ret < 0) 1911 if (ret < 0)
1862 goto out; 1912 goto out;
1863 ret = gspca_set_alt0(gspca_dev); 1913 ret = gspca_set_alt0(gspca_dev);
@@ -1871,18 +1921,15 @@ int gspca_dev_probe(struct usb_interface *intf,
1871 init_waitqueue_head(&gspca_dev->wq); 1921 init_waitqueue_head(&gspca_dev->wq);
1872 1922
1873 /* init video stuff */ 1923 /* init video stuff */
1874 gspca_dev->vdev = video_device_alloc(); 1924 memcpy(&gspca_dev->vdev, &gspca_template, sizeof gspca_template);
1875 memcpy(gspca_dev->vdev, &gspca_template, sizeof gspca_template); 1925 gspca_dev->vdev.parent = &dev->dev;
1876 gspca_dev->vdev->parent = &dev->dev;
1877 gspca_dev->module = module; 1926 gspca_dev->module = module;
1878 gspca_dev->present = 1; 1927 gspca_dev->present = 1;
1879 video_set_drvdata(gspca_dev->vdev, gspca_dev); 1928 ret = video_register_device(&gspca_dev->vdev,
1880 ret = video_register_device(gspca_dev->vdev,
1881 VFL_TYPE_GRABBER, 1929 VFL_TYPE_GRABBER,
1882 video_nr); 1930 video_nr);
1883 if (ret < 0) { 1931 if (ret < 0) {
1884 err("video_register_device err %d", ret); 1932 err("video_register_device err %d", ret);
1885 video_device_release(gspca_dev->vdev);
1886 goto out; 1933 goto out;
1887 } 1934 }
1888 1935
@@ -1906,15 +1953,14 @@ void gspca_disconnect(struct usb_interface *intf)
1906{ 1953{
1907 struct gspca_dev *gspca_dev = usb_get_intfdata(intf); 1954 struct gspca_dev *gspca_dev = usb_get_intfdata(intf);
1908 1955
1909 usb_set_intfdata(intf, NULL);
1910
1911/* We don't want people trying to open up the device */
1912 video_unregister_device(gspca_dev->vdev);
1913
1914 gspca_dev->present = 0; 1956 gspca_dev->present = 0;
1915 gspca_dev->streaming = 0; 1957 gspca_dev->streaming = 0;
1916 1958
1917 kref_put(&gspca_dev->kref, gspca_delete); 1959 usb_set_intfdata(intf, NULL);
1960
1961 /* release the device */
1962 /* (this will call gspca_release() immediatly or on last close) */
1963 video_unregister_device(&gspca_dev->vdev);
1918 1964
1919 PDEBUG(D_PROBE, "disconnect complete"); 1965 PDEBUG(D_PROBE, "disconnect complete");
1920} 1966}
@@ -1992,7 +2038,7 @@ int gspca_auto_gain_n_exposure(struct gspca_dev *gspca_dev, int avg_lum,
1992 desired lumination fast (with the risc of a slight overshoot) */ 2038 desired lumination fast (with the risc of a slight overshoot) */
1993 steps = abs(desired_avg_lum - avg_lum) / deadzone; 2039 steps = abs(desired_avg_lum - avg_lum) / deadzone;
1994 2040
1995 PDEBUG(D_FRAM, "autogain: lum: %d, desired: %d, steps: %d\n", 2041 PDEBUG(D_FRAM, "autogain: lum: %d, desired: %d, steps: %d",
1996 avg_lum, desired_avg_lum, steps); 2042 avg_lum, desired_avg_lum, steps);
1997 2043
1998 for (i = 0; i < steps; i++) { 2044 for (i = 0; i < steps; i++) {
diff --git a/drivers/media/video/gspca/gspca.h b/drivers/media/video/gspca/gspca.h
index d25e8d69373b..c90af9cb1e07 100644
--- a/drivers/media/video/gspca/gspca.h
+++ b/drivers/media/video/gspca/gspca.h
@@ -56,8 +56,12 @@ extern int gspca_debug;
56/* device information - set at probe time */ 56/* device information - set at probe time */
57struct cam { 57struct cam {
58 int bulk_size; /* buffer size when image transfer by bulk */ 58 int bulk_size; /* buffer size when image transfer by bulk */
59 struct v4l2_pix_format *cam_mode; /* size nmodes */ 59 const struct v4l2_pix_format *cam_mode; /* size nmodes */
60 char nmodes; 60 char nmodes;
61 __u8 bulk_nurbs; /* number of URBs in bulk mode
62 * - cannot be > MAX_NURBS
63 * - when 0 and bulk_size != 0 means
64 * 1 URB and submit done by subdriver */
61 __u8 epaddr; 65 __u8 epaddr;
62}; 66};
63 67
@@ -70,6 +74,8 @@ typedef void (*cam_v_op) (struct gspca_dev *);
70typedef int (*cam_cf_op) (struct gspca_dev *, const struct usb_device_id *); 74typedef int (*cam_cf_op) (struct gspca_dev *, const struct usb_device_id *);
71typedef int (*cam_jpg_op) (struct gspca_dev *, 75typedef int (*cam_jpg_op) (struct gspca_dev *,
72 struct v4l2_jpegcompression *); 76 struct v4l2_jpegcompression *);
77typedef int (*cam_streamparm_op) (struct gspca_dev *,
78 struct v4l2_streamparm *);
73typedef int (*cam_qmnu_op) (struct gspca_dev *, 79typedef int (*cam_qmnu_op) (struct gspca_dev *,
74 struct v4l2_querymenu *); 80 struct v4l2_querymenu *);
75typedef void (*cam_pkt_op) (struct gspca_dev *gspca_dev, 81typedef void (*cam_pkt_op) (struct gspca_dev *gspca_dev,
@@ -102,6 +108,8 @@ struct sd_desc {
102 cam_jpg_op get_jcomp; 108 cam_jpg_op get_jcomp;
103 cam_jpg_op set_jcomp; 109 cam_jpg_op set_jcomp;
104 cam_qmnu_op querymenu; 110 cam_qmnu_op querymenu;
111 cam_streamparm_op get_streamparm;
112 cam_streamparm_op set_streamparm;
105}; 113};
106 114
107/* packet types when moving from iso buf to frame buf */ 115/* packet types when moving from iso buf to frame buf */
@@ -120,10 +128,9 @@ struct gspca_frame {
120}; 128};
121 129
122struct gspca_dev { 130struct gspca_dev {
123 struct video_device *vdev; 131 struct video_device vdev; /* !! must be the first item */
124 struct module *module; /* subdriver handling the device */ 132 struct module *module; /* subdriver handling the device */
125 struct usb_device *dev; 133 struct usb_device *dev;
126 struct kref kref;
127 struct file *capt_file; /* file doing video capture */ 134 struct file *capt_file; /* file doing video capture */
128 135
129 struct cam cam; /* device information */ 136 struct cam cam; /* device information */
@@ -142,22 +149,20 @@ struct gspca_dev {
142 char fr_q; /* next frame to queue */ 149 char fr_q; /* next frame to queue */
143 char fr_o; /* next frame to dequeue */ 150 char fr_o; /* next frame to dequeue */
144 signed char fr_queue[GSPCA_MAX_FRAMES]; /* frame queue */ 151 signed char fr_queue[GSPCA_MAX_FRAMES]; /* frame queue */
145 char last_packet_type; 152 __u8 last_packet_type;
153 __s8 empty_packet; /* if (-1) don't check empty packets */
154 __u8 streaming;
146 155
147 __u8 iface; /* USB interface number */
148 __u8 alt; /* USB alternate setting */
149 __u8 curr_mode; /* current camera mode */ 156 __u8 curr_mode; /* current camera mode */
150 __u32 pixfmt; /* current mode parameters */ 157 __u32 pixfmt; /* current mode parameters */
151 __u16 width; 158 __u16 width;
152 __u16 height; 159 __u16 height;
160 __u32 sequence; /* frame sequence number */
153 161
154 atomic_t nevent; /* number of frames done */
155 wait_queue_head_t wq; /* wait queue */ 162 wait_queue_head_t wq; /* wait queue */
156 struct mutex usb_lock; /* usb exchange protection */ 163 struct mutex usb_lock; /* usb exchange protection */
157 struct mutex read_lock; /* read protection */ 164 struct mutex read_lock; /* read protection */
158 struct mutex queue_lock; /* ISOC queue protection */ 165 struct mutex queue_lock; /* ISOC queue protection */
159 __u32 sequence; /* frame sequence number */
160 char streaming;
161#ifdef CONFIG_PM 166#ifdef CONFIG_PM
162 char frozen; /* suspend - resume */ 167 char frozen; /* suspend - resume */
163#endif 168#endif
@@ -166,6 +171,8 @@ struct gspca_dev {
166 char nbufread; /* number of buffers for read() */ 171 char nbufread; /* number of buffers for read() */
167 char nurbs; /* number of allocated URBs */ 172 char nurbs; /* number of allocated URBs */
168 char memory; /* memory type (V4L2_MEMORY_xxx) */ 173 char memory; /* memory type (V4L2_MEMORY_xxx) */
174 __u8 iface; /* USB interface number */
175 __u8 alt; /* USB alternate setting */
169 __u8 nbalt; /* number of USB alternate settings */ 176 __u8 nbalt; /* number of USB alternate settings */
170}; 177};
171 178
diff --git a/drivers/media/video/gspca/m5602/m5602_bridge.h b/drivers/media/video/gspca/m5602/m5602_bridge.h
index 1a37ae4bc82d..a3f3b7a0c7e7 100644
--- a/drivers/media/video/gspca/m5602/m5602_bridge.h
+++ b/drivers/media/video/gspca/m5602/m5602_bridge.h
@@ -25,59 +25,59 @@
25 25
26/*****************************************************************************/ 26/*****************************************************************************/
27 27
28#define M5602_XB_SENSOR_TYPE 0x00 28#define M5602_XB_SENSOR_TYPE 0x00
29#define M5602_XB_SENSOR_CTRL 0x01 29#define M5602_XB_SENSOR_CTRL 0x01
30#define M5602_XB_LINE_OF_FRAME_H 0x02 30#define M5602_XB_LINE_OF_FRAME_H 0x02
31#define M5602_XB_LINE_OF_FRAME_L 0x03 31#define M5602_XB_LINE_OF_FRAME_L 0x03
32#define M5602_XB_PIX_OF_LINE_H 0x04 32#define M5602_XB_PIX_OF_LINE_H 0x04
33#define M5602_XB_PIX_OF_LINE_L 0x05 33#define M5602_XB_PIX_OF_LINE_L 0x05
34#define M5602_XB_VSYNC_PARA 0x06 34#define M5602_XB_VSYNC_PARA 0x06
35#define M5602_XB_HSYNC_PARA 0x07 35#define M5602_XB_HSYNC_PARA 0x07
36#define M5602_XB_TEST_MODE_1 0x08 36#define M5602_XB_TEST_MODE_1 0x08
37#define M5602_XB_TEST_MODE_2 0x09 37#define M5602_XB_TEST_MODE_2 0x09
38#define M5602_XB_SIG_INI 0x0a 38#define M5602_XB_SIG_INI 0x0a
39#define M5602_XB_DS_PARA 0x0e 39#define M5602_XB_DS_PARA 0x0e
40#define M5602_XB_TRIG_PARA 0x0f 40#define M5602_XB_TRIG_PARA 0x0f
41#define M5602_XB_CLK_PD 0x10 41#define M5602_XB_CLK_PD 0x10
42#define M5602_XB_MCU_CLK_CTRL 0x12 42#define M5602_XB_MCU_CLK_CTRL 0x12
43#define M5602_XB_MCU_CLK_DIV 0x13 43#define M5602_XB_MCU_CLK_DIV 0x13
44#define M5602_XB_SEN_CLK_CTRL 0x14 44#define M5602_XB_SEN_CLK_CTRL 0x14
45#define M5602_XB_SEN_CLK_DIV 0x15 45#define M5602_XB_SEN_CLK_DIV 0x15
46#define M5602_XB_AUD_CLK_CTRL 0x16 46#define M5602_XB_AUD_CLK_CTRL 0x16
47#define M5602_XB_AUD_CLK_DIV 0x17 47#define M5602_XB_AUD_CLK_DIV 0x17
48#define M5602_XB_DEVCTR1 0x41 48#define M5602_XB_DEVCTR1 0x41
49#define M5602_XB_EPSETR0 0x42 49#define M5602_XB_EPSETR0 0x42
50#define M5602_XB_EPAFCTR 0x47 50#define M5602_XB_EPAFCTR 0x47
51#define M5602_XB_EPBFCTR 0x49 51#define M5602_XB_EPBFCTR 0x49
52#define M5602_XB_EPEFCTR 0x4f 52#define M5602_XB_EPEFCTR 0x4f
53#define M5602_XB_TEST_REG 0x53 53#define M5602_XB_TEST_REG 0x53
54#define M5602_XB_ALT2SIZE 0x54 54#define M5602_XB_ALT2SIZE 0x54
55#define M5602_XB_ALT3SIZE 0x55 55#define M5602_XB_ALT3SIZE 0x55
56#define M5602_XB_OBSFRAME 0x56 56#define M5602_XB_OBSFRAME 0x56
57#define M5602_XB_PWR_CTL 0x59 57#define M5602_XB_PWR_CTL 0x59
58#define M5602_XB_ADC_CTRL 0x60 58#define M5602_XB_ADC_CTRL 0x60
59#define M5602_XB_ADC_DATA 0x61 59#define M5602_XB_ADC_DATA 0x61
60#define M5602_XB_MISC_CTRL 0x62 60#define M5602_XB_MISC_CTRL 0x62
61#define M5602_XB_SNAPSHOT 0x63 61#define M5602_XB_SNAPSHOT 0x63
62#define M5602_XB_SCRATCH_1 0x64 62#define M5602_XB_SCRATCH_1 0x64
63#define M5602_XB_SCRATCH_2 0x65 63#define M5602_XB_SCRATCH_2 0x65
64#define M5602_XB_SCRATCH_3 0x66 64#define M5602_XB_SCRATCH_3 0x66
65#define M5602_XB_SCRATCH_4 0x67 65#define M5602_XB_SCRATCH_4 0x67
66#define M5602_XB_I2C_CTRL 0x68 66#define M5602_XB_I2C_CTRL 0x68
67#define M5602_XB_I2C_CLK_DIV 0x69 67#define M5602_XB_I2C_CLK_DIV 0x69
68#define M5602_XB_I2C_DEV_ADDR 0x6a 68#define M5602_XB_I2C_DEV_ADDR 0x6a
69#define M5602_XB_I2C_REG_ADDR 0x6b 69#define M5602_XB_I2C_REG_ADDR 0x6b
70#define M5602_XB_I2C_DATA 0x6c 70#define M5602_XB_I2C_DATA 0x6c
71#define M5602_XB_I2C_STATUS 0x6d 71#define M5602_XB_I2C_STATUS 0x6d
72#define M5602_XB_GPIO_DAT_H 0x70 72#define M5602_XB_GPIO_DAT_H 0x70
73#define M5602_XB_GPIO_DAT_L 0x71 73#define M5602_XB_GPIO_DAT_L 0x71
74#define M5602_XB_GPIO_DIR_H 0x72 74#define M5602_XB_GPIO_DIR_H 0x72
75#define M5602_XB_GPIO_DIR_L 0x73 75#define M5602_XB_GPIO_DIR_L 0x73
76#define M5602_XB_GPIO_EN_H 0x74 76#define M5602_XB_GPIO_EN_H 0x74
77#define M5602_XB_GPIO_EN_L 0x75 77#define M5602_XB_GPIO_EN_L 0x75
78#define M5602_XB_GPIO_DAT 0x76 78#define M5602_XB_GPIO_DAT 0x76
79#define M5602_XB_GPIO_DIR 0x77 79#define M5602_XB_GPIO_DIR 0x77
80#define M5602_XB_MISC_CTL 0x70 80#define M5602_XB_MISC_CTL 0x70
81 81
82#define I2C_BUSY 0x80 82#define I2C_BUSY 0x80
83 83
@@ -90,13 +90,7 @@
90#define M5602_ISOC_ENDPOINT_ADDR 0x81 90#define M5602_ISOC_ENDPOINT_ADDR 0x81
91#define M5602_INTR_ENDPOINT_ADDR 0x82 91#define M5602_INTR_ENDPOINT_ADDR 0x82
92 92
93#define M5602_MAX_FRAMES 32
94#define M5602_URBS 2
95#define M5602_ISOC_PACKETS 14
96
97#define M5602_URB_TIMEOUT msecs_to_jiffies(2 * M5602_ISOC_PACKETS)
98#define M5602_URB_MSG_TIMEOUT 5000 93#define M5602_URB_MSG_TIMEOUT 5000
99#define M5602_FRAME_TIMEOUT 2
100 94
101/*****************************************************************************/ 95/*****************************************************************************/
102 96
@@ -115,7 +109,6 @@ static const unsigned char sensor_urb_skeleton[] = {
115 0x13, M5602_XB_I2C_CTRL, 0x81, 0x11 109 0x13, M5602_XB_I2C_CTRL, 0x81, 0x11
116}; 110};
117 111
118/* m5602 device descriptor, currently it just wraps the m5602_camera struct */
119struct sd { 112struct sd {
120 struct gspca_dev gspca_dev; 113 struct gspca_dev gspca_dev;
121 114
@@ -140,4 +133,10 @@ int m5602_read_bridge(
140int m5602_write_bridge( 133int m5602_write_bridge(
141 struct sd *sd, u8 address, u8 i2c_data); 134 struct sd *sd, u8 address, u8 i2c_data);
142 135
136int m5602_write_sensor(struct sd *sd, const u8 address,
137 u8 *i2c_data, const u8 len);
138
139int m5602_read_sensor(struct sd *sd, const u8 address,
140 u8 *i2c_data, const u8 len);
141
143#endif 142#endif
diff --git a/drivers/media/video/gspca/m5602/m5602_core.c b/drivers/media/video/gspca/m5602/m5602_core.c
index fd6ce384b487..ed906fe31287 100644
--- a/drivers/media/video/gspca/m5602/m5602_core.c
+++ b/drivers/media/video/gspca/m5602/m5602_core.c
@@ -24,7 +24,7 @@
24 24
25/* Kernel module parameters */ 25/* Kernel module parameters */
26int force_sensor; 26int force_sensor;
27int dump_bridge; 27static int dump_bridge;
28int dump_sensor; 28int dump_sensor;
29 29
30static const __devinitdata struct usb_device_id m5602_table[] = { 30static const __devinitdata struct usb_device_id m5602_table[] = {
@@ -80,6 +80,97 @@ int m5602_write_bridge(struct sd *sd, u8 address, u8 i2c_data)
80 return (err < 0) ? err : 0; 80 return (err < 0) ? err : 0;
81} 81}
82 82
83int m5602_read_sensor(struct sd *sd, const u8 address,
84 u8 *i2c_data, const u8 len)
85{
86 int err, i;
87
88 if (!len || len > sd->sensor->i2c_regW)
89 return -EINVAL;
90
91 do {
92 err = m5602_read_bridge(sd, M5602_XB_I2C_STATUS, i2c_data);
93 } while ((*i2c_data & I2C_BUSY) && !err);
94 if (err < 0)
95 goto out;
96
97 err = m5602_write_bridge(sd, M5602_XB_I2C_DEV_ADDR,
98 sd->sensor->i2c_slave_id);
99 if (err < 0)
100 goto out;
101
102 err = m5602_write_bridge(sd, M5602_XB_I2C_REG_ADDR, address);
103 if (err < 0)
104 goto out;
105
106 if (sd->sensor->i2c_regW == 1) {
107 err = m5602_write_bridge(sd, M5602_XB_I2C_CTRL, len);
108 if (err < 0)
109 goto out;
110
111 err = m5602_write_bridge(sd, M5602_XB_I2C_CTRL, 0x08);
112 if (err < 0)
113 goto out;
114 } else {
115 err = m5602_write_bridge(sd, M5602_XB_I2C_CTRL, 0x18 + len);
116 if (err < 0)
117 goto out;
118 }
119
120 for (i = 0; (i < len) && !err; i++) {
121 err = m5602_read_bridge(sd, M5602_XB_I2C_DATA, &(i2c_data[i]));
122
123 PDEBUG(D_CONF, "Reading sensor register "
124 "0x%x containing 0x%x ", address, *i2c_data);
125 }
126out:
127 return err;
128}
129
130int m5602_write_sensor(struct sd *sd, const u8 address,
131 u8 *i2c_data, const u8 len)
132{
133 int err, i;
134 u8 *p;
135 struct usb_device *udev = sd->gspca_dev.dev;
136 __u8 *buf = sd->gspca_dev.usb_buf;
137
138 /* No sensor with a data width larger than 16 bits has yet been seen */
139 if (len > sd->sensor->i2c_regW || !len)
140 return -EINVAL;
141
142 memcpy(buf, sensor_urb_skeleton,
143 sizeof(sensor_urb_skeleton));
144
145 buf[11] = sd->sensor->i2c_slave_id;
146 buf[15] = address;
147
148 /* Special case larger sensor writes */
149 p = buf + 16;
150
151 /* Copy a four byte write sequence for each byte to be written to */
152 for (i = 0; i < len; i++) {
153 memcpy(p, sensor_urb_skeleton + 16, 4);
154 p[3] = i2c_data[i];
155 p += 4;
156 PDEBUG(D_CONF, "Writing sensor register 0x%x with 0x%x",
157 address, i2c_data[i]);
158 }
159
160 /* Copy the tailer */
161 memcpy(p, sensor_urb_skeleton + 20, 4);
162
163 /* Set the total length */
164 p[3] = 0x10 + len;
165
166 err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
167 0x04, 0x40, 0x19,
168 0x0000, buf,
169 20 + len * 4, M5602_URB_MSG_TIMEOUT);
170
171 return (err < 0) ? err : 0;
172}
173
83/* Dump all the registers of the m5602 bridge, 174/* Dump all the registers of the m5602 bridge,
84 unfortunately this breaks the camera until it's power cycled */ 175 unfortunately this breaks the camera until it's power cycled */
85static void m5602_dump_bridge(struct sd *sd) 176static void m5602_dump_bridge(struct sd *sd)
@@ -150,11 +241,15 @@ static int m5602_start_transfer(struct gspca_dev *gspca_dev)
150 241
151 /* Send start command to the camera */ 242 /* Send start command to the camera */
152 const u8 buffer[4] = {0x13, 0xf9, 0x0f, 0x01}; 243 const u8 buffer[4] = {0x13, 0xf9, 0x0f, 0x01};
244
245 if (sd->sensor->start)
246 sd->sensor->start(sd);
247
153 memcpy(buf, buffer, sizeof(buffer)); 248 memcpy(buf, buffer, sizeof(buffer));
154 err = usb_control_msg(gspca_dev->dev, 249 err = usb_control_msg(gspca_dev->dev,
155 usb_sndctrlpipe(gspca_dev->dev, 0), 250 usb_sndctrlpipe(gspca_dev->dev, 0),
156 0x04, 0x40, 0x19, 0x0000, buf, 251 0x04, 0x40, 0x19, 0x0000, buf,
157 4, M5602_URB_MSG_TIMEOUT); 252 sizeof(buffer), M5602_URB_MSG_TIMEOUT);
158 253
159 PDEBUG(D_STREAM, "Transfer started"); 254 PDEBUG(D_STREAM, "Transfer started");
160 return (err < 0) ? err : 0; 255 return (err < 0) ? err : 0;
@@ -284,6 +379,7 @@ static int __init mod_m5602_init(void)
284 PDEBUG(D_PROBE, "registered"); 379 PDEBUG(D_PROBE, "registered");
285 return 0; 380 return 0;
286} 381}
382
287static void __exit mod_m5602_exit(void) 383static void __exit mod_m5602_exit(void)
288{ 384{
289 usb_deregister(&sd_driver); 385 usb_deregister(&sd_driver);
diff --git a/drivers/media/video/gspca/m5602/m5602_mt9m111.c b/drivers/media/video/gspca/m5602/m5602_mt9m111.c
index fb700c2d055a..c0e71c331454 100644
--- a/drivers/media/video/gspca/m5602/m5602_mt9m111.c
+++ b/drivers/media/video/gspca/m5602/m5602_mt9m111.c
@@ -18,6 +18,8 @@
18 18
19#include "m5602_mt9m111.h" 19#include "m5602_mt9m111.h"
20 20
21static void mt9m111_dump_registers(struct sd *sd);
22
21int mt9m111_probe(struct sd *sd) 23int mt9m111_probe(struct sd *sd)
22{ 24{
23 u8 data[2] = {0x00, 0x00}; 25 u8 data[2] = {0x00, 0x00};
@@ -44,12 +46,12 @@ int mt9m111_probe(struct sd *sd)
44 } else { 46 } else {
45 data[0] = preinit_mt9m111[i][2]; 47 data[0] = preinit_mt9m111[i][2];
46 data[1] = preinit_mt9m111[i][3]; 48 data[1] = preinit_mt9m111[i][3];
47 mt9m111_write_sensor(sd, 49 m5602_write_sensor(sd,
48 preinit_mt9m111[i][1], data, 2); 50 preinit_mt9m111[i][1], data, 2);
49 } 51 }
50 } 52 }
51 53
52 if (mt9m111_read_sensor(sd, MT9M111_SC_CHIPVER, data, 2)) 54 if (m5602_read_sensor(sd, MT9M111_SC_CHIPVER, data, 2))
53 return -ENODEV; 55 return -ENODEV;
54 56
55 if ((data[0] == 0x14) && (data[1] == 0x3a)) { 57 if ((data[0] == 0x14) && (data[1] == 0x3a)) {
@@ -72,7 +74,7 @@ int mt9m111_init(struct sd *sd)
72 int i, err = 0; 74 int i, err = 0;
73 75
74 /* Init the sensor */ 76 /* Init the sensor */
75 for (i = 0; i < ARRAY_SIZE(init_mt9m111); i++) { 77 for (i = 0; i < ARRAY_SIZE(init_mt9m111) && !err; i++) {
76 u8 data[2]; 78 u8 data[2];
77 79
78 if (init_mt9m111[i][0] == BRIDGE) { 80 if (init_mt9m111[i][0] == BRIDGE) {
@@ -82,7 +84,7 @@ int mt9m111_init(struct sd *sd)
82 } else { 84 } else {
83 data[0] = init_mt9m111[i][2]; 85 data[0] = init_mt9m111[i][2];
84 data[1] = init_mt9m111[i][3]; 86 data[1] = init_mt9m111[i][3];
85 err = mt9m111_write_sensor(sd, 87 err = m5602_write_sensor(sd,
86 init_mt9m111[i][1], data, 2); 88 init_mt9m111[i][1], data, 2);
87 } 89 }
88 } 90 }
@@ -104,12 +106,12 @@ int mt9m111_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
104 u8 data[2] = {0x00, 0x00}; 106 u8 data[2] = {0x00, 0x00};
105 struct sd *sd = (struct sd *) gspca_dev; 107 struct sd *sd = (struct sd *) gspca_dev;
106 108
107 err = mt9m111_read_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B, 109 err = m5602_read_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B,
108 data, 2); 110 data, 2);
109 *val = data[0] & MT9M111_RMB_MIRROR_ROWS; 111 *val = data[0] & MT9M111_RMB_MIRROR_ROWS;
110 PDEBUG(D_V4L2, "Read vertical flip %d", *val); 112 PDEBUG(D_V4L2, "Read vertical flip %d", *val);
111 113
112 return (err < 0) ? err : 0; 114 return err;
113} 115}
114 116
115int mt9m111_set_vflip(struct gspca_dev *gspca_dev, __s32 val) 117int mt9m111_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
@@ -121,19 +123,19 @@ int mt9m111_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
121 PDEBUG(D_V4L2, "Set vertical flip to %d", val); 123 PDEBUG(D_V4L2, "Set vertical flip to %d", val);
122 124
123 /* Set the correct page map */ 125 /* Set the correct page map */
124 err = mt9m111_write_sensor(sd, MT9M111_PAGE_MAP, data, 2); 126 err = m5602_write_sensor(sd, MT9M111_PAGE_MAP, data, 2);
125 if (err < 0) 127 if (err < 0)
126 goto out; 128 goto out;
127 129
128 err = mt9m111_read_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B, data, 2); 130 err = m5602_read_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B, data, 2);
129 if (err < 0) 131 if (err < 0)
130 goto out; 132 goto out;
131 133
132 data[0] = (data[0] & 0xfe) | val; 134 data[0] = (data[0] & 0xfe) | val;
133 err = mt9m111_write_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B, 135 err = m5602_write_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B,
134 data, 2); 136 data, 2);
135out: 137out:
136 return (err < 0) ? err : 0; 138 return err;
137} 139}
138 140
139int mt9m111_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) 141int mt9m111_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
@@ -142,12 +144,12 @@ int mt9m111_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
142 u8 data[2] = {0x00, 0x00}; 144 u8 data[2] = {0x00, 0x00};
143 struct sd *sd = (struct sd *) gspca_dev; 145 struct sd *sd = (struct sd *) gspca_dev;
144 146
145 err = mt9m111_read_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B, 147 err = m5602_read_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B,
146 data, 2); 148 data, 2);
147 *val = data[0] & MT9M111_RMB_MIRROR_COLS; 149 *val = data[0] & MT9M111_RMB_MIRROR_COLS;
148 PDEBUG(D_V4L2, "Read horizontal flip %d", *val); 150 PDEBUG(D_V4L2, "Read horizontal flip %d", *val);
149 151
150 return (err < 0) ? err : 0; 152 return err;
151} 153}
152 154
153int mt9m111_set_hflip(struct gspca_dev *gspca_dev, __s32 val) 155int mt9m111_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
@@ -159,19 +161,19 @@ int mt9m111_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
159 PDEBUG(D_V4L2, "Set horizontal flip to %d", val); 161 PDEBUG(D_V4L2, "Set horizontal flip to %d", val);
160 162
161 /* Set the correct page map */ 163 /* Set the correct page map */
162 err = mt9m111_write_sensor(sd, MT9M111_PAGE_MAP, data, 2); 164 err = m5602_write_sensor(sd, MT9M111_PAGE_MAP, data, 2);
163 if (err < 0) 165 if (err < 0)
164 goto out; 166 goto out;
165 167
166 err = mt9m111_read_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B, data, 2); 168 err = m5602_read_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B, data, 2);
167 if (err < 0) 169 if (err < 0)
168 goto out; 170 goto out;
169 171
170 data[0] = (data[0] & 0xfd) | ((val << 1) & 0x02); 172 data[0] = (data[0] & 0xfd) | ((val << 1) & 0x02);
171 err = mt9m111_write_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B, 173 err = m5602_write_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B,
172 data, 2); 174 data, 2);
173out: 175out:
174 return (err < 0) ? err : 0; 176 return err;
175} 177}
176 178
177int mt9m111_get_gain(struct gspca_dev *gspca_dev, __s32 *val) 179int mt9m111_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
@@ -180,7 +182,7 @@ int mt9m111_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
180 u8 data[2] = {0x00, 0x00}; 182 u8 data[2] = {0x00, 0x00};
181 struct sd *sd = (struct sd *) gspca_dev; 183 struct sd *sd = (struct sd *) gspca_dev;
182 184
183 err = mt9m111_read_sensor(sd, MT9M111_SC_GLOBAL_GAIN, data, 2); 185 err = m5602_read_sensor(sd, MT9M111_SC_GLOBAL_GAIN, data, 2);
184 tmp = ((data[1] << 8) | data[0]); 186 tmp = ((data[1] << 8) | data[0]);
185 187
186 *val = ((tmp & (1 << 10)) * 2) | 188 *val = ((tmp & (1 << 10)) * 2) |
@@ -190,7 +192,7 @@ int mt9m111_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
190 192
191 PDEBUG(D_V4L2, "Read gain %d", *val); 193 PDEBUG(D_V4L2, "Read gain %d", *val);
192 194
193 return (err < 0) ? err : 0; 195 return err;
194} 196}
195 197
196int mt9m111_set_gain(struct gspca_dev *gspca_dev, __s32 val) 198int mt9m111_set_gain(struct gspca_dev *gspca_dev, __s32 val)
@@ -200,7 +202,7 @@ int mt9m111_set_gain(struct gspca_dev *gspca_dev, __s32 val)
200 struct sd *sd = (struct sd *) gspca_dev; 202 struct sd *sd = (struct sd *) gspca_dev;
201 203
202 /* Set the correct page map */ 204 /* Set the correct page map */
203 err = mt9m111_write_sensor(sd, MT9M111_PAGE_MAP, data, 2); 205 err = m5602_write_sensor(sd, MT9M111_PAGE_MAP, data, 2);
204 if (err < 0) 206 if (err < 0)
205 goto out; 207 goto out;
206 208
@@ -225,90 +227,13 @@ int mt9m111_set_gain(struct gspca_dev *gspca_dev, __s32 val)
225 PDEBUG(D_V4L2, "tmp=%d, data[1]=%d, data[0]=%d", tmp, 227 PDEBUG(D_V4L2, "tmp=%d, data[1]=%d, data[0]=%d", tmp,
226 data[1], data[0]); 228 data[1], data[0]);
227 229
228 err = mt9m111_write_sensor(sd, MT9M111_SC_GLOBAL_GAIN, 230 err = m5602_write_sensor(sd, MT9M111_SC_GLOBAL_GAIN,
229 data, 2); 231 data, 2);
230out: 232out:
231 return (err < 0) ? err : 0; 233 return err;
232}
233
234int mt9m111_read_sensor(struct sd *sd, const u8 address,
235 u8 *i2c_data, const u8 len) {
236 int err, i;
237
238 do {
239 err = m5602_read_bridge(sd, M5602_XB_I2C_STATUS, i2c_data);
240 } while ((*i2c_data & I2C_BUSY) && !err);
241 if (err < 0)
242 goto out;
243
244 err = m5602_write_bridge(sd, M5602_XB_I2C_DEV_ADDR,
245 sd->sensor->i2c_slave_id);
246 if (err < 0)
247 goto out;
248
249 err = m5602_write_bridge(sd, M5602_XB_I2C_REG_ADDR, address);
250 if (err < 0)
251 goto out;
252
253 err = m5602_write_bridge(sd, M5602_XB_I2C_CTRL, 0x1a);
254 if (err < 0)
255 goto out;
256
257 for (i = 0; i < len && !err; i++) {
258 err = m5602_read_bridge(sd, M5602_XB_I2C_DATA, &(i2c_data[i]));
259
260 PDEBUG(D_CONF, "Reading sensor register "
261 "0x%x contains 0x%x ", address, *i2c_data);
262 }
263out:
264 return (err < 0) ? err : 0;
265}
266
267int mt9m111_write_sensor(struct sd *sd, const u8 address,
268 u8 *i2c_data, const u8 len)
269{
270 int err, i;
271 u8 *p;
272 struct usb_device *udev = sd->gspca_dev.dev;
273 __u8 *buf = sd->gspca_dev.usb_buf;
274
275 /* No sensor with a data width larger
276 than 16 bits has yet been seen, nor with 0 :p*/
277 if (len > 2 || !len)
278 return -EINVAL;
279
280 memcpy(buf, sensor_urb_skeleton,
281 sizeof(sensor_urb_skeleton));
282
283 buf[11] = sd->sensor->i2c_slave_id;
284 buf[15] = address;
285
286 p = buf + 16;
287
288 /* Copy a four byte write sequence for each byte to be written to */
289 for (i = 0; i < len; i++) {
290 memcpy(p, sensor_urb_skeleton + 16, 4);
291 p[3] = i2c_data[i];
292 p += 4;
293 PDEBUG(D_CONF, "Writing sensor register 0x%x with 0x%x",
294 address, i2c_data[i]);
295 }
296
297 /* Copy the tailer */
298 memcpy(p, sensor_urb_skeleton + 20, 4);
299
300 /* Set the total length */
301 p[3] = 0x10 + len;
302
303 err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
304 0x04, 0x40, 0x19,
305 0x0000, buf,
306 20 + len * 4, M5602_URB_MSG_TIMEOUT);
307
308 return (err < 0) ? err : 0;
309} 234}
310 235
311void mt9m111_dump_registers(struct sd *sd) 236static void mt9m111_dump_registers(struct sd *sd)
312{ 237{
313 u8 address, value[2] = {0x00, 0x00}; 238 u8 address, value[2] = {0x00, 0x00};
314 239
@@ -316,27 +241,27 @@ void mt9m111_dump_registers(struct sd *sd)
316 241
317 info("Dumping the mt9m111 sensor core registers"); 242 info("Dumping the mt9m111 sensor core registers");
318 value[1] = MT9M111_SENSOR_CORE; 243 value[1] = MT9M111_SENSOR_CORE;
319 mt9m111_write_sensor(sd, MT9M111_PAGE_MAP, value, 2); 244 m5602_write_sensor(sd, MT9M111_PAGE_MAP, value, 2);
320 for (address = 0; address < 0xff; address++) { 245 for (address = 0; address < 0xff; address++) {
321 mt9m111_read_sensor(sd, address, value, 2); 246 m5602_read_sensor(sd, address, value, 2);
322 info("register 0x%x contains 0x%x%x", 247 info("register 0x%x contains 0x%x%x",
323 address, value[0], value[1]); 248 address, value[0], value[1]);
324 } 249 }
325 250
326 info("Dumping the mt9m111 color pipeline registers"); 251 info("Dumping the mt9m111 color pipeline registers");
327 value[1] = MT9M111_COLORPIPE; 252 value[1] = MT9M111_COLORPIPE;
328 mt9m111_write_sensor(sd, MT9M111_PAGE_MAP, value, 2); 253 m5602_write_sensor(sd, MT9M111_PAGE_MAP, value, 2);
329 for (address = 0; address < 0xff; address++) { 254 for (address = 0; address < 0xff; address++) {
330 mt9m111_read_sensor(sd, address, value, 2); 255 m5602_read_sensor(sd, address, value, 2);
331 info("register 0x%x contains 0x%x%x", 256 info("register 0x%x contains 0x%x%x",
332 address, value[0], value[1]); 257 address, value[0], value[1]);
333 } 258 }
334 259
335 info("Dumping the mt9m111 camera control registers"); 260 info("Dumping the mt9m111 camera control registers");
336 value[1] = MT9M111_CAMERA_CONTROL; 261 value[1] = MT9M111_CAMERA_CONTROL;
337 mt9m111_write_sensor(sd, MT9M111_PAGE_MAP, value, 2); 262 m5602_write_sensor(sd, MT9M111_PAGE_MAP, value, 2);
338 for (address = 0; address < 0xff; address++) { 263 for (address = 0; address < 0xff; address++) {
339 mt9m111_read_sensor(sd, address, value, 2); 264 m5602_read_sensor(sd, address, value, 2);
340 info("register 0x%x contains 0x%x%x", 265 info("register 0x%x contains 0x%x%x",
341 address, value[0], value[1]); 266 address, value[0], value[1]);
342 } 267 }
diff --git a/drivers/media/video/gspca/m5602/m5602_mt9m111.h b/drivers/media/video/gspca/m5602/m5602_mt9m111.h
index 315209d5aeef..e795ab7a36c9 100644
--- a/drivers/media/video/gspca/m5602/m5602_mt9m111.h
+++ b/drivers/media/video/gspca/m5602/m5602_mt9m111.h
@@ -87,14 +87,6 @@ int mt9m111_probe(struct sd *sd);
87int mt9m111_init(struct sd *sd); 87int mt9m111_init(struct sd *sd);
88int mt9m111_power_down(struct sd *sd); 88int mt9m111_power_down(struct sd *sd);
89 89
90int mt9m111_read_sensor(struct sd *sd, const u8 address,
91 u8 *i2c_data, const u8 len);
92
93int mt9m111_write_sensor(struct sd *sd, const u8 address,
94 u8 *i2c_data, const u8 len);
95
96void mt9m111_dump_registers(struct sd *sd);
97
98int mt9m111_set_vflip(struct gspca_dev *gspca_dev, __s32 val); 90int mt9m111_set_vflip(struct gspca_dev *gspca_dev, __s32 val);
99int mt9m111_get_vflip(struct gspca_dev *gspca_dev, __s32 *val); 91int mt9m111_get_vflip(struct gspca_dev *gspca_dev, __s32 *val);
100int mt9m111_get_hflip(struct gspca_dev *gspca_dev, __s32 *val); 92int mt9m111_get_hflip(struct gspca_dev *gspca_dev, __s32 *val);
@@ -106,14 +98,12 @@ static struct m5602_sensor mt9m111 = {
106 .name = "MT9M111", 98 .name = "MT9M111",
107 99
108 .i2c_slave_id = 0xba, 100 .i2c_slave_id = 0xba,
101 .i2c_regW = 2,
109 102
110 .probe = mt9m111_probe, 103 .probe = mt9m111_probe,
111 .init = mt9m111_init, 104 .init = mt9m111_init,
112 .power_down = mt9m111_power_down, 105 .power_down = mt9m111_power_down,
113 106
114 .read_sensor = mt9m111_read_sensor,
115 .write_sensor = mt9m111_write_sensor,
116
117 .nctrls = 3, 107 .nctrls = 3,
118 .ctrls = { 108 .ctrls = {
119 { 109 {
@@ -1003,7 +993,7 @@ static const unsigned char init_mt9m111[][4] =
1003 {BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00}, 993 {BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00},
1004 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, 994 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
1005 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, 995 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
1006 {BRIDGE, M5602_XB_HSYNC_PARA, 0x02, 0x00}, 996 {BRIDGE, M5602_XB_HSYNC_PARA, 0x02, 0x00}, /* 639*/
1007 {BRIDGE, M5602_XB_HSYNC_PARA, 0x7f, 0x00}, 997 {BRIDGE, M5602_XB_HSYNC_PARA, 0x7f, 0x00},
1008 {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, 998 {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
1009 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, 999 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
diff --git a/drivers/media/video/gspca/m5602/m5602_ov9650.c b/drivers/media/video/gspca/m5602/m5602_ov9650.c
index 837c7e47661c..c908a8d6970a 100644
--- a/drivers/media/video/gspca/m5602/m5602_ov9650.c
+++ b/drivers/media/video/gspca/m5602/m5602_ov9650.c
@@ -18,77 +18,57 @@
18 18
19#include "m5602_ov9650.h" 19#include "m5602_ov9650.h"
20 20
21int ov9650_read_sensor(struct sd *sd, const u8 address, 21/* Vertically and horizontally flips the image if matched, needed for machines
22 u8 *i2c_data, const u8 len) 22 where the sensor is mounted upside down */
23{ 23static
24 int err, i; 24 const
25 25 struct dmi_system_id ov9650_flip_dmi_table[] = {
26 /* The ov9650 registers have a max depth of one byte */ 26 {
27 if (len > 1 || !len) 27 .ident = "ASUS A6VC",
28 return -EINVAL; 28 .matches = {
29 29 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
30 do { 30 DMI_MATCH(DMI_PRODUCT_NAME, "A6VC")
31 err = m5602_read_bridge(sd, M5602_XB_I2C_STATUS, i2c_data); 31 }
32 } while ((*i2c_data & I2C_BUSY) && !err); 32 },
33 33 {
34 m5602_write_bridge(sd, M5602_XB_I2C_DEV_ADDR, 34 .ident = "ASUS A6VM",
35 ov9650.i2c_slave_id); 35 .matches = {
36 m5602_write_bridge(sd, M5602_XB_I2C_REG_ADDR, address); 36 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
37 m5602_write_bridge(sd, M5602_XB_I2C_CTRL, 0x10 + len); 37 DMI_MATCH(DMI_PRODUCT_NAME, "A6VM")
38 m5602_write_bridge(sd, M5602_XB_I2C_CTRL, 0x08); 38 }
39 39 },
40 for (i = 0; i < len; i++) { 40 {
41 err = m5602_read_bridge(sd, M5602_XB_I2C_DATA, &(i2c_data[i])); 41 .ident = "ASUS A6JC",
42 42 .matches = {
43 PDEBUG(D_CONF, "Reading sensor register " 43 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
44 "0x%x containing 0x%x ", address, *i2c_data); 44 DMI_MATCH(DMI_PRODUCT_NAME, "A6JC")
45 } 45 }
46 return (err < 0) ? err : 0; 46 },
47} 47 {
48 48 .ident = "ASUS A6Ja",
49int ov9650_write_sensor(struct sd *sd, const u8 address, 49 .matches = {
50 u8 *i2c_data, const u8 len) 50 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
51{ 51 DMI_MATCH(DMI_PRODUCT_NAME, "A6J")
52 int err, i; 52 }
53 u8 *p; 53 },
54 struct usb_device *udev = sd->gspca_dev.dev; 54 {
55 __u8 *buf = sd->gspca_dev.usb_buf; 55 .ident = "ASUS A6Kt",
56 56 .matches = {
57 /* The ov9650 only supports one byte writes */ 57 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
58 if (len > 1 || !len) 58 DMI_MATCH(DMI_PRODUCT_NAME, "A6Kt")
59 return -EINVAL; 59 }
60 60 },
61 memcpy(buf, sensor_urb_skeleton, 61 {
62 sizeof(sensor_urb_skeleton)); 62 .ident = "Alienware Aurora m9700",
63 63 .matches = {
64 buf[11] = sd->sensor->i2c_slave_id; 64 DMI_MATCH(DMI_SYS_VENDOR, "alienware"),
65 buf[15] = address; 65 DMI_MATCH(DMI_PRODUCT_NAME, "Aurora m9700")
66 66 }
67 /* Special case larger sensor writes */ 67 },
68 p = buf + 16; 68 { }
69 69};
70 /* Copy a four byte write sequence for each byte to be written to */
71 for (i = 0; i < len; i++) {
72 memcpy(p, sensor_urb_skeleton + 16, 4);
73 p[3] = i2c_data[i];
74 p += 4;
75 PDEBUG(D_CONF, "Writing sensor register 0x%x with 0x%x",
76 address, i2c_data[i]);
77 }
78
79 /* Copy the tailer */
80 memcpy(p, sensor_urb_skeleton + 20, 4);
81
82 /* Set the total length */
83 p[3] = 0x10 + len;
84
85 err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
86 0x04, 0x40, 0x19,
87 0x0000, buf,
88 20 + len * 4, M5602_URB_MSG_TIMEOUT);
89 70
90 return (err < 0) ? err : 0; 71static void ov9650_dump_registers(struct sd *sd);
91}
92 72
93int ov9650_probe(struct sd *sd) 73int ov9650_probe(struct sd *sd)
94{ 74{
@@ -110,16 +90,16 @@ int ov9650_probe(struct sd *sd)
110 for (i = 0; i < ARRAY_SIZE(preinit_ov9650); i++) { 90 for (i = 0; i < ARRAY_SIZE(preinit_ov9650); i++) {
111 u8 data = preinit_ov9650[i][2]; 91 u8 data = preinit_ov9650[i][2];
112 if (preinit_ov9650[i][0] == SENSOR) 92 if (preinit_ov9650[i][0] == SENSOR)
113 ov9650_write_sensor(sd, 93 m5602_write_sensor(sd,
114 preinit_ov9650[i][1], &data, 1); 94 preinit_ov9650[i][1], &data, 1);
115 else 95 else
116 m5602_write_bridge(sd, preinit_ov9650[i][1], data); 96 m5602_write_bridge(sd, preinit_ov9650[i][1], data);
117 } 97 }
118 98
119 if (ov9650_read_sensor(sd, OV9650_PID, &prod_id, 1)) 99 if (m5602_read_sensor(sd, OV9650_PID, &prod_id, 1))
120 return -ENODEV; 100 return -ENODEV;
121 101
122 if (ov9650_read_sensor(sd, OV9650_VER, &ver_id, 1)) 102 if (m5602_read_sensor(sd, OV9650_VER, &ver_id, 1))
123 return -ENODEV; 103 return -ENODEV;
124 104
125 if ((prod_id == 0x96) && (ver_id == 0x52)) { 105 if ((prod_id == 0x96) && (ver_id == 0x52)) {
@@ -148,34 +128,90 @@ int ov9650_init(struct sd *sd)
148 for (i = 0; i < ARRAY_SIZE(init_ov9650) && !err; i++) { 128 for (i = 0; i < ARRAY_SIZE(init_ov9650) && !err; i++) {
149 data = init_ov9650[i][2]; 129 data = init_ov9650[i][2];
150 if (init_ov9650[i][0] == SENSOR) 130 if (init_ov9650[i][0] == SENSOR)
151 err = ov9650_write_sensor(sd, init_ov9650[i][1], 131 err = m5602_write_sensor(sd, init_ov9650[i][1],
152 &data, 1); 132 &data, 1);
153 else 133 else
154 err = m5602_write_bridge(sd, init_ov9650[i][1], data); 134 err = m5602_write_bridge(sd, init_ov9650[i][1], data);
155 } 135 }
156 136
157 if (!err && dmi_check_system(ov9650_flip_dmi_table)) { 137 if (dmi_check_system(ov9650_flip_dmi_table) && !err) {
158 info("vflip quirk active"); 138 info("vflip quirk active");
159 data = 0x30; 139 data = 0x30;
160 err = ov9650_write_sensor(sd, OV9650_MVFP, &data, 1); 140 err = m5602_write_sensor(sd, OV9650_MVFP, &data, 1);
161 } 141 }
142 return err;
143}
144
145int ov9650_start(struct sd *sd)
146{
147 int i, err = 0;
148 struct cam *cam = &sd->gspca_dev.cam;
162 149
163 return (err < 0) ? err : 0; 150 for (i = 0; i < ARRAY_SIZE(res_init_ov9650) && !err; i++) {
151 u8 data = res_init_ov9650[i][1];
152 err = m5602_write_bridge(sd, res_init_ov9650[i][0], data);
153 }
154 if (err < 0)
155 return err;
156
157 switch (cam->cam_mode[sd->gspca_dev.curr_mode].width)
158 {
159 case 640:
160 PDEBUG(D_V4L2, "Configuring camera for VGA mode");
161
162 for (i = 0; i < ARRAY_SIZE(VGA_ov9650) && !err; i++) {
163 u8 data = VGA_ov9650[i][2];
164 if (VGA_ov9650[i][0] == SENSOR)
165 err = m5602_write_sensor(sd,
166 VGA_ov9650[i][1], &data, 1);
167 else
168 err = m5602_write_bridge(sd, VGA_ov9650[i][1], data);
169 }
170 break;
171
172 case 352:
173 PDEBUG(D_V4L2, "Configuring camera for CIF mode");
174
175 for (i = 0; i < ARRAY_SIZE(CIF_ov9650) && !err; i++) {
176 u8 data = CIF_ov9650[i][2];
177 if (CIF_ov9650[i][0] == SENSOR)
178 err = m5602_write_sensor(sd,
179 CIF_ov9650[i][1], &data, 1);
180 else
181 err = m5602_write_bridge(sd, CIF_ov9650[i][1], data);
182 }
183 break;
184
185 case 320:
186 PDEBUG(D_V4L2, "Configuring camera for QVGA mode");
187
188 for (i = 0; i < ARRAY_SIZE(QVGA_ov9650) && !err; i++) {
189 u8 data = QVGA_ov9650[i][2];
190 if (QVGA_ov9650[i][0] == SENSOR)
191 err = m5602_write_sensor(sd,
192 QVGA_ov9650[i][1], &data, 1);
193 else
194 err = m5602_write_bridge(sd, QVGA_ov9650[i][1], data);
195 }
196 break;
197 }
198 return err;
164} 199}
165 200
166int ov9650_power_down(struct sd *sd) 201int ov9650_power_down(struct sd *sd)
167{ 202{
168 int i; 203 int i, err = 0;
169 for (i = 0; i < ARRAY_SIZE(power_down_ov9650); i++) { 204 for (i = 0; i < ARRAY_SIZE(power_down_ov9650) && !err; i++) {
170 u8 data = power_down_ov9650[i][2]; 205 u8 data = power_down_ov9650[i][2];
171 if (power_down_ov9650[i][0] == SENSOR) 206 if (power_down_ov9650[i][0] == SENSOR)
172 ov9650_write_sensor(sd, 207 err = m5602_write_sensor(sd,
173 power_down_ov9650[i][1], &data, 1); 208 power_down_ov9650[i][1], &data, 1);
174 else 209 else
175 m5602_write_bridge(sd, power_down_ov9650[i][1], data); 210 err = m5602_write_bridge(sd, power_down_ov9650[i][1],
211 data);
176 } 212 }
177 213
178 return 0; 214 return err;
179} 215}
180 216
181int ov9650_get_exposure(struct gspca_dev *gspca_dev, __s32 *val) 217int ov9650_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
@@ -184,24 +220,24 @@ int ov9650_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
184 u8 i2c_data; 220 u8 i2c_data;
185 int err; 221 int err;
186 222
187 err = ov9650_read_sensor(sd, OV9650_COM1, &i2c_data, 1); 223 err = m5602_read_sensor(sd, OV9650_COM1, &i2c_data, 1);
188 if (err < 0) 224 if (err < 0)
189 goto out; 225 goto out;
190 *val = i2c_data & 0x03; 226 *val = i2c_data & 0x03;
191 227
192 err = ov9650_read_sensor(sd, OV9650_AECH, &i2c_data, 1); 228 err = m5602_read_sensor(sd, OV9650_AECH, &i2c_data, 1);
193 if (err < 0) 229 if (err < 0)
194 goto out; 230 goto out;
195 *val |= (i2c_data << 2); 231 *val |= (i2c_data << 2);
196 232
197 err = ov9650_read_sensor(sd, OV9650_AECHM, &i2c_data, 1); 233 err = m5602_read_sensor(sd, OV9650_AECHM, &i2c_data, 1);
198 if (err < 0) 234 if (err < 0)
199 goto out; 235 goto out;
200 *val |= (i2c_data & 0x3f) << 10; 236 *val |= (i2c_data & 0x3f) << 10;
201 237
202 PDEBUG(D_V4L2, "Read exposure %d", *val); 238 PDEBUG(D_V4L2, "Read exposure %d", *val);
203out: 239out:
204 return (err < 0) ? err : 0; 240 return err;
205} 241}
206 242
207int ov9650_set_exposure(struct gspca_dev *gspca_dev, __s32 val) 243int ov9650_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
@@ -215,24 +251,24 @@ int ov9650_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
215 251
216 /* The 6 MSBs */ 252 /* The 6 MSBs */
217 i2c_data = (val >> 10) & 0x3f; 253 i2c_data = (val >> 10) & 0x3f;
218 err = ov9650_write_sensor(sd, OV9650_AECHM, 254 err = m5602_write_sensor(sd, OV9650_AECHM,
219 &i2c_data, 1); 255 &i2c_data, 1);
220 if (err < 0) 256 if (err < 0)
221 goto out; 257 goto out;
222 258
223 /* The 8 middle bits */ 259 /* The 8 middle bits */
224 i2c_data = (val >> 2) & 0xff; 260 i2c_data = (val >> 2) & 0xff;
225 err = ov9650_write_sensor(sd, OV9650_AECH, 261 err = m5602_write_sensor(sd, OV9650_AECH,
226 &i2c_data, 1); 262 &i2c_data, 1);
227 if (err < 0) 263 if (err < 0)
228 goto out; 264 goto out;
229 265
230 /* The 2 LSBs */ 266 /* The 2 LSBs */
231 i2c_data = val & 0x03; 267 i2c_data = val & 0x03;
232 err = ov9650_write_sensor(sd, OV9650_COM1, &i2c_data, 1); 268 err = m5602_write_sensor(sd, OV9650_COM1, &i2c_data, 1);
233 269
234out: 270out:
235 return (err < 0) ? err : 0; 271 return err;
236} 272}
237 273
238int ov9650_get_gain(struct gspca_dev *gspca_dev, __s32 *val) 274int ov9650_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
@@ -241,13 +277,13 @@ int ov9650_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
241 u8 i2c_data; 277 u8 i2c_data;
242 struct sd *sd = (struct sd *) gspca_dev; 278 struct sd *sd = (struct sd *) gspca_dev;
243 279
244 ov9650_read_sensor(sd, OV9650_VREF, &i2c_data, 1); 280 m5602_read_sensor(sd, OV9650_VREF, &i2c_data, 1);
245 *val = (i2c_data & 0x03) << 8; 281 *val = (i2c_data & 0x03) << 8;
246 282
247 err = ov9650_read_sensor(sd, OV9650_GAIN, &i2c_data, 1); 283 err = m5602_read_sensor(sd, OV9650_GAIN, &i2c_data, 1);
248 *val |= i2c_data; 284 *val |= i2c_data;
249 PDEBUG(D_V4L2, "Read gain %d", *val); 285 PDEBUG(D_V4L2, "Read gain %d", *val);
250 return (err < 0) ? err : 0; 286 return err;
251} 287}
252 288
253int ov9650_set_gain(struct gspca_dev *gspca_dev, __s32 val) 289int ov9650_set_gain(struct gspca_dev *gspca_dev, __s32 val)
@@ -259,16 +295,16 @@ int ov9650_set_gain(struct gspca_dev *gspca_dev, __s32 val)
259 /* The 2 MSB */ 295 /* The 2 MSB */
260 /* Read the OV9650_VREF register first to avoid 296 /* Read the OV9650_VREF register first to avoid
261 corrupting the VREF high and low bits */ 297 corrupting the VREF high and low bits */
262 ov9650_read_sensor(sd, OV9650_VREF, &i2c_data, 1); 298 m5602_read_sensor(sd, OV9650_VREF, &i2c_data, 1);
263 /* Mask away all uninteresting bits */ 299 /* Mask away all uninteresting bits */
264 i2c_data = ((val & 0x0300) >> 2) | 300 i2c_data = ((val & 0x0300) >> 2) |
265 (i2c_data & 0x3F); 301 (i2c_data & 0x3F);
266 err = ov9650_write_sensor(sd, OV9650_VREF, &i2c_data, 1); 302 err = m5602_write_sensor(sd, OV9650_VREF, &i2c_data, 1);
267 303
268 /* The 8 LSBs */ 304 /* The 8 LSBs */
269 i2c_data = val & 0xff; 305 i2c_data = val & 0xff;
270 err = ov9650_write_sensor(sd, OV9650_GAIN, &i2c_data, 1); 306 err = m5602_write_sensor(sd, OV9650_GAIN, &i2c_data, 1);
271 return (err < 0) ? err : 0; 307 return err;
272} 308}
273 309
274int ov9650_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val) 310int ov9650_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val)
@@ -277,12 +313,12 @@ int ov9650_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val)
277 u8 i2c_data; 313 u8 i2c_data;
278 struct sd *sd = (struct sd *) gspca_dev; 314 struct sd *sd = (struct sd *) gspca_dev;
279 315
280 err = ov9650_read_sensor(sd, OV9650_RED, &i2c_data, 1); 316 err = m5602_read_sensor(sd, OV9650_RED, &i2c_data, 1);
281 *val = i2c_data; 317 *val = i2c_data;
282 318
283 PDEBUG(D_V4L2, "Read red gain %d", *val); 319 PDEBUG(D_V4L2, "Read red gain %d", *val);
284 320
285 return (err < 0) ? err : 0; 321 return err;
286} 322}
287 323
288int ov9650_set_red_balance(struct gspca_dev *gspca_dev, __s32 val) 324int ov9650_set_red_balance(struct gspca_dev *gspca_dev, __s32 val)
@@ -295,9 +331,9 @@ int ov9650_set_red_balance(struct gspca_dev *gspca_dev, __s32 val)
295 val & 0xff); 331 val & 0xff);
296 332
297 i2c_data = val & 0xff; 333 i2c_data = val & 0xff;
298 err = ov9650_write_sensor(sd, OV9650_RED, &i2c_data, 1); 334 err = m5602_write_sensor(sd, OV9650_RED, &i2c_data, 1);
299 335
300 return (err < 0) ? err : 0; 336 return err;
301} 337}
302 338
303int ov9650_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val) 339int ov9650_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val)
@@ -306,12 +342,12 @@ int ov9650_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val)
306 u8 i2c_data; 342 u8 i2c_data;
307 struct sd *sd = (struct sd *) gspca_dev; 343 struct sd *sd = (struct sd *) gspca_dev;
308 344
309 err = ov9650_read_sensor(sd, OV9650_BLUE, &i2c_data, 1); 345 err = m5602_read_sensor(sd, OV9650_BLUE, &i2c_data, 1);
310 *val = i2c_data; 346 *val = i2c_data;
311 347
312 PDEBUG(D_V4L2, "Read blue gain %d", *val); 348 PDEBUG(D_V4L2, "Read blue gain %d", *val);
313 349
314 return (err < 0) ? err : 0; 350 return err;
315} 351}
316 352
317int ov9650_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val) 353int ov9650_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val)
@@ -324,9 +360,9 @@ int ov9650_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val)
324 val & 0xff); 360 val & 0xff);
325 361
326 i2c_data = val & 0xff; 362 i2c_data = val & 0xff;
327 err = ov9650_write_sensor(sd, OV9650_BLUE, &i2c_data, 1); 363 err = m5602_write_sensor(sd, OV9650_BLUE, &i2c_data, 1);
328 364
329 return (err < 0) ? err : 0; 365 return err;
330} 366}
331 367
332int ov9650_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) 368int ov9650_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
@@ -335,14 +371,14 @@ int ov9650_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
335 u8 i2c_data; 371 u8 i2c_data;
336 struct sd *sd = (struct sd *) gspca_dev; 372 struct sd *sd = (struct sd *) gspca_dev;
337 373
338 err = ov9650_read_sensor(sd, OV9650_MVFP, &i2c_data, 1); 374 err = m5602_read_sensor(sd, OV9650_MVFP, &i2c_data, 1);
339 if (dmi_check_system(ov9650_flip_dmi_table)) 375 if (dmi_check_system(ov9650_flip_dmi_table))
340 *val = ((i2c_data & OV9650_HFLIP) >> 5) ? 0 : 1; 376 *val = ((i2c_data & OV9650_HFLIP) >> 5) ? 0 : 1;
341 else 377 else
342 *val = (i2c_data & OV9650_HFLIP) >> 5; 378 *val = (i2c_data & OV9650_HFLIP) >> 5;
343 PDEBUG(D_V4L2, "Read horizontal flip %d", *val); 379 PDEBUG(D_V4L2, "Read horizontal flip %d", *val);
344 380
345 return (err < 0) ? err : 0; 381 return err;
346} 382}
347 383
348int ov9650_set_hflip(struct gspca_dev *gspca_dev, __s32 val) 384int ov9650_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
@@ -352,20 +388,20 @@ int ov9650_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
352 struct sd *sd = (struct sd *) gspca_dev; 388 struct sd *sd = (struct sd *) gspca_dev;
353 389
354 PDEBUG(D_V4L2, "Set horizontal flip to %d", val); 390 PDEBUG(D_V4L2, "Set horizontal flip to %d", val);
355 err = ov9650_read_sensor(sd, OV9650_MVFP, &i2c_data, 1); 391 err = m5602_read_sensor(sd, OV9650_MVFP, &i2c_data, 1);
356 if (err < 0) 392 if (err < 0)
357 goto out; 393 goto out;
358 394
359 if (dmi_check_system(ov9650_flip_dmi_table)) 395 if (dmi_check_system(ov9650_flip_dmi_table))
360 i2c_data = ((i2c_data & 0xdf) | 396 i2c_data = ((i2c_data & 0xdf) |
361 (((val ? 0 : 1) & 0x01) << 5)); 397 (((val ? 0 : 1) & 0x01) << 5));
362 else 398 else
363 i2c_data = ((i2c_data & 0xdf) | 399 i2c_data = ((i2c_data & 0xdf) |
364 ((val & 0x01) << 5)); 400 ((val & 0x01) << 5));
365 401
366 err = ov9650_write_sensor(sd, OV9650_MVFP, &i2c_data, 1); 402 err = m5602_write_sensor(sd, OV9650_MVFP, &i2c_data, 1);
367out: 403out:
368 return (err < 0) ? err : 0; 404 return err;
369} 405}
370 406
371int ov9650_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) 407int ov9650_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
@@ -374,14 +410,14 @@ int ov9650_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
374 u8 i2c_data; 410 u8 i2c_data;
375 struct sd *sd = (struct sd *) gspca_dev; 411 struct sd *sd = (struct sd *) gspca_dev;
376 412
377 err = ov9650_read_sensor(sd, OV9650_MVFP, &i2c_data, 1); 413 err = m5602_read_sensor(sd, OV9650_MVFP, &i2c_data, 1);
378 if (dmi_check_system(ov9650_flip_dmi_table)) 414 if (dmi_check_system(ov9650_flip_dmi_table))
379 *val = ((i2c_data & 0x10) >> 4) ? 0 : 1; 415 *val = ((i2c_data & 0x10) >> 4) ? 0 : 1;
380 else 416 else
381 *val = (i2c_data & 0x10) >> 4; 417 *val = (i2c_data & 0x10) >> 4;
382 PDEBUG(D_V4L2, "Read vertical flip %d", *val); 418 PDEBUG(D_V4L2, "Read vertical flip %d", *val);
383 419
384 return (err < 0) ? err : 0; 420 return err;
385} 421}
386 422
387int ov9650_set_vflip(struct gspca_dev *gspca_dev, __s32 val) 423int ov9650_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
@@ -391,7 +427,7 @@ int ov9650_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
391 struct sd *sd = (struct sd *) gspca_dev; 427 struct sd *sd = (struct sd *) gspca_dev;
392 428
393 PDEBUG(D_V4L2, "Set vertical flip to %d", val); 429 PDEBUG(D_V4L2, "Set vertical flip to %d", val);
394 err = ov9650_read_sensor(sd, OV9650_MVFP, &i2c_data, 1); 430 err = m5602_read_sensor(sd, OV9650_MVFP, &i2c_data, 1);
395 if (err < 0) 431 if (err < 0)
396 goto out; 432 goto out;
397 433
@@ -402,9 +438,9 @@ int ov9650_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
402 i2c_data = ((i2c_data & 0xef) | 438 i2c_data = ((i2c_data & 0xef) |
403 ((val & 0x01) << 4)); 439 ((val & 0x01) << 4));
404 440
405 err = ov9650_write_sensor(sd, OV9650_MVFP, &i2c_data, 1); 441 err = m5602_write_sensor(sd, OV9650_MVFP, &i2c_data, 1);
406out: 442out:
407 return (err < 0) ? err : 0; 443 return err;
408} 444}
409 445
410int ov9650_get_brightness(struct gspca_dev *gspca_dev, __s32 *val) 446int ov9650_get_brightness(struct gspca_dev *gspca_dev, __s32 *val)
@@ -413,16 +449,16 @@ int ov9650_get_brightness(struct gspca_dev *gspca_dev, __s32 *val)
413 u8 i2c_data; 449 u8 i2c_data;
414 struct sd *sd = (struct sd *) gspca_dev; 450 struct sd *sd = (struct sd *) gspca_dev;
415 451
416 err = ov9650_read_sensor(sd, OV9650_VREF, &i2c_data, 1); 452 err = m5602_read_sensor(sd, OV9650_VREF, &i2c_data, 1);
417 if (err < 0) 453 if (err < 0)
418 goto out; 454 goto out;
419 *val = (i2c_data & 0x03) << 8; 455 *val = (i2c_data & 0x03) << 8;
420 456
421 err = ov9650_read_sensor(sd, OV9650_GAIN, &i2c_data, 1); 457 err = m5602_read_sensor(sd, OV9650_GAIN, &i2c_data, 1);
422 *val |= i2c_data; 458 *val |= i2c_data;
423 PDEBUG(D_V4L2, "Read gain %d", *val); 459 PDEBUG(D_V4L2, "Read gain %d", *val);
424out: 460out:
425 return (err < 0) ? err : 0; 461 return err;
426} 462}
427 463
428int ov9650_set_brightness(struct gspca_dev *gspca_dev, __s32 val) 464int ov9650_set_brightness(struct gspca_dev *gspca_dev, __s32 val)
@@ -435,22 +471,22 @@ int ov9650_set_brightness(struct gspca_dev *gspca_dev, __s32 val)
435 471
436 /* Read the OV9650_VREF register first to avoid 472 /* Read the OV9650_VREF register first to avoid
437 corrupting the VREF high and low bits */ 473 corrupting the VREF high and low bits */
438 err = ov9650_read_sensor(sd, OV9650_VREF, &i2c_data, 1); 474 err = m5602_read_sensor(sd, OV9650_VREF, &i2c_data, 1);
439 if (err < 0) 475 if (err < 0)
440 goto out; 476 goto out;
441 477
442 /* Mask away all uninteresting bits */ 478 /* Mask away all uninteresting bits */
443 i2c_data = ((val & 0x0300) >> 2) | (i2c_data & 0x3F); 479 i2c_data = ((val & 0x0300) >> 2) | (i2c_data & 0x3F);
444 err = ov9650_write_sensor(sd, OV9650_VREF, &i2c_data, 1); 480 err = m5602_write_sensor(sd, OV9650_VREF, &i2c_data, 1);
445 if (err < 0) 481 if (err < 0)
446 goto out; 482 goto out;
447 483
448 /* The 8 LSBs */ 484 /* The 8 LSBs */
449 i2c_data = val & 0xff; 485 i2c_data = val & 0xff;
450 err = ov9650_write_sensor(sd, OV9650_GAIN, &i2c_data, 1); 486 err = m5602_write_sensor(sd, OV9650_GAIN, &i2c_data, 1);
451 487
452out: 488out:
453 return (err < 0) ? err : 0; 489 return err;
454} 490}
455 491
456int ov9650_get_auto_white_balance(struct gspca_dev *gspca_dev, __s32 *val) 492int ov9650_get_auto_white_balance(struct gspca_dev *gspca_dev, __s32 *val)
@@ -459,11 +495,11 @@ int ov9650_get_auto_white_balance(struct gspca_dev *gspca_dev, __s32 *val)
459 u8 i2c_data; 495 u8 i2c_data;
460 struct sd *sd = (struct sd *) gspca_dev; 496 struct sd *sd = (struct sd *) gspca_dev;
461 497
462 err = ov9650_read_sensor(sd, OV9650_COM8, &i2c_data, 1); 498 err = m5602_read_sensor(sd, OV9650_COM8, &i2c_data, 1);
463 *val = (i2c_data & OV9650_AWB_EN) >> 1; 499 *val = (i2c_data & OV9650_AWB_EN) >> 1;
464 PDEBUG(D_V4L2, "Read auto white balance %d", *val); 500 PDEBUG(D_V4L2, "Read auto white balance %d", *val);
465 501
466 return (err < 0) ? err : 0; 502 return err;
467} 503}
468 504
469int ov9650_set_auto_white_balance(struct gspca_dev *gspca_dev, __s32 val) 505int ov9650_set_auto_white_balance(struct gspca_dev *gspca_dev, __s32 val)
@@ -473,14 +509,14 @@ int ov9650_set_auto_white_balance(struct gspca_dev *gspca_dev, __s32 val)
473 struct sd *sd = (struct sd *) gspca_dev; 509 struct sd *sd = (struct sd *) gspca_dev;
474 510
475 PDEBUG(D_V4L2, "Set auto white balance to %d", val); 511 PDEBUG(D_V4L2, "Set auto white balance to %d", val);
476 err = ov9650_read_sensor(sd, OV9650_COM8, &i2c_data, 1); 512 err = m5602_read_sensor(sd, OV9650_COM8, &i2c_data, 1);
477 if (err < 0) 513 if (err < 0)
478 goto out; 514 goto out;
479 515
480 i2c_data = ((i2c_data & 0xfd) | ((val & 0x01) << 1)); 516 i2c_data = ((i2c_data & 0xfd) | ((val & 0x01) << 1));
481 err = ov9650_write_sensor(sd, OV9650_COM8, &i2c_data, 1); 517 err = m5602_write_sensor(sd, OV9650_COM8, &i2c_data, 1);
482out: 518out:
483 return (err < 0) ? err : 0; 519 return err;
484} 520}
485 521
486int ov9650_get_auto_gain(struct gspca_dev *gspca_dev, __s32 *val) 522int ov9650_get_auto_gain(struct gspca_dev *gspca_dev, __s32 *val)
@@ -489,11 +525,11 @@ int ov9650_get_auto_gain(struct gspca_dev *gspca_dev, __s32 *val)
489 u8 i2c_data; 525 u8 i2c_data;
490 struct sd *sd = (struct sd *) gspca_dev; 526 struct sd *sd = (struct sd *) gspca_dev;
491 527
492 err = ov9650_read_sensor(sd, OV9650_COM8, &i2c_data, 1); 528 err = m5602_read_sensor(sd, OV9650_COM8, &i2c_data, 1);
493 *val = (i2c_data & OV9650_AGC_EN) >> 2; 529 *val = (i2c_data & OV9650_AGC_EN) >> 2;
494 PDEBUG(D_V4L2, "Read auto gain control %d", *val); 530 PDEBUG(D_V4L2, "Read auto gain control %d", *val);
495 531
496 return (err < 0) ? err : 0; 532 return err;
497} 533}
498 534
499int ov9650_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val) 535int ov9650_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val)
@@ -503,23 +539,23 @@ int ov9650_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val)
503 struct sd *sd = (struct sd *) gspca_dev; 539 struct sd *sd = (struct sd *) gspca_dev;
504 540
505 PDEBUG(D_V4L2, "Set auto gain control to %d", val); 541 PDEBUG(D_V4L2, "Set auto gain control to %d", val);
506 err = ov9650_read_sensor(sd, OV9650_COM8, &i2c_data, 1); 542 err = m5602_read_sensor(sd, OV9650_COM8, &i2c_data, 1);
507 if (err < 0) 543 if (err < 0)
508 goto out; 544 goto out;
509 545
510 i2c_data = ((i2c_data & 0xfb) | ((val & 0x01) << 2)); 546 i2c_data = ((i2c_data & 0xfb) | ((val & 0x01) << 2));
511 err = ov9650_write_sensor(sd, OV9650_COM8, &i2c_data, 1); 547 err = m5602_write_sensor(sd, OV9650_COM8, &i2c_data, 1);
512out: 548out:
513 return (err < 0) ? err : 0; 549 return err;
514} 550}
515 551
516void ov9650_dump_registers(struct sd *sd) 552static void ov9650_dump_registers(struct sd *sd)
517{ 553{
518 int address; 554 int address;
519 info("Dumping the ov9650 register state"); 555 info("Dumping the ov9650 register state");
520 for (address = 0; address < 0xa9; address++) { 556 for (address = 0; address < 0xa9; address++) {
521 u8 value; 557 u8 value;
522 ov9650_read_sensor(sd, address, &value, 1); 558 m5602_read_sensor(sd, address, &value, 1);
523 info("register 0x%x contains 0x%x", 559 info("register 0x%x contains 0x%x",
524 address, value); 560 address, value);
525 } 561 }
@@ -531,9 +567,9 @@ void ov9650_dump_registers(struct sd *sd)
531 u8 old_value, ctrl_value; 567 u8 old_value, ctrl_value;
532 u8 test_value[2] = {0xff, 0xff}; 568 u8 test_value[2] = {0xff, 0xff};
533 569
534 ov9650_read_sensor(sd, address, &old_value, 1); 570 m5602_read_sensor(sd, address, &old_value, 1);
535 ov9650_write_sensor(sd, address, test_value, 1); 571 m5602_write_sensor(sd, address, test_value, 1);
536 ov9650_read_sensor(sd, address, &ctrl_value, 1); 572 m5602_read_sensor(sd, address, &ctrl_value, 1);
537 573
538 if (ctrl_value == test_value[0]) 574 if (ctrl_value == test_value[0])
539 info("register 0x%x is writeable", address); 575 info("register 0x%x is writeable", address);
@@ -541,6 +577,6 @@ void ov9650_dump_registers(struct sd *sd)
541 info("register 0x%x is read only", address); 577 info("register 0x%x is read only", address);
542 578
543 /* Restore original value */ 579 /* Restore original value */
544 ov9650_write_sensor(sd, address, &old_value, 1); 580 m5602_write_sensor(sd, address, &old_value, 1);
545 } 581 }
546} 582}
diff --git a/drivers/media/video/gspca/m5602/m5602_ov9650.h b/drivers/media/video/gspca/m5602/m5602_ov9650.h
index 065632f0378e..f4b33b8e8dae 100644
--- a/drivers/media/video/gspca/m5602/m5602_ov9650.h
+++ b/drivers/media/video/gspca/m5602/m5602_ov9650.h
@@ -20,7 +20,6 @@
20#define M5602_OV9650_H_ 20#define M5602_OV9650_H_
21 21
22#include <linux/dmi.h> 22#include <linux/dmi.h>
23
24#include "m5602_sensor.h" 23#include "m5602_sensor.h"
25 24
26/*****************************************************************************/ 25/*****************************************************************************/
@@ -36,6 +35,7 @@
36#define OV9650_PID 0x0a 35#define OV9650_PID 0x0a
37#define OV9650_VER 0x0b 36#define OV9650_VER 0x0b
38#define OV9650_COM3 0x0c 37#define OV9650_COM3 0x0c
38#define OV9650_COM4 0x0d
39#define OV9650_COM5 0x0e 39#define OV9650_COM5 0x0e
40#define OV9650_COM6 0x0f 40#define OV9650_COM6 0x0f
41#define OV9650_AECH 0x10 41#define OV9650_AECH 0x10
@@ -94,6 +94,8 @@
94 94
95#define OV9650_REGISTER_RESET (1 << 7) 95#define OV9650_REGISTER_RESET (1 << 7)
96#define OV9650_VGA_SELECT (1 << 6) 96#define OV9650_VGA_SELECT (1 << 6)
97#define OV9650_CIF_SELECT (1 << 5)
98#define OV9650_QVGA_SELECT (1 << 4)
97#define OV9650_RGB_SELECT (1 << 2) 99#define OV9650_RGB_SELECT (1 << 2)
98#define OV9650_RAW_RGB_SELECT (1 << 0) 100#define OV9650_RAW_RGB_SELECT (1 << 0)
99 101
@@ -108,6 +110,8 @@
108#define OV9650_SYSTEM_CLK_SEL (1 << 7) 110#define OV9650_SYSTEM_CLK_SEL (1 << 7)
109#define OV9650_SLAM_MODE (1 << 4) 111#define OV9650_SLAM_MODE (1 << 4)
110 112
113#define OV9650_QVGA_VARIOPIXEL (1 << 7)
114
111#define OV9650_VFLIP (1 << 4) 115#define OV9650_VFLIP (1 << 4)
112#define OV9650_HFLIP (1 << 5) 116#define OV9650_HFLIP (1 << 5)
113 117
@@ -124,15 +128,9 @@ extern int dump_sensor;
124 128
125int ov9650_probe(struct sd *sd); 129int ov9650_probe(struct sd *sd);
126int ov9650_init(struct sd *sd); 130int ov9650_init(struct sd *sd);
131int ov9650_start(struct sd *sd);
127int ov9650_power_down(struct sd *sd); 132int ov9650_power_down(struct sd *sd);
128 133
129int ov9650_read_sensor(struct sd *sd, const u8 address,
130 u8 *i2c_data, const u8 len);
131int ov9650_write_sensor(struct sd *sd, const u8 address,
132 u8 *i2c_data, const u8 len);
133
134void ov9650_dump_registers(struct sd *sd);
135
136int ov9650_set_exposure(struct gspca_dev *gspca_dev, __s32 val); 134int ov9650_set_exposure(struct gspca_dev *gspca_dev, __s32 val);
137int ov9650_get_exposure(struct gspca_dev *gspca_dev, __s32 *val); 135int ov9650_get_exposure(struct gspca_dev *gspca_dev, __s32 *val);
138int ov9650_get_gain(struct gspca_dev *gspca_dev, __s32 *val); 136int ov9650_get_gain(struct gspca_dev *gspca_dev, __s32 *val);
@@ -155,11 +153,11 @@ int ov9650_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val);
155static struct m5602_sensor ov9650 = { 153static struct m5602_sensor ov9650 = {
156 .name = "OV9650", 154 .name = "OV9650",
157 .i2c_slave_id = 0x60, 155 .i2c_slave_id = 0x60,
156 .i2c_regW = 1,
158 .probe = ov9650_probe, 157 .probe = ov9650_probe,
159 .init = ov9650_init, 158 .init = ov9650_init,
159 .start = ov9650_start,
160 .power_down = ov9650_power_down, 160 .power_down = ov9650_power_down,
161 .read_sensor = ov9650_read_sensor,
162 .write_sensor = ov9650_write_sensor,
163 161
164 .nctrls = 8, 162 .nctrls = 8,
165 .ctrls = { 163 .ctrls = {
@@ -264,18 +262,38 @@ static struct m5602_sensor ov9650 = {
264 } 262 }
265 }, 263 },
266 264
267 .nmodes = 1, 265 .nmodes = 3,
268 .modes = { 266 .modes = {
269 { 267 {
270 M5602_DEFAULT_FRAME_WIDTH, 268 320,
271 M5602_DEFAULT_FRAME_HEIGHT, 269 240,
270 V4L2_PIX_FMT_SBGGR8,
271 V4L2_FIELD_NONE,
272 .sizeimage =
273 320 * 240,
274 .bytesperline = 320,
275 .colorspace = V4L2_COLORSPACE_SRGB,
276 .priv = 0
277 }, {
278 352,
279 288,
280 V4L2_PIX_FMT_SBGGR8,
281 V4L2_FIELD_NONE,
282 .sizeimage =
283 352 * 288,
284 .bytesperline = 352,
285 .colorspace = V4L2_COLORSPACE_SRGB,
286 .priv = 0
287 }, {
288 640,
289 480,
272 V4L2_PIX_FMT_SBGGR8, 290 V4L2_PIX_FMT_SBGGR8,
273 V4L2_FIELD_NONE, 291 V4L2_FIELD_NONE,
274 .sizeimage = 292 .sizeimage =
275 M5602_DEFAULT_FRAME_WIDTH * M5602_DEFAULT_FRAME_HEIGHT, 293 640 * 480,
276 .bytesperline = M5602_DEFAULT_FRAME_WIDTH, 294 .bytesperline = 640,
277 .colorspace = V4L2_COLORSPACE_SRGB, 295 .colorspace = V4L2_COLORSPACE_SRGB,
278 .priv = 1 296 .priv = 0
279 } 297 }
280 } 298 }
281}; 299};
@@ -324,6 +342,7 @@ static const unsigned char init_ov9650[][3] =
324 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00}, 342 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00},
325 {BRIDGE, M5602_XB_GPIO_DAT, 0x00}, 343 {BRIDGE, M5602_XB_GPIO_DAT, 0x00},
326 {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x0a}, 344 {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x0a},
345
327 /* Reset chip */ 346 /* Reset chip */
328 {SENSOR, OV9650_COM7, OV9650_REGISTER_RESET}, 347 {SENSOR, OV9650_COM7, OV9650_REGISTER_RESET},
329 /* Enable double clock */ 348 /* Enable double clock */
@@ -331,8 +350,6 @@ static const unsigned char init_ov9650[][3] =
331 /* Do something out of spec with the power */ 350 /* Do something out of spec with the power */
332 {SENSOR, OV9650_OFON, 0x40}, 351 {SENSOR, OV9650_OFON, 0x40},
333 352
334 /* Set QQVGA */
335 {SENSOR, OV9650_COM1, 0x20},
336 /* Set fast AGC/AEC algorithm with unlimited step size */ 353 /* Set fast AGC/AEC algorithm with unlimited step size */
337 {SENSOR, OV9650_COM8, OV9650_FAST_AGC_AEC | 354 {SENSOR, OV9650_COM8, OV9650_FAST_AGC_AEC |
338 OV9650_AEC_UNLIM_STEP_SIZE | 355 OV9650_AEC_UNLIM_STEP_SIZE |
@@ -343,7 +360,7 @@ static const unsigned char init_ov9650[][3] =
343 {SENSOR, OV9650_ACOM38, 0x81}, 360 {SENSOR, OV9650_ACOM38, 0x81},
344 /* Turn off color matrix coefficient double option */ 361 /* Turn off color matrix coefficient double option */
345 {SENSOR, OV9650_COM16, 0x00}, 362 {SENSOR, OV9650_COM16, 0x00},
346 /* Enable color matrix for RGB/YUV, Delay Y channel, 363 /* Enable color matrix for RGB/YUV, Delay Y channel,
347 set output Y/UV delay to 1 */ 364 set output Y/UV delay to 1 */
348 {SENSOR, OV9650_COM13, 0x19}, 365 {SENSOR, OV9650_COM13, 0x19},
349 /* Enable digital BLC, Set output mode to U Y V Y */ 366 /* Enable digital BLC, Set output mode to U Y V Y */
@@ -352,7 +369,7 @@ static const unsigned char init_ov9650[][3] =
352 {SENSOR, OV9650_COM24, 0x00}, 369 {SENSOR, OV9650_COM24, 0x00},
353 /* Enable HREF and some out of spec things */ 370 /* Enable HREF and some out of spec things */
354 {SENSOR, OV9650_COM12, 0x73}, 371 {SENSOR, OV9650_COM12, 0x73},
355 /* Set all DBLC offset signs to positive and 372 /* Set all DBLC offset signs to positive and
356 do some out of spec stuff */ 373 do some out of spec stuff */
357 {SENSOR, OV9650_DBLC1, 0xdf}, 374 {SENSOR, OV9650_DBLC1, 0xdf},
358 {SENSOR, OV9650_COM21, 0x06}, 375 {SENSOR, OV9650_COM21, 0x06},
@@ -364,7 +381,7 @@ static const unsigned char init_ov9650[][3] =
364 {SENSOR, OV9650_RSVD96, 0x04}, 381 {SENSOR, OV9650_RSVD96, 0x04},
365 /* Enable full range output */ 382 /* Enable full range output */
366 {SENSOR, OV9650_COM15, 0x0}, 383 {SENSOR, OV9650_COM15, 0x0},
367 /* Enable HREF at optical black, enable ADBLC bias, 384 /* Enable HREF at optical black, enable ADBLC bias,
368 enable ADBLC, reset timings at format change */ 385 enable ADBLC, reset timings at format change */
369 {SENSOR, OV9650_COM6, 0x4b}, 386 {SENSOR, OV9650_COM6, 0x4b},
370 /* Subtract 32 from the B channel bias */ 387 /* Subtract 32 from the B channel bias */
@@ -385,7 +402,7 @@ static const unsigned char init_ov9650[][3] =
385 {SENSOR, OV9650_AEB, 0x5c}, 402 {SENSOR, OV9650_AEB, 0x5c},
386 /* Set the high and low limit nibbles to 3 */ 403 /* Set the high and low limit nibbles to 3 */
387 {SENSOR, OV9650_VPT, 0xc3}, 404 {SENSOR, OV9650_VPT, 0xc3},
388 /* Set the Automatic Gain Ceiling (AGC) to 128x, 405 /* Set the Automatic Gain Ceiling (AGC) to 128x,
389 drop VSYNC at frame drop, 406 drop VSYNC at frame drop,
390 limit exposure timing, 407 limit exposure timing,
391 drop frame when the AEC step is larger than the exposure gap */ 408 drop frame when the AEC step is larger than the exposure gap */
@@ -394,9 +411,9 @@ static const unsigned char init_ov9650[][3] =
394 and set PWDN to SLVS (slave mode vertical sync) */ 411 and set PWDN to SLVS (slave mode vertical sync) */
395 {SENSOR, OV9650_COM10, 0x42}, 412 {SENSOR, OV9650_COM10, 0x42},
396 /* Set horizontal column start high to default value */ 413 /* Set horizontal column start high to default value */
397 {SENSOR, OV9650_HSTART, 0x1a}, 414 {SENSOR, OV9650_HSTART, 0x1a}, /* 210 */
398 /* Set horizontal column end */ 415 /* Set horizontal column end */
399 {SENSOR, OV9650_HSTOP, 0xbf}, 416 {SENSOR, OV9650_HSTOP, 0xbf}, /* 1534 */
400 /* Complementing register to the two writes above */ 417 /* Complementing register to the two writes above */
401 {SENSOR, OV9650_HREF, 0xb2}, 418 {SENSOR, OV9650_HREF, 0xb2},
402 /* Set vertical row start high bits */ 419 /* Set vertical row start high bits */
@@ -405,10 +422,6 @@ static const unsigned char init_ov9650[][3] =
405 {SENSOR, OV9650_VSTOP, 0x7e}, 422 {SENSOR, OV9650_VSTOP, 0x7e},
406 /* Set complementing vertical frame control */ 423 /* Set complementing vertical frame control */
407 {SENSOR, OV9650_VREF, 0x10}, 424 {SENSOR, OV9650_VREF, 0x10},
408 /* Set raw RGB output format with VGA resolution */
409 {SENSOR, OV9650_COM7, OV9650_VGA_SELECT |
410 OV9650_RGB_SELECT |
411 OV9650_RAW_RGB_SELECT},
412 {SENSOR, OV9650_ADC, 0x04}, 425 {SENSOR, OV9650_ADC, 0x04},
413 {SENSOR, OV9650_HV, 0x40}, 426 {SENSOR, OV9650_HV, 0x40},
414 /* Enable denoise, and white-pixel erase */ 427 /* Enable denoise, and white-pixel erase */
@@ -417,30 +430,15 @@ static const unsigned char init_ov9650[][3] =
417 /* Set the high bits of the exposure value */ 430 /* Set the high bits of the exposure value */
418 {SENSOR, OV9650_AECH, ((EXPOSURE_DEFAULT & 0xff00) >> 8)}, 431 {SENSOR, OV9650_AECH, ((EXPOSURE_DEFAULT & 0xff00) >> 8)},
419 432
433 /* Enable VARIOPIXEL */
434 {SENSOR, OV9650_COM3, OV9650_VARIOPIXEL},
435 {SENSOR, OV9650_COM4, OV9650_QVGA_VARIOPIXEL},
436
420 /* Set the low bits of the exposure value */ 437 /* Set the low bits of the exposure value */
421 {SENSOR, OV9650_COM1, (EXPOSURE_DEFAULT & 0xff)}, 438 {SENSOR, OV9650_COM1, (EXPOSURE_DEFAULT & 0xff)},
422 {SENSOR, OV9650_GAIN, GAIN_DEFAULT}, 439 {SENSOR, OV9650_GAIN, GAIN_DEFAULT},
423 {SENSOR, OV9650_BLUE, BLUE_GAIN_DEFAULT}, 440 {SENSOR, OV9650_BLUE, BLUE_GAIN_DEFAULT},
424 {SENSOR, OV9650_RED, RED_GAIN_DEFAULT}, 441 {SENSOR, OV9650_RED, RED_GAIN_DEFAULT},
425
426 {SENSOR, OV9650_COM3, OV9650_VARIOPIXEL},
427 {SENSOR, OV9650_COM5, OV9650_SYSTEM_CLK_SEL},
428
429 {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x82},
430 {BRIDGE, M5602_XB_LINE_OF_FRAME_L, 0x00},
431 {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82},
432 {BRIDGE, M5602_XB_PIX_OF_LINE_L, 0x00},
433 {BRIDGE, M5602_XB_SIG_INI, 0x01},
434 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
435 {BRIDGE, M5602_XB_VSYNC_PARA, 0x09},
436 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
437 {BRIDGE, M5602_XB_VSYNC_PARA, 0x01},
438 {BRIDGE, M5602_XB_VSYNC_PARA, 0xe0},
439 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
440 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00},
441 {BRIDGE, M5602_XB_HSYNC_PARA, 0x5e},
442 {BRIDGE, M5602_XB_HSYNC_PARA, 0x02},
443 {BRIDGE, M5602_XB_HSYNC_PARA, 0xde}
444}; 442};
445 443
446static const unsigned char power_down_ov9650[][3] = 444static const unsigned char power_down_ov9650[][3] =
@@ -460,43 +458,76 @@ static const unsigned char power_down_ov9650[][3] =
460 {BRIDGE, M5602_XB_GPIO_EN_L, 0x06}, 458 {BRIDGE, M5602_XB_GPIO_EN_L, 0x06},
461 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02}, 459 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02},
462 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04}, 460 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04},
463 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0} 461 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
464}; 462};
465 463
466/* Vertically and horizontally flips the image if matched, needed for machines 464static const unsigned char res_init_ov9650[][2] =
467 where the sensor is mounted upside down */ 465{
468static 466 {M5602_XB_LINE_OF_FRAME_H, 0x82},
469 const 467 {M5602_XB_LINE_OF_FRAME_L, 0x00},
470 struct dmi_system_id ov9650_flip_dmi_table[] = { 468 {M5602_XB_PIX_OF_LINE_H, 0x82},
471 { 469 {M5602_XB_PIX_OF_LINE_L, 0x00},
472 .ident = "ASUS A6VC", 470 {M5602_XB_SIG_INI, 0x01}
473 .matches = { 471};
474 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), 472
475 DMI_MATCH(DMI_PRODUCT_NAME, "A6VC") 473static const unsigned char VGA_ov9650[][3] =
476 } 474{
477 }, 475 /* Moves the view window in a vertical orientation */
478 { 476 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
479 .ident = "ASUS A6VM", 477 {BRIDGE, M5602_XB_VSYNC_PARA, 0x09},
480 .matches = { 478 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
481 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), 479 {BRIDGE, M5602_XB_VSYNC_PARA, 0x01},
482 DMI_MATCH(DMI_PRODUCT_NAME, "A6VM") 480 {BRIDGE, M5602_XB_VSYNC_PARA, 0xe0}, /* 480 */
483 } 481 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
484 }, 482 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
485 { 483 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00},
486 .ident = "ASUS A6JC", 484 {BRIDGE, M5602_XB_HSYNC_PARA, 0x62}, /* 98 */
487 .matches = { 485 {BRIDGE, M5602_XB_HSYNC_PARA, 0x02}, /* 640 + 98 */
488 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), 486 {BRIDGE, M5602_XB_HSYNC_PARA, 0xe2},
489 DMI_MATCH(DMI_PRODUCT_NAME, "A6JC") 487
490 } 488 {SENSOR, OV9650_COM7, OV9650_VGA_SELECT |
491 }, 489 OV9650_RGB_SELECT |
492 { 490 OV9650_RAW_RGB_SELECT},
493 .ident = "ASUS A6Kt", 491};
494 .matches = { 492
495 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), 493static const unsigned char CIF_ov9650[][3] =
496 DMI_MATCH(DMI_PRODUCT_NAME, "A6Kt") 494{
497 } 495 /* Moves the view window in a vertical orientation */
498 }, 496 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
499 { } 497 {BRIDGE, M5602_XB_VSYNC_PARA, 0x09},
498 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
499 {BRIDGE, M5602_XB_VSYNC_PARA, 0x01},
500 {BRIDGE, M5602_XB_VSYNC_PARA, 0x20}, /* 288 */
501 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
502 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
503 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00},
504 {BRIDGE, M5602_XB_HSYNC_PARA, 0x62}, /* 98 */
505 {BRIDGE, M5602_XB_HSYNC_PARA, 0x01}, /* 352 + 98 */
506 {BRIDGE, M5602_XB_HSYNC_PARA, 0xc2},
507
508 {SENSOR, OV9650_COM7, OV9650_CIF_SELECT |
509 OV9650_RGB_SELECT |
510 OV9650_RAW_RGB_SELECT},
511};
512
513static const unsigned char QVGA_ov9650[][3] =
514{
515 /* Moves the view window in a vertical orientation */
516 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
517 {BRIDGE, M5602_XB_VSYNC_PARA, 0x08},
518 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
519 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
520 {BRIDGE, M5602_XB_VSYNC_PARA, 0xf0}, /* 240 */
521 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
522 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
523 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00},
524 {BRIDGE, M5602_XB_HSYNC_PARA, 0x31}, /* 50 */
525 {BRIDGE, M5602_XB_HSYNC_PARA, 0x01}, /* 320 + 50 */
526 {BRIDGE, M5602_XB_HSYNC_PARA, 0x71},
527
528 {SENSOR, OV9650_COM7, OV9650_QVGA_SELECT |
529 OV9650_RGB_SELECT |
530 OV9650_RAW_RGB_SELECT},
500}; 531};
501 532
502#endif 533#endif
diff --git a/drivers/media/video/gspca/m5602/m5602_po1030.c b/drivers/media/video/gspca/m5602/m5602_po1030.c
index d17ac52566e6..2e7fb91673cf 100644
--- a/drivers/media/video/gspca/m5602/m5602_po1030.c
+++ b/drivers/media/video/gspca/m5602/m5602_po1030.c
@@ -18,6 +18,8 @@
18 18
19#include "m5602_po1030.h" 19#include "m5602_po1030.h"
20 20
21static void po1030_dump_registers(struct sd *sd);
22
21int po1030_probe(struct sd *sd) 23int po1030_probe(struct sd *sd)
22{ 24{
23 u8 prod_id = 0, ver_id = 0, i; 25 u8 prod_id = 0, ver_id = 0, i;
@@ -38,16 +40,16 @@ int po1030_probe(struct sd *sd)
38 for (i = 0; i < ARRAY_SIZE(preinit_po1030); i++) { 40 for (i = 0; i < ARRAY_SIZE(preinit_po1030); i++) {
39 u8 data = preinit_po1030[i][2]; 41 u8 data = preinit_po1030[i][2];
40 if (preinit_po1030[i][0] == SENSOR) 42 if (preinit_po1030[i][0] == SENSOR)
41 po1030_write_sensor(sd, 43 m5602_write_sensor(sd,
42 preinit_po1030[i][1], &data, 1); 44 preinit_po1030[i][1], &data, 1);
43 else 45 else
44 m5602_write_bridge(sd, preinit_po1030[i][1], data); 46 m5602_write_bridge(sd, preinit_po1030[i][1], data);
45 } 47 }
46 48
47 if (po1030_read_sensor(sd, 0x3, &prod_id, 1)) 49 if (m5602_read_sensor(sd, 0x3, &prod_id, 1))
48 return -ENODEV; 50 return -ENODEV;
49 51
50 if (po1030_read_sensor(sd, 0x4, &ver_id, 1)) 52 if (m5602_read_sensor(sd, 0x4, &ver_id, 1))
51 return -ENODEV; 53 return -ENODEV;
52 54
53 if ((prod_id == 0x02) && (ver_id == 0xef)) { 55 if ((prod_id == 0x02) && (ver_id == 0xef)) {
@@ -64,78 +66,12 @@ sensor_found:
64 return 0; 66 return 0;
65} 67}
66 68
67int po1030_read_sensor(struct sd *sd, const u8 address,
68 u8 *i2c_data, const u8 len)
69{
70 int err, i;
71
72 do {
73 err = m5602_read_bridge(sd, M5602_XB_I2C_STATUS, i2c_data);
74 } while ((*i2c_data & I2C_BUSY) && !err);
75
76 m5602_write_bridge(sd, M5602_XB_I2C_DEV_ADDR,
77 sd->sensor->i2c_slave_id);
78 m5602_write_bridge(sd, M5602_XB_I2C_REG_ADDR, address);
79 m5602_write_bridge(sd, M5602_XB_I2C_CTRL, 0x10 + len);
80 m5602_write_bridge(sd, M5602_XB_I2C_CTRL, 0x08);
81
82 for (i = 0; i < len; i++) {
83 err = m5602_read_bridge(sd, M5602_XB_I2C_DATA, &(i2c_data[i]));
84
85 PDEBUG(D_CONF, "Reading sensor register "
86 "0x%x containing 0x%x ", address, *i2c_data);
87 }
88 return (err < 0) ? err : 0;
89}
90
91int po1030_write_sensor(struct sd *sd, const u8 address,
92 u8 *i2c_data, const u8 len)
93{
94 int err, i;
95 u8 *p;
96 struct usb_device *udev = sd->gspca_dev.dev;
97 __u8 *buf = sd->gspca_dev.usb_buf;
98
99 /* The po1030 only supports one byte writes */
100 if (len > 1 || !len)
101 return -EINVAL;
102
103 memcpy(buf, sensor_urb_skeleton, sizeof(sensor_urb_skeleton));
104
105 buf[11] = sd->sensor->i2c_slave_id;
106 buf[15] = address;
107
108 p = buf + 16;
109
110 /* Copy a four byte write sequence for each byte to be written to */
111 for (i = 0; i < len; i++) {
112 memcpy(p, sensor_urb_skeleton + 16, 4);
113 p[3] = i2c_data[i];
114 p += 4;
115 PDEBUG(D_CONF, "Writing sensor register 0x%x with 0x%x",
116 address, i2c_data[i]);
117 }
118
119 /* Copy the footer */
120 memcpy(p, sensor_urb_skeleton + 20, 4);
121
122 /* Set the total length */
123 p[3] = 0x10 + len;
124
125 err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
126 0x04, 0x40, 0x19,
127 0x0000, buf,
128 20 + len * 4, M5602_URB_MSG_TIMEOUT);
129
130 return (err < 0) ? err : 0;
131}
132
133int po1030_init(struct sd *sd) 69int po1030_init(struct sd *sd)
134{ 70{
135 int i, err = 0; 71 int i, err = 0;
136 72
137 /* Init the sensor */ 73 /* Init the sensor */
138 for (i = 0; i < ARRAY_SIZE(init_po1030); i++) { 74 for (i = 0; i < ARRAY_SIZE(init_po1030) && !err; i++) {
139 u8 data[2] = {0x00, 0x00}; 75 u8 data[2] = {0x00, 0x00};
140 76
141 switch (init_po1030[i][0]) { 77 switch (init_po1030[i][0]) {
@@ -147,16 +83,10 @@ int po1030_init(struct sd *sd)
147 83
148 case SENSOR: 84 case SENSOR:
149 data[0] = init_po1030[i][2]; 85 data[0] = init_po1030[i][2];
150 err = po1030_write_sensor(sd, 86 err = m5602_write_sensor(sd,
151 init_po1030[i][1], data, 1); 87 init_po1030[i][1], data, 1);
152 break; 88 break;
153 89
154 case SENSOR_LONG:
155 data[0] = init_po1030[i][2];
156 data[1] = init_po1030[i][3];
157 err = po1030_write_sensor(sd,
158 init_po1030[i][1], data, 2);
159 break;
160 default: 90 default:
161 info("Invalid stream command, exiting init"); 91 info("Invalid stream command, exiting init");
162 return -EINVAL; 92 return -EINVAL;
@@ -166,7 +96,7 @@ int po1030_init(struct sd *sd)
166 if (dump_sensor) 96 if (dump_sensor)
167 po1030_dump_registers(sd); 97 po1030_dump_registers(sd);
168 98
169 return (err < 0) ? err : 0; 99 return err;
170} 100}
171 101
172int po1030_get_exposure(struct gspca_dev *gspca_dev, __s32 *val) 102int po1030_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
@@ -175,19 +105,19 @@ int po1030_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
175 u8 i2c_data; 105 u8 i2c_data;
176 int err; 106 int err;
177 107
178 err = po1030_read_sensor(sd, PO1030_REG_INTEGLINES_H, 108 err = m5602_read_sensor(sd, PO1030_REG_INTEGLINES_H,
179 &i2c_data, 1); 109 &i2c_data, 1);
180 if (err < 0) 110 if (err < 0)
181 goto out; 111 goto out;
182 *val = (i2c_data << 8); 112 *val = (i2c_data << 8);
183 113
184 err = po1030_read_sensor(sd, PO1030_REG_INTEGLINES_M, 114 err = m5602_read_sensor(sd, PO1030_REG_INTEGLINES_M,
185 &i2c_data, 1); 115 &i2c_data, 1);
186 *val |= i2c_data; 116 *val |= i2c_data;
187 117
188 PDEBUG(D_V4L2, "Exposure read as %d", *val); 118 PDEBUG(D_V4L2, "Exposure read as %d", *val);
189out: 119out:
190 return (err < 0) ? err : 0; 120 return err;
191} 121}
192 122
193int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val) 123int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
@@ -202,7 +132,7 @@ int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
202 PDEBUG(D_V4L2, "Set exposure to high byte to 0x%x", 132 PDEBUG(D_V4L2, "Set exposure to high byte to 0x%x",
203 i2c_data); 133 i2c_data);
204 134
205 err = po1030_write_sensor(sd, PO1030_REG_INTEGLINES_H, 135 err = m5602_write_sensor(sd, PO1030_REG_INTEGLINES_H,
206 &i2c_data, 1); 136 &i2c_data, 1);
207 if (err < 0) 137 if (err < 0)
208 goto out; 138 goto out;
@@ -210,11 +140,11 @@ int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
210 i2c_data = (val & 0xff); 140 i2c_data = (val & 0xff);
211 PDEBUG(D_V4L2, "Set exposure to low byte to 0x%x", 141 PDEBUG(D_V4L2, "Set exposure to low byte to 0x%x",
212 i2c_data); 142 i2c_data);
213 err = po1030_write_sensor(sd, PO1030_REG_INTEGLINES_M, 143 err = m5602_write_sensor(sd, PO1030_REG_INTEGLINES_M,
214 &i2c_data, 1); 144 &i2c_data, 1);
215 145
216out: 146out:
217 return (err < 0) ? err : 0; 147 return err;
218} 148}
219 149
220int po1030_get_gain(struct gspca_dev *gspca_dev, __s32 *val) 150int po1030_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
@@ -223,12 +153,12 @@ int po1030_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
223 u8 i2c_data; 153 u8 i2c_data;
224 int err; 154 int err;
225 155
226 err = po1030_read_sensor(sd, PO1030_REG_GLOBALGAIN, 156 err = m5602_read_sensor(sd, PO1030_REG_GLOBALGAIN,
227 &i2c_data, 1); 157 &i2c_data, 1);
228 *val = i2c_data; 158 *val = i2c_data;
229 PDEBUG(D_V4L2, "Read global gain %d", *val); 159 PDEBUG(D_V4L2, "Read global gain %d", *val);
230 160
231 return (err < 0) ? err : 0; 161 return err;
232} 162}
233 163
234int po1030_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) 164int po1030_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
@@ -237,14 +167,14 @@ int po1030_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
237 u8 i2c_data; 167 u8 i2c_data;
238 int err; 168 int err;
239 169
240 err = po1030_read_sensor(sd, PO1030_REG_CONTROL2, 170 err = m5602_read_sensor(sd, PO1030_REG_CONTROL2,
241 &i2c_data, 1); 171 &i2c_data, 1);
242 172
243 *val = (i2c_data >> 7) & 0x01 ; 173 *val = (i2c_data >> 7) & 0x01 ;
244 174
245 PDEBUG(D_V4L2, "Read hflip %d", *val); 175 PDEBUG(D_V4L2, "Read hflip %d", *val);
246 176
247 return (err < 0) ? err : 0; 177 return err;
248} 178}
249 179
250int po1030_set_hflip(struct gspca_dev *gspca_dev, __s32 val) 180int po1030_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
@@ -254,13 +184,17 @@ int po1030_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
254 int err; 184 int err;
255 185
256 PDEBUG(D_V4L2, "Set hflip %d", val); 186 PDEBUG(D_V4L2, "Set hflip %d", val);
187 err = m5602_read_sensor(sd, PO1030_REG_CONTROL2, &i2c_data, 1);
188 if (err < 0)
189 goto out;
257 190
258 i2c_data = (val & 0x01) << 7; 191 i2c_data = (0x7f & i2c_data) | ((val & 0x01) << 7);
259 192
260 err = po1030_write_sensor(sd, PO1030_REG_CONTROL2, 193 err = m5602_write_sensor(sd, PO1030_REG_CONTROL2,
261 &i2c_data, 1); 194 &i2c_data, 1);
262 195
263 return (err < 0) ? err : 0; 196out:
197 return err;
264} 198}
265 199
266int po1030_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) 200int po1030_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
@@ -269,14 +203,14 @@ int po1030_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
269 u8 i2c_data; 203 u8 i2c_data;
270 int err; 204 int err;
271 205
272 err = po1030_read_sensor(sd, PO1030_REG_GLOBALGAIN, 206 err = m5602_read_sensor(sd, PO1030_REG_GLOBALGAIN,
273 &i2c_data, 1); 207 &i2c_data, 1);
274 208
275 *val = (i2c_data >> 6) & 0x01; 209 *val = (i2c_data >> 6) & 0x01;
276 210
277 PDEBUG(D_V4L2, "Read vflip %d", *val); 211 PDEBUG(D_V4L2, "Read vflip %d", *val);
278 212
279 return (err < 0) ? err : 0; 213 return err;
280} 214}
281 215
282int po1030_set_vflip(struct gspca_dev *gspca_dev, __s32 val) 216int po1030_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
@@ -286,13 +220,17 @@ int po1030_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
286 int err; 220 int err;
287 221
288 PDEBUG(D_V4L2, "Set vflip %d", val); 222 PDEBUG(D_V4L2, "Set vflip %d", val);
223 err = m5602_read_sensor(sd, PO1030_REG_CONTROL2, &i2c_data, 1);
224 if (err < 0)
225 goto out;
289 226
290 i2c_data = (val & 0x01) << 6; 227 i2c_data = (i2c_data & 0xbf) | ((val & 0x01) << 6);
291 228
292 err = po1030_write_sensor(sd, PO1030_REG_CONTROL2, 229 err = m5602_write_sensor(sd, PO1030_REG_CONTROL2,
293 &i2c_data, 1); 230 &i2c_data, 1);
294 231
295 return (err < 0) ? err : 0; 232out:
233 return err;
296} 234}
297 235
298int po1030_set_gain(struct gspca_dev *gspca_dev, __s32 val) 236int po1030_set_gain(struct gspca_dev *gspca_dev, __s32 val)
@@ -303,9 +241,9 @@ int po1030_set_gain(struct gspca_dev *gspca_dev, __s32 val)
303 241
304 i2c_data = val & 0xff; 242 i2c_data = val & 0xff;
305 PDEBUG(D_V4L2, "Set global gain to %d", i2c_data); 243 PDEBUG(D_V4L2, "Set global gain to %d", i2c_data);
306 err = po1030_write_sensor(sd, PO1030_REG_GLOBALGAIN, 244 err = m5602_write_sensor(sd, PO1030_REG_GLOBALGAIN,
307 &i2c_data, 1); 245 &i2c_data, 1);
308 return (err < 0) ? err : 0; 246 return err;
309} 247}
310 248
311int po1030_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val) 249int po1030_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val)
@@ -314,11 +252,11 @@ int po1030_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val)
314 u8 i2c_data; 252 u8 i2c_data;
315 int err; 253 int err;
316 254
317 err = po1030_read_sensor(sd, PO1030_REG_RED_GAIN, 255 err = m5602_read_sensor(sd, PO1030_REG_RED_GAIN,
318 &i2c_data, 1); 256 &i2c_data, 1);
319 *val = i2c_data; 257 *val = i2c_data;
320 PDEBUG(D_V4L2, "Read red gain %d", *val); 258 PDEBUG(D_V4L2, "Read red gain %d", *val);
321 return (err < 0) ? err : 0; 259 return err;
322} 260}
323 261
324int po1030_set_red_balance(struct gspca_dev *gspca_dev, __s32 val) 262int po1030_set_red_balance(struct gspca_dev *gspca_dev, __s32 val)
@@ -329,9 +267,9 @@ int po1030_set_red_balance(struct gspca_dev *gspca_dev, __s32 val)
329 267
330 i2c_data = val & 0xff; 268 i2c_data = val & 0xff;
331 PDEBUG(D_V4L2, "Set red gain to %d", i2c_data); 269 PDEBUG(D_V4L2, "Set red gain to %d", i2c_data);
332 err = po1030_write_sensor(sd, PO1030_REG_RED_GAIN, 270 err = m5602_write_sensor(sd, PO1030_REG_RED_GAIN,
333 &i2c_data, 1); 271 &i2c_data, 1);
334 return (err < 0) ? err : 0; 272 return err;
335} 273}
336 274
337int po1030_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val) 275int po1030_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val)
@@ -340,12 +278,12 @@ int po1030_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val)
340 u8 i2c_data; 278 u8 i2c_data;
341 int err; 279 int err;
342 280
343 err = po1030_read_sensor(sd, PO1030_REG_BLUE_GAIN, 281 err = m5602_read_sensor(sd, PO1030_REG_BLUE_GAIN,
344 &i2c_data, 1); 282 &i2c_data, 1);
345 *val = i2c_data; 283 *val = i2c_data;
346 PDEBUG(D_V4L2, "Read blue gain %d", *val); 284 PDEBUG(D_V4L2, "Read blue gain %d", *val);
347 285
348 return (err < 0) ? err : 0; 286 return err;
349} 287}
350 288
351int po1030_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val) 289int po1030_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val)
@@ -355,10 +293,10 @@ int po1030_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val)
355 int err; 293 int err;
356 i2c_data = val & 0xff; 294 i2c_data = val & 0xff;
357 PDEBUG(D_V4L2, "Set blue gain to %d", i2c_data); 295 PDEBUG(D_V4L2, "Set blue gain to %d", i2c_data);
358 err = po1030_write_sensor(sd, PO1030_REG_BLUE_GAIN, 296 err = m5602_write_sensor(sd, PO1030_REG_BLUE_GAIN,
359 &i2c_data, 1); 297 &i2c_data, 1);
360 298
361 return (err < 0) ? err : 0; 299 return err;
362} 300}
363 301
364int po1030_power_down(struct sd *sd) 302int po1030_power_down(struct sd *sd)
@@ -366,14 +304,14 @@ int po1030_power_down(struct sd *sd)
366 return 0; 304 return 0;
367} 305}
368 306
369void po1030_dump_registers(struct sd *sd) 307static void po1030_dump_registers(struct sd *sd)
370{ 308{
371 int address; 309 int address;
372 u8 value = 0; 310 u8 value = 0;
373 311
374 info("Dumping the po1030 sensor core registers"); 312 info("Dumping the po1030 sensor core registers");
375 for (address = 0; address < 0x7f; address++) { 313 for (address = 0; address < 0x7f; address++) {
376 po1030_read_sensor(sd, address, &value, 1); 314 m5602_read_sensor(sd, address, &value, 1);
377 info("register 0x%x contains 0x%x", 315 info("register 0x%x contains 0x%x",
378 address, value); 316 address, value);
379 } 317 }
@@ -385,9 +323,9 @@ void po1030_dump_registers(struct sd *sd)
385 u8 old_value, ctrl_value; 323 u8 old_value, ctrl_value;
386 u8 test_value[2] = {0xff, 0xff}; 324 u8 test_value[2] = {0xff, 0xff};
387 325
388 po1030_read_sensor(sd, address, &old_value, 1); 326 m5602_read_sensor(sd, address, &old_value, 1);
389 po1030_write_sensor(sd, address, test_value, 1); 327 m5602_write_sensor(sd, address, test_value, 1);
390 po1030_read_sensor(sd, address, &ctrl_value, 1); 328 m5602_read_sensor(sd, address, &ctrl_value, 1);
391 329
392 if (ctrl_value == test_value[0]) 330 if (ctrl_value == test_value[0])
393 info("register 0x%x is writeable", address); 331 info("register 0x%x is writeable", address);
@@ -395,6 +333,6 @@ void po1030_dump_registers(struct sd *sd)
395 info("register 0x%x is read only", address); 333 info("register 0x%x is read only", address);
396 334
397 /* Restore original value */ 335 /* Restore original value */
398 po1030_write_sensor(sd, address, &old_value, 1); 336 m5602_write_sensor(sd, address, &old_value, 1);
399 } 337 }
400} 338}
diff --git a/drivers/media/video/gspca/m5602/m5602_po1030.h b/drivers/media/video/gspca/m5602/m5602_po1030.h
index a0b75ff61d79..def39d5bcec6 100644
--- a/drivers/media/video/gspca/m5602/m5602_po1030.h
+++ b/drivers/media/video/gspca/m5602/m5602_po1030.h
@@ -10,7 +10,7 @@
10 * v4l2 interface modeled after the V4L2 driver 10 * v4l2 interface modeled after the V4L2 driver
11 * for SN9C10x PC Camera Controllers 11 * for SN9C10x PC Camera Controllers
12 * 12 *
13 * Register defines taken from Pascal Stangs Proxycon Armlib 13 * Register defines taken from Pascal Stangs Procyon Armlib
14 * 14 *
15 * This program is free software; you can redistribute it and/or 15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License as 16 * modify it under the terms of the GNU General Public License as
@@ -128,13 +128,6 @@ int po1030_probe(struct sd *sd);
128int po1030_init(struct sd *sd); 128int po1030_init(struct sd *sd);
129int po1030_power_down(struct sd *sd); 129int po1030_power_down(struct sd *sd);
130 130
131void po1030_dump_registers(struct sd *sd);
132
133int po1030_read_sensor(struct sd *sd, const u8 address,
134 u8 *i2c_data, const u8 len);
135int po1030_write_sensor(struct sd *sd, const u8 address,
136 u8 *i2c_data, const u8 len);
137
138int po1030_get_exposure(struct gspca_dev *gspca_dev, __s32 *val); 131int po1030_get_exposure(struct gspca_dev *gspca_dev, __s32 *val);
139int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val); 132int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val);
140int po1030_get_gain(struct gspca_dev *gspca_dev, __s32 *val); 133int po1030_get_gain(struct gspca_dev *gspca_dev, __s32 *val);
@@ -152,6 +145,7 @@ static struct m5602_sensor po1030 = {
152 .name = "PO1030", 145 .name = "PO1030",
153 146
154 .i2c_slave_id = 0xdc, 147 .i2c_slave_id = 0xdc,
148 .i2c_regW = 1,
155 149
156 .probe = po1030_probe, 150 .probe = po1030_probe,
157 .init = po1030_init, 151 .init = po1030_init,
diff --git a/drivers/media/video/gspca/m5602/m5602_s5k4aa.c b/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
index 14b1eac5b812..e564a61a72d7 100644
--- a/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
+++ b/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
@@ -18,6 +18,40 @@
18 18
19#include "m5602_s5k4aa.h" 19#include "m5602_s5k4aa.h"
20 20
21static
22 const
23 struct dmi_system_id s5k4aa_vflip_dmi_table[] = {
24 {
25 .ident = "Fujitsu-Siemens Amilo Xa 2528",
26 .matches = {
27 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
28 DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Xa 2528")
29 }
30 }, {
31 .ident = "Fujitsu-Siemens Amilo Xi 2550",
32 .matches = {
33 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
34 DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Xi 2550")
35 }
36 }, {
37 .ident = "MSI GX700",
38 .matches = {
39 DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star International"),
40 DMI_MATCH(DMI_PRODUCT_NAME, "GX700"),
41 DMI_MATCH(DMI_BIOS_DATE, "07/26/2007")
42 }
43 }, {
44 .ident = "MSI GX700/GX705/EX700",
45 .matches = {
46 DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star International"),
47 DMI_MATCH(DMI_PRODUCT_NAME, "GX700/GX705/EX700")
48 }
49 },
50 { }
51};
52
53static void s5k4aa_dump_registers(struct sd *sd);
54
21int s5k4aa_probe(struct sd *sd) 55int s5k4aa_probe(struct sd *sd)
22{ 56{
23 u8 prod_id[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 57 u8 prod_id[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
@@ -49,7 +83,7 @@ int s5k4aa_probe(struct sd *sd)
49 83
50 case SENSOR: 84 case SENSOR:
51 data[0] = preinit_s5k4aa[i][2]; 85 data[0] = preinit_s5k4aa[i][2];
52 err = s5k4aa_write_sensor(sd, 86 err = m5602_write_sensor(sd,
53 preinit_s5k4aa[i][1], 87 preinit_s5k4aa[i][1],
54 data, 1); 88 data, 1);
55 break; 89 break;
@@ -57,7 +91,7 @@ int s5k4aa_probe(struct sd *sd)
57 case SENSOR_LONG: 91 case SENSOR_LONG:
58 data[0] = preinit_s5k4aa[i][2]; 92 data[0] = preinit_s5k4aa[i][2];
59 data[1] = preinit_s5k4aa[i][3]; 93 data[1] = preinit_s5k4aa[i][3];
60 err = s5k4aa_write_sensor(sd, 94 err = m5602_write_sensor(sd,
61 preinit_s5k4aa[i][1], 95 preinit_s5k4aa[i][1],
62 data, 2); 96 data, 2);
63 break; 97 break;
@@ -68,13 +102,14 @@ int s5k4aa_probe(struct sd *sd)
68 } 102 }
69 103
70 /* Test some registers, but we don't know their exact meaning yet */ 104 /* Test some registers, but we don't know their exact meaning yet */
71 if (s5k4aa_read_sensor(sd, 0x00, prod_id, sizeof(prod_id))) 105 if (m5602_read_sensor(sd, 0x00, prod_id, sizeof(prod_id)))
72 return -ENODEV; 106 return -ENODEV;
73 107
74 if (memcmp(prod_id, expected_prod_id, sizeof(prod_id))) 108 if (memcmp(prod_id, expected_prod_id, sizeof(prod_id)))
75 return -ENODEV; 109 return -ENODEV;
76 else 110 else
77 info("Detected a s5k4aa sensor"); 111 info("Detected a s5k4aa sensor");
112
78sensor_found: 113sensor_found:
79 sd->gspca_dev.cam.cam_mode = s5k4aa.modes; 114 sd->gspca_dev.cam.cam_mode = s5k4aa.modes;
80 sd->gspca_dev.cam.nmodes = s5k4aa.nmodes; 115 sd->gspca_dev.cam.nmodes = s5k4aa.nmodes;
@@ -84,90 +119,6 @@ sensor_found:
84 return 0; 119 return 0;
85} 120}
86 121
87int s5k4aa_read_sensor(struct sd *sd, const u8 address,
88 u8 *i2c_data, const u8 len)
89{
90 int err, i;
91
92 do {
93 err = m5602_read_bridge(sd, M5602_XB_I2C_STATUS, i2c_data);
94 } while ((*i2c_data & I2C_BUSY) && !err);
95 if (err < 0)
96 goto out;
97
98 err = m5602_write_bridge(sd, M5602_XB_I2C_DEV_ADDR,
99 sd->sensor->i2c_slave_id);
100 if (err < 0)
101 goto out;
102
103 err = m5602_write_bridge(sd, M5602_XB_I2C_REG_ADDR, address);
104 if (err < 0)
105 goto out;
106
107 err = m5602_write_bridge(sd, M5602_XB_I2C_CTRL, 0x18 + len);
108 if (err < 0)
109 goto out;
110
111 do {
112 err = m5602_read_bridge(sd, M5602_XB_I2C_STATUS, i2c_data);
113 } while ((*i2c_data & I2C_BUSY) && !err);
114 if (err < 0)
115 goto out;
116
117 for (i = 0; (i < len) & !err; i++) {
118 err = m5602_read_bridge(sd, M5602_XB_I2C_DATA, &(i2c_data[i]));
119
120 PDEBUG(D_CONF, "Reading sensor register "
121 "0x%x containing 0x%x ", address, *i2c_data);
122 }
123out:
124 return (err < 0) ? err : 0;
125}
126
127int s5k4aa_write_sensor(struct sd *sd, const u8 address,
128 u8 *i2c_data, const u8 len)
129{
130 int err, i;
131 u8 *p;
132 struct usb_device *udev = sd->gspca_dev.dev;
133 __u8 *buf = sd->gspca_dev.usb_buf;
134
135 /* No sensor with a data width larger than 16 bits has yet been seen */
136 if (len > 2 || !len)
137 return -EINVAL;
138
139 memcpy(buf, sensor_urb_skeleton,
140 sizeof(sensor_urb_skeleton));
141
142 buf[11] = sd->sensor->i2c_slave_id;
143 buf[15] = address;
144
145 /* Special case larger sensor writes */
146 p = buf + 16;
147
148 /* Copy a four byte write sequence for each byte to be written to */
149 for (i = 0; i < len; i++) {
150 memcpy(p, sensor_urb_skeleton + 16, 4);
151 p[3] = i2c_data[i];
152 p += 4;
153 PDEBUG(D_CONF, "Writing sensor register 0x%x with 0x%x",
154 address, i2c_data[i]);
155 }
156
157 /* Copy the tailer */
158 memcpy(p, sensor_urb_skeleton + 20, 4);
159
160 /* Set the total length */
161 p[3] = 0x10 + len;
162
163 err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
164 0x04, 0x40, 0x19,
165 0x0000, buf,
166 20 + len * 4, M5602_URB_MSG_TIMEOUT);
167
168 return (err < 0) ? err : 0;
169}
170
171int s5k4aa_init(struct sd *sd) 122int s5k4aa_init(struct sd *sd)
172{ 123{
173 int i, err = 0; 124 int i, err = 0;
@@ -184,14 +135,14 @@ int s5k4aa_init(struct sd *sd)
184 135
185 case SENSOR: 136 case SENSOR:
186 data[0] = init_s5k4aa[i][2]; 137 data[0] = init_s5k4aa[i][2];
187 err = s5k4aa_write_sensor(sd, 138 err = m5602_write_sensor(sd,
188 init_s5k4aa[i][1], data, 1); 139 init_s5k4aa[i][1], data, 1);
189 break; 140 break;
190 141
191 case SENSOR_LONG: 142 case SENSOR_LONG:
192 data[0] = init_s5k4aa[i][2]; 143 data[0] = init_s5k4aa[i][2];
193 data[1] = init_s5k4aa[i][3]; 144 data[1] = init_s5k4aa[i][3];
194 err = s5k4aa_write_sensor(sd, 145 err = m5602_write_sensor(sd,
195 init_s5k4aa[i][1], data, 2); 146 init_s5k4aa[i][1], data, 2);
196 break; 147 break;
197 default: 148 default:
@@ -206,21 +157,21 @@ int s5k4aa_init(struct sd *sd)
206 if (!err && dmi_check_system(s5k4aa_vflip_dmi_table)) { 157 if (!err && dmi_check_system(s5k4aa_vflip_dmi_table)) {
207 u8 data = 0x02; 158 u8 data = 0x02;
208 info("vertical flip quirk active"); 159 info("vertical flip quirk active");
209 s5k4aa_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); 160 m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
210 s5k4aa_read_sensor(sd, S5K4AA_READ_MODE, &data, 1); 161 m5602_read_sensor(sd, S5K4AA_READ_MODE, &data, 1);
211 data |= S5K4AA_RM_V_FLIP; 162 data |= S5K4AA_RM_V_FLIP;
212 data &= ~S5K4AA_RM_H_FLIP; 163 data &= ~S5K4AA_RM_H_FLIP;
213 s5k4aa_write_sensor(sd, S5K4AA_READ_MODE, &data, 1); 164 m5602_write_sensor(sd, S5K4AA_READ_MODE, &data, 1);
214 165
215 /* Decrement COLSTART to preserve color order (BGGR) */ 166 /* Decrement COLSTART to preserve color order (BGGR) */
216 s5k4aa_read_sensor(sd, S5K4AA_COLSTART_LO, &data, 1); 167 m5602_read_sensor(sd, S5K4AA_COLSTART_LO, &data, 1);
217 data--; 168 data--;
218 s5k4aa_write_sensor(sd, S5K4AA_COLSTART_LO, &data, 1); 169 m5602_write_sensor(sd, S5K4AA_COLSTART_LO, &data, 1);
219 170
220 /* Increment ROWSTART to preserve color order (BGGR) */ 171 /* Increment ROWSTART to preserve color order (BGGR) */
221 s5k4aa_read_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1); 172 m5602_read_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1);
222 data++; 173 data++;
223 s5k4aa_write_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1); 174 m5602_write_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1);
224 } 175 }
225 176
226 return (err < 0) ? err : 0; 177 return (err < 0) ? err : 0;
@@ -237,20 +188,20 @@ int s5k4aa_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
237 u8 data = S5K4AA_PAGE_MAP_2; 188 u8 data = S5K4AA_PAGE_MAP_2;
238 int err; 189 int err;
239 190
240 err = s5k4aa_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); 191 err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
241 if (err < 0) 192 if (err < 0)
242 goto out; 193 goto out;
243 194
244 err = s5k4aa_read_sensor(sd, S5K4AA_EXPOSURE_HI, &data, 1); 195 err = m5602_read_sensor(sd, S5K4AA_EXPOSURE_HI, &data, 1);
245 if (err < 0) 196 if (err < 0)
246 goto out; 197 goto out;
247 198
248 *val = data << 8; 199 *val = data << 8;
249 err = s5k4aa_read_sensor(sd, S5K4AA_EXPOSURE_LO, &data, 1); 200 err = m5602_read_sensor(sd, S5K4AA_EXPOSURE_LO, &data, 1);
250 *val |= data; 201 *val |= data;
251 PDEBUG(D_V4L2, "Read exposure %d", *val); 202 PDEBUG(D_V4L2, "Read exposure %d", *val);
252out: 203out:
253 return (err < 0) ? err : 0; 204 return err;
254} 205}
255 206
256int s5k4aa_set_exposure(struct gspca_dev *gspca_dev, __s32 val) 207int s5k4aa_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
@@ -260,17 +211,17 @@ int s5k4aa_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
260 int err; 211 int err;
261 212
262 PDEBUG(D_V4L2, "Set exposure to %d", val); 213 PDEBUG(D_V4L2, "Set exposure to %d", val);
263 err = s5k4aa_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); 214 err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
264 if (err < 0) 215 if (err < 0)
265 goto out; 216 goto out;
266 data = (val >> 8) & 0xff; 217 data = (val >> 8) & 0xff;
267 err = s5k4aa_write_sensor(sd, S5K4AA_EXPOSURE_HI, &data, 1); 218 err = m5602_write_sensor(sd, S5K4AA_EXPOSURE_HI, &data, 1);
268 if (err < 0) 219 if (err < 0)
269 goto out; 220 goto out;
270 data = val & 0xff; 221 data = val & 0xff;
271 err = s5k4aa_write_sensor(sd, S5K4AA_EXPOSURE_LO, &data, 1); 222 err = m5602_write_sensor(sd, S5K4AA_EXPOSURE_LO, &data, 1);
272out: 223out:
273 return (err < 0) ? err : 0; 224 return err;
274} 225}
275 226
276int s5k4aa_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) 227int s5k4aa_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
@@ -279,16 +230,16 @@ int s5k4aa_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
279 u8 data = S5K4AA_PAGE_MAP_2; 230 u8 data = S5K4AA_PAGE_MAP_2;
280 int err; 231 int err;
281 232
282 err = s5k4aa_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); 233 err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
283 if (err < 0) 234 if (err < 0)
284 goto out; 235 goto out;
285 236
286 err = s5k4aa_read_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); 237 err = m5602_read_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
287 *val = (data & S5K4AA_RM_V_FLIP) >> 7; 238 *val = (data & S5K4AA_RM_V_FLIP) >> 7;
288 PDEBUG(D_V4L2, "Read vertical flip %d", *val); 239 PDEBUG(D_V4L2, "Read vertical flip %d", *val);
289 240
290out: 241out:
291 return (err < 0) ? err : 0; 242 return err;
292} 243}
293 244
294int s5k4aa_set_vflip(struct gspca_dev *gspca_dev, __s32 val) 245int s5k4aa_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
@@ -298,35 +249,35 @@ int s5k4aa_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
298 int err; 249 int err;
299 250
300 PDEBUG(D_V4L2, "Set vertical flip to %d", val); 251 PDEBUG(D_V4L2, "Set vertical flip to %d", val);
301 err = s5k4aa_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); 252 err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
302 if (err < 0) 253 if (err < 0)
303 goto out; 254 goto out;
304 err = s5k4aa_write_sensor(sd, S5K4AA_READ_MODE, &data, 1); 255 err = m5602_write_sensor(sd, S5K4AA_READ_MODE, &data, 1);
305 if (err < 0) 256 if (err < 0)
306 goto out; 257 goto out;
307 data = ((data & ~S5K4AA_RM_V_FLIP) 258 data = ((data & ~S5K4AA_RM_V_FLIP)
308 | ((val & 0x01) << 7)); 259 | ((val & 0x01) << 7));
309 err = s5k4aa_write_sensor(sd, S5K4AA_READ_MODE, &data, 1); 260 err = m5602_write_sensor(sd, S5K4AA_READ_MODE, &data, 1);
310 if (err < 0) 261 if (err < 0)
311 goto out; 262 goto out;
312 263
313 if (val) { 264 if (val) {
314 err = s5k4aa_read_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1); 265 err = m5602_read_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1);
315 if (err < 0) 266 if (err < 0)
316 goto out; 267 goto out;
317 268
318 data++; 269 data++;
319 err = s5k4aa_write_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1); 270 err = m5602_write_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1);
320 } else { 271 } else {
321 err = s5k4aa_read_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1); 272 err = m5602_read_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1);
322 if (err < 0) 273 if (err < 0)
323 goto out; 274 goto out;
324 275
325 data--; 276 data--;
326 err = s5k4aa_write_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1); 277 err = m5602_write_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1);
327 } 278 }
328out: 279out:
329 return (err < 0) ? err : 0; 280 return err;
330} 281}
331 282
332int s5k4aa_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) 283int s5k4aa_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
@@ -335,15 +286,15 @@ int s5k4aa_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
335 u8 data = S5K4AA_PAGE_MAP_2; 286 u8 data = S5K4AA_PAGE_MAP_2;
336 int err; 287 int err;
337 288
338 err = s5k4aa_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); 289 err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
339 if (err < 0) 290 if (err < 0)
340 goto out; 291 goto out;
341 292
342 err = s5k4aa_read_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); 293 err = m5602_read_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
343 *val = (data & S5K4AA_RM_H_FLIP) >> 6; 294 *val = (data & S5K4AA_RM_H_FLIP) >> 6;
344 PDEBUG(D_V4L2, "Read horizontal flip %d", *val); 295 PDEBUG(D_V4L2, "Read horizontal flip %d", *val);
345out: 296out:
346 return (err < 0) ? err : 0; 297 return err;
347} 298}
348 299
349int s5k4aa_set_hflip(struct gspca_dev *gspca_dev, __s32 val) 300int s5k4aa_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
@@ -354,35 +305,35 @@ int s5k4aa_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
354 305
355 PDEBUG(D_V4L2, "Set horizontal flip to %d", 306 PDEBUG(D_V4L2, "Set horizontal flip to %d",
356 val); 307 val);
357 err = s5k4aa_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); 308 err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
358 if (err < 0) 309 if (err < 0)
359 goto out; 310 goto out;
360 err = s5k4aa_write_sensor(sd, S5K4AA_READ_MODE, &data, 1); 311 err = m5602_write_sensor(sd, S5K4AA_READ_MODE, &data, 1);
361 if (err < 0) 312 if (err < 0)
362 goto out; 313 goto out;
363 314
364 data = ((data & ~S5K4AA_RM_H_FLIP) | ((val & 0x01) << 6)); 315 data = ((data & ~S5K4AA_RM_H_FLIP) | ((val & 0x01) << 6));
365 err = s5k4aa_write_sensor(sd, S5K4AA_READ_MODE, &data, 1); 316 err = m5602_write_sensor(sd, S5K4AA_READ_MODE, &data, 1);
366 if (err < 0) 317 if (err < 0)
367 goto out; 318 goto out;
368 319
369 if (val) { 320 if (val) {
370 err = s5k4aa_read_sensor(sd, S5K4AA_COLSTART_LO, &data, 1); 321 err = m5602_read_sensor(sd, S5K4AA_COLSTART_LO, &data, 1);
371 if (err < 0) 322 if (err < 0)
372 goto out; 323 goto out;
373 data++; 324 data++;
374 err = s5k4aa_write_sensor(sd, S5K4AA_COLSTART_LO, &data, 1); 325 err = m5602_write_sensor(sd, S5K4AA_COLSTART_LO, &data, 1);
375 if (err < 0) 326 if (err < 0)
376 goto out; 327 goto out;
377 } else { 328 } else {
378 err = s5k4aa_read_sensor(sd, S5K4AA_COLSTART_LO, &data, 1); 329 err = m5602_read_sensor(sd, S5K4AA_COLSTART_LO, &data, 1);
379 if (err < 0) 330 if (err < 0)
380 goto out; 331 goto out;
381 data--; 332 data--;
382 err = s5k4aa_write_sensor(sd, S5K4AA_COLSTART_LO, &data, 1); 333 err = m5602_write_sensor(sd, S5K4AA_COLSTART_LO, &data, 1);
383 } 334 }
384out: 335out:
385 return (err < 0) ? err : 0; 336 return err;
386} 337}
387 338
388int s5k4aa_get_gain(struct gspca_dev *gspca_dev, __s32 *val) 339int s5k4aa_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
@@ -391,16 +342,16 @@ int s5k4aa_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
391 u8 data = S5K4AA_PAGE_MAP_2; 342 u8 data = S5K4AA_PAGE_MAP_2;
392 int err; 343 int err;
393 344
394 err = s5k4aa_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); 345 err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
395 if (err < 0) 346 if (err < 0)
396 goto out; 347 goto out;
397 348
398 err = s5k4aa_read_sensor(sd, S5K4AA_GAIN_2, &data, 1); 349 err = m5602_read_sensor(sd, S5K4AA_GAIN_2, &data, 1);
399 *val = data; 350 *val = data;
400 PDEBUG(D_V4L2, "Read gain %d", *val); 351 PDEBUG(D_V4L2, "Read gain %d", *val);
401 352
402out: 353out:
403 return (err < 0) ? err : 0; 354 return err;
404} 355}
405 356
406int s5k4aa_set_gain(struct gspca_dev *gspca_dev, __s32 val) 357int s5k4aa_set_gain(struct gspca_dev *gspca_dev, __s32 val)
@@ -410,28 +361,28 @@ int s5k4aa_set_gain(struct gspca_dev *gspca_dev, __s32 val)
410 int err; 361 int err;
411 362
412 PDEBUG(D_V4L2, "Set gain to %d", val); 363 PDEBUG(D_V4L2, "Set gain to %d", val);
413 err = s5k4aa_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); 364 err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
414 if (err < 0) 365 if (err < 0)
415 goto out; 366 goto out;
416 367
417 data = val & 0xff; 368 data = val & 0xff;
418 err = s5k4aa_write_sensor(sd, S5K4AA_GAIN_2, &data, 1); 369 err = m5602_write_sensor(sd, S5K4AA_GAIN_2, &data, 1);
419 370
420out: 371out:
421 return (err < 0) ? err : 0; 372 return err;
422} 373}
423 374
424void s5k4aa_dump_registers(struct sd *sd) 375static void s5k4aa_dump_registers(struct sd *sd)
425{ 376{
426 int address; 377 int address;
427 u8 page, old_page; 378 u8 page, old_page;
428 s5k4aa_read_sensor(sd, S5K4AA_PAGE_MAP, &old_page, 1); 379 m5602_read_sensor(sd, S5K4AA_PAGE_MAP, &old_page, 1);
429 for (page = 0; page < 16; page++) { 380 for (page = 0; page < 16; page++) {
430 s5k4aa_write_sensor(sd, S5K4AA_PAGE_MAP, &page, 1); 381 m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &page, 1);
431 info("Dumping the s5k4aa register state for page 0x%x", page); 382 info("Dumping the s5k4aa register state for page 0x%x", page);
432 for (address = 0; address <= 0xff; address++) { 383 for (address = 0; address <= 0xff; address++) {
433 u8 value = 0; 384 u8 value = 0;
434 s5k4aa_read_sensor(sd, address, &value, 1); 385 m5602_read_sensor(sd, address, &value, 1);
435 info("register 0x%x contains 0x%x", 386 info("register 0x%x contains 0x%x",
436 address, value); 387 address, value);
437 } 388 }
@@ -439,15 +390,15 @@ void s5k4aa_dump_registers(struct sd *sd)
439 info("s5k4aa register state dump complete"); 390 info("s5k4aa register state dump complete");
440 391
441 for (page = 0; page < 16; page++) { 392 for (page = 0; page < 16; page++) {
442 s5k4aa_write_sensor(sd, S5K4AA_PAGE_MAP, &page, 1); 393 m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &page, 1);
443 info("Probing for which registers that are " 394 info("Probing for which registers that are "
444 "read/write for page 0x%x", page); 395 "read/write for page 0x%x", page);
445 for (address = 0; address <= 0xff; address++) { 396 for (address = 0; address <= 0xff; address++) {
446 u8 old_value, ctrl_value, test_value = 0xff; 397 u8 old_value, ctrl_value, test_value = 0xff;
447 398
448 s5k4aa_read_sensor(sd, address, &old_value, 1); 399 m5602_read_sensor(sd, address, &old_value, 1);
449 s5k4aa_write_sensor(sd, address, &test_value, 1); 400 m5602_write_sensor(sd, address, &test_value, 1);
450 s5k4aa_read_sensor(sd, address, &ctrl_value, 1); 401 m5602_read_sensor(sd, address, &ctrl_value, 1);
451 402
452 if (ctrl_value == test_value) 403 if (ctrl_value == test_value)
453 info("register 0x%x is writeable", address); 404 info("register 0x%x is writeable", address);
@@ -455,9 +406,9 @@ void s5k4aa_dump_registers(struct sd *sd)
455 info("register 0x%x is read only", address); 406 info("register 0x%x is read only", address);
456 407
457 /* Restore original value */ 408 /* Restore original value */
458 s5k4aa_write_sensor(sd, address, &old_value, 1); 409 m5602_write_sensor(sd, address, &old_value, 1);
459 } 410 }
460 } 411 }
461 info("Read/write register probing complete"); 412 info("Read/write register probing complete");
462 s5k4aa_write_sensor(sd, S5K4AA_PAGE_MAP, &old_page, 1); 413 m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &old_page, 1);
463} 414}
diff --git a/drivers/media/video/gspca/m5602/m5602_s5k4aa.h b/drivers/media/video/gspca/m5602/m5602_s5k4aa.h
index eaef67655afa..1f88b0d040c4 100644
--- a/drivers/media/video/gspca/m5602/m5602_s5k4aa.h
+++ b/drivers/media/video/gspca/m5602/m5602_s5k4aa.h
@@ -41,11 +41,10 @@
41#define S5K4AA_WINDOW_HEIGHT_LO 0x09 41#define S5K4AA_WINDOW_HEIGHT_LO 0x09
42#define S5K4AA_WINDOW_WIDTH_HI 0x0a 42#define S5K4AA_WINDOW_WIDTH_HI 0x0a
43#define S5K4AA_WINDOW_WIDTH_LO 0x0b 43#define S5K4AA_WINDOW_WIDTH_LO 0x0b
44#define S5K4AA_GLOBAL_GAIN__ 0x0f /* Only a guess ATM !!! */ 44#define S5K4AA_GLOBAL_GAIN__ 0x0f
45#define S5K4AA_H_BLANK_HI__ 0x1d /* Only a guess ATM !!! sync lost 45/* sync lost, if too low, reduces frame rate if too high */
46 if too low, reduces frame rate 46#define S5K4AA_H_BLANK_HI__ 0x1d
47 if too high */ 47#define S5K4AA_H_BLANK_LO__ 0x1e
48#define S5K4AA_H_BLANK_LO__ 0x1e /* Only a guess ATM !!! */
49#define S5K4AA_EXPOSURE_HI 0x17 48#define S5K4AA_EXPOSURE_HI 0x17
50#define S5K4AA_EXPOSURE_LO 0x18 49#define S5K4AA_EXPOSURE_LO 0x18
51#define S5K4AA_GAIN_1 0x1f /* (digital?) gain : 5 bits */ 50#define S5K4AA_GAIN_1 0x1f /* (digital?) gain : 5 bits */
@@ -68,13 +67,6 @@ int s5k4aa_probe(struct sd *sd);
68int s5k4aa_init(struct sd *sd); 67int s5k4aa_init(struct sd *sd);
69int s5k4aa_power_down(struct sd *sd); 68int s5k4aa_power_down(struct sd *sd);
70 69
71void s5k4aa_dump_registers(struct sd *sd);
72
73int s5k4aa_read_sensor(struct sd *sd, const u8 address,
74 u8 *i2c_data, const u8 len);
75int s5k4aa_write_sensor(struct sd *sd, const u8 address,
76 u8 *i2c_data, const u8 len);
77
78int s5k4aa_get_exposure(struct gspca_dev *gspca_dev, __s32 *val); 70int s5k4aa_get_exposure(struct gspca_dev *gspca_dev, __s32 *val);
79int s5k4aa_set_exposure(struct gspca_dev *gspca_dev, __s32 val); 71int s5k4aa_set_exposure(struct gspca_dev *gspca_dev, __s32 val);
80int s5k4aa_get_vflip(struct gspca_dev *gspca_dev, __s32 *val); 72int s5k4aa_get_vflip(struct gspca_dev *gspca_dev, __s32 *val);
@@ -89,9 +81,8 @@ static struct m5602_sensor s5k4aa = {
89 .probe = s5k4aa_probe, 81 .probe = s5k4aa_probe,
90 .init = s5k4aa_init, 82 .init = s5k4aa_init,
91 .power_down = s5k4aa_power_down, 83 .power_down = s5k4aa_power_down,
92 .read_sensor = s5k4aa_read_sensor,
93 .write_sensor = s5k4aa_write_sensor,
94 .i2c_slave_id = 0x5a, 84 .i2c_slave_id = 0x5a,
85 .i2c_regW = 2,
95 .nctrls = 4, 86 .nctrls = 4,
96 .ctrls = { 87 .ctrls = {
97 { 88 {
@@ -338,32 +329,4 @@ static const unsigned char init_s5k4aa[][4] =
338 {SENSOR, S5K4AA_GAIN_2, 0xa0, 0x00} 329 {SENSOR, S5K4AA_GAIN_2, 0xa0, 0x00}
339}; 330};
340 331
341static
342 const
343 struct dmi_system_id s5k4aa_vflip_dmi_table[] = {
344 {
345 .ident = "Fujitsu-Siemens Amilo Xa 2528",
346 .matches = {
347 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
348 DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Xa 2528")
349 }
350 },
351 {
352 .ident = "Fujitsu-Siemens Amilo Xi 2550",
353 .matches = {
354 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
355 DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Xi 2550")
356 }
357 },
358 {
359 .ident = "MSI GX700",
360 .matches = {
361 DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star International"),
362 DMI_MATCH(DMI_PRODUCT_NAME, "GX700"),
363 DMI_MATCH(DMI_BIOS_DATE, "07/26/2007")
364 }
365 },
366 { }
367};
368
369#endif 332#endif
diff --git a/drivers/media/video/gspca/m5602/m5602_s5k83a.c b/drivers/media/video/gspca/m5602/m5602_s5k83a.c
index 8988a728e0b4..af3f2dc2c702 100644
--- a/drivers/media/video/gspca/m5602/m5602_s5k83a.c
+++ b/drivers/media/video/gspca/m5602/m5602_s5k83a.c
@@ -18,6 +18,8 @@
18 18
19#include "m5602_s5k83a.h" 19#include "m5602_s5k83a.h"
20 20
21static void s5k83a_dump_registers(struct sd *sd);
22
21int s5k83a_probe(struct sd *sd) 23int s5k83a_probe(struct sd *sd)
22{ 24{
23 u8 prod_id = 0, ver_id = 0; 25 u8 prod_id = 0, ver_id = 0;
@@ -39,7 +41,7 @@ int s5k83a_probe(struct sd *sd)
39 for (i = 0; i < ARRAY_SIZE(preinit_s5k83a) && !err; i++) { 41 for (i = 0; i < ARRAY_SIZE(preinit_s5k83a) && !err; i++) {
40 u8 data[2] = {preinit_s5k83a[i][2], preinit_s5k83a[i][3]}; 42 u8 data[2] = {preinit_s5k83a[i][2], preinit_s5k83a[i][3]};
41 if (preinit_s5k83a[i][0] == SENSOR) 43 if (preinit_s5k83a[i][0] == SENSOR)
42 err = s5k83a_write_sensor(sd, preinit_s5k83a[i][1], 44 err = m5602_write_sensor(sd, preinit_s5k83a[i][1],
43 data, 2); 45 data, 2);
44 else 46 else
45 err = m5602_write_bridge(sd, preinit_s5k83a[i][1], 47 err = m5602_write_bridge(sd, preinit_s5k83a[i][1],
@@ -49,10 +51,10 @@ int s5k83a_probe(struct sd *sd)
49 /* We don't know what register (if any) that contain the product id 51 /* We don't know what register (if any) that contain the product id
50 * Just pick the first addresses that seem to produce the same results 52 * Just pick the first addresses that seem to produce the same results
51 * on multiple machines */ 53 * on multiple machines */
52 if (s5k83a_read_sensor(sd, 0x00, &prod_id, 1)) 54 if (m5602_read_sensor(sd, 0x00, &prod_id, 1))
53 return -ENODEV; 55 return -ENODEV;
54 56
55 if (s5k83a_read_sensor(sd, 0x01, &ver_id, 1)) 57 if (m5602_read_sensor(sd, 0x01, &ver_id, 1))
56 return -ENODEV; 58 return -ENODEV;
57 59
58 if ((prod_id == 0xff) || (ver_id == 0xff)) 60 if ((prod_id == 0xff) || (ver_id == 0xff))
@@ -68,91 +70,6 @@ sensor_found:
68 return 0; 70 return 0;
69} 71}
70 72
71int s5k83a_read_sensor(struct sd *sd, const u8 address,
72 u8 *i2c_data, const u8 len)
73{
74 int err, i;
75
76 do {
77 err = m5602_read_bridge(sd, M5602_XB_I2C_STATUS, i2c_data);
78 } while ((*i2c_data & I2C_BUSY) && !err);
79 if (err < 0)
80 goto out;
81
82 err = m5602_write_bridge(sd, M5602_XB_I2C_DEV_ADDR,
83 sd->sensor->i2c_slave_id);
84 if (err < 0)
85 goto out;
86
87 err = m5602_write_bridge(sd, M5602_XB_I2C_REG_ADDR, address);
88 if (err < 0)
89 goto out;
90
91 err = m5602_write_bridge(sd, M5602_XB_I2C_CTRL, 0x18 + len);
92 if (err < 0)
93 goto out;
94
95 do {
96 err = m5602_read_bridge(sd, M5602_XB_I2C_STATUS, i2c_data);
97 } while ((*i2c_data & I2C_BUSY) && !err);
98
99 if (err < 0)
100 goto out;
101 for (i = 0; i < len && !len; i++) {
102 err = m5602_read_bridge(sd, M5602_XB_I2C_DATA, &(i2c_data[i]));
103
104 PDEBUG(D_CONF, "Reading sensor register "
105 "0x%x containing 0x%x ", address, *i2c_data);
106 }
107
108out:
109 return (err < 0) ? err : 0;
110}
111
112int s5k83a_write_sensor(struct sd *sd, const u8 address,
113 u8 *i2c_data, const u8 len)
114{
115 int err, i;
116 u8 *p;
117 struct usb_device *udev = sd->gspca_dev.dev;
118 __u8 *buf = sd->gspca_dev.usb_buf;
119
120 /* No sensor with a data width larger than 16 bits has yet been seen */
121 if (len > 2 || !len)
122 return -EINVAL;
123
124 memcpy(buf, sensor_urb_skeleton,
125 sizeof(sensor_urb_skeleton));
126
127 buf[11] = sd->sensor->i2c_slave_id;
128 buf[15] = address;
129
130 /* Special case larger sensor writes */
131 p = buf + 16;
132
133 /* Copy a four byte write sequence for each byte to be written to */
134 for (i = 0; i < len; i++) {
135 memcpy(p, sensor_urb_skeleton + 16, 4);
136 p[3] = i2c_data[i];
137 p += 4;
138 PDEBUG(D_CONF, "Writing sensor register 0x%x with 0x%x",
139 address, i2c_data[i]);
140 }
141
142 /* Copy the tailer */
143 memcpy(p, sensor_urb_skeleton + 20, 4);
144
145 /* Set the total length */
146 p[3] = 0x10 + len;
147
148 err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
149 0x04, 0x40, 0x19,
150 0x0000, buf,
151 20 + len * 4, M5602_URB_MSG_TIMEOUT);
152
153 return (err < 0) ? err : 0;
154}
155
156int s5k83a_init(struct sd *sd) 73int s5k83a_init(struct sd *sd)
157{ 74{
158 int i, err = 0; 75 int i, err = 0;
@@ -169,14 +86,14 @@ int s5k83a_init(struct sd *sd)
169 86
170 case SENSOR: 87 case SENSOR:
171 data[0] = init_s5k83a[i][2]; 88 data[0] = init_s5k83a[i][2];
172 err = s5k83a_write_sensor(sd, 89 err = m5602_write_sensor(sd,
173 init_s5k83a[i][1], data, 1); 90 init_s5k83a[i][1], data, 1);
174 break; 91 break;
175 92
176 case SENSOR_LONG: 93 case SENSOR_LONG:
177 data[0] = init_s5k83a[i][2]; 94 data[0] = init_s5k83a[i][2];
178 data[1] = init_s5k83a[i][3]; 95 data[1] = init_s5k83a[i][3];
179 err = s5k83a_write_sensor(sd, 96 err = m5602_write_sensor(sd,
180 init_s5k83a[i][1], data, 2); 97 init_s5k83a[i][1], data, 2);
181 break; 98 break;
182 default: 99 default:
@@ -200,14 +117,14 @@ void s5k83a_dump_registers(struct sd *sd)
200{ 117{
201 int address; 118 int address;
202 u8 page, old_page; 119 u8 page, old_page;
203 s5k83a_read_sensor(sd, S5K83A_PAGE_MAP, &old_page, 1); 120 m5602_read_sensor(sd, S5K83A_PAGE_MAP, &old_page, 1);
204 121
205 for (page = 0; page < 16; page++) { 122 for (page = 0; page < 16; page++) {
206 s5k83a_write_sensor(sd, S5K83A_PAGE_MAP, &page, 1); 123 m5602_write_sensor(sd, S5K83A_PAGE_MAP, &page, 1);
207 info("Dumping the s5k83a register state for page 0x%x", page); 124 info("Dumping the s5k83a register state for page 0x%x", page);
208 for (address = 0; address <= 0xff; address++) { 125 for (address = 0; address <= 0xff; address++) {
209 u8 val = 0; 126 u8 val = 0;
210 s5k83a_read_sensor(sd, address, &val, 1); 127 m5602_read_sensor(sd, address, &val, 1);
211 info("register 0x%x contains 0x%x", 128 info("register 0x%x contains 0x%x",
212 address, val); 129 address, val);
213 } 130 }
@@ -215,15 +132,15 @@ void s5k83a_dump_registers(struct sd *sd)
215 info("s5k83a register state dump complete"); 132 info("s5k83a register state dump complete");
216 133
217 for (page = 0; page < 16; page++) { 134 for (page = 0; page < 16; page++) {
218 s5k83a_write_sensor(sd, S5K83A_PAGE_MAP, &page, 1); 135 m5602_write_sensor(sd, S5K83A_PAGE_MAP, &page, 1);
219 info("Probing for which registers that are read/write " 136 info("Probing for which registers that are read/write "
220 "for page 0x%x", page); 137 "for page 0x%x", page);
221 for (address = 0; address <= 0xff; address++) { 138 for (address = 0; address <= 0xff; address++) {
222 u8 old_val, ctrl_val, test_val = 0xff; 139 u8 old_val, ctrl_val, test_val = 0xff;
223 140
224 s5k83a_read_sensor(sd, address, &old_val, 1); 141 m5602_read_sensor(sd, address, &old_val, 1);
225 s5k83a_write_sensor(sd, address, &test_val, 1); 142 m5602_write_sensor(sd, address, &test_val, 1);
226 s5k83a_read_sensor(sd, address, &ctrl_val, 1); 143 m5602_read_sensor(sd, address, &ctrl_val, 1);
227 144
228 if (ctrl_val == test_val) 145 if (ctrl_val == test_val)
229 info("register 0x%x is writeable", address); 146 info("register 0x%x is writeable", address);
@@ -231,11 +148,11 @@ void s5k83a_dump_registers(struct sd *sd)
231 info("register 0x%x is read only", address); 148 info("register 0x%x is read only", address);
232 149
233 /* Restore original val */ 150 /* Restore original val */
234 s5k83a_write_sensor(sd, address, &old_val, 1); 151 m5602_write_sensor(sd, address, &old_val, 1);
235 } 152 }
236 } 153 }
237 info("Read/write register probing complete"); 154 info("Read/write register probing complete");
238 s5k83a_write_sensor(sd, S5K83A_PAGE_MAP, &old_page, 1); 155 m5602_write_sensor(sd, S5K83A_PAGE_MAP, &old_page, 1);
239} 156}
240 157
241int s5k83a_get_brightness(struct gspca_dev *gspca_dev, __s32 *val) 158int s5k83a_get_brightness(struct gspca_dev *gspca_dev, __s32 *val)
@@ -244,11 +161,15 @@ int s5k83a_get_brightness(struct gspca_dev *gspca_dev, __s32 *val)
244 u8 data[2]; 161 u8 data[2];
245 struct sd *sd = (struct sd *) gspca_dev; 162 struct sd *sd = (struct sd *) gspca_dev;
246 163
247 err = s5k83a_read_sensor(sd, S5K83A_BRIGHTNESS, data, 2); 164 err = m5602_read_sensor(sd, S5K83A_BRIGHTNESS, data, 2);
165 if (err < 0)
166 goto out;
167
248 data[1] = data[1] << 1; 168 data[1] = data[1] << 1;
249 *val = data[1]; 169 *val = data[1];
250 170
251 return (err < 0) ? err : 0; 171out:
172 return err;
252} 173}
253 174
254int s5k83a_set_brightness(struct gspca_dev *gspca_dev, __s32 val) 175int s5k83a_set_brightness(struct gspca_dev *gspca_dev, __s32 val)
@@ -259,23 +180,24 @@ int s5k83a_set_brightness(struct gspca_dev *gspca_dev, __s32 val)
259 180
260 data[0] = 0x00; 181 data[0] = 0x00;
261 data[1] = 0x20; 182 data[1] = 0x20;
262 err = s5k83a_write_sensor(sd, 0x14, data, 2); 183 err = m5602_write_sensor(sd, 0x14, data, 2);
263 if (err < 0) 184 if (err < 0)
264 return err; 185 goto out;
265 186
266 data[0] = 0x01; 187 data[0] = 0x01;
267 data[1] = 0x00; 188 data[1] = 0x00;
268 err = s5k83a_write_sensor(sd, 0x0d, data, 2); 189 err = m5602_write_sensor(sd, 0x0d, data, 2);
269 if (err < 0) 190 if (err < 0)
270 return err; 191 goto out;
271 192
272 /* FIXME: This is not sane, we need to figure out the composition 193 /* FIXME: This is not sane, we need to figure out the composition
273 of these registers */ 194 of these registers */
274 data[0] = val >> 3; /* brightness, high 5 bits */ 195 data[0] = val >> 3; /* brightness, high 5 bits */
275 data[1] = val >> 1; /* brightness, high 7 bits */ 196 data[1] = val >> 1; /* brightness, high 7 bits */
276 err = s5k83a_write_sensor(sd, S5K83A_BRIGHTNESS, data, 2); 197 err = m5602_write_sensor(sd, S5K83A_BRIGHTNESS, data, 2);
277 198
278 return (err < 0) ? err : 0; 199out:
200 return err;
279} 201}
280 202
281int s5k83a_get_whiteness(struct gspca_dev *gspca_dev, __s32 *val) 203int s5k83a_get_whiteness(struct gspca_dev *gspca_dev, __s32 *val)
@@ -284,10 +206,14 @@ int s5k83a_get_whiteness(struct gspca_dev *gspca_dev, __s32 *val)
284 u8 data; 206 u8 data;
285 struct sd *sd = (struct sd *) gspca_dev; 207 struct sd *sd = (struct sd *) gspca_dev;
286 208
287 err = s5k83a_read_sensor(sd, S5K83A_WHITENESS, &data, 1); 209 err = m5602_read_sensor(sd, S5K83A_WHITENESS, &data, 1);
210 if (err < 0)
211 goto out;
288 212
289 *val = data; 213 *val = data;
290 return (err < 0) ? err : 0; 214
215out:
216 return err;
291} 217}
292 218
293int s5k83a_set_whiteness(struct gspca_dev *gspca_dev, __s32 val) 219int s5k83a_set_whiteness(struct gspca_dev *gspca_dev, __s32 val)
@@ -297,9 +223,9 @@ int s5k83a_set_whiteness(struct gspca_dev *gspca_dev, __s32 val)
297 struct sd *sd = (struct sd *) gspca_dev; 223 struct sd *sd = (struct sd *) gspca_dev;
298 224
299 data[0] = val; 225 data[0] = val;
300 err = s5k83a_write_sensor(sd, S5K83A_WHITENESS, data, 1); 226 err = m5602_write_sensor(sd, S5K83A_WHITENESS, data, 1);
301 227
302 return (err < 0) ? err : 0; 228 return err;
303} 229}
304 230
305int s5k83a_get_gain(struct gspca_dev *gspca_dev, __s32 *val) 231int s5k83a_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
@@ -308,7 +234,9 @@ int s5k83a_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
308 u8 data[2]; 234 u8 data[2];
309 struct sd *sd = (struct sd *) gspca_dev; 235 struct sd *sd = (struct sd *) gspca_dev;
310 236
311 err = s5k83a_read_sensor(sd, S5K83A_GAIN, data, 2); 237 err = m5602_read_sensor(sd, S5K83A_GAIN, data, 2);
238 if (err < 0)
239 goto out;
312 240
313 data[1] = data[1] & 0x3f; 241 data[1] = data[1] & 0x3f;
314 if (data[1] > S5K83A_MAXIMUM_GAIN) 242 if (data[1] > S5K83A_MAXIMUM_GAIN)
@@ -316,7 +244,8 @@ int s5k83a_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
316 244
317 *val = data[1]; 245 *val = data[1];
318 246
319 return (err < 0) ? err : 0; 247out:
248 return err;
320} 249}
321 250
322int s5k83a_set_gain(struct gspca_dev *gspca_dev, __s32 val) 251int s5k83a_set_gain(struct gspca_dev *gspca_dev, __s32 val)
@@ -327,9 +256,8 @@ int s5k83a_set_gain(struct gspca_dev *gspca_dev, __s32 val)
327 256
328 data[0] = 0; 257 data[0] = 0;
329 data[1] = val; 258 data[1] = val;
330 err = s5k83a_write_sensor(sd, S5K83A_GAIN, data, 2); 259 err = m5602_write_sensor(sd, S5K83A_GAIN, data, 2);
331 260 return err;
332 return (err < 0) ? err : 0;
333} 261}
334 262
335int s5k83a_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) 263int s5k83a_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
@@ -339,14 +267,15 @@ int s5k83a_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
339 struct sd *sd = (struct sd *) gspca_dev; 267 struct sd *sd = (struct sd *) gspca_dev;
340 268
341 data[0] = 0x05; 269 data[0] = 0x05;
342 err = s5k83a_write_sensor(sd, S5K83A_PAGE_MAP, data, 1); 270 err = m5602_write_sensor(sd, S5K83A_PAGE_MAP, data, 1);
343 if (err < 0) 271 if (err < 0)
344 return err; 272 goto out;
345 273
346 err = s5k83a_read_sensor(sd, S5K83A_FLIP, data, 1); 274 err = m5602_read_sensor(sd, S5K83A_FLIP, data, 1);
347 *val = (data[0] | 0x40) ? 1 : 0; 275 *val = (data[0] | 0x40) ? 1 : 0;
348 276
349 return (err < 0) ? err : 0; 277out:
278 return err;
350} 279}
351 280
352int s5k83a_set_vflip(struct gspca_dev *gspca_dev, __s32 val) 281int s5k83a_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
@@ -356,25 +285,26 @@ int s5k83a_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
356 struct sd *sd = (struct sd *) gspca_dev; 285 struct sd *sd = (struct sd *) gspca_dev;
357 286
358 data[0] = 0x05; 287 data[0] = 0x05;
359 err = s5k83a_write_sensor(sd, S5K83A_PAGE_MAP, data, 1); 288 err = m5602_write_sensor(sd, S5K83A_PAGE_MAP, data, 1);
360 if (err < 0) 289 if (err < 0)
361 return err; 290 goto out;
362 291
363 err = s5k83a_read_sensor(sd, S5K83A_FLIP, data, 1); 292 err = m5602_read_sensor(sd, S5K83A_FLIP, data, 1);
364 if (err < 0) 293 if (err < 0)
365 return err; 294 goto out;
366 295
367 /* set or zero six bit, seven is hflip */ 296 /* set or zero six bit, seven is hflip */
368 data[0] = (val) ? (data[0] & 0x80) | 0x40 | S5K83A_FLIP_MASK 297 data[0] = (val) ? (data[0] & 0x80) | 0x40 | S5K83A_FLIP_MASK
369 : (data[0] & 0x80) | S5K83A_FLIP_MASK; 298 : (data[0] & 0x80) | S5K83A_FLIP_MASK;
370 err = s5k83a_write_sensor(sd, S5K83A_FLIP, data, 1); 299 err = m5602_write_sensor(sd, S5K83A_FLIP, data, 1);
371 if (err < 0) 300 if (err < 0)
372 return err; 301 goto out;
373 302
374 data[0] = (val) ? 0x0b : 0x0a; 303 data[0] = (val) ? 0x0b : 0x0a;
375 err = s5k83a_write_sensor(sd, S5K83A_VFLIP_TUNE, data, 1); 304 err = m5602_write_sensor(sd, S5K83A_VFLIP_TUNE, data, 1);
376 305
377 return (err < 0) ? err : 0; 306out:
307 return err;
378} 308}
379 309
380int s5k83a_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) 310int s5k83a_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
@@ -384,14 +314,15 @@ int s5k83a_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
384 struct sd *sd = (struct sd *) gspca_dev; 314 struct sd *sd = (struct sd *) gspca_dev;
385 315
386 data[0] = 0x05; 316 data[0] = 0x05;
387 err = s5k83a_write_sensor(sd, S5K83A_PAGE_MAP, data, 1); 317 err = m5602_write_sensor(sd, S5K83A_PAGE_MAP, data, 1);
388 if (err < 0) 318 if (err < 0)
389 return err; 319 goto out;
390 320
391 err = s5k83a_read_sensor(sd, S5K83A_FLIP, data, 1); 321 err = m5602_read_sensor(sd, S5K83A_FLIP, data, 1);
392 *val = (data[0] | 0x80) ? 1 : 0; 322 *val = (data[0] | 0x80) ? 1 : 0;
393 323
394 return (err < 0) ? err : 0; 324out:
325 return err;
395} 326}
396 327
397int s5k83a_set_hflip(struct gspca_dev *gspca_dev, __s32 val) 328int s5k83a_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
@@ -401,23 +332,23 @@ int s5k83a_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
401 struct sd *sd = (struct sd *) gspca_dev; 332 struct sd *sd = (struct sd *) gspca_dev;
402 333
403 data[0] = 0x05; 334 data[0] = 0x05;
404 err = s5k83a_write_sensor(sd, S5K83A_PAGE_MAP, data, 1); 335 err = m5602_write_sensor(sd, S5K83A_PAGE_MAP, data, 1);
405 if (err < 0) 336 if (err < 0)
406 return err; 337 goto out;
407 338
408 err = s5k83a_read_sensor(sd, S5K83A_FLIP, data, 1); 339 err = m5602_read_sensor(sd, S5K83A_FLIP, data, 1);
409 if (err < 0) 340 if (err < 0)
410 return err; 341 goto out;
411 342
412 /* set or zero seven bit, six is vflip */ 343 /* set or zero seven bit, six is vflip */
413 data[0] = (val) ? (data[0] & 0x40) | 0x80 | S5K83A_FLIP_MASK 344 data[0] = (val) ? (data[0] & 0x40) | 0x80 | S5K83A_FLIP_MASK
414 : (data[0] & 0x40) | S5K83A_FLIP_MASK; 345 : (data[0] & 0x40) | S5K83A_FLIP_MASK;
415 err = s5k83a_write_sensor(sd, S5K83A_FLIP, data, 1); 346 err = m5602_write_sensor(sd, S5K83A_FLIP, data, 1);
416 if (err < 0) 347 if (err < 0)
417 return err; 348 goto out;
418 349
419 data[0] = (val) ? 0x0a : 0x0b; 350 data[0] = (val) ? 0x0a : 0x0b;
420 err = s5k83a_write_sensor(sd, S5K83A_HFLIP_TUNE, data, 1); 351 err = m5602_write_sensor(sd, S5K83A_HFLIP_TUNE, data, 1);
421 352out:
422 return (err < 0) ? err : 0; 353 return err;
423} 354}
diff --git a/drivers/media/video/gspca/m5602/m5602_s5k83a.h b/drivers/media/video/gspca/m5602/m5602_s5k83a.h
index ee3ee9cfca1d..05ccb5b57a88 100644
--- a/drivers/media/video/gspca/m5602/m5602_s5k83a.h
+++ b/drivers/media/video/gspca/m5602/m5602_s5k83a.h
@@ -22,15 +22,15 @@
22#include "m5602_sensor.h" 22#include "m5602_sensor.h"
23 23
24#define S5K83A_FLIP 0x01 24#define S5K83A_FLIP 0x01
25#define S5K83A_HFLIP_TUNE 0x03 25#define S5K83A_HFLIP_TUNE 0x03
26#define S5K83A_VFLIP_TUNE 0x05 26#define S5K83A_VFLIP_TUNE 0x05
27#define S5K83A_WHITENESS 0x0a 27#define S5K83A_WHITENESS 0x0a
28#define S5K83A_GAIN 0x18 28#define S5K83A_GAIN 0x18
29#define S5K83A_BRIGHTNESS 0x1b 29#define S5K83A_BRIGHTNESS 0x1b
30#define S5K83A_PAGE_MAP 0xec 30#define S5K83A_PAGE_MAP 0xec
31 31
32#define S5K83A_DEFAULT_BRIGHTNESS 0x71 32#define S5K83A_DEFAULT_BRIGHTNESS 0x71
33#define S5K83A_DEFAULT_WHITENESS 0x7e 33#define S5K83A_DEFAULT_WHITENESS 0x7e
34#define S5K83A_DEFAULT_GAIN 0x00 34#define S5K83A_DEFAULT_GAIN 0x00
35#define S5K83A_MAXIMUM_GAIN 0x3c 35#define S5K83A_MAXIMUM_GAIN 0x3c
36#define S5K83A_FLIP_MASK 0x10 36#define S5K83A_FLIP_MASK 0x10
@@ -46,13 +46,6 @@ int s5k83a_probe(struct sd *sd);
46int s5k83a_init(struct sd *sd); 46int s5k83a_init(struct sd *sd);
47int s5k83a_power_down(struct sd *sd); 47int s5k83a_power_down(struct sd *sd);
48 48
49void s5k83a_dump_registers(struct sd *sd);
50
51int s5k83a_read_sensor(struct sd *sd, const u8 address,
52 u8 *i2c_data, const u8 len);
53int s5k83a_write_sensor(struct sd *sd, const u8 address,
54 u8 *i2c_data, const u8 len);
55
56int s5k83a_set_brightness(struct gspca_dev *gspca_dev, __s32 val); 49int s5k83a_set_brightness(struct gspca_dev *gspca_dev, __s32 val);
57int s5k83a_get_brightness(struct gspca_dev *gspca_dev, __s32 *val); 50int s5k83a_get_brightness(struct gspca_dev *gspca_dev, __s32 *val);
58int s5k83a_set_whiteness(struct gspca_dev *gspca_dev, __s32 val); 51int s5k83a_set_whiteness(struct gspca_dev *gspca_dev, __s32 val);
@@ -64,15 +57,13 @@ int s5k83a_set_vflip(struct gspca_dev *gspca_dev, __s32 val);
64int s5k83a_get_hflip(struct gspca_dev *gspca_dev, __s32 *val); 57int s5k83a_get_hflip(struct gspca_dev *gspca_dev, __s32 *val);
65int s5k83a_set_hflip(struct gspca_dev *gspca_dev, __s32 val); 58int s5k83a_set_hflip(struct gspca_dev *gspca_dev, __s32 val);
66 59
67
68static struct m5602_sensor s5k83a = { 60static struct m5602_sensor s5k83a = {
69 .name = "S5K83A", 61 .name = "S5K83A",
70 .probe = s5k83a_probe, 62 .probe = s5k83a_probe,
71 .init = s5k83a_init, 63 .init = s5k83a_init,
72 .power_down = s5k83a_power_down, 64 .power_down = s5k83a_power_down,
73 .read_sensor = s5k83a_read_sensor,
74 .write_sensor = s5k83a_write_sensor,
75 .i2c_slave_id = 0x5a, 65 .i2c_slave_id = 0x5a,
66 .i2c_regW = 2,
76 .nctrls = 5, 67 .nctrls = 5,
77 .ctrls = { 68 .ctrls = {
78 { 69 {
diff --git a/drivers/media/video/gspca/m5602/m5602_sensor.h b/drivers/media/video/gspca/m5602/m5602_sensor.h
index 60c9a48e0c02..261623f0da48 100644
--- a/drivers/media/video/gspca/m5602/m5602_sensor.h
+++ b/drivers/media/video/gspca/m5602/m5602_sensor.h
@@ -49,23 +49,21 @@ struct m5602_sensor {
49 /* What i2c address the sensor is connected to */ 49 /* What i2c address the sensor is connected to */
50 u8 i2c_slave_id; 50 u8 i2c_slave_id;
51 51
52 /* Width of each i2c register (in bytes) */
53 u8 i2c_regW;
54
52 /* Probes if the sensor is connected */ 55 /* Probes if the sensor is connected */
53 int (*probe)(struct sd *sd); 56 int (*probe)(struct sd *sd);
54 57
55 /* Performs a initialization sequence */ 58 /* Performs a initialization sequence */
56 int (*init)(struct sd *sd); 59 int (*init)(struct sd *sd);
57 60
61 /* Executed when the camera starts to send data */
62 int (*start)(struct sd *sd);
63
58 /* Performs a power down sequence */ 64 /* Performs a power down sequence */
59 int (*power_down)(struct sd *sd); 65 int (*power_down)(struct sd *sd);
60 66
61 /* Reads a sensor register */
62 int (*read_sensor)(struct sd *sd, const u8 address,
63 u8 *i2c_data, const u8 len);
64
65 /* Writes to a sensor register */
66 int (*write_sensor)(struct sd *sd, const u8 address,
67 u8 *i2c_data, const u8 len);
68
69 int nctrls; 67 int nctrls;
70 struct ctrl ctrls[M5602_MAX_CTRLS]; 68 struct ctrl ctrls[M5602_MAX_CTRLS];
71 69
diff --git a/drivers/media/video/gspca/mars.c b/drivers/media/video/gspca/mars.c
index 277ca34a8817..3d2090e67a63 100644
--- a/drivers/media/video/gspca/mars.c
+++ b/drivers/media/video/gspca/mars.c
@@ -39,7 +39,7 @@ struct sd {
39static struct ctrl sd_ctrls[] = { 39static struct ctrl sd_ctrls[] = {
40}; 40};
41 41
42static struct v4l2_pix_format vga_mode[] = { 42static const struct v4l2_pix_format vga_mode[] = {
43 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 43 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
44 .bytesperline = 320, 44 .bytesperline = 320,
45 .sizeimage = 320 * 240 * 3 / 8 + 589, 45 .sizeimage = 320 * 240 * 3 / 8 + 589,
@@ -123,7 +123,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
123 cam = &gspca_dev->cam; 123 cam = &gspca_dev->cam;
124 cam->epaddr = 0x01; 124 cam->epaddr = 0x01;
125 cam->cam_mode = vga_mode; 125 cam->cam_mode = vga_mode;
126 cam->nmodes = sizeof vga_mode / sizeof vga_mode[0]; 126 cam->nmodes = ARRAY_SIZE(vga_mode);
127 sd->qindex = 1; /* set the quantization table */ 127 sd->qindex = 1; /* set the quantization table */
128 return 0; 128 return 0;
129} 129}
diff --git a/drivers/media/video/gspca/ov519.c b/drivers/media/video/gspca/ov519.c
index ca671194679e..ee232956c812 100644
--- a/drivers/media/video/gspca/ov519.c
+++ b/drivers/media/video/gspca/ov519.c
@@ -3,7 +3,18 @@
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 * 5 *
6 * (This module is adapted from the ov51x-jpeg package) 6 * This module is adapted from the ov51x-jpeg package, which itself
7 * was adapted from the ov511 driver.
8 *
9 * Original copyright for the ov511 driver is:
10 *
11 * Copyright (c) 1999-2004 Mark W. McClelland
12 * Support for OV519, OV8610 Copyright (c) 2003 Joerg Heckenbach
13 *
14 * ov51x-jpeg original copyright is:
15 *
16 * Copyright (c) 2004-2007 Romain Beauxis <toots@rastageeks.org>
17 * Support for OV7670 sensors was contributed by Sam Skipsey <aoanla@yahoo.com>
7 * 18 *
8 * This program is free software; you can redistribute it and/or modify 19 * 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 20 * it under the terms of the GNU General Public License as published by
@@ -40,22 +51,18 @@ struct sd {
40 struct gspca_dev gspca_dev; /* !! must be the first item */ 51 struct gspca_dev gspca_dev; /* !! must be the first item */
41 52
42 /* Determined by sensor type */ 53 /* Determined by sensor type */
43 char sif; 54 __u8 sif;
44
45 unsigned char primary_i2c_slave; /* I2C write id of sensor */
46 55
47 unsigned char brightness; 56 __u8 brightness;
48 unsigned char contrast; 57 __u8 contrast;
49 unsigned char colors; 58 __u8 colors;
50 __u8 hflip; 59 __u8 hflip;
51 __u8 vflip; 60 __u8 vflip;
52 61
53 char compress; /* Should the next frame be compressed? */ 62 __u8 stopped; /* Streaming is temporarily paused */
54 char compress_inited; /* Are compression params uploaded? */
55 char stopped; /* Streaming is temporarily paused */
56 63
57 char frame_rate; /* current Framerate (OV519 only) */ 64 __u8 frame_rate; /* current Framerate (OV519 only) */
58 char clockdiv; /* clockdiv override for OV519 only */ 65 __u8 clockdiv; /* clockdiv override for OV519 only */
59 66
60 char sensor; /* Type of image sensor chip (SEN_*) */ 67 char sensor; /* Type of image sensor chip (SEN_*) */
61#define SEN_UNKNOWN 0 68#define SEN_UNKNOWN 0
@@ -67,7 +74,6 @@ struct sd {
67#define SEN_OV7670 6 74#define SEN_OV7670 6
68#define SEN_OV76BE 7 75#define SEN_OV76BE 7
69#define SEN_OV8610 8 76#define SEN_OV8610 8
70
71}; 77};
72 78
73/* V4L2 controls supported by the driver */ 79/* V4L2 controls supported by the driver */
@@ -158,7 +164,7 @@ static struct ctrl sd_ctrls[] = {
158 }, 164 },
159}; 165};
160 166
161static struct v4l2_pix_format vga_mode[] = { 167static const struct v4l2_pix_format vga_mode[] = {
162 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 168 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
163 .bytesperline = 320, 169 .bytesperline = 320,
164 .sizeimage = 320 * 240 * 3 / 8 + 590, 170 .sizeimage = 320 * 240 * 3 / 8 + 590,
@@ -170,7 +176,7 @@ static struct v4l2_pix_format vga_mode[] = {
170 .colorspace = V4L2_COLORSPACE_JPEG, 176 .colorspace = V4L2_COLORSPACE_JPEG,
171 .priv = 0}, 177 .priv = 0},
172}; 178};
173static struct v4l2_pix_format sif_mode[] = { 179static const struct v4l2_pix_format sif_mode[] = {
174 {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 180 {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
175 .bytesperline = 176, 181 .bytesperline = 176,
176 .sizeimage = 176 * 144 * 3 / 8 + 590, 182 .sizeimage = 176 * 144 * 3 / 8 + 590,
@@ -184,15 +190,15 @@ static struct v4l2_pix_format sif_mode[] = {
184}; 190};
185 191
186/* OV519 Camera interface register numbers */ 192/* OV519 Camera interface register numbers */
187#define OV519_CAM_H_SIZE 0x10 193#define OV519_R10_H_SIZE 0x10
188#define OV519_CAM_V_SIZE 0x11 194#define OV519_R11_V_SIZE 0x11
189#define OV519_CAM_X_OFFSETL 0x12 195#define OV519_R12_X_OFFSETL 0x12
190#define OV519_CAM_X_OFFSETH 0x13 196#define OV519_R13_X_OFFSETH 0x13
191#define OV519_CAM_Y_OFFSETL 0x14 197#define OV519_R14_Y_OFFSETL 0x14
192#define OV519_CAM_Y_OFFSETH 0x15 198#define OV519_R15_Y_OFFSETH 0x15
193#define OV519_CAM_DIVIDER 0x16 199#define OV519_R16_DIVIDER 0x16
194#define OV519_CAM_DFR 0x20 200#define OV519_R20_DFR 0x20
195#define OV519_CAM_FORMAT 0x25 201#define OV519_R25_FORMAT 0x25
196 202
197/* OV519 System Controller register numbers */ 203/* OV519 System Controller register numbers */
198#define OV519_SYS_RESET1 0x51 204#define OV519_SYS_RESET1 0x51
@@ -562,8 +568,8 @@ static const struct ov_i2c_regvals norm_7670[] = {
562 { OV7670_REG_VSTOP, 0x7a }, 568 { OV7670_REG_VSTOP, 0x7a },
563 { OV7670_REG_VREF, 0x0a }, 569 { OV7670_REG_VREF, 0x0a },
564 570
565 { OV7670_REG_COM3, 0 }, 571 { OV7670_REG_COM3, 0x00 },
566 { OV7670_REG_COM14, 0 }, 572 { OV7670_REG_COM14, 0x00 },
567/* Mystery scaling numbers */ 573/* Mystery scaling numbers */
568 { 0x70, 0x3a }, 574 { 0x70, 0x3a },
569 { 0x71, 0x35 }, 575 { 0x71, 0x35 },
@@ -595,8 +601,8 @@ static const struct ov_i2c_regvals norm_7670[] = {
595 { OV7670_REG_COM8, OV7670_COM8_FASTAEC 601 { OV7670_REG_COM8, OV7670_COM8_FASTAEC
596 | OV7670_COM8_AECSTEP 602 | OV7670_COM8_AECSTEP
597 | OV7670_COM8_BFILT }, 603 | OV7670_COM8_BFILT },
598 { OV7670_REG_GAIN, 0 }, 604 { OV7670_REG_GAIN, 0x00 },
599 { OV7670_REG_AECH, 0 }, 605 { OV7670_REG_AECH, 0x00 },
600 { OV7670_REG_COM4, 0x40 }, /* magic reserved bit */ 606 { OV7670_REG_COM4, 0x40 }, /* magic reserved bit */
601 { OV7670_REG_COM9, 0x18 }, /* 4x gain + magic rsvd bit */ 607 { OV7670_REG_COM9, 0x18 }, /* 4x gain + magic rsvd bit */
602 { OV7670_REG_BD50MAX, 0x05 }, 608 { OV7670_REG_BD50MAX, 0x05 },
@@ -634,16 +640,16 @@ static const struct ov_i2c_regvals norm_7670[] = {
634 { OV7670_REG_COM12, 0x78 }, 640 { OV7670_REG_COM12, 0x78 },
635 { 0x4d, 0x40 }, 641 { 0x4d, 0x40 },
636 { 0x4e, 0x20 }, 642 { 0x4e, 0x20 },
637 { OV7670_REG_GFIX, 0 }, 643 { OV7670_REG_GFIX, 0x00 },
638 { 0x6b, 0x4a }, 644 { 0x6b, 0x4a },
639 { 0x74, 0x10 }, 645 { 0x74, 0x10 },
640 { 0x8d, 0x4f }, 646 { 0x8d, 0x4f },
641 { 0x8e, 0 }, 647 { 0x8e, 0x00 },
642 { 0x8f, 0 }, 648 { 0x8f, 0x00 },
643 { 0x90, 0 }, 649 { 0x90, 0x00 },
644 { 0x91, 0 }, 650 { 0x91, 0x00 },
645 { 0x96, 0 }, 651 { 0x96, 0x00 },
646 { 0x9a, 0 }, 652 { 0x9a, 0x00 },
647 { 0xb0, 0x84 }, 653 { 0xb0, 0x84 },
648 { 0xb1, 0x0c }, 654 { 0xb1, 0x0c },
649 { 0xb2, 0x0e }, 655 { 0xb2, 0x0e },
@@ -681,17 +687,17 @@ static const struct ov_i2c_regvals norm_7670[] = {
681/* Matrix coefficients */ 687/* Matrix coefficients */
682 { 0x4f, 0x80 }, 688 { 0x4f, 0x80 },
683 { 0x50, 0x80 }, 689 { 0x50, 0x80 },
684 { 0x51, 0 }, 690 { 0x51, 0x00 },
685 { 0x52, 0x22 }, 691 { 0x52, 0x22 },
686 { 0x53, 0x5e }, 692 { 0x53, 0x5e },
687 { 0x54, 0x80 }, 693 { 0x54, 0x80 },
688 { 0x58, 0x9e }, 694 { 0x58, 0x9e },
689 695
690 { OV7670_REG_COM16, OV7670_COM16_AWBGAIN }, 696 { OV7670_REG_COM16, OV7670_COM16_AWBGAIN },
691 { OV7670_REG_EDGE, 0 }, 697 { OV7670_REG_EDGE, 0x00 },
692 { 0x75, 0x05 }, 698 { 0x75, 0x05 },
693 { 0x76, 0xe1 }, 699 { 0x76, 0xe1 },
694 { 0x4c, 0 }, 700 { 0x4c, 0x00 },
695 { 0x77, 0x01 }, 701 { 0x77, 0x01 },
696 { OV7670_REG_COM13, OV7670_COM13_GAMMA 702 { OV7670_REG_COM13, OV7670_COM13_GAMMA
697 | OV7670_COM13_UVSAT 703 | OV7670_COM13_UVSAT
@@ -704,7 +710,7 @@ static const struct ov_i2c_regvals norm_7670[] = {
704 { 0x34, 0x11 }, 710 { 0x34, 0x11 },
705 { OV7670_REG_COM11, OV7670_COM11_EXP|OV7670_COM11_HZAUTO }, 711 { OV7670_REG_COM11, OV7670_COM11_EXP|OV7670_COM11_HZAUTO },
706 { 0xa4, 0x88 }, 712 { 0xa4, 0x88 },
707 { 0x96, 0 }, 713 { 0x96, 0x00 },
708 { 0x97, 0x30 }, 714 { 0x97, 0x30 },
709 { 0x98, 0x20 }, 715 { 0x98, 0x20 },
710 { 0x99, 0x30 }, 716 { 0x99, 0x30 },
@@ -942,11 +948,11 @@ static int i2c_w(struct sd *sd,
942 948
943 /* Initiate 3-byte write cycle */ 949 /* Initiate 3-byte write cycle */
944 rc = reg_w(sd, R518_I2C_CTL, 0x01); 950 rc = reg_w(sd, R518_I2C_CTL, 0x01);
951 if (rc < 0)
952 return rc;
945 953
946 /* wait for write complete */ 954 /* wait for write complete */
947 msleep(4); 955 msleep(4);
948 if (rc < 0)
949 return rc;
950 return reg_r8(sd, R518_I2C_CTL); 956 return reg_r8(sd, R518_I2C_CTL);
951} 957}
952 958
@@ -1029,7 +1035,7 @@ static inline int ov51x_restart(struct sd *sd)
1029 */ 1035 */
1030static int init_ov_sensor(struct sd *sd) 1036static int init_ov_sensor(struct sd *sd)
1031{ 1037{
1032 int i, success; 1038 int i;
1033 1039
1034 /* Reset the sensor */ 1040 /* Reset the sensor */
1035 if (i2c_w(sd, 0x12, 0x80) < 0) 1041 if (i2c_w(sd, 0x12, 0x80) < 0)
@@ -1038,11 +1044,11 @@ static int init_ov_sensor(struct sd *sd)
1038 /* Wait for it to initialize */ 1044 /* Wait for it to initialize */
1039 msleep(150); 1045 msleep(150);
1040 1046
1041 for (i = 0, success = 0; i < i2c_detect_tries && !success; i++) { 1047 for (i = 0; i < i2c_detect_tries; i++) {
1042 if (i2c_r(sd, OV7610_REG_ID_HIGH) == 0x7f && 1048 if (i2c_r(sd, OV7610_REG_ID_HIGH) == 0x7f &&
1043 i2c_r(sd, OV7610_REG_ID_LOW) == 0xa2) { 1049 i2c_r(sd, OV7610_REG_ID_LOW) == 0xa2) {
1044 success = 1; 1050 PDEBUG(D_PROBE, "I2C synced in %d attempt(s)", i);
1045 continue; 1051 return 0;
1046 } 1052 }
1047 1053
1048 /* Reset the sensor */ 1054 /* Reset the sensor */
@@ -1054,10 +1060,7 @@ static int init_ov_sensor(struct sd *sd)
1054 if (i2c_r(sd, 0x00) < 0) 1060 if (i2c_r(sd, 0x00) < 0)
1055 return -EIO; 1061 return -EIO;
1056 } 1062 }
1057 if (!success) 1063 return -EIO;
1058 return -EIO;
1059 PDEBUG(D_PROBE, "I2C synced in %d attempt(s)", i);
1060 return 0;
1061} 1064}
1062 1065
1063/* Set the read and write slave IDs. The "slave" argument is the write slave, 1066/* Set the read and write slave IDs. The "slave" argument is the write slave,
@@ -1073,7 +1076,6 @@ static int ov51x_set_slave_ids(struct sd *sd,
1073 rc = reg_w(sd, R51x_I2C_W_SID, slave); 1076 rc = reg_w(sd, R51x_I2C_W_SID, slave);
1074 if (rc < 0) 1077 if (rc < 0)
1075 return rc; 1078 return rc;
1076 sd->primary_i2c_slave = slave;
1077 return reg_w(sd, R51x_I2C_R_SID, slave + 1); 1079 return reg_w(sd, R51x_I2C_R_SID, slave + 1);
1078} 1080}
1079 1081
@@ -1285,7 +1287,6 @@ static int ov6xx0_configure(struct sd *sd)
1285/* Turns on or off the LED. Only has an effect with OV511+/OV518(+)/OV519 */ 1287/* Turns on or off the LED. Only has an effect with OV511+/OV518(+)/OV519 */
1286static void ov51x_led_control(struct sd *sd, int on) 1288static void ov51x_led_control(struct sd *sd, int on)
1287{ 1289{
1288/* PDEBUG(D_STREAM, "LED (%s)", on ? "on" : "off"); */
1289 reg_w_mask(sd, OV519_GPIO_DATA_OUT0, !on, 1); /* 0 / 1 */ 1290 reg_w_mask(sd, OV519_GPIO_DATA_OUT0, !on, 1); /* 0 / 1 */
1290} 1291}
1291 1292
@@ -1352,7 +1353,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
1352 } 1353 }
1353 if (ov8xx0_configure(sd) < 0) { 1354 if (ov8xx0_configure(sd) < 0) {
1354 PDEBUG(D_ERR, 1355 PDEBUG(D_ERR,
1355 "Failed to configure OV8xx0 sensor"); 1356 "Failed to configure OV8xx0 sensor");
1356 goto error; 1357 goto error;
1357 } 1358 }
1358 } 1359 }
@@ -1482,7 +1483,7 @@ static int ov519_mode_init_regs(struct sd *sd)
1482 return -EIO; 1483 return -EIO;
1483 if (sd->sensor == SEN_OV7640) { 1484 if (sd->sensor == SEN_OV7640) {
1484 /* Select 8-bit input mode */ 1485 /* Select 8-bit input mode */
1485 reg_w_mask(sd, OV519_CAM_DFR, 0x10, 0x10); 1486 reg_w_mask(sd, OV519_R20_DFR, 0x10, 0x10);
1486 } 1487 }
1487 } else { 1488 } else {
1488 if (write_regvals(sd, mode_init_519_ov7670, 1489 if (write_regvals(sd, mode_init_519_ov7670,
@@ -1490,14 +1491,14 @@ static int ov519_mode_init_regs(struct sd *sd)
1490 return -EIO; 1491 return -EIO;
1491 } 1492 }
1492 1493
1493 reg_w(sd, OV519_CAM_H_SIZE, sd->gspca_dev.width >> 4); 1494 reg_w(sd, OV519_R10_H_SIZE, sd->gspca_dev.width >> 4);
1494 reg_w(sd, OV519_CAM_V_SIZE, sd->gspca_dev.height >> 3); 1495 reg_w(sd, OV519_R11_V_SIZE, sd->gspca_dev.height >> 3);
1495 reg_w(sd, OV519_CAM_X_OFFSETL, 0x00); 1496 reg_w(sd, OV519_R12_X_OFFSETL, 0x00);
1496 reg_w(sd, OV519_CAM_X_OFFSETH, 0x00); 1497 reg_w(sd, OV519_R13_X_OFFSETH, 0x00);
1497 reg_w(sd, OV519_CAM_Y_OFFSETL, 0x00); 1498 reg_w(sd, OV519_R14_Y_OFFSETL, 0x00);
1498 reg_w(sd, OV519_CAM_Y_OFFSETH, 0x00); 1499 reg_w(sd, OV519_R15_Y_OFFSETH, 0x00);
1499 reg_w(sd, OV519_CAM_DIVIDER, 0x00); 1500 reg_w(sd, OV519_R16_DIVIDER, 0x00);
1500 reg_w(sd, OV519_CAM_FORMAT, 0x03); /* YUV422 */ 1501 reg_w(sd, OV519_R25_FORMAT, 0x03); /* YUV422 */
1501 reg_w(sd, 0x26, 0x00); /* Undocumented */ 1502 reg_w(sd, 0x26, 0x00); /* Undocumented */
1502 1503
1503 /******** Set the framerate ********/ 1504 /******** Set the framerate ********/
@@ -1509,8 +1510,8 @@ static int ov519_mode_init_regs(struct sd *sd)
1509 switch (sd->sensor) { 1510 switch (sd->sensor) {
1510 case SEN_OV7640: 1511 case SEN_OV7640:
1511 switch (sd->frame_rate) { 1512 switch (sd->frame_rate) {
1512/*fixme: default was 30 fps */ 1513 default:
1513 case 30: 1514/* case 30: */
1514 reg_w(sd, 0xa4, 0x0c); 1515 reg_w(sd, 0xa4, 0x0c);
1515 reg_w(sd, 0x23, 0xff); 1516 reg_w(sd, 0x23, 0xff);
1516 break; 1517 break;
@@ -1522,8 +1523,7 @@ static int ov519_mode_init_regs(struct sd *sd)
1522 reg_w(sd, 0xa4, 0x0c); 1523 reg_w(sd, 0xa4, 0x0c);
1523 reg_w(sd, 0x23, 0x1b); 1524 reg_w(sd, 0x23, 0x1b);
1524 break; 1525 break;
1525 default: 1526 case 15:
1526/* case 15: */
1527 reg_w(sd, 0xa4, 0x04); 1527 reg_w(sd, 0xa4, 0x04);
1528 reg_w(sd, 0x23, 0xff); 1528 reg_w(sd, 0x23, 0xff);
1529 sd->clockdiv = 1; 1529 sd->clockdiv = 1;
@@ -1576,7 +1576,6 @@ static int ov519_mode_init_regs(struct sd *sd)
1576 } 1576 }
1577 break; 1577 break;
1578 } 1578 }
1579
1580 return 0; 1579 return 0;
1581} 1580}
1582 1581
@@ -1667,7 +1666,7 @@ static int mode_init_ov_sensor_regs(struct sd *sd)
1667 * the gain or the contrast. The "reserved" bits seem 1666 * the gain or the contrast. The "reserved" bits seem
1668 * to have some effect in this case. */ 1667 * to have some effect in this case. */
1669 i2c_w(sd, 0x2d, 0x85); 1668 i2c_w(sd, 0x2d, 0x85);
1670 } else if (sd->clockdiv >= 0) { 1669 } else {
1671 i2c_w(sd, 0x11, sd->clockdiv); 1670 i2c_w(sd, 0x11, sd->clockdiv);
1672 } 1671 }
1673 1672
@@ -1869,7 +1868,6 @@ static int sd_start(struct gspca_dev *gspca_dev)
1869 ret = ov51x_restart(sd); 1868 ret = ov51x_restart(sd);
1870 if (ret < 0) 1869 if (ret < 0)
1871 goto out; 1870 goto out;
1872 PDEBUG(D_STREAM, "camera started alt: 0x%02x", gspca_dev->alt);
1873 ov51x_led_control(sd, 1); 1871 ov51x_led_control(sd, 1);
1874 return 0; 1872 return 0;
1875out: 1873out:
@@ -1879,8 +1877,10 @@ out:
1879 1877
1880static void sd_stopN(struct gspca_dev *gspca_dev) 1878static void sd_stopN(struct gspca_dev *gspca_dev)
1881{ 1879{
1882 ov51x_stop((struct sd *) gspca_dev); 1880 struct sd *sd = (struct sd *) gspca_dev;
1883 ov51x_led_control((struct sd *) gspca_dev, 0); 1881
1882 ov51x_stop(sd);
1883 ov51x_led_control(sd, 0);
1884} 1884}
1885 1885
1886static void sd_pkt_scan(struct gspca_dev *gspca_dev, 1886static void sd_pkt_scan(struct gspca_dev *gspca_dev,
@@ -1935,9 +1935,6 @@ static void setbrightness(struct gspca_dev *gspca_dev)
1935 int val; 1935 int val;
1936 1936
1937 val = sd->brightness; 1937 val = sd->brightness;
1938 PDEBUG(D_CONF, "brightness:%d", val);
1939/* if (gspca_dev->streaming)
1940 * ov51x_stop(sd); */
1941 switch (sd->sensor) { 1938 switch (sd->sensor) {
1942 case SEN_OV8610: 1939 case SEN_OV8610:
1943 case SEN_OV7610: 1940 case SEN_OV7610:
@@ -1959,8 +1956,6 @@ static void setbrightness(struct gspca_dev *gspca_dev)
1959 i2c_w(sd, OV7670_REG_BRIGHT, ov7670_abs_to_sm(val)); 1956 i2c_w(sd, OV7670_REG_BRIGHT, ov7670_abs_to_sm(val));
1960 break; 1957 break;
1961 } 1958 }
1962/* if (gspca_dev->streaming)
1963 * ov51x_restart(sd); */
1964} 1959}
1965 1960
1966static void setcontrast(struct gspca_dev *gspca_dev) 1961static void setcontrast(struct gspca_dev *gspca_dev)
@@ -1969,9 +1964,6 @@ static void setcontrast(struct gspca_dev *gspca_dev)
1969 int val; 1964 int val;
1970 1965
1971 val = sd->contrast; 1966 val = sd->contrast;
1972 PDEBUG(D_CONF, "contrast:%d", val);
1973/* if (gspca_dev->streaming)
1974 ov51x_stop(sd); */
1975 switch (sd->sensor) { 1967 switch (sd->sensor) {
1976 case SEN_OV7610: 1968 case SEN_OV7610:
1977 case SEN_OV6620: 1969 case SEN_OV6620:
@@ -2007,8 +1999,6 @@ static void setcontrast(struct gspca_dev *gspca_dev)
2007 i2c_w(sd, OV7670_REG_CONTRAS, val >> 1); 1999 i2c_w(sd, OV7670_REG_CONTRAS, val >> 1);
2008 break; 2000 break;
2009 } 2001 }
2010/* if (gspca_dev->streaming)
2011 ov51x_restart(sd); */
2012} 2002}
2013 2003
2014static void setcolors(struct gspca_dev *gspca_dev) 2004static void setcolors(struct gspca_dev *gspca_dev)
@@ -2017,9 +2007,6 @@ static void setcolors(struct gspca_dev *gspca_dev)
2017 int val; 2007 int val;
2018 2008
2019 val = sd->colors; 2009 val = sd->colors;
2020 PDEBUG(D_CONF, "saturation:%d", val);
2021/* if (gspca_dev->streaming)
2022 ov51x_stop(sd); */
2023 switch (sd->sensor) { 2010 switch (sd->sensor) {
2024 case SEN_OV8610: 2011 case SEN_OV8610:
2025 case SEN_OV7610: 2012 case SEN_OV7610:
@@ -2044,8 +2031,6 @@ static void setcolors(struct gspca_dev *gspca_dev)
2044 /* set REG_COM13 values for UV sat auto mode */ 2031 /* set REG_COM13 values for UV sat auto mode */
2045 break; 2032 break;
2046 } 2033 }
2047/* if (gspca_dev->streaming)
2048 ov51x_restart(sd); */
2049} 2034}
2050 2035
2051static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) 2036static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
@@ -2053,7 +2038,8 @@ static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
2053 struct sd *sd = (struct sd *) gspca_dev; 2038 struct sd *sd = (struct sd *) gspca_dev;
2054 2039
2055 sd->brightness = val; 2040 sd->brightness = val;
2056 setbrightness(gspca_dev); 2041 if (gspca_dev->streaming)
2042 setbrightness(gspca_dev);
2057 return 0; 2043 return 0;
2058} 2044}
2059 2045
@@ -2070,7 +2056,8 @@ static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
2070 struct sd *sd = (struct sd *) gspca_dev; 2056 struct sd *sd = (struct sd *) gspca_dev;
2071 2057
2072 sd->contrast = val; 2058 sd->contrast = val;
2073 setcontrast(gspca_dev); 2059 if (gspca_dev->streaming)
2060 setcontrast(gspca_dev);
2074 return 0; 2061 return 0;
2075} 2062}
2076 2063
@@ -2087,7 +2074,8 @@ static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
2087 struct sd *sd = (struct sd *) gspca_dev; 2074 struct sd *sd = (struct sd *) gspca_dev;
2088 2075
2089 sd->colors = val; 2076 sd->colors = val;
2090 setcolors(gspca_dev); 2077 if (gspca_dev->streaming)
2078 setcolors(gspca_dev);
2091 return 0; 2079 return 0;
2092} 2080}
2093 2081
@@ -2104,7 +2092,8 @@ static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val)
2104 struct sd *sd = (struct sd *) gspca_dev; 2092 struct sd *sd = (struct sd *) gspca_dev;
2105 2093
2106 sd->hflip = val; 2094 sd->hflip = val;
2107 sethvflip(sd); 2095 if (gspca_dev->streaming)
2096 sethvflip(sd);
2108 return 0; 2097 return 0;
2109} 2098}
2110 2099
@@ -2121,7 +2110,8 @@ static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val)
2121 struct sd *sd = (struct sd *) gspca_dev; 2110 struct sd *sd = (struct sd *) gspca_dev;
2122 2111
2123 sd->vflip = val; 2112 sd->vflip = val;
2124 sethvflip(sd); 2113 if (gspca_dev->streaming)
2114 sethvflip(sd);
2125 return 0; 2115 return 0;
2126} 2116}
2127 2117
@@ -2162,7 +2152,7 @@ static const __devinitdata struct usb_device_id device_table[] = {
2162 {USB_DEVICE(0x05a9, 0x8519)}, 2152 {USB_DEVICE(0x05a9, 0x8519)},
2163 {} 2153 {}
2164}; 2154};
2165#undef DVNAME 2155
2166MODULE_DEVICE_TABLE(usb, device_table); 2156MODULE_DEVICE_TABLE(usb, device_table);
2167 2157
2168/* -- device connect -- */ 2158/* -- device connect -- */
diff --git a/drivers/media/video/gspca/ov534.c b/drivers/media/video/gspca/ov534.c
new file mode 100644
index 000000000000..3bf15e401693
--- /dev/null
+++ b/drivers/media/video/gspca/ov534.c
@@ -0,0 +1,601 @@
1/*
2 * ov534/ov772x gspca driver
3 * Copyright (C) 2008 Antonio Ospite <ospite@studenti.unina.it>
4 * Copyright (C) 2008 Jim Paris <jim@jtan.com>
5 *
6 * Based on a prototype written by Mark Ferrell <majortrips@gmail.com>
7 * USB protocol reverse engineered by Jim Paris <jim@jtan.com>
8 * https://jim.sh/svn/jim/devl/playstation/ps3/eye/test/
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 */
24
25#define MODULE_NAME "ov534"
26
27#include "gspca.h"
28
29#define OV534_REG_ADDRESS 0xf1 /* ? */
30#define OV534_REG_SUBADDR 0xf2
31#define OV534_REG_WRITE 0xf3
32#define OV534_REG_READ 0xf4
33#define OV534_REG_OPERATION 0xf5
34#define OV534_REG_STATUS 0xf6
35
36#define OV534_OP_WRITE_3 0x37
37#define OV534_OP_WRITE_2 0x33
38#define OV534_OP_READ_2 0xf9
39
40#define CTRL_TIMEOUT 500
41
42MODULE_AUTHOR("Antonio Ospite <ospite@studenti.unina.it>");
43MODULE_DESCRIPTION("GSPCA/OV534 USB Camera Driver");
44MODULE_LICENSE("GPL");
45
46/* specific webcam descriptor */
47struct sd {
48 struct gspca_dev gspca_dev; /* !! must be the first item */
49 __u32 last_fid;
50 __u32 last_pts;
51 int frame_rate;
52};
53
54/* V4L2 controls supported by the driver */
55static struct ctrl sd_ctrls[] = {
56};
57
58static const struct v4l2_pix_format vga_mode[] = {
59 {640, 480, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE,
60 .bytesperline = 640 * 2,
61 .sizeimage = 640 * 480 * 2,
62 .colorspace = V4L2_COLORSPACE_JPEG,
63 .priv = 0},
64};
65
66static void ov534_reg_write(struct gspca_dev *gspca_dev, u16 reg, u8 val)
67{
68 struct usb_device *udev = gspca_dev->dev;
69 int ret;
70
71 PDEBUG(D_USBO, "reg=0x%04x, val=0%02x", reg, val);
72 gspca_dev->usb_buf[0] = val;
73 ret = usb_control_msg(udev,
74 usb_sndctrlpipe(udev, 0),
75 0x1,
76 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
77 0x0, reg, gspca_dev->usb_buf, 1, CTRL_TIMEOUT);
78 if (ret < 0)
79 PDEBUG(D_ERR, "write failed");
80}
81
82static u8 ov534_reg_read(struct gspca_dev *gspca_dev, u16 reg)
83{
84 struct usb_device *udev = gspca_dev->dev;
85 int ret;
86
87 ret = usb_control_msg(udev,
88 usb_rcvctrlpipe(udev, 0),
89 0x1,
90 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
91 0x0, reg, gspca_dev->usb_buf, 1, CTRL_TIMEOUT);
92 PDEBUG(D_USBI, "reg=0x%04x, data=0x%02x", reg, gspca_dev->usb_buf[0]);
93 if (ret < 0)
94 PDEBUG(D_ERR, "read failed");
95 return gspca_dev->usb_buf[0];
96}
97
98/* Two bits control LED: 0x21 bit 7 and 0x23 bit 7.
99 * (direction and output)? */
100static void ov534_set_led(struct gspca_dev *gspca_dev, int status)
101{
102 u8 data;
103
104 PDEBUG(D_CONF, "led status: %d", status);
105
106 data = ov534_reg_read(gspca_dev, 0x21);
107 data |= 0x80;
108 ov534_reg_write(gspca_dev, 0x21, data);
109
110 data = ov534_reg_read(gspca_dev, 0x23);
111 if (status)
112 data |= 0x80;
113 else
114 data &= ~(0x80);
115
116 ov534_reg_write(gspca_dev, 0x23, data);
117}
118
119static int sccb_check_status(struct gspca_dev *gspca_dev)
120{
121 u8 data;
122 int i;
123
124 for (i = 0; i < 5; i++) {
125 data = ov534_reg_read(gspca_dev, OV534_REG_STATUS);
126
127 switch (data) {
128 case 0x00:
129 return 1;
130 case 0x04:
131 return 0;
132 case 0x03:
133 break;
134 default:
135 PDEBUG(D_ERR, "sccb status 0x%02x, attempt %d/5",
136 data, i + 1);
137 }
138 }
139 return 0;
140}
141
142static void sccb_reg_write(struct gspca_dev *gspca_dev, u16 reg, u8 val)
143{
144 PDEBUG(D_USBO, "reg: 0x%04x, val: 0x%02x", reg, val);
145 ov534_reg_write(gspca_dev, OV534_REG_SUBADDR, reg);
146 ov534_reg_write(gspca_dev, OV534_REG_WRITE, val);
147 ov534_reg_write(gspca_dev, OV534_REG_OPERATION, OV534_OP_WRITE_3);
148
149 if (!sccb_check_status(gspca_dev))
150 PDEBUG(D_ERR, "sccb_reg_write failed");
151}
152
153#ifdef GSPCA_DEBUG
154static u8 sccb_reg_read(struct gspca_dev *gspca_dev, u16 reg)
155{
156 ov534_reg_write(gspca_dev, OV534_REG_SUBADDR, reg);
157 ov534_reg_write(gspca_dev, OV534_REG_OPERATION, OV534_OP_WRITE_2);
158 if (!sccb_check_status(gspca_dev))
159 PDEBUG(D_ERR, "sccb_reg_read failed 1");
160
161 ov534_reg_write(gspca_dev, OV534_REG_OPERATION, OV534_OP_READ_2);
162 if (!sccb_check_status(gspca_dev))
163 PDEBUG(D_ERR, "sccb_reg_read failed 2");
164
165 return ov534_reg_read(gspca_dev, OV534_REG_READ);
166}
167#endif
168
169static const __u8 ov534_reg_initdata[][2] = {
170 { 0xe7, 0x3a },
171
172 { OV534_REG_ADDRESS, 0x42 }, /* select OV772x sensor */
173
174 { 0xc2, 0x0c },
175 { 0x88, 0xf8 },
176 { 0xc3, 0x69 },
177 { 0x89, 0xff },
178 { 0x76, 0x03 },
179 { 0x92, 0x01 },
180 { 0x93, 0x18 },
181 { 0x94, 0x10 },
182 { 0x95, 0x10 },
183 { 0xe2, 0x00 },
184 { 0xe7, 0x3e },
185
186 { 0x96, 0x00 },
187
188 { 0x97, 0x20 },
189 { 0x97, 0x20 },
190 { 0x97, 0x20 },
191 { 0x97, 0x0a },
192 { 0x97, 0x3f },
193 { 0x97, 0x4a },
194 { 0x97, 0x20 },
195 { 0x97, 0x15 },
196 { 0x97, 0x0b },
197
198 { 0x8e, 0x40 },
199 { 0x1f, 0x81 },
200 { 0x34, 0x05 },
201 { 0xe3, 0x04 },
202 { 0x88, 0x00 },
203 { 0x89, 0x00 },
204 { 0x76, 0x00 },
205 { 0xe7, 0x2e },
206 { 0x31, 0xf9 },
207 { 0x25, 0x42 },
208 { 0x21, 0xf0 },
209
210 { 0x1c, 0x00 },
211 { 0x1d, 0x40 },
212 { 0x1d, 0x02 }, /* payload size 0x0200 * 4 = 2048 bytes */
213 { 0x1d, 0x00 }, /* payload size */
214 { 0x1d, 0x02 }, /* frame size 0x025800 * 4 = 614400 */
215 { 0x1d, 0x58 }, /* frame size */
216 { 0x1d, 0x00 }, /* frame size */
217
218 { 0x1c, 0x0a },
219 { 0x1d, 0x08 }, /* turn on UVC header */
220 { 0x1d, 0x0e }, /* .. */
221
222 { 0x8d, 0x1c },
223 { 0x8e, 0x80 },
224 { 0xe5, 0x04 },
225
226 { 0xc0, 0x50 },
227 { 0xc1, 0x3c },
228 { 0xc2, 0x0c },
229};
230
231static const __u8 ov772x_reg_initdata[][2] = {
232 { 0x12, 0x80 },
233 { 0x11, 0x01 },
234
235 { 0x3d, 0x03 },
236 { 0x17, 0x26 },
237 { 0x18, 0xa0 },
238 { 0x19, 0x07 },
239 { 0x1a, 0xf0 },
240 { 0x32, 0x00 },
241 { 0x29, 0xa0 },
242 { 0x2c, 0xf0 },
243 { 0x65, 0x20 },
244 { 0x11, 0x01 },
245 { 0x42, 0x7f },
246 { 0x63, 0xe0 },
247 { 0x64, 0xff },
248 { 0x66, 0x00 },
249 { 0x13, 0xf0 },
250 { 0x0d, 0x41 },
251 { 0x0f, 0xc5 },
252 { 0x14, 0x11 },
253
254 { 0x22, 0x7f },
255 { 0x23, 0x03 },
256 { 0x24, 0x40 },
257 { 0x25, 0x30 },
258 { 0x26, 0xa1 },
259 { 0x2a, 0x00 },
260 { 0x2b, 0x00 },
261 { 0x6b, 0xaa },
262 { 0x13, 0xff },
263
264 { 0x90, 0x05 },
265 { 0x91, 0x01 },
266 { 0x92, 0x03 },
267 { 0x93, 0x00 },
268 { 0x94, 0x60 },
269 { 0x95, 0x3c },
270 { 0x96, 0x24 },
271 { 0x97, 0x1e },
272 { 0x98, 0x62 },
273 { 0x99, 0x80 },
274 { 0x9a, 0x1e },
275 { 0x9b, 0x08 },
276 { 0x9c, 0x20 },
277 { 0x9e, 0x81 },
278
279 { 0xa6, 0x04 },
280 { 0x7e, 0x0c },
281 { 0x7f, 0x16 },
282 { 0x80, 0x2a },
283 { 0x81, 0x4e },
284 { 0x82, 0x61 },
285 { 0x83, 0x6f },
286 { 0x84, 0x7b },
287 { 0x85, 0x86 },
288 { 0x86, 0x8e },
289 { 0x87, 0x97 },
290 { 0x88, 0xa4 },
291 { 0x89, 0xaf },
292 { 0x8a, 0xc5 },
293 { 0x8b, 0xd7 },
294 { 0x8c, 0xe8 },
295 { 0x8d, 0x20 },
296
297 { 0x0c, 0x90 },
298
299 { 0x2b, 0x00 },
300 { 0x22, 0x7f },
301 { 0x23, 0x03 },
302 { 0x11, 0x01 },
303 { 0x0c, 0xd0 },
304 { 0x64, 0xff },
305 { 0x0d, 0x41 },
306
307 { 0x14, 0x41 },
308 { 0x0e, 0xcd },
309 { 0xac, 0xbf },
310 { 0x8e, 0x00 },
311 { 0x0c, 0xd0 }
312};
313
314/* set framerate */
315static void ov534_set_frame_rate(struct gspca_dev *gspca_dev)
316{
317 struct sd *sd = (struct sd *) gspca_dev;
318 int fr = sd->frame_rate;
319
320 switch (fr) {
321 case 50:
322 sccb_reg_write(gspca_dev, 0x11, 0x01);
323 sccb_reg_write(gspca_dev, 0x0d, 0x41);
324 ov534_reg_write(gspca_dev, 0xe5, 0x02);
325 break;
326 case 40:
327 sccb_reg_write(gspca_dev, 0x11, 0x02);
328 sccb_reg_write(gspca_dev, 0x0d, 0xc1);
329 ov534_reg_write(gspca_dev, 0xe5, 0x04);
330 break;
331/* case 30: */
332 default:
333 fr = 30;
334 sccb_reg_write(gspca_dev, 0x11, 0x04);
335 sccb_reg_write(gspca_dev, 0x0d, 0x81);
336 ov534_reg_write(gspca_dev, 0xe5, 0x02);
337 break;
338 case 15:
339 sccb_reg_write(gspca_dev, 0x11, 0x03);
340 sccb_reg_write(gspca_dev, 0x0d, 0x41);
341 ov534_reg_write(gspca_dev, 0xe5, 0x04);
342 break;
343 }
344
345 sd->frame_rate = fr;
346 PDEBUG(D_PROBE, "frame_rate: %d", fr);
347}
348
349/* setup method */
350static void ov534_setup(struct gspca_dev *gspca_dev)
351{
352 int i;
353
354 /* Initialize bridge chip */
355 for (i = 0; i < ARRAY_SIZE(ov534_reg_initdata); i++)
356 ov534_reg_write(gspca_dev, ov534_reg_initdata[i][0],
357 ov534_reg_initdata[i][1]);
358
359 PDEBUG(D_PROBE, "sensor is ov%02x%02x",
360 sccb_reg_read(gspca_dev, 0x0a),
361 sccb_reg_read(gspca_dev, 0x0b));
362
363 ov534_set_led(gspca_dev, 1);
364
365 /* Initialize sensor */
366 for (i = 0; i < ARRAY_SIZE(ov772x_reg_initdata); i++)
367 sccb_reg_write(gspca_dev, ov772x_reg_initdata[i][0],
368 ov772x_reg_initdata[i][1]);
369
370 ov534_reg_write(gspca_dev, 0xe0, 0x09);
371 ov534_set_led(gspca_dev, 0);
372}
373
374/* this function is called at probe time */
375static int sd_config(struct gspca_dev *gspca_dev,
376 const struct usb_device_id *id)
377{
378 struct cam *cam;
379
380 cam = &gspca_dev->cam;
381
382 cam->epaddr = 0x01;
383 cam->cam_mode = vga_mode;
384 cam->nmodes = ARRAY_SIZE(vga_mode);
385
386 cam->bulk_size = 16384;
387 cam->bulk_nurbs = 2;
388
389 return 0;
390}
391
392/* this function is called at probe and resume time */
393static int sd_init(struct gspca_dev *gspca_dev)
394{
395 ov534_setup(gspca_dev);
396 ov534_set_frame_rate(gspca_dev);
397
398 return 0;
399}
400
401static int sd_start(struct gspca_dev *gspca_dev)
402{
403 /* start streaming data */
404 ov534_set_led(gspca_dev, 1);
405 ov534_reg_write(gspca_dev, 0xe0, 0x00);
406
407 return 0;
408}
409
410static void sd_stopN(struct gspca_dev *gspca_dev)
411{
412 /* stop streaming data */
413 ov534_reg_write(gspca_dev, 0xe0, 0x09);
414 ov534_set_led(gspca_dev, 0);
415}
416
417/* Values for bmHeaderInfo (Video and Still Image Payload Headers, 2.4.3.3) */
418#define UVC_STREAM_EOH (1 << 7)
419#define UVC_STREAM_ERR (1 << 6)
420#define UVC_STREAM_STI (1 << 5)
421#define UVC_STREAM_RES (1 << 4)
422#define UVC_STREAM_SCR (1 << 3)
423#define UVC_STREAM_PTS (1 << 2)
424#define UVC_STREAM_EOF (1 << 1)
425#define UVC_STREAM_FID (1 << 0)
426
427static void sd_pkt_scan(struct gspca_dev *gspca_dev, struct gspca_frame *frame,
428 __u8 *data, int len)
429{
430 struct sd *sd = (struct sd *) gspca_dev;
431 __u32 this_pts;
432 int this_fid;
433 int remaining_len = len;
434 __u8 *next_data = data;
435
436scan_next:
437 if (remaining_len <= 0)
438 return;
439
440 data = next_data;
441 len = min(remaining_len, 2048);
442 remaining_len -= len;
443 next_data += len;
444
445 /* Payloads are prefixed with a UVC-style header. We
446 consider a frame to start when the FID toggles, or the PTS
447 changes. A frame ends when EOF is set, and we've received
448 the correct number of bytes. */
449
450 /* Verify UVC header. Header length is always 12 */
451 if (data[0] != 12 || len < 12) {
452 PDEBUG(D_PACK, "bad header");
453 goto discard;
454 }
455
456 /* Check errors */
457 if (data[1] & UVC_STREAM_ERR) {
458 PDEBUG(D_PACK, "payload error");
459 goto discard;
460 }
461
462 /* Extract PTS and FID */
463 if (!(data[1] & UVC_STREAM_PTS)) {
464 PDEBUG(D_PACK, "PTS not present");
465 goto discard;
466 }
467 this_pts = (data[5] << 24) | (data[4] << 16) | (data[3] << 8) | data[2];
468 this_fid = (data[1] & UVC_STREAM_FID) ? 1 : 0;
469
470 /* If PTS or FID has changed, start a new frame. */
471 if (this_pts != sd->last_pts || this_fid != sd->last_fid) {
472 gspca_frame_add(gspca_dev, FIRST_PACKET, frame, NULL, 0);
473 sd->last_pts = this_pts;
474 sd->last_fid = this_fid;
475 }
476
477 /* Add the data from this payload */
478 gspca_frame_add(gspca_dev, INTER_PACKET, frame,
479 data + 12, len - 12);
480
481 /* If this packet is marked as EOF, end the frame */
482 if (data[1] & UVC_STREAM_EOF) {
483 sd->last_pts = 0;
484
485 if ((frame->data_end - frame->data) !=
486 (gspca_dev->width * gspca_dev->height * 2)) {
487 PDEBUG(D_PACK, "short frame");
488 goto discard;
489 }
490
491 gspca_frame_add(gspca_dev, LAST_PACKET, frame, NULL, 0);
492 }
493
494 /* Done this payload */
495 goto scan_next;
496
497discard:
498 /* Discard data until a new frame starts. */
499 gspca_frame_add(gspca_dev, DISCARD_PACKET, frame, NULL, 0);
500 goto scan_next;
501}
502
503/* get stream parameters (framerate) */
504static int sd_get_streamparm(struct gspca_dev *gspca_dev,
505 struct v4l2_streamparm *parm)
506{
507 struct v4l2_captureparm *cp = &parm->parm.capture;
508 struct v4l2_fract *tpf = &cp->timeperframe;
509 struct sd *sd = (struct sd *) gspca_dev;
510
511 if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
512 return -EINVAL;
513
514 cp->capability |= V4L2_CAP_TIMEPERFRAME;
515 tpf->numerator = 1;
516 tpf->denominator = sd->frame_rate;
517
518 return 0;
519}
520
521/* set stream parameters (framerate) */
522static int sd_set_streamparm(struct gspca_dev *gspca_dev,
523 struct v4l2_streamparm *parm)
524{
525 struct v4l2_captureparm *cp = &parm->parm.capture;
526 struct v4l2_fract *tpf = &cp->timeperframe;
527 struct sd *sd = (struct sd *) gspca_dev;
528
529 if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
530 return -EINVAL;
531
532 /* Set requested framerate */
533 sd->frame_rate = tpf->denominator / tpf->numerator;
534 ov534_set_frame_rate(gspca_dev);
535
536 /* Return the actual framerate */
537 tpf->numerator = 1;
538 tpf->denominator = sd->frame_rate;
539
540 return 0;
541}
542
543/* sub-driver description */
544static const struct sd_desc sd_desc = {
545 .name = MODULE_NAME,
546 .ctrls = sd_ctrls,
547 .nctrls = ARRAY_SIZE(sd_ctrls),
548 .config = sd_config,
549 .init = sd_init,
550 .start = sd_start,
551 .stopN = sd_stopN,
552 .pkt_scan = sd_pkt_scan,
553 .get_streamparm = sd_get_streamparm,
554 .set_streamparm = sd_set_streamparm,
555};
556
557/* -- module initialisation -- */
558static const __devinitdata struct usb_device_id device_table[] = {
559 {USB_DEVICE(0x06f8, 0x3002)}, /* Hercules Blog Webcam */
560 {USB_DEVICE(0x06f8, 0x3003)}, /* Hercules Dualpix HD Weblog */
561 {USB_DEVICE(0x1415, 0x2000)}, /* Sony HD Eye for PS3 (SLEH 00201) */
562 {}
563};
564
565MODULE_DEVICE_TABLE(usb, device_table);
566
567/* -- device connect -- */
568static int sd_probe(struct usb_interface *intf, const struct usb_device_id *id)
569{
570 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
571 THIS_MODULE);
572}
573
574static struct usb_driver sd_driver = {
575 .name = MODULE_NAME,
576 .id_table = device_table,
577 .probe = sd_probe,
578 .disconnect = gspca_disconnect,
579#ifdef CONFIG_PM
580 .suspend = gspca_suspend,
581 .resume = gspca_resume,
582#endif
583};
584
585/* -- module insert / remove -- */
586static int __init sd_mod_init(void)
587{
588 if (usb_register(&sd_driver) < 0)
589 return -1;
590 PDEBUG(D_PROBE, "registered");
591 return 0;
592}
593
594static void __exit sd_mod_exit(void)
595{
596 usb_deregister(&sd_driver);
597 PDEBUG(D_PROBE, "deregistered");
598}
599
600module_init(sd_mod_init);
601module_exit(sd_mod_exit);
diff --git a/drivers/media/video/gspca/pac207.c b/drivers/media/video/gspca/pac207.c
index 0b0c573d06da..c90ac852bac0 100644
--- a/drivers/media/video/gspca/pac207.c
+++ b/drivers/media/video/gspca/pac207.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Pixart PAC207BCA library 2 * Pixart PAC207BCA library
3 * 3 *
4 * Copyright (C) 2008 Hans de Goede <j.w.r.degoede@hhs.nl> 4 * Copyright (C) 2008 Hans de Goede <hdgoede@redhat.com>
5 * Copyright (C) 2005 Thomas Kaiser thomas@kaiser-linux.li 5 * Copyright (C) 2005 Thomas Kaiser thomas@kaiser-linux.li
6 * Copyleft (C) 2005 Michel Xhaard mxhaard@magic.fr 6 * Copyleft (C) 2005 Michel Xhaard mxhaard@magic.fr
7 * 7 *
@@ -27,7 +27,7 @@
27 27
28#include "gspca.h" 28#include "gspca.h"
29 29
30MODULE_AUTHOR("Hans de Goede <j.w.r.degoede@hhs.nl>"); 30MODULE_AUTHOR("Hans de Goede <hdgoede@redhat.com>");
31MODULE_DESCRIPTION("Pixart PAC207"); 31MODULE_DESCRIPTION("Pixart PAC207");
32MODULE_LICENSE("GPL"); 32MODULE_LICENSE("GPL");
33 33
@@ -149,7 +149,7 @@ static struct ctrl sd_ctrls[] = {
149 }, 149 },
150}; 150};
151 151
152static struct v4l2_pix_format sif_mode[] = { 152static const struct v4l2_pix_format sif_mode[] = {
153 {176, 144, V4L2_PIX_FMT_PAC207, V4L2_FIELD_NONE, 153 {176, 144, V4L2_PIX_FMT_PAC207, V4L2_FIELD_NONE,
154 .bytesperline = 176, 154 .bytesperline = 176,
155 .sizeimage = (176 + 2) * 144, 155 .sizeimage = (176 + 2) * 144,
@@ -529,6 +529,7 @@ static const struct sd_desc sd_desc = {
529static const __devinitdata struct usb_device_id device_table[] = { 529static const __devinitdata struct usb_device_id device_table[] = {
530 {USB_DEVICE(0x041e, 0x4028)}, 530 {USB_DEVICE(0x041e, 0x4028)},
531 {USB_DEVICE(0x093a, 0x2460)}, 531 {USB_DEVICE(0x093a, 0x2460)},
532 {USB_DEVICE(0x093a, 0x2461)},
532 {USB_DEVICE(0x093a, 0x2463)}, 533 {USB_DEVICE(0x093a, 0x2463)},
533 {USB_DEVICE(0x093a, 0x2464)}, 534 {USB_DEVICE(0x093a, 0x2464)},
534 {USB_DEVICE(0x093a, 0x2468)}, 535 {USB_DEVICE(0x093a, 0x2468)},
@@ -536,6 +537,7 @@ static const __devinitdata struct usb_device_id device_table[] = {
536 {USB_DEVICE(0x093a, 0x2471)}, 537 {USB_DEVICE(0x093a, 0x2471)},
537 {USB_DEVICE(0x093a, 0x2472)}, 538 {USB_DEVICE(0x093a, 0x2472)},
538 {USB_DEVICE(0x093a, 0x2476)}, 539 {USB_DEVICE(0x093a, 0x2476)},
540 {USB_DEVICE(0x145f, 0x013a)},
539 {USB_DEVICE(0x2001, 0xf115)}, 541 {USB_DEVICE(0x2001, 0xf115)},
540 {} 542 {}
541}; 543};
diff --git a/drivers/media/video/gspca/pac7311.c b/drivers/media/video/gspca/pac7311.c
index fbd45e235d97..a9c95cba710e 100644
--- a/drivers/media/video/gspca/pac7311.c
+++ b/drivers/media/video/gspca/pac7311.c
@@ -226,7 +226,7 @@ static struct ctrl sd_ctrls[] = {
226 }, 226 },
227}; 227};
228 228
229static struct v4l2_pix_format vga_mode[] = { 229static const struct v4l2_pix_format vga_mode[] = {
230 {160, 120, V4L2_PIX_FMT_PJPG, V4L2_FIELD_NONE, 230 {160, 120, V4L2_PIX_FMT_PJPG, V4L2_FIELD_NONE,
231 .bytesperline = 160, 231 .bytesperline = 160,
232 .sizeimage = 160 * 120 * 3 / 8 + 590, 232 .sizeimage = 160 * 120 * 3 / 8 + 590,
@@ -1064,10 +1064,13 @@ static __devinitdata struct usb_device_id device_table[] = {
1064 {USB_DEVICE(0x093a, 0x2608), .driver_info = SENSOR_PAC7311}, 1064 {USB_DEVICE(0x093a, 0x2608), .driver_info = SENSOR_PAC7311},
1065 {USB_DEVICE(0x093a, 0x260e), .driver_info = SENSOR_PAC7311}, 1065 {USB_DEVICE(0x093a, 0x260e), .driver_info = SENSOR_PAC7311},
1066 {USB_DEVICE(0x093a, 0x260f), .driver_info = SENSOR_PAC7311}, 1066 {USB_DEVICE(0x093a, 0x260f), .driver_info = SENSOR_PAC7311},
1067 {USB_DEVICE(0x093a, 0x2620), .driver_info = SENSOR_PAC7302},
1067 {USB_DEVICE(0x093a, 0x2621), .driver_info = SENSOR_PAC7302}, 1068 {USB_DEVICE(0x093a, 0x2621), .driver_info = SENSOR_PAC7302},
1069 {USB_DEVICE(0x093a, 0x2622), .driver_info = SENSOR_PAC7302},
1068 {USB_DEVICE(0x093a, 0x2624), .driver_info = SENSOR_PAC7302}, 1070 {USB_DEVICE(0x093a, 0x2624), .driver_info = SENSOR_PAC7302},
1069 {USB_DEVICE(0x093a, 0x2626), .driver_info = SENSOR_PAC7302}, 1071 {USB_DEVICE(0x093a, 0x2626), .driver_info = SENSOR_PAC7302},
1070 {USB_DEVICE(0x093a, 0x262a), .driver_info = SENSOR_PAC7302}, 1072 {USB_DEVICE(0x093a, 0x262a), .driver_info = SENSOR_PAC7302},
1073 {USB_DEVICE(0x093a, 0x262c), .driver_info = SENSOR_PAC7302},
1071 {} 1074 {}
1072}; 1075};
1073MODULE_DEVICE_TABLE(usb, device_table); 1076MODULE_DEVICE_TABLE(usb, device_table);
diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c
index 6c69bc7778fc..b3e4e0677b68 100644
--- a/drivers/media/video/gspca/sonixb.c
+++ b/drivers/media/video/gspca/sonixb.c
@@ -132,8 +132,6 @@ struct sensor_data {
132 ignore atleast the 2 next frames for the new settings to come into effect 132 ignore atleast the 2 next frames for the new settings to come into effect
133 before doing any other adjustments */ 133 before doing any other adjustments */
134#define AUTOGAIN_IGNORE_FRAMES 3 134#define AUTOGAIN_IGNORE_FRAMES 3
135#define AUTOGAIN_DEADZONE 1000
136#define DESIRED_AVG_LUM 7000
137 135
138/* V4L2 controls supported by the driver */ 136/* V4L2 controls supported by the driver */
139static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); 137static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
@@ -229,7 +227,7 @@ static struct ctrl sd_ctrls[] = {
229 }, 227 },
230}; 228};
231 229
232static struct v4l2_pix_format vga_mode[] = { 230static const struct v4l2_pix_format vga_mode[] = {
233 {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, 231 {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
234 .bytesperline = 160, 232 .bytesperline = 160,
235 .sizeimage = 160 * 120, 233 .sizeimage = 160 * 120,
@@ -251,7 +249,7 @@ static struct v4l2_pix_format vga_mode[] = {
251 .colorspace = V4L2_COLORSPACE_SRGB, 249 .colorspace = V4L2_COLORSPACE_SRGB,
252 .priv = 0}, 250 .priv = 0},
253}; 251};
254static struct v4l2_pix_format sif_mode[] = { 252static const struct v4l2_pix_format sif_mode[] = {
255 {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, 253 {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
256 .bytesperline = 160, 254 .bytesperline = 160,
257 .sizeimage = 160 * 120, 255 .sizeimage = 160 * 120,
@@ -827,18 +825,29 @@ static void setfreq(struct gspca_dev *gspca_dev)
827 825
828static void do_autogain(struct gspca_dev *gspca_dev) 826static void do_autogain(struct gspca_dev *gspca_dev)
829{ 827{
828 int deadzone, desired_avg_lum;
830 struct sd *sd = (struct sd *) gspca_dev; 829 struct sd *sd = (struct sd *) gspca_dev;
831 int avg_lum = atomic_read(&sd->avg_lum); 830 int avg_lum = atomic_read(&sd->avg_lum);
832 831
833 if (avg_lum == -1) 832 if (avg_lum == -1)
834 return; 833 return;
835 834
835 /* SIF / VGA sensors have a different autoexposure area and thus
836 different avg_lum values for the same picture brightness */
837 if (sensor_data[sd->sensor].flags & F_SIF) {
838 deadzone = 1000;
839 desired_avg_lum = 7000;
840 } else {
841 deadzone = 3000;
842 desired_avg_lum = 23000;
843 }
844
836 if (sd->autogain_ignore_frames > 0) 845 if (sd->autogain_ignore_frames > 0)
837 sd->autogain_ignore_frames--; 846 sd->autogain_ignore_frames--;
838 else if (gspca_auto_gain_n_exposure(gspca_dev, avg_lum, 847 else if (gspca_auto_gain_n_exposure(gspca_dev, avg_lum,
839 sd->brightness * DESIRED_AVG_LUM / 127, 848 sd->brightness * desired_avg_lum / 127,
840 AUTOGAIN_DEADZONE, GAIN_KNEE, EXPOSURE_KNEE)) { 849 deadzone, GAIN_KNEE, EXPOSURE_KNEE)) {
841 PDEBUG(D_FRAM, "autogain: gain changed: gain: %d expo: %d\n", 850 PDEBUG(D_FRAM, "autogain: gain changed: gain: %d expo: %d",
842 (int)sd->gain, (int)sd->exposure); 851 (int)sd->gain, (int)sd->exposure);
843 sd->autogain_ignore_frames = AUTOGAIN_IGNORE_FRAMES; 852 sd->autogain_ignore_frames = AUTOGAIN_IGNORE_FRAMES;
844 } 853 }
@@ -1226,8 +1235,8 @@ static __devinitdata struct usb_device_id device_table[] = {
1226 {USB_DEVICE(0x0c45, 0x6025), SB(TAS5130CXX, 102)}, 1235 {USB_DEVICE(0x0c45, 0x6025), SB(TAS5130CXX, 102)},
1227 {USB_DEVICE(0x0c45, 0x6028), SB(PAS202, 102)}, 1236 {USB_DEVICE(0x0c45, 0x6028), SB(PAS202, 102)},
1228 {USB_DEVICE(0x0c45, 0x6029), SB(PAS106, 102)}, 1237 {USB_DEVICE(0x0c45, 0x6029), SB(PAS106, 102)},
1229 {USB_DEVICE(0x0c45, 0x602c), SB(OV7630, 102)},
1230#endif 1238#endif
1239 {USB_DEVICE(0x0c45, 0x602c), SB(OV7630, 102)},
1231 {USB_DEVICE(0x0c45, 0x602d), SB(HV7131R, 102)}, 1240 {USB_DEVICE(0x0c45, 0x602d), SB(HV7131R, 102)},
1232#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE 1241#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1233 {USB_DEVICE(0x0c45, 0x602e), SB(OV7630, 102)}, 1242 {USB_DEVICE(0x0c45, 0x602e), SB(OV7630, 102)},
diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c
index 53cb82d9e7c6..3373b8d9d2a8 100644
--- a/drivers/media/video/gspca/sonixj.c
+++ b/drivers/media/video/gspca/sonixj.c
@@ -24,6 +24,8 @@
24#include "gspca.h" 24#include "gspca.h"
25#include "jpeg.h" 25#include "jpeg.h"
26 26
27#define V4L2_CID_INFRARED (V4L2_CID_PRIVATE_BASE + 0)
28
27MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>"); 29MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
28MODULE_DESCRIPTION("GSPCA/SONIX JPEG USB Camera Driver"); 30MODULE_DESCRIPTION("GSPCA/SONIX JPEG USB Camera Driver");
29MODULE_LICENSE("GPL"); 31MODULE_LICENSE("GPL");
@@ -35,23 +37,26 @@ struct sd {
35 atomic_t avg_lum; 37 atomic_t avg_lum;
36 unsigned int exposure; 38 unsigned int exposure;
37 39
38 unsigned short brightness; 40 __u16 brightness;
39 unsigned char contrast; 41 __u8 contrast;
40 unsigned char colors; 42 __u8 colors;
41 unsigned char autogain; 43 __u8 autogain;
44 __u8 blue;
45 __u8 red;
42 __u8 vflip; /* ov7630 only */ 46 __u8 vflip; /* ov7630 only */
47 __u8 infrared; /* mi0360 only */
43 48
44 signed char ag_cnt; 49 __s8 ag_cnt;
45#define AG_CNT_START 13 50#define AG_CNT_START 13
46 51
47 char qindex; 52 __u8 qindex;
48 unsigned char bridge; 53 __u8 bridge;
49#define BRIDGE_SN9C102P 0 54#define BRIDGE_SN9C102P 0
50#define BRIDGE_SN9C105 1 55#define BRIDGE_SN9C105 1
51#define BRIDGE_SN9C110 2 56#define BRIDGE_SN9C110 2
52#define BRIDGE_SN9C120 3 57#define BRIDGE_SN9C120 3
53#define BRIDGE_SN9C325 4 58#define BRIDGE_SN9C325 4
54 char sensor; /* Type of image sensor chip */ 59 __u8 sensor; /* Type of image sensor chip */
55#define SENSOR_HV7131R 0 60#define SENSOR_HV7131R 0
56#define SENSOR_MI0360 1 61#define SENSOR_MI0360 1
57#define SENSOR_MO4000 2 62#define SENSOR_MO4000 2
@@ -59,7 +64,7 @@ struct sd {
59#define SENSOR_OV7630 4 64#define SENSOR_OV7630 4
60#define SENSOR_OV7648 5 65#define SENSOR_OV7648 5
61#define SENSOR_OV7660 6 66#define SENSOR_OV7660 6
62 unsigned char i2c_base; 67 __u8 i2c_base;
63}; 68};
64 69
65/* V4L2 controls supported by the driver */ 70/* V4L2 controls supported by the driver */
@@ -69,10 +74,16 @@ static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
69static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); 74static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
70static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val); 75static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
71static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val); 76static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
77static int sd_setblue_balance(struct gspca_dev *gspca_dev, __s32 val);
78static int sd_getblue_balance(struct gspca_dev *gspca_dev, __s32 *val);
79static int sd_setred_balance(struct gspca_dev *gspca_dev, __s32 val);
80static int sd_getred_balance(struct gspca_dev *gspca_dev, __s32 *val);
72static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); 81static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
73static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val); 82static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
74static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val); 83static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val);
75static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val); 84static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val);
85static int sd_setinfrared(struct gspca_dev *gspca_dev, __s32 val);
86static int sd_getinfrared(struct gspca_dev *gspca_dev, __s32 *val);
76 87
77static struct ctrl sd_ctrls[] = { 88static struct ctrl sd_ctrls[] = {
78 { 89 {
@@ -84,7 +95,7 @@ static struct ctrl sd_ctrls[] = {
84#define BRIGHTNESS_MAX 0xffff 95#define BRIGHTNESS_MAX 0xffff
85 .maximum = BRIGHTNESS_MAX, 96 .maximum = BRIGHTNESS_MAX,
86 .step = 1, 97 .step = 1,
87#define BRIGHTNESS_DEF 0x7fff 98#define BRIGHTNESS_DEF 0x8000
88 .default_value = BRIGHTNESS_DEF, 99 .default_value = BRIGHTNESS_DEF,
89 }, 100 },
90 .set = sd_setbrightness, 101 .set = sd_setbrightness,
@@ -111,7 +122,7 @@ static struct ctrl sd_ctrls[] = {
111 .type = V4L2_CTRL_TYPE_INTEGER, 122 .type = V4L2_CTRL_TYPE_INTEGER,
112 .name = "Color", 123 .name = "Color",
113 .minimum = 0, 124 .minimum = 0,
114 .maximum = 64, 125 .maximum = 40,
115 .step = 1, 126 .step = 1,
116#define COLOR_DEF 32 127#define COLOR_DEF 32
117 .default_value = COLOR_DEF, 128 .default_value = COLOR_DEF,
@@ -119,7 +130,35 @@ static struct ctrl sd_ctrls[] = {
119 .set = sd_setcolors, 130 .set = sd_setcolors,
120 .get = sd_getcolors, 131 .get = sd_getcolors,
121 }, 132 },
122#define AUTOGAIN_IDX 3 133 {
134 {
135 .id = V4L2_CID_BLUE_BALANCE,
136 .type = V4L2_CTRL_TYPE_INTEGER,
137 .name = "Blue Balance",
138 .minimum = 24,
139 .maximum = 40,
140 .step = 1,
141#define BLUE_BALANCE_DEF 32
142 .default_value = BLUE_BALANCE_DEF,
143 },
144 .set = sd_setblue_balance,
145 .get = sd_getblue_balance,
146 },
147 {
148 {
149 .id = V4L2_CID_RED_BALANCE,
150 .type = V4L2_CTRL_TYPE_INTEGER,
151 .name = "Red Balance",
152 .minimum = 24,
153 .maximum = 40,
154 .step = 1,
155#define RED_BALANCE_DEF 32
156 .default_value = RED_BALANCE_DEF,
157 },
158 .set = sd_setred_balance,
159 .get = sd_getred_balance,
160 },
161#define AUTOGAIN_IDX 5
123 { 162 {
124 { 163 {
125 .id = V4L2_CID_AUTOGAIN, 164 .id = V4L2_CID_AUTOGAIN,
@@ -135,7 +174,7 @@ static struct ctrl sd_ctrls[] = {
135 .get = sd_getautogain, 174 .get = sd_getautogain,
136 }, 175 },
137/* ov7630 only */ 176/* ov7630 only */
138#define VFLIP_IDX 4 177#define VFLIP_IDX 6
139 { 178 {
140 { 179 {
141 .id = V4L2_CID_VFLIP, 180 .id = V4L2_CID_VFLIP,
@@ -150,9 +189,43 @@ static struct ctrl sd_ctrls[] = {
150 .set = sd_setvflip, 189 .set = sd_setvflip,
151 .get = sd_getvflip, 190 .get = sd_getvflip,
152 }, 191 },
192/* mi0360 only */
193#define INFRARED_IDX 7
194 {
195 {
196 .id = V4L2_CID_INFRARED,
197 .type = V4L2_CTRL_TYPE_BOOLEAN,
198 .name = "Infrared",
199 .minimum = 0,
200 .maximum = 1,
201 .step = 1,
202#define INFRARED_DEF 0
203 .default_value = INFRARED_DEF,
204 },
205 .set = sd_setinfrared,
206 .get = sd_getinfrared,
207 },
208};
209
210/* table of the disabled controls */
211static __u32 ctrl_dis[] = {
212 (1 << INFRARED_IDX) | (1 << VFLIP_IDX),
213 /* SENSOR_HV7131R 0 */
214 (1 << VFLIP_IDX),
215 /* SENSOR_MI0360 1 */
216 (1 << INFRARED_IDX) | (1 << VFLIP_IDX),
217 /* SENSOR_MO4000 2 */
218 (1 << INFRARED_IDX) | (1 << VFLIP_IDX),
219 /* SENSOR_OM6802 3 */
220 (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX),
221 /* SENSOR_OV7630 4 */
222 (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX),
223 /* SENSOR_OV7648 5 */
224 (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX),
225 /* SENSOR_OV7660 6 */
153}; 226};
154 227
155static struct v4l2_pix_format vga_mode[] = { 228static const struct v4l2_pix_format vga_mode[] = {
156 {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 229 {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
157 .bytesperline = 160, 230 .bytesperline = 160,
158 .sizeimage = 160 * 120 * 4 / 8 + 590, 231 .sizeimage = 160 * 120 * 4 / 8 + 590,
@@ -231,13 +304,13 @@ static const __u8 sn_ov7630[] = {
231 304
232static const __u8 sn_ov7648[] = { 305static const __u8 sn_ov7648[] = {
233/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ 306/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
234 0x00, 0x21, 0x62, 0x00, 0x1a, 0x20, 0x20, 0x20, 307 0x00, 0x63, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20,
235/* reg8 reg9 rega regb regc regd rege regf */ 308/* reg8 reg9 rega regb regc regd rege regf */
236 0xa1, 0x6e, 0x18, 0x65, 0x00, 0x00, 0x00, 0x10, 309 0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
237/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */ 310/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
238 0x03, 0x00, 0x00, 0x06, 0x06, 0x28, 0x1e, 0x82, 311 0x03, 0x00, 0x00, 0x01, 0x00, 0x28, 0x1e, 0x00,
239/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */ 312/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
240 0x07, 0x00, 0x00, 0x00, 0x00, 0x00 313 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00
241}; 314};
242 315
243static const __u8 sn_ov7660[] = { 316static const __u8 sn_ov7660[] = {
@@ -469,6 +542,53 @@ static const __u8 ov7630_sensor_init[][8] = {
469/* {0xb1, 0x21, 0x01, 0x88, 0x70, 0x00, 0x00, 0x10}, */ 542/* {0xb1, 0x21, 0x01, 0x88, 0x70, 0x00, 0x00, 0x10}, */
470 {} 543 {}
471}; 544};
545
546static const __u8 ov7648_sensor_init[][8] = {
547 {0xa1, 0x21, 0x76, 0x00, 0x00, 0x00, 0x00, 0x10},
548 {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset */
549 {0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
550 {0xd1, 0x21, 0x03, 0xa4, 0x30, 0x88, 0x00, 0x10},
551 {0xb1, 0x21, 0x11, 0x80, 0x08, 0x00, 0x00, 0x10},
552 {0xc1, 0x21, 0x13, 0xa0, 0x04, 0x84, 0x00, 0x10},
553 {0xd1, 0x21, 0x17, 0x1a, 0x02, 0xba, 0xf4, 0x10},
554 {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
555 {0xd1, 0x21, 0x1f, 0x41, 0xc0, 0x80, 0x80, 0x10},
556 {0xd1, 0x21, 0x23, 0xde, 0xa0, 0x80, 0x32, 0x10},
557 {0xd1, 0x21, 0x27, 0xfe, 0xa0, 0x00, 0x91, 0x10},
558 {0xd1, 0x21, 0x2b, 0x00, 0x88, 0x85, 0x80, 0x10},
559 {0xc1, 0x21, 0x2f, 0x9c, 0x00, 0xc4, 0x00, 0x10},
560 {0xd1, 0x21, 0x60, 0xa6, 0x60, 0x88, 0x12, 0x10},
561 {0xd1, 0x21, 0x64, 0x88, 0x00, 0x00, 0x94, 0x10},
562 {0xd1, 0x21, 0x68, 0x7a, 0x0c, 0x00, 0x00, 0x10},
563 {0xd1, 0x21, 0x6c, 0x11, 0x33, 0x22, 0x00, 0x10},
564 {0xd1, 0x21, 0x70, 0x11, 0x00, 0x10, 0x50, 0x10},
565 {0xd1, 0x21, 0x74, 0x20, 0x06, 0x00, 0xb5, 0x10},
566 {0xd1, 0x21, 0x78, 0x8a, 0x00, 0x00, 0x00, 0x10},
567 {0xb1, 0x21, 0x7c, 0x00, 0x43, 0x00, 0x00, 0x10},
568
569 {0xd1, 0x21, 0x21, 0x86, 0x00, 0xde, 0xa0, 0x10},
570/* {0xd1, 0x21, 0x25, 0x80, 0x32, 0xfe, 0xa0, 0x10}, jfm done */
571/* {0xd1, 0x21, 0x29, 0x00, 0x91, 0x00, 0x88, 0x10}, jfm done */
572 {0xb1, 0x21, 0x2d, 0x85, 0x00, 0x00, 0x00, 0x10},
573/*...*/
574/* {0xa1, 0x21, 0x12, 0x08, 0x00, 0x00, 0x00, 0x10}, jfm done */
575/* {0xa1, 0x21, 0x75, 0x06, 0x00, 0x00, 0x00, 0x10}, jfm done */
576 {0xa1, 0x21, 0x19, 0x02, 0x00, 0x00, 0x00, 0x10},
577 {0xa1, 0x21, 0x10, 0x32, 0x00, 0x00, 0x00, 0x10},
578/* {0xa1, 0x21, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
579/* {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}, * GAIN - def */
580/* {0xb1, 0x21, 0x01, 0x6c, 0x6c, 0x00, 0x00, 0x10}, * B R - def: 80 */
581/*...*/
582 {0xa1, 0x21, 0x11, 0x81, 0x00, 0x00, 0x00, 0x10}, /* CLKRC */
583/* {0xa1, 0x21, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
584/* {0xa1, 0x21, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
585/* {0xa1, 0x21, 0x2a, 0x91, 0x00, 0x00, 0x00, 0x10}, jfm done */
586/* {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
587/* {0xb1, 0x21, 0x01, 0x64, 0x84, 0x00, 0x00, 0x10}, * B R - def: 80 */
588
589 {}
590};
591
472static const __u8 ov7660_sensor_init[][8] = { 592static const __u8 ov7660_sensor_init[][8] = {
473 {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset SCCB */ 593 {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset SCCB */
474/* (delay 20ms) */ 594/* (delay 20ms) */
@@ -557,64 +677,6 @@ static const __u8 ov7660_sensor_init[][8] = {
557 {0xa1, 0x21, 0x2b, 0xc3, 0x00, 0x00, 0x00, 0x10}, 677 {0xa1, 0x21, 0x2b, 0xc3, 0x00, 0x00, 0x00, 0x10},
558 {} 678 {}
559}; 679};
560/* reg 0x04 reg 0x07 reg 0x10 */
561/* expo = (COM1 & 0x02) | ((AECHH & 0x2f) << 10) | (AECh << 2) */
562
563static const __u8 ov7648_sensor_init[][8] = {
564 {0xC1, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00},
565 {0xC1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00},
566 {0xC1, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00},
567 {0xA1, 0x6E, 0x3F, 0x20, 0x00, 0x00, 0x00, 0x10},
568 {0xA1, 0x6E, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x10},
569 {0xA1, 0x6E, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x10},
570 {0xD1, 0x6E, 0x04, 0x02, 0xB1, 0x02, 0x39, 0x10},
571 {0xD1, 0x6E, 0x08, 0x00, 0x01, 0x00, 0x00, 0x10},
572 {0xD1, 0x6E, 0x0C, 0x02, 0x7F, 0x01, 0xE0, 0x10},
573 {0xD1, 0x6E, 0x12, 0x03, 0x02, 0x00, 0x03, 0x10},
574 {0xD1, 0x6E, 0x16, 0x85, 0x40, 0x4A, 0x40, 0x10},
575 {0xC1, 0x6E, 0x1A, 0x00, 0x80, 0x00, 0x00, 0x10},
576 {0xD1, 0x6E, 0x1D, 0x08, 0x03, 0x00, 0x00, 0x10},
577 {0xD1, 0x6E, 0x23, 0x00, 0xB0, 0x00, 0x94, 0x10},
578 {0xD1, 0x6E, 0x27, 0x58, 0x00, 0x00, 0x00, 0x10},
579 {0xD1, 0x6E, 0x2D, 0x14, 0x35, 0x61, 0x84, 0x10},
580 {0xD1, 0x6E, 0x31, 0xA2, 0xBD, 0xD8, 0xFF, 0x10},
581 {0xD1, 0x6E, 0x35, 0x06, 0x1E, 0x12, 0x02, 0x10},
582 {0xD1, 0x6E, 0x39, 0xAA, 0x53, 0x37, 0xD5, 0x10},
583 {0xA1, 0x6E, 0x3D, 0xF2, 0x00, 0x00, 0x00, 0x10},
584 {0xD1, 0x6E, 0x3E, 0x00, 0x00, 0x80, 0x03, 0x10},
585 {0xD1, 0x6E, 0x42, 0x03, 0x00, 0x00, 0x00, 0x10},
586 {0xC1, 0x6E, 0x46, 0x00, 0x80, 0x80, 0x00, 0x10},
587 {0xD1, 0x6E, 0x4B, 0x02, 0xEF, 0x08, 0xCD, 0x10},
588 {0xD1, 0x6E, 0x4F, 0x00, 0xD0, 0x00, 0xA0, 0x10},
589 {0xD1, 0x6E, 0x53, 0x01, 0xAA, 0x01, 0x40, 0x10},
590 {0xD1, 0x6E, 0x5A, 0x50, 0x04, 0x30, 0x03, 0x10},
591 {0xA1, 0x6E, 0x5E, 0x00, 0x00, 0x00, 0x00, 0x10},
592 {0xD1, 0x6E, 0x5F, 0x10, 0x40, 0xFF, 0x00, 0x10},
593 /* {0xD1, 0x6E, 0x63, 0x40, 0x40, 0x00, 0x00, 0x10},
594 {0xD1, 0x6E, 0x67, 0x00, 0x00, 0x00, 0x00, 0x10},
595 * This is currently setting a
596 * blue tint, and some things more , i leave it here for future test if
597 * somene is having problems with color on this sensor
598 {0xD1, 0x6E, 0x6B, 0x00, 0x00, 0x00, 0x00, 0x10},
599 {0xD1, 0x6E, 0x6F, 0x00, 0x00, 0x00, 0x00, 0x10},
600 {0xC1, 0x6E, 0x73, 0x10, 0x80, 0xEB, 0x00, 0x10},
601 {0xA1, 0x6E, 0x1E, 0x03, 0x00, 0x00, 0x00, 0x10},
602 {0xA1, 0x6E, 0x15, 0x01, 0x00, 0x00, 0x00, 0x10},
603 {0xC1, 0x6E, 0x16, 0x40, 0x40, 0x40, 0x00, 0x10},
604 {0xA1, 0x6E, 0x1D, 0x08, 0x00, 0x00, 0x00, 0x10},
605 {0xA1, 0x6E, 0x06, 0x02, 0x00, 0x00, 0x00, 0x10},
606 {0xA1, 0x6E, 0x07, 0xB5, 0x00, 0x00, 0x00, 0x10},
607 {0xA1, 0x6E, 0x18, 0x6B, 0x00, 0x00, 0x00, 0x10},
608 {0xA1, 0x6E, 0x1D, 0x08, 0x00, 0x00, 0x00, 0x10},
609 {0xA1, 0x6E, 0x06, 0x02, 0x00, 0x00, 0x00, 0x10},
610 {0xA1, 0x6E, 0x07, 0xB8, 0x00, 0x00, 0x00, 0x10}, */
611 {0xC1, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00},
612 {0xA1, 0x6E, 0x06, 0x03, 0x00, 0x00, 0x00, 0x10}, /* Bright... */
613 {0xA1, 0x6E, 0x07, 0x66, 0x00, 0x00, 0x00, 0x10}, /* B.. */
614 {0xC1, 0x6E, 0x1A, 0x03, 0x65, 0x90, 0x00, 0x10}, /* Bright/Witen....*/
615/* {0xC1, 0x6E, 0x16, 0x45, 0x40, 0x60, 0x00, 0x10}, * Bright/Witene */
616 {}
617};
618 680
619static const __u8 qtable4[] = { 681static const __u8 qtable4[] = {
620 0x06, 0x04, 0x04, 0x06, 0x04, 0x04, 0x06, 0x06, 0x06, 0x06, 0x08, 0x06, 682 0x06, 0x04, 0x04, 0x06, 0x04, 0x04, 0x06, 0x06, 0x06, 0x06, 0x08, 0x06,
@@ -757,8 +819,6 @@ static void i2c_r5(struct gspca_dev *gspca_dev, __u8 reg)
757 819
758static int probesensor(struct gspca_dev *gspca_dev) 820static int probesensor(struct gspca_dev *gspca_dev)
759{ 821{
760 struct sd *sd = (struct sd *) gspca_dev;
761
762 i2c_w1(gspca_dev, 0x02, 0); /* sensor wakeup */ 822 i2c_w1(gspca_dev, 0x02, 0); /* sensor wakeup */
763 msleep(10); 823 msleep(10);
764 reg_w1(gspca_dev, 0x02, 0x66); /* Gpio on */ 824 reg_w1(gspca_dev, 0x02, 0x66); /* Gpio on */
@@ -770,8 +830,7 @@ static int probesensor(struct gspca_dev *gspca_dev)
770 && gspca_dev->usb_buf[3] == 0x00 830 && gspca_dev->usb_buf[3] == 0x00
771 && gspca_dev->usb_buf[4] == 0x00) { 831 && gspca_dev->usb_buf[4] == 0x00) {
772 PDEBUG(D_PROBE, "Find Sensor sn9c102P HV7131R"); 832 PDEBUG(D_PROBE, "Find Sensor sn9c102P HV7131R");
773 sd->sensor = SENSOR_HV7131R; 833 return 0;
774 return SENSOR_HV7131R;
775 } 834 }
776 PDEBUG(D_PROBE, "Find Sensor 0x%02x 0x%02x 0x%02x", 835 PDEBUG(D_PROBE, "Find Sensor 0x%02x 0x%02x 0x%02x",
777 gspca_dev->usb_buf[0], gspca_dev->usb_buf[1], 836 gspca_dev->usb_buf[0], gspca_dev->usb_buf[1],
@@ -827,17 +886,20 @@ static int configure_gpio(struct gspca_dev *gspca_dev,
827 reg_w1(gspca_dev, 0x01, 0x40); 886 reg_w1(gspca_dev, 0x01, 0x40);
828 break; 887 break;
829 case SENSOR_OV7648: 888 case SENSOR_OV7648:
830 reg_w1(gspca_dev, 0x01, 0x43); 889 reg_w1(gspca_dev, 0x01, 0x63);
831 reg_w1(gspca_dev, 0x17, 0xae); 890 reg_w1(gspca_dev, 0x17, 0x20);
832 reg_w1(gspca_dev, 0x01, 0x42); 891 reg_w1(gspca_dev, 0x01, 0x42);
833 break; 892 break;
834/*jfm: from win trace */ 893/*jfm: from win trace */
835 case SENSOR_OV7660: 894 case SENSOR_OV7660:
836 reg_w1(gspca_dev, 0x01, 0x61); 895 if (sd->bridge == BRIDGE_SN9C120) {
837 reg_w1(gspca_dev, 0x17, 0x20); 896 reg_w1(gspca_dev, 0x01, 0x61);
838 reg_w1(gspca_dev, 0x01, 0x60); 897 reg_w1(gspca_dev, 0x17, 0x20);
839 reg_w1(gspca_dev, 0x01, 0x40); 898 reg_w1(gspca_dev, 0x01, 0x60);
840 break; 899 reg_w1(gspca_dev, 0x01, 0x40);
900 break;
901 }
902 /* fall thru */
841 default: 903 default:
842 reg_w1(gspca_dev, 0x01, 0x43); 904 reg_w1(gspca_dev, 0x01, 0x43);
843 reg_w1(gspca_dev, 0x17, 0x61); 905 reg_w1(gspca_dev, 0x17, 0x61);
@@ -922,6 +984,13 @@ static void ov7648_InitSensor(struct gspca_dev *gspca_dev)
922{ 984{
923 int i = 0; 985 int i = 0;
924 986
987 i2c_w8(gspca_dev, ov7648_sensor_init[i]);
988 i++;
989/* win: dble reset */
990 i2c_w8(gspca_dev, ov7648_sensor_init[i]); /* reset */
991 i++;
992 msleep(20);
993/* win: i2c reg read 00..7f */
925 while (ov7648_sensor_init[i][0]) { 994 while (ov7648_sensor_init[i][0]) {
926 i2c_w8(gspca_dev, ov7648_sensor_init[i]); 995 i2c_w8(gspca_dev, ov7648_sensor_init[i]);
927 i++; 996 i++;
@@ -961,19 +1030,14 @@ static int sd_config(struct gspca_dev *gspca_dev,
961 sd->brightness = BRIGHTNESS_DEF; 1030 sd->brightness = BRIGHTNESS_DEF;
962 sd->contrast = CONTRAST_DEF; 1031 sd->contrast = CONTRAST_DEF;
963 sd->colors = COLOR_DEF; 1032 sd->colors = COLOR_DEF;
1033 sd->blue = BLUE_BALANCE_DEF;
1034 sd->red = RED_BALANCE_DEF;
964 sd->autogain = AUTOGAIN_DEF; 1035 sd->autogain = AUTOGAIN_DEF;
965 sd->ag_cnt = -1; 1036 sd->ag_cnt = -1;
1037 sd->vflip = VFLIP_DEF;
1038 sd->infrared = INFRARED_DEF;
966 1039
967 switch (sd->sensor) { 1040 gspca_dev->ctrl_dis = ctrl_dis[sd->sensor];
968 case SENSOR_OV7630:
969 case SENSOR_OV7648:
970 case SENSOR_OV7660:
971 gspca_dev->ctrl_dis = (1 << AUTOGAIN_IDX);
972 break;
973 }
974 if (sd->sensor != SENSOR_OV7630)
975 gspca_dev->ctrl_dis |= (1 << VFLIP_IDX);
976
977 return 0; 1041 return 0;
978} 1042}
979 1043
@@ -981,7 +1045,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
981static int sd_init(struct gspca_dev *gspca_dev) 1045static int sd_init(struct gspca_dev *gspca_dev)
982{ 1046{
983 struct sd *sd = (struct sd *) gspca_dev; 1047 struct sd *sd = (struct sd *) gspca_dev;
984/* const __u8 *sn9c1xx; */
985 __u8 regGpio[] = { 0x29, 0x74 }; 1048 __u8 regGpio[] = { 0x29, 0x74 };
986 __u8 regF1; 1049 __u8 regF1;
987 1050
@@ -1100,32 +1163,13 @@ static unsigned int setexposure(struct gspca_dev *gspca_dev,
1100 return expo; 1163 return expo;
1101} 1164}
1102 1165
1103/* this function is used for sensors o76xx only */
1104static void setbrightcont(struct gspca_dev *gspca_dev)
1105{
1106 struct sd *sd = (struct sd *) gspca_dev;
1107 int val;
1108 __u8 reg84_full[0x15];
1109
1110 memcpy(reg84_full, reg84, sizeof reg84_full);
1111 val = sd->contrast * 0x30 / CONTRAST_MAX + 0x10; /* 10..40 */
1112 reg84_full[0] = (val + 1) / 2; /* red */
1113 reg84_full[2] = val; /* green */
1114 reg84_full[4] = (val + 1) / 5; /* blue */
1115 val = (sd->brightness - BRIGHTNESS_DEF) * 0x10
1116 / BRIGHTNESS_MAX;
1117 reg84_full[0x12] = val & 0x1f; /* 5:0 signed value */
1118 reg_w(gspca_dev, 0x84, reg84_full, sizeof reg84_full);
1119}
1120
1121/* sensor != ov76xx */
1122static void setbrightness(struct gspca_dev *gspca_dev) 1166static void setbrightness(struct gspca_dev *gspca_dev)
1123{ 1167{
1124 struct sd *sd = (struct sd *) gspca_dev; 1168 struct sd *sd = (struct sd *) gspca_dev;
1125 unsigned int expo; 1169 unsigned int expo;
1126 __u8 k2; 1170 __u8 k2;
1127 1171
1128 k2 = sd->brightness >> 10; 1172 k2 = ((int) sd->brightness - 0x8000) >> 10;
1129 switch (sd->sensor) { 1173 switch (sd->sensor) {
1130 case SENSOR_HV7131R: 1174 case SENSOR_HV7131R:
1131 expo = sd->brightness << 4; 1175 expo = sd->brightness << 4;
@@ -1147,38 +1191,49 @@ static void setbrightness(struct gspca_dev *gspca_dev)
1147 break; 1191 break;
1148 } 1192 }
1149 1193
1150 reg_w1(gspca_dev, 0x96, k2); 1194 reg_w1(gspca_dev, 0x96, k2); /* color matrix Y offset */
1151} 1195}
1152 1196
1153/* sensor != ov76xx */
1154static void setcontrast(struct gspca_dev *gspca_dev) 1197static void setcontrast(struct gspca_dev *gspca_dev)
1155{ 1198{
1156 struct sd *sd = (struct sd *) gspca_dev; 1199 struct sd *sd = (struct sd *) gspca_dev;
1157 __u8 k2; 1200 __u8 k2;
1158 __u8 contrast[] = { 0x00, 0x00, 0x28, 0x00, 0x07, 0x00 }; 1201 __u8 contrast[6];
1159 1202
1160 k2 = sd->contrast; 1203 k2 = sd->contrast * 0x30 / (CONTRAST_MAX + 1) + 0x10; /* 10..40 */
1161 contrast[2] = k2; 1204 contrast[0] = (k2 + 1) / 2; /* red */
1162 contrast[0] = (k2 + 1) >> 1; 1205 contrast[1] = 0;
1163 contrast[4] = (k2 + 1) / 5; 1206 contrast[2] = k2; /* green */
1164 reg_w(gspca_dev, 0x84, contrast, 6); 1207 contrast[3] = 0;
1208 contrast[4] = (k2 + 1) / 5; /* blue */
1209 contrast[5] = 0;
1210 reg_w(gspca_dev, 0x84, contrast, sizeof contrast);
1165} 1211}
1166 1212
1167static void setcolors(struct gspca_dev *gspca_dev) 1213static void setcolors(struct gspca_dev *gspca_dev)
1168{ 1214{
1169 struct sd *sd = (struct sd *) gspca_dev; 1215 struct sd *sd = (struct sd *) gspca_dev;
1170 __u8 blue, red; 1216 int i, v;
1171 1217 __u8 reg8a[12]; /* U & V gains */
1172 if (sd->colors >= 32) { 1218 static __s16 uv[6] = { /* same as reg84 in signed decimal */
1173 red = 32 + (sd->colors - 32) / 2; 1219 -24, -38, 64, /* UR UG UB */
1174 blue = 64 - sd->colors; 1220 62, -51, -9 /* VR VG VB */
1175 } else { 1221 };
1176 red = sd->colors; 1222 for (i = 0; i < 6; i++) {
1177 blue = 32 + (32 - sd->colors) / 2; 1223 v = uv[i] * sd->colors / COLOR_DEF;
1224 reg8a[i * 2] = v;
1225 reg8a[i * 2 + 1] = (v >> 8) & 0x0f;
1178 } 1226 }
1179 reg_w1(gspca_dev, 0x05, red); 1227 reg_w(gspca_dev, 0x8a, reg8a, sizeof reg8a);
1228}
1229
1230static void setredblue(struct gspca_dev *gspca_dev)
1231{
1232 struct sd *sd = (struct sd *) gspca_dev;
1233
1234 reg_w1(gspca_dev, 0x05, sd->red);
1180/* reg_w1(gspca_dev, 0x07, 32); */ 1235/* reg_w1(gspca_dev, 0x07, 32); */
1181 reg_w1(gspca_dev, 0x06, blue); 1236 reg_w1(gspca_dev, 0x06, sd->blue);
1182} 1237}
1183 1238
1184static void setautogain(struct gspca_dev *gspca_dev) 1239static void setautogain(struct gspca_dev *gspca_dev)
@@ -1195,12 +1250,18 @@ static void setautogain(struct gspca_dev *gspca_dev)
1195 1250
1196static void setvflip(struct sd *sd) 1251static void setvflip(struct sd *sd)
1197{ 1252{
1198 if (sd->sensor != SENSOR_OV7630)
1199 return;
1200 i2c_w1(&sd->gspca_dev, 0x75, /* COMN */ 1253 i2c_w1(&sd->gspca_dev, 0x75, /* COMN */
1201 sd->vflip ? 0x82 : 0x02); 1254 sd->vflip ? 0x82 : 0x02);
1202} 1255}
1203 1256
1257static void setinfrared(struct sd *sd)
1258{
1259/*fixme: different sequence for StarCam Clip and StarCam 370i */
1260/* Clip */
1261 i2c_w1(&sd->gspca_dev, 0x02, /* gpio */
1262 sd->infrared ? 0x66 : 0x64);
1263}
1264
1204/* -- start the camera -- */ 1265/* -- start the camera -- */
1205static int sd_start(struct gspca_dev *gspca_dev) 1266static int sd_start(struct gspca_dev *gspca_dev)
1206{ 1267{
@@ -1235,28 +1296,39 @@ static int sd_start(struct gspca_dev *gspca_dev)
1235 reg17 = 0xe2; 1296 reg17 = 0xe2;
1236 break; 1297 break;
1237 case SENSOR_OV7648: 1298 case SENSOR_OV7648:
1238 reg17 = 0xae; 1299 reg17 = 0x20;
1239 break; 1300 break;
1240/*jfm: from win trace */ 1301/*jfm: from win trace */
1241 case SENSOR_OV7660: 1302 case SENSOR_OV7660:
1242 reg17 = 0xa0; 1303 if (sd->bridge == BRIDGE_SN9C120) {
1243 break; 1304 reg17 = 0xa0;
1305 break;
1306 }
1307 /* fall thru */
1244 default: 1308 default:
1245 reg17 = 0x60; 1309 reg17 = 0x60;
1246 break; 1310 break;
1247 } 1311 }
1248 reg_w1(gspca_dev, 0x17, reg17); 1312 reg_w1(gspca_dev, 0x17, reg17);
1249 reg_w1(gspca_dev, 0x05, sn9c1xx[5]); 1313/* set reg1 was here */
1250 reg_w1(gspca_dev, 0x07, sn9c1xx[7]); 1314 reg_w1(gspca_dev, 0x05, sn9c1xx[5]); /* red */
1251 reg_w1(gspca_dev, 0x06, sn9c1xx[6]); 1315 reg_w1(gspca_dev, 0x07, sn9c1xx[7]); /* green */
1316 reg_w1(gspca_dev, 0x06, sn9c1xx[6]); /* blue */
1252 reg_w1(gspca_dev, 0x14, sn9c1xx[0x14]); 1317 reg_w1(gspca_dev, 0x14, sn9c1xx[0x14]);
1253 reg_w(gspca_dev, 0x20, gamma_def, sizeof gamma_def); 1318 reg_w(gspca_dev, 0x20, gamma_def, sizeof gamma_def);
1254 for (i = 0; i < 8; i++) 1319 for (i = 0; i < 8; i++)
1255 reg_w(gspca_dev, 0x84, reg84, sizeof reg84); 1320 reg_w(gspca_dev, 0x84, reg84, sizeof reg84);
1256 switch (sd->sensor) { 1321 switch (sd->sensor) {
1257 case SENSOR_OV7660: 1322 case SENSOR_OV7648:
1258 reg_w1(gspca_dev, 0x9a, 0x05); 1323 reg_w1(gspca_dev, 0x9a, 0x0a);
1324 reg_w1(gspca_dev, 0x99, 0x60);
1259 break; 1325 break;
1326 case SENSOR_OV7660:
1327 if (sd->bridge == BRIDGE_SN9C120) {
1328 reg_w1(gspca_dev, 0x9a, 0x05);
1329 break;
1330 }
1331 /* fall thru */
1260 default: 1332 default:
1261 reg_w1(gspca_dev, 0x9a, 0x08); 1333 reg_w1(gspca_dev, 0x9a, 0x08);
1262 reg_w1(gspca_dev, 0x99, 0x59); 1334 reg_w1(gspca_dev, 0x99, 0x59);
@@ -1265,10 +1337,10 @@ static int sd_start(struct gspca_dev *gspca_dev)
1265 1337
1266 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; 1338 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
1267 if (mode) 1339 if (mode)
1268 reg1 = 0x46; /* 320 clk 48Mhz */ 1340 reg1 = 0x46; /* 320x240: clk 48Mhz, video trf enable */
1269 else 1341 else
1270 reg1 = 0x06; /* 640 clk 24Mz */ 1342 reg1 = 0x06; /* 640x480: clk 24Mhz, video trf enable */
1271 reg17 = 0x61; 1343 reg17 = 0x61; /* 0x:20: enable sensor clock */
1272 switch (sd->sensor) { 1344 switch (sd->sensor) {
1273 case SENSOR_HV7131R: 1345 case SENSOR_HV7131R:
1274 hv7131R_InitSensor(gspca_dev); 1346 hv7131R_InitSensor(gspca_dev);
@@ -1298,23 +1370,21 @@ static int sd_start(struct gspca_dev *gspca_dev)
1298 break; 1370 break;
1299 case SENSOR_OV7648: 1371 case SENSOR_OV7648:
1300 ov7648_InitSensor(gspca_dev); 1372 ov7648_InitSensor(gspca_dev);
1301 reg17 = 0xa2; 1373 reg17 = 0x21;
1302 reg1 = 0x44; 1374/* reg1 = 0x42; * 42 - 46? */
1303/* if (mode)
1304 ; * 320x2...
1305 else
1306 ; * 640x... */
1307 break; 1375 break;
1308 default: 1376 default:
1309/* case SENSOR_OV7660: */ 1377/* case SENSOR_OV7660: */
1310 ov7660_InitSensor(gspca_dev); 1378 ov7660_InitSensor(gspca_dev);
1311 if (mode) { 1379 if (sd->bridge == BRIDGE_SN9C120) {
1312/* reg17 = 0x21; * 320 */ 1380 if (mode) { /* 320x240 - 160x120 */
1313/* reg1 = 0x44; */ 1381 reg17 = 0xa2;
1314/* reg1 = 0x46; (done) */ 1382 reg1 = 0x44; /* 48 Mhz, video trf eneble */
1383 }
1315 } else { 1384 } else {
1316 reg17 = 0xa2; /* 640 */ 1385 reg17 = 0x22;
1317 reg1 = 0x44; 1386 reg1 = 0x06; /* 24 Mhz, video trf eneble
1387 * inverse power down */
1318 } 1388 }
1319 break; 1389 break;
1320 } 1390 }
@@ -1342,23 +1412,18 @@ static int sd_start(struct gspca_dev *gspca_dev)
1342 reg_w1(gspca_dev, 0x18, reg18); 1412 reg_w1(gspca_dev, 0x18, reg18);
1343 1413
1344 reg_w1(gspca_dev, 0x17, reg17); 1414 reg_w1(gspca_dev, 0x17, reg17);
1415 reg_w1(gspca_dev, 0x01, reg1);
1345 switch (sd->sensor) { 1416 switch (sd->sensor) {
1346 case SENSOR_HV7131R:
1347 case SENSOR_MI0360: 1417 case SENSOR_MI0360:
1348 case SENSOR_MO4000: 1418 setinfrared(sd);
1349 case SENSOR_OM6802:
1350 setbrightness(gspca_dev);
1351 setcontrast(gspca_dev);
1352 break; 1419 break;
1353 case SENSOR_OV7630: 1420 case SENSOR_OV7630:
1354 setvflip(sd); 1421 setvflip(sd);
1355 /* fall thru */
1356 default: /* OV76xx */
1357 setbrightcont(gspca_dev);
1358 break; 1422 break;
1359 } 1423 }
1424 setbrightness(gspca_dev);
1425 setcontrast(gspca_dev);
1360 setautogain(gspca_dev); 1426 setautogain(gspca_dev);
1361 reg_w1(gspca_dev, 0x01, reg1);
1362 return 0; 1427 return 0;
1363} 1428}
1364 1429
@@ -1369,6 +1434,8 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
1369 { 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10 }; 1434 { 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10 };
1370 static const __u8 stopmi0360[] = 1435 static const __u8 stopmi0360[] =
1371 { 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10 }; 1436 { 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10 };
1437 static const __u8 stopov7648[] =
1438 { 0xa1, 0x21, 0x76, 0x20, 0x00, 0x00, 0x00, 0x10 };
1372 __u8 data; 1439 __u8 data;
1373 const __u8 *sn9c1xx; 1440 const __u8 *sn9c1xx;
1374 1441
@@ -1382,8 +1449,10 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
1382 i2c_w8(gspca_dev, stopmi0360); 1449 i2c_w8(gspca_dev, stopmi0360);
1383 data = 0x29; 1450 data = 0x29;
1384 break; 1451 break;
1385 case SENSOR_OV7630:
1386 case SENSOR_OV7648: 1452 case SENSOR_OV7648:
1453 i2c_w8(gspca_dev, stopov7648);
1454 /* fall thru */
1455 case SENSOR_OV7630:
1387 data = 0x29; 1456 data = 0x29;
1388 break; 1457 break;
1389 default: 1458 default:
@@ -1437,7 +1506,7 @@ static void do_autogain(struct gspca_dev *gspca_dev)
1437 expotimes = 0; 1506 expotimes = 0;
1438 sd->exposure = setexposure(gspca_dev, 1507 sd->exposure = setexposure(gspca_dev,
1439 (unsigned int) expotimes); 1508 (unsigned int) expotimes);
1440 setcolors(gspca_dev); 1509 setredblue(gspca_dev);
1441 break; 1510 break;
1442 } 1511 }
1443 } 1512 }
@@ -1491,19 +1560,8 @@ static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1491 struct sd *sd = (struct sd *) gspca_dev; 1560 struct sd *sd = (struct sd *) gspca_dev;
1492 1561
1493 sd->brightness = val; 1562 sd->brightness = val;
1494 if (gspca_dev->streaming) { 1563 if (gspca_dev->streaming)
1495 switch (sd->sensor) { 1564 setbrightness(gspca_dev);
1496 case SENSOR_HV7131R:
1497 case SENSOR_MI0360:
1498 case SENSOR_MO4000:
1499 case SENSOR_OM6802:
1500 setbrightness(gspca_dev);
1501 break;
1502 default: /* OV76xx */
1503 setbrightcont(gspca_dev);
1504 break;
1505 }
1506 }
1507 return 0; 1565 return 0;
1508} 1566}
1509 1567
@@ -1520,19 +1578,8 @@ static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
1520 struct sd *sd = (struct sd *) gspca_dev; 1578 struct sd *sd = (struct sd *) gspca_dev;
1521 1579
1522 sd->contrast = val; 1580 sd->contrast = val;
1523 if (gspca_dev->streaming) { 1581 if (gspca_dev->streaming)
1524 switch (sd->sensor) { 1582 setcontrast(gspca_dev);
1525 case SENSOR_HV7131R:
1526 case SENSOR_MI0360:
1527 case SENSOR_MO4000:
1528 case SENSOR_OM6802:
1529 setcontrast(gspca_dev);
1530 break;
1531 default: /* OV76xx */
1532 setbrightcont(gspca_dev);
1533 break;
1534 }
1535 }
1536 return 0; 1583 return 0;
1537} 1584}
1538 1585
@@ -1562,6 +1609,42 @@ static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
1562 return 0; 1609 return 0;
1563} 1610}
1564 1611
1612static int sd_setblue_balance(struct gspca_dev *gspca_dev, __s32 val)
1613{
1614 struct sd *sd = (struct sd *) gspca_dev;
1615
1616 sd->blue = val;
1617 if (gspca_dev->streaming)
1618 setredblue(gspca_dev);
1619 return 0;
1620}
1621
1622static int sd_getblue_balance(struct gspca_dev *gspca_dev, __s32 *val)
1623{
1624 struct sd *sd = (struct sd *) gspca_dev;
1625
1626 *val = sd->blue;
1627 return 0;
1628}
1629
1630static int sd_setred_balance(struct gspca_dev *gspca_dev, __s32 val)
1631{
1632 struct sd *sd = (struct sd *) gspca_dev;
1633
1634 sd->red = val;
1635 if (gspca_dev->streaming)
1636 setredblue(gspca_dev);
1637 return 0;
1638}
1639
1640static int sd_getred_balance(struct gspca_dev *gspca_dev, __s32 *val)
1641{
1642 struct sd *sd = (struct sd *) gspca_dev;
1643
1644 *val = sd->red;
1645 return 0;
1646}
1647
1565static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val) 1648static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
1566{ 1649{
1567 struct sd *sd = (struct sd *) gspca_dev; 1650 struct sd *sd = (struct sd *) gspca_dev;
@@ -1598,6 +1681,24 @@ static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val)
1598 return 0; 1681 return 0;
1599} 1682}
1600 1683
1684static int sd_setinfrared(struct gspca_dev *gspca_dev, __s32 val)
1685{
1686 struct sd *sd = (struct sd *) gspca_dev;
1687
1688 sd->infrared = val;
1689 if (gspca_dev->streaming)
1690 setinfrared(sd);
1691 return 0;
1692}
1693
1694static int sd_getinfrared(struct gspca_dev *gspca_dev, __s32 *val)
1695{
1696 struct sd *sd = (struct sd *) gspca_dev;
1697
1698 *val = sd->infrared;
1699 return 0;
1700}
1701
1601/* sub-driver description */ 1702/* sub-driver description */
1602static const struct sd_desc sd_desc = { 1703static const struct sd_desc sd_desc = {
1603 .name = MODULE_NAME, 1704 .name = MODULE_NAME,
@@ -1620,12 +1721,15 @@ static const __devinitdata struct usb_device_id device_table[] = {
1620#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE 1721#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1621 {USB_DEVICE(0x0458, 0x7025), BSI(SN9C120, MI0360, 0x5d)}, 1722 {USB_DEVICE(0x0458, 0x7025), BSI(SN9C120, MI0360, 0x5d)},
1622 {USB_DEVICE(0x0458, 0x702e), BSI(SN9C120, OV7660, 0x21)}, 1723 {USB_DEVICE(0x0458, 0x702e), BSI(SN9C120, OV7660, 0x21)},
1724#endif
1623 {USB_DEVICE(0x045e, 0x00f5), BSI(SN9C105, OV7660, 0x21)}, 1725 {USB_DEVICE(0x045e, 0x00f5), BSI(SN9C105, OV7660, 0x21)},
1624 {USB_DEVICE(0x045e, 0x00f7), BSI(SN9C105, OV7660, 0x21)}, 1726 {USB_DEVICE(0x045e, 0x00f7), BSI(SN9C105, OV7660, 0x21)},
1727#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1625 {USB_DEVICE(0x0471, 0x0327), BSI(SN9C105, MI0360, 0x5d)}, 1728 {USB_DEVICE(0x0471, 0x0327), BSI(SN9C105, MI0360, 0x5d)},
1626 {USB_DEVICE(0x0471, 0x0328), BSI(SN9C105, MI0360, 0x5d)},
1627#endif 1729#endif
1730 {USB_DEVICE(0x0471, 0x0328), BSI(SN9C105, MI0360, 0x5d)},
1628 {USB_DEVICE(0x0471, 0x0330), BSI(SN9C105, MI0360, 0x5d)}, 1731 {USB_DEVICE(0x0471, 0x0330), BSI(SN9C105, MI0360, 0x5d)},
1732 {USB_DEVICE(0x06f8, 0x3004), BSI(SN9C105, OV7660, 0x21)},
1629 {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, HV7131R, 0x11)}, 1733 {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, HV7131R, 0x11)},
1630/* bw600.inf: 1734/* bw600.inf:
1631 {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, MI0360, 0x5d)}, */ 1735 {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, MI0360, 0x5d)}, */
@@ -1649,7 +1753,7 @@ static const __devinitdata struct usb_device_id device_table[] = {
1649/* {USB_DEVICE(0x0c45, 0x6123), BSI(SN9C110, SanyoCCD, 0x??)}, */ 1753/* {USB_DEVICE(0x0c45, 0x6123), BSI(SN9C110, SanyoCCD, 0x??)}, */
1650 {USB_DEVICE(0x0c45, 0x6128), BSI(SN9C110, OM6802, 0x21)}, /*sn9c325?*/ 1754 {USB_DEVICE(0x0c45, 0x6128), BSI(SN9C110, OM6802, 0x21)}, /*sn9c325?*/
1651/*bw600.inf:*/ 1755/*bw600.inf:*/
1652 {USB_DEVICE(0x0c45, 0x612a), BSI(SN9C110, OV7648, 0x21)}, /*sn9c325?*/ 1756 {USB_DEVICE(0x0c45, 0x612a), BSI(SN9C120, OV7648, 0x21)}, /*sn9c110?*/
1653 {USB_DEVICE(0x0c45, 0x612c), BSI(SN9C110, MO4000, 0x21)}, 1757 {USB_DEVICE(0x0c45, 0x612c), BSI(SN9C110, MO4000, 0x21)},
1654 {USB_DEVICE(0x0c45, 0x612e), BSI(SN9C110, OV7630, 0x21)}, 1758 {USB_DEVICE(0x0c45, 0x612e), BSI(SN9C110, OV7630, 0x21)},
1655/* {USB_DEVICE(0x0c45, 0x612f), BSI(SN9C110, ICM105C, 0x??)}, */ 1759/* {USB_DEVICE(0x0c45, 0x612f), BSI(SN9C110, ICM105C, 0x??)}, */
@@ -1657,8 +1761,8 @@ static const __devinitdata struct usb_device_id device_table[] = {
1657 {USB_DEVICE(0x0c45, 0x6130), BSI(SN9C120, MI0360, 0x5d)}, 1761 {USB_DEVICE(0x0c45, 0x6130), BSI(SN9C120, MI0360, 0x5d)},
1658#endif 1762#endif
1659 {USB_DEVICE(0x0c45, 0x6138), BSI(SN9C120, MO4000, 0x21)}, 1763 {USB_DEVICE(0x0c45, 0x6138), BSI(SN9C120, MO4000, 0x21)},
1764 {USB_DEVICE(0x0c45, 0x613a), BSI(SN9C120, OV7648, 0x21)},
1660#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE 1765#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1661/* {USB_DEVICE(0x0c45, 0x613a), BSI(SN9C120, OV7648, 0x??)}, */
1662 {USB_DEVICE(0x0c45, 0x613b), BSI(SN9C120, OV7660, 0x21)}, 1766 {USB_DEVICE(0x0c45, 0x613b), BSI(SN9C120, OV7660, 0x21)},
1663 {USB_DEVICE(0x0c45, 0x613c), BSI(SN9C120, HV7131R, 0x11)}, 1767 {USB_DEVICE(0x0c45, 0x613c), BSI(SN9C120, HV7131R, 0x11)},
1664/* {USB_DEVICE(0x0c45, 0x613e), BSI(SN9C120, OV7630, 0x??)}, */ 1768/* {USB_DEVICE(0x0c45, 0x613e), BSI(SN9C120, OV7630, 0x??)}, */
diff --git a/drivers/media/video/gspca/spca500.c b/drivers/media/video/gspca/spca500.c
index bca106c153fa..942f04cd44dd 100644
--- a/drivers/media/video/gspca/spca500.c
+++ b/drivers/media/video/gspca/spca500.c
@@ -111,7 +111,7 @@ static struct ctrl sd_ctrls[] = {
111 }, 111 },
112}; 112};
113 113
114static struct v4l2_pix_format vga_mode[] = { 114static const struct v4l2_pix_format vga_mode[] = {
115 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 115 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
116 .bytesperline = 320, 116 .bytesperline = 320,
117 .sizeimage = 320 * 240 * 3 / 8 + 590, 117 .sizeimage = 320 * 240 * 3 / 8 + 590,
@@ -124,7 +124,7 @@ static struct v4l2_pix_format vga_mode[] = {
124 .priv = 0}, 124 .priv = 0},
125}; 125};
126 126
127static struct v4l2_pix_format sif_mode[] = { 127static const struct v4l2_pix_format sif_mode[] = {
128 {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 128 {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
129 .bytesperline = 176, 129 .bytesperline = 176,
130 .sizeimage = 176 * 144 * 3 / 8 + 590, 130 .sizeimage = 176 * 144 * 3 / 8 + 590,
@@ -633,10 +633,10 @@ static int sd_config(struct gspca_dev *gspca_dev,
633 sd->subtype = id->driver_info; 633 sd->subtype = id->driver_info;
634 if (sd->subtype != LogitechClickSmart310) { 634 if (sd->subtype != LogitechClickSmart310) {
635 cam->cam_mode = vga_mode; 635 cam->cam_mode = vga_mode;
636 cam->nmodes = sizeof vga_mode / sizeof vga_mode[0]; 636 cam->nmodes = ARRAY_SIZE(vga_mode);
637 } else { 637 } else {
638 cam->cam_mode = sif_mode; 638 cam->cam_mode = sif_mode;
639 cam->nmodes = sizeof sif_mode / sizeof sif_mode[0]; 639 cam->nmodes = ARRAY_SIZE(sif_mode);
640 } 640 }
641 sd->qindex = 5; 641 sd->qindex = 5;
642 sd->brightness = BRIGHTNESS_DEF; 642 sd->brightness = BRIGHTNESS_DEF;
diff --git a/drivers/media/video/gspca/spca501.c b/drivers/media/video/gspca/spca501.c
index e29954c1c38c..82e3e3e2ada1 100644
--- a/drivers/media/video/gspca/spca501.c
+++ b/drivers/media/video/gspca/spca501.c
@@ -34,6 +34,8 @@ struct sd {
34 unsigned short contrast; 34 unsigned short contrast;
35 __u8 brightness; 35 __u8 brightness;
36 __u8 colors; 36 __u8 colors;
37 __u8 blue_balance;
38 __u8 red_balance;
37 39
38 char subtype; 40 char subtype;
39#define Arowana300KCMOSCamera 0 41#define Arowana300KCMOSCamera 0
@@ -52,6 +54,10 @@ static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
52static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); 54static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
53static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val); 55static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
54static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val); 56static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
57static int sd_setblue_balance(struct gspca_dev *gspca_dev, __s32 val);
58static int sd_getblue_balance(struct gspca_dev *gspca_dev, __s32 *val);
59static int sd_setred_balance(struct gspca_dev *gspca_dev, __s32 val);
60static int sd_getred_balance(struct gspca_dev *gspca_dev, __s32 *val);
55 61
56static struct ctrl sd_ctrls[] = { 62static struct ctrl sd_ctrls[] = {
57#define MY_BRIGHTNESS 0 63#define MY_BRIGHTNESS 0
@@ -63,7 +69,7 @@ static struct ctrl sd_ctrls[] = {
63 .minimum = 0, 69 .minimum = 0,
64 .maximum = 127, 70 .maximum = 127,
65 .step = 1, 71 .step = 1,
66 .default_value = 63, 72 .default_value = 0,
67 }, 73 },
68 .set = sd_setbrightness, 74 .set = sd_setbrightness,
69 .get = sd_getbrightness, 75 .get = sd_getbrightness,
@@ -75,9 +81,9 @@ static struct ctrl sd_ctrls[] = {
75 .type = V4L2_CTRL_TYPE_INTEGER, 81 .type = V4L2_CTRL_TYPE_INTEGER,
76 .name = "Contrast", 82 .name = "Contrast",
77 .minimum = 0, 83 .minimum = 0,
78 .maximum = 0xffff, 84 .maximum = 64725,
79 .step = 1, 85 .step = 1,
80 .default_value = 0xaa00, 86 .default_value = 64725,
81 }, 87 },
82 .set = sd_setcontrast, 88 .set = sd_setcontrast,
83 .get = sd_getcontrast, 89 .get = sd_getcontrast,
@@ -91,14 +97,42 @@ static struct ctrl sd_ctrls[] = {
91 .minimum = 0, 97 .minimum = 0,
92 .maximum = 63, 98 .maximum = 63,
93 .step = 1, 99 .step = 1,
94 .default_value = 31, 100 .default_value = 20,
95 }, 101 },
96 .set = sd_setcolors, 102 .set = sd_setcolors,
97 .get = sd_getcolors, 103 .get = sd_getcolors,
98 }, 104 },
105#define MY_BLUE_BALANCE 3
106 {
107 {
108 .id = V4L2_CID_BLUE_BALANCE,
109 .type = V4L2_CTRL_TYPE_INTEGER,
110 .name = "Blue Balance",
111 .minimum = 0,
112 .maximum = 127,
113 .step = 1,
114 .default_value = 0,
115 },
116 .set = sd_setblue_balance,
117 .get = sd_getblue_balance,
118 },
119#define MY_RED_BALANCE 4
120 {
121 {
122 .id = V4L2_CID_RED_BALANCE,
123 .type = V4L2_CTRL_TYPE_INTEGER,
124 .name = "Red Balance",
125 .minimum = 0,
126 .maximum = 127,
127 .step = 1,
128 .default_value = 0,
129 },
130 .set = sd_setred_balance,
131 .get = sd_getred_balance,
132 },
99}; 133};
100 134
101static struct v4l2_pix_format vga_mode[] = { 135static const struct v4l2_pix_format vga_mode[] = {
102 {160, 120, V4L2_PIX_FMT_SPCA501, V4L2_FIELD_NONE, 136 {160, 120, V4L2_PIX_FMT_SPCA501, V4L2_FIELD_NONE,
103 .bytesperline = 160, 137 .bytesperline = 160,
104 .sizeimage = 160 * 120 * 3 / 2, 138 .sizeimage = 160 * 120 * 3 / 2,
@@ -1822,29 +1856,6 @@ static int reg_write(struct usb_device *dev,
1822 return ret; 1856 return ret;
1823} 1857}
1824 1858
1825/* returns: negative is error, pos or zero is data */
1826static int reg_read(struct gspca_dev *gspca_dev,
1827 __u16 req, /* bRequest */
1828 __u16 index, /* wIndex */
1829 __u16 length) /* wLength (1 or 2 only) */
1830{
1831 int ret;
1832
1833 gspca_dev->usb_buf[1] = 0;
1834 ret = usb_control_msg(gspca_dev->dev,
1835 usb_rcvctrlpipe(gspca_dev->dev, 0),
1836 req,
1837 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
1838 0, /* value */
1839 index,
1840 gspca_dev->usb_buf, length,
1841 500); /* timeout */
1842 if (ret < 0) {
1843 PDEBUG(D_ERR, "reg_read err %d", ret);
1844 return -1;
1845 }
1846 return (gspca_dev->usb_buf[1] << 8) + gspca_dev->usb_buf[0];
1847}
1848 1859
1849static int write_vector(struct gspca_dev *gspca_dev, 1860static int write_vector(struct gspca_dev *gspca_dev,
1850 const __u16 data[][3]) 1861 const __u16 data[][3])
@@ -1869,18 +1880,11 @@ static void setbrightness(struct gspca_dev *gspca_dev)
1869{ 1880{
1870 struct sd *sd = (struct sd *) gspca_dev; 1881 struct sd *sd = (struct sd *) gspca_dev;
1871 1882
1872 reg_write(gspca_dev->dev, SPCA501_REG_CCDSP, 0x11, sd->brightness);
1873 reg_write(gspca_dev->dev, SPCA501_REG_CCDSP, 0x12, sd->brightness); 1883 reg_write(gspca_dev->dev, SPCA501_REG_CCDSP, 0x12, sd->brightness);
1874 reg_write(gspca_dev->dev, SPCA501_REG_CCDSP, 0x13, sd->brightness);
1875} 1884}
1876 1885
1877static void getbrightness(struct gspca_dev *gspca_dev) 1886static void getbrightness(struct gspca_dev *gspca_dev)
1878{ 1887{
1879 struct sd *sd = (struct sd *) gspca_dev;
1880 __u16 brightness;
1881
1882 brightness = reg_read(gspca_dev, SPCA501_REG_CCDSP, 0x11, 2);
1883 sd->brightness = brightness << 1;
1884} 1888}
1885 1889
1886static void setcontrast(struct gspca_dev *gspca_dev) 1890static void setcontrast(struct gspca_dev *gspca_dev)
@@ -1895,7 +1899,6 @@ static void setcontrast(struct gspca_dev *gspca_dev)
1895 1899
1896static void getcontrast(struct gspca_dev *gspca_dev) 1900static void getcontrast(struct gspca_dev *gspca_dev)
1897{ 1901{
1898/* spca50x->contrast = 0xaa01; */
1899} 1902}
1900 1903
1901static void setcolors(struct gspca_dev *gspca_dev) 1904static void setcolors(struct gspca_dev *gspca_dev)
@@ -1907,11 +1910,20 @@ static void setcolors(struct gspca_dev *gspca_dev)
1907 1910
1908static void getcolors(struct gspca_dev *gspca_dev) 1911static void getcolors(struct gspca_dev *gspca_dev)
1909{ 1912{
1913}
1914
1915static void setblue_balance(struct gspca_dev *gspca_dev)
1916{
1917 struct sd *sd = (struct sd *) gspca_dev;
1918
1919 reg_write(gspca_dev->dev, SPCA501_REG_CCDSP, 0x11, sd->blue_balance);
1920}
1921
1922static void setred_balance(struct gspca_dev *gspca_dev)
1923{
1910 struct sd *sd = (struct sd *) gspca_dev; 1924 struct sd *sd = (struct sd *) gspca_dev;
1911 1925
1912 sd->colors = reg_read(gspca_dev, SPCA501_REG_CCDSP, 0x0c, 2); 1926 reg_write(gspca_dev->dev, SPCA501_REG_CCDSP, 0x13, sd->red_balance);
1913/* sd->hue = (reg_read(gspca_dev, SPCA501_REG_CCDSP, 0x13, */
1914/* 2) & 0xFF) << 8; */
1915} 1927}
1916 1928
1917/* this function is called at probe time */ 1929/* this function is called at probe time */
@@ -1930,6 +1942,14 @@ static int sd_config(struct gspca_dev *gspca_dev,
1930 sd->contrast = sd_ctrls[MY_CONTRAST].qctrl.default_value; 1942 sd->contrast = sd_ctrls[MY_CONTRAST].qctrl.default_value;
1931 sd->colors = sd_ctrls[MY_COLOR].qctrl.default_value; 1943 sd->colors = sd_ctrls[MY_COLOR].qctrl.default_value;
1932 1944
1945 return 0;
1946}
1947
1948/* this function is called at probe and resume time */
1949static int sd_init(struct gspca_dev *gspca_dev)
1950{
1951 struct sd *sd = (struct sd *) gspca_dev;
1952
1933 switch (sd->subtype) { 1953 switch (sd->subtype) {
1934 case Arowana300KCMOSCamera: 1954 case Arowana300KCMOSCamera:
1935 case SmileIntlCamera: 1955 case SmileIntlCamera:
@@ -1948,15 +1968,17 @@ static int sd_config(struct gspca_dev *gspca_dev,
1948 goto error; 1968 goto error;
1949 break; 1969 break;
1950 } 1970 }
1971 PDEBUG(D_STREAM, "Initializing SPCA501 finished");
1951 return 0; 1972 return 0;
1952error: 1973error:
1953 return -EINVAL; 1974 return -EINVAL;
1954} 1975}
1955 1976
1956/* this function is called at probe and resume time */ 1977static int sd_start(struct gspca_dev *gspca_dev)
1957static int sd_init(struct gspca_dev *gspca_dev)
1958{ 1978{
1959 struct sd *sd = (struct sd *) gspca_dev; 1979 struct sd *sd = (struct sd *) gspca_dev;
1980 struct usb_device *dev = gspca_dev->dev;
1981 int mode;
1960 1982
1961 switch (sd->subtype) { 1983 switch (sd->subtype) {
1962 case ThreeComHomeConnectLite: 1984 case ThreeComHomeConnectLite:
@@ -1976,14 +1998,6 @@ static int sd_init(struct gspca_dev *gspca_dev)
1976 /* Generic 501 open data */ 1998 /* Generic 501 open data */
1977 write_vector(gspca_dev, spca501_open_data); 1999 write_vector(gspca_dev, spca501_open_data);
1978 } 2000 }
1979 PDEBUG(D_STREAM, "Initializing SPCA501 finished");
1980 return 0;
1981}
1982
1983static int sd_start(struct gspca_dev *gspca_dev)
1984{
1985 struct usb_device *dev = gspca_dev->dev;
1986 int mode;
1987 2001
1988 /* memorize the wanted pixel format */ 2002 /* memorize the wanted pixel format */
1989 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; 2003 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
@@ -2113,6 +2127,42 @@ static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
2113 return 0; 2127 return 0;
2114} 2128}
2115 2129
2130static int sd_setblue_balance(struct gspca_dev *gspca_dev, __s32 val)
2131{
2132 struct sd *sd = (struct sd *) gspca_dev;
2133
2134 sd->blue_balance = val;
2135 if (gspca_dev->streaming)
2136 setblue_balance(gspca_dev);
2137 return 0;
2138}
2139
2140static int sd_getblue_balance(struct gspca_dev *gspca_dev, __s32 *val)
2141{
2142 struct sd *sd = (struct sd *) gspca_dev;
2143
2144 *val = sd->blue_balance;
2145 return 0;
2146}
2147
2148static int sd_setred_balance(struct gspca_dev *gspca_dev, __s32 val)
2149{
2150 struct sd *sd = (struct sd *) gspca_dev;
2151
2152 sd->red_balance = val;
2153 if (gspca_dev->streaming)
2154 setred_balance(gspca_dev);
2155 return 0;
2156}
2157
2158static int sd_getred_balance(struct gspca_dev *gspca_dev, __s32 *val)
2159{
2160 struct sd *sd = (struct sd *) gspca_dev;
2161
2162 *val = sd->red_balance;
2163 return 0;
2164}
2165
2116/* sub-driver description */ 2166/* sub-driver description */
2117static const struct sd_desc sd_desc = { 2167static const struct sd_desc sd_desc = {
2118 .name = MODULE_NAME, 2168 .name = MODULE_NAME,
diff --git a/drivers/media/video/gspca/spca505.c b/drivers/media/video/gspca/spca505.c
index 895b9fe4018c..2a33a29010ee 100644
--- a/drivers/media/video/gspca/spca505.c
+++ b/drivers/media/video/gspca/spca505.c
@@ -59,7 +59,7 @@ static struct ctrl sd_ctrls[] = {
59 }, 59 },
60}; 60};
61 61
62static struct v4l2_pix_format vga_mode[] = { 62static const struct v4l2_pix_format vga_mode[] = {
63 {160, 120, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, 63 {160, 120, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE,
64 .bytesperline = 160, 64 .bytesperline = 160,
65 .sizeimage = 160 * 120 * 3 / 2, 65 .sizeimage = 160 * 120 * 3 / 2,
diff --git a/drivers/media/video/gspca/spca506.c b/drivers/media/video/gspca/spca506.c
index 645ee9d44d02..96e2512e0621 100644
--- a/drivers/media/video/gspca/spca506.c
+++ b/drivers/media/video/gspca/spca506.c
@@ -110,7 +110,7 @@ static struct ctrl sd_ctrls[] = {
110 }, 110 },
111}; 111};
112 112
113static struct v4l2_pix_format vga_mode[] = { 113static const struct v4l2_pix_format vga_mode[] = {
114 {160, 120, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, 114 {160, 120, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE,
115 .bytesperline = 160, 115 .bytesperline = 160,
116 .sizeimage = 160 * 120 * 3 / 2, 116 .sizeimage = 160 * 120 * 3 / 2,
diff --git a/drivers/media/video/gspca/spca508.c b/drivers/media/video/gspca/spca508.c
index 63ec902c895d..be5d740a315d 100644
--- a/drivers/media/video/gspca/spca508.c
+++ b/drivers/media/video/gspca/spca508.c
@@ -62,7 +62,7 @@ static struct ctrl sd_ctrls[] = {
62 }, 62 },
63}; 63};
64 64
65static struct v4l2_pix_format sif_mode[] = { 65static const struct v4l2_pix_format sif_mode[] = {
66 {160, 120, V4L2_PIX_FMT_SPCA508, V4L2_FIELD_NONE, 66 {160, 120, V4L2_PIX_FMT_SPCA508, V4L2_FIELD_NONE,
67 .bytesperline = 160, 67 .bytesperline = 160,
68 .sizeimage = 160 * 120 * 3 / 2, 68 .sizeimage = 160 * 120 * 3 / 2,
diff --git a/drivers/media/video/gspca/spca561.c b/drivers/media/video/gspca/spca561.c
index c3de4e44123d..3c9288019e96 100644
--- a/drivers/media/video/gspca/spca561.c
+++ b/drivers/media/video/gspca/spca561.c
@@ -32,22 +32,22 @@ MODULE_LICENSE("GPL");
32struct sd { 32struct sd {
33 struct gspca_dev gspca_dev; /* !! must be the first item */ 33 struct gspca_dev gspca_dev; /* !! must be the first item */
34 34
35 __u16 contrast; /* rev72a only */
36#define CONTRAST_MIN 0x0000
37#define CONTRAST_DEF 0x2000
38#define CONTRAST_MAX 0x3fff
39
40 __u16 exposure; /* rev12a only */ 35 __u16 exposure; /* rev12a only */
41#define EXPOSURE_MIN 1 36#define EXPOSURE_MIN 1
42#define EXPOSURE_DEF 200 37#define EXPOSURE_DEF 200
43#define EXPOSURE_MAX (4095 - 900) /* see set_exposure */ 38#define EXPOSURE_MAX (4095 - 900) /* see set_exposure */
44 39
40 __u8 contrast; /* rev72a only */
41#define CONTRAST_MIN 0x00
42#define CONTRAST_DEF 0x20
43#define CONTRAST_MAX 0x3f
44
45 __u8 brightness; /* rev72a only */ 45 __u8 brightness; /* rev72a only */
46#define BRIGHTNESS_MIN 0 46#define BRIGHTNESS_MIN 0
47#define BRIGHTNESS_DEF 32 47#define BRIGHTNESS_DEF 0x20
48#define BRIGHTNESS_MAX 63 48#define BRIGHTNESS_MAX 0x3f
49 49
50 __u8 white; /* rev12a only */ 50 __u8 white;
51#define WHITE_MIN 1 51#define WHITE_MIN 1
52#define WHITE_DEF 0x40 52#define WHITE_DEF 0x40
53#define WHITE_MAX 0x7f 53#define WHITE_MAX 0x7f
@@ -73,7 +73,7 @@ struct sd {
73#define AG_CNT_START 13 73#define AG_CNT_START 13
74}; 74};
75 75
76static struct v4l2_pix_format sif_012a_mode[] = { 76static const struct v4l2_pix_format sif_012a_mode[] = {
77 {160, 120, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE, 77 {160, 120, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
78 .bytesperline = 160, 78 .bytesperline = 160,
79 .sizeimage = 160 * 120, 79 .sizeimage = 160 * 120,
@@ -96,7 +96,7 @@ static struct v4l2_pix_format sif_012a_mode[] = {
96 .priv = 0}, 96 .priv = 0},
97}; 97};
98 98
99static struct v4l2_pix_format sif_072a_mode[] = { 99static const struct v4l2_pix_format sif_072a_mode[] = {
100 {160, 120, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE, 100 {160, 120, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
101 .bytesperline = 160, 101 .bytesperline = 160,
102 .sizeimage = 160 * 120, 102 .sizeimage = 160 * 120,
@@ -146,98 +146,7 @@ static struct v4l2_pix_format sif_072a_mode[] = {
146#define SPCA561_SNAPBIT 0x20 146#define SPCA561_SNAPBIT 0x20
147#define SPCA561_SNAPCTRL 0x40 147#define SPCA561_SNAPCTRL 0x40
148 148
149static void reg_w_val(struct usb_device *dev, __u16 index, __u8 value) 149static const __u16 rev72a_init_data1[][2] = {
150{
151 int ret;
152
153 ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
154 0, /* request */
155 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
156 value, index, NULL, 0, 500);
157 PDEBUG(D_USBO, "reg write: 0x%02x:0x%02x", index, value);
158 if (ret < 0)
159 PDEBUG(D_ERR, "reg write: error %d", ret);
160}
161
162static void write_vector(struct gspca_dev *gspca_dev,
163 const __u16 data[][2])
164{
165 struct usb_device *dev = gspca_dev->dev;
166 int i;
167
168 i = 0;
169 while (data[i][1] != 0) {
170 reg_w_val(dev, data[i][1], data[i][0]);
171 i++;
172 }
173}
174
175/* read 'len' bytes to gspca_dev->usb_buf */
176static void reg_r(struct gspca_dev *gspca_dev,
177 __u16 index, __u16 length)
178{
179 usb_control_msg(gspca_dev->dev,
180 usb_rcvctrlpipe(gspca_dev->dev, 0),
181 0, /* request */
182 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
183 0, /* value */
184 index, gspca_dev->usb_buf, length, 500);
185}
186
187static void reg_w_buf(struct gspca_dev *gspca_dev,
188 __u16 index, const __u8 *buffer, __u16 len)
189{
190 memcpy(gspca_dev->usb_buf, buffer, len);
191 usb_control_msg(gspca_dev->dev,
192 usb_sndctrlpipe(gspca_dev->dev, 0),
193 0, /* request */
194 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
195 0, /* value */
196 index, gspca_dev->usb_buf, len, 500);
197}
198
199static void i2c_write(struct gspca_dev *gspca_dev, __u16 valeur, __u16 reg)
200{
201 int retry = 60;
202 __u8 DataLow;
203 __u8 DataHight;
204
205 DataLow = valeur;
206 DataHight = valeur >> 8;
207 reg_w_val(gspca_dev->dev, 0x8801, reg);
208 reg_w_val(gspca_dev->dev, 0x8805, DataLow);
209 reg_w_val(gspca_dev->dev, 0x8800, DataHight);
210 while (retry--) {
211 reg_r(gspca_dev, 0x8803, 1);
212 if (!gspca_dev->usb_buf[0])
213 break;
214 }
215}
216
217static int i2c_read(struct gspca_dev *gspca_dev, __u16 reg, __u8 mode)
218{
219 int retry = 60;
220 __u8 value;
221 __u8 vallsb;
222
223 reg_w_val(gspca_dev->dev, 0x8804, 0x92);
224 reg_w_val(gspca_dev->dev, 0x8801, reg);
225 reg_w_val(gspca_dev->dev, 0x8802, (mode | 0x01));
226 do {
227 reg_r(gspca_dev, 0x8803, 1);
228 if (!gspca_dev->usb_buf[0])
229 break;
230 } while (--retry);
231 if (retry == 0)
232 return -1;
233 reg_r(gspca_dev, 0x8800, 1);
234 value = gspca_dev->usb_buf[0];
235 reg_r(gspca_dev, 0x8805, 1);
236 vallsb = gspca_dev->usb_buf[0];
237 return ((int) value << 8) | vallsb;
238}
239
240static const __u16 spca561_init_data[][2] = {
241 {0x0000, 0x8114}, /* Software GPIO output data */ 150 {0x0000, 0x8114}, /* Software GPIO output data */
242 {0x0001, 0x8114}, /* Software GPIO output data */ 151 {0x0001, 0x8114}, /* Software GPIO output data */
243 {0x0000, 0x8112}, /* Some kind of reset */ 152 {0x0000, 0x8112}, /* Some kind of reset */
@@ -247,44 +156,26 @@ static const __u16 spca561_init_data[][2] = {
247 {0x0001, 0x8118}, /* Conf sensor */ 156 {0x0001, 0x8118}, /* Conf sensor */
248 {0x0092, 0x8804}, /* I know nothing about these */ 157 {0x0092, 0x8804}, /* I know nothing about these */
249 {0x0010, 0x8802}, /* 0x88xx registers, so I won't */ 158 {0x0010, 0x8802}, /* 0x88xx registers, so I won't */
250 /***************/
251 {0x000d, 0x8805}, /* sensor default setting */ 159 {0x000d, 0x8805}, /* sensor default setting */
252 {0x0001, 0x8801}, /* 1 <- 0x0d */ 160 {}
253 {0x0000, 0x8800}, 161};
254 {0x0018, 0x8805}, 162static const __u16 rev72a_init_sensor1[][2] = {
255 {0x0002, 0x8801}, /* 2 <- 0x18 */ 163 /* ms-win values */
256 {0x0000, 0x8800}, 164 {0x0001, 0x0018}, /* 0x01 <- 0x0d */
257 {0x0065, 0x8805}, 165 {0x0002, 0x0065}, /* 0x02 <- 0x18 */
258 {0x0004, 0x8801}, /* 4 <- 0x01 0x65 */ 166 {0x0004, 0x0121}, /* 0x04 <- 0x0165 */
259 {0x0001, 0x8800}, 167 {0x0005, 0x00aa}, /* 0x05 <- 0x21 */
260 {0x0021, 0x8805}, 168 {0x0007, 0x0004}, /* 0x07 <- 0xaa */
261 {0x0005, 0x8801}, /* 5 <- 0x21 */ 169 {0x0020, 0x1502}, /* 0x20 <- 0x1504 */
262 {0x0000, 0x8800}, 170 {0x0039, 0x0010}, /* 0x39 <- 0x02 */
263 {0x00aa, 0x8805}, 171 {0x0035, 0x0049}, /* 0x35 <- 0x10 */
264 {0x0007, 0x8801}, /* 7 <- 0xaa */ 172 {0x0009, 0x100b}, /* 0x09 <- 0x1049 */
265 {0x0000, 0x8800}, 173 {0x0028, 0x000f}, /* 0x28 <- 0x0b */
266 {0x0004, 0x8805}, 174 {0x003b, 0x003c}, /* 0x3b <- 0x0f */
267 {0x0020, 0x8801}, /* 0x20 <- 0x15 0x04 */ 175 {0x003c, 0x0000}, /* 0x3c <- 0x00 */
268 {0x0015, 0x8800}, 176 {}
269 {0x0002, 0x8805}, 177};
270 {0x0039, 0x8801}, /* 0x39 <- 0x02 */ 178static const __u16 rev72a_init_data2[][2] = {
271 {0x0000, 0x8800},
272 {0x0010, 0x8805},
273 {0x0035, 0x8801}, /* 0x35 <- 0x10 */
274 {0x0000, 0x8800},
275 {0x0049, 0x8805},
276 {0x0009, 0x8801}, /* 0x09 <- 0x10 0x49 */
277 {0x0010, 0x8800},
278 {0x000b, 0x8805},
279 {0x0028, 0x8801}, /* 0x28 <- 0x0b */
280 {0x0000, 0x8800},
281 {0x000f, 0x8805},
282 {0x003b, 0x8801}, /* 0x3b <- 0x0f */
283 {0x0000, 0x8800},
284 {0x0000, 0x8805},
285 {0x003c, 0x8801}, /* 0x3c <- 0x00 */
286 {0x0000, 0x8800},
287 /***************/
288 {0x0018, 0x8601}, /* Pixel/line selection for color separation */ 179 {0x0018, 0x8601}, /* Pixel/line selection for color separation */
289 {0x0000, 0x8602}, /* Optical black level for user setting */ 180 {0x0000, 0x8602}, /* Optical black level for user setting */
290 {0x0060, 0x8604}, /* Optical black horizontal offset */ 181 {0x0060, 0x8604}, /* Optical black horizontal offset */
@@ -309,10 +200,11 @@ static const __u16 spca561_init_data[][2] = {
309 {0x0004, 0x8612}, /* Gr offset for white balance */ 200 {0x0004, 0x8612}, /* Gr offset for white balance */
310 {0x0007, 0x8613}, /* B offset for white balance */ 201 {0x0007, 0x8613}, /* B offset for white balance */
311 {0x0000, 0x8614}, /* Gb offset for white balance */ 202 {0x0000, 0x8614}, /* Gb offset for white balance */
312 {0x008c, 0x8651}, /* R gain for white balance */ 203/* from ms-win */
313 {0x008c, 0x8652}, /* Gr gain for white balance */ 204 {0x0035, 0x8651}, /* R gain for white balance */
314 {0x00b5, 0x8653}, /* B gain for white balance */ 205 {0x0040, 0x8652}, /* Gr gain for white balance */
315 {0x008c, 0x8654}, /* Gb gain for white balance */ 206 {0x005f, 0x8653}, /* B gain for white balance */
207 {0x0040, 0x8654}, /* Gb gain for white balance */
316 {0x0002, 0x8502}, /* Maximum average bit rate stuff */ 208 {0x0002, 0x8502}, /* Maximum average bit rate stuff */
317 209
318 {0x0011, 0x8802}, 210 {0x0011, 0x8802},
@@ -324,29 +216,22 @@ static const __u16 spca561_init_data[][2] = {
324 216
325 {0x0002, 0x865b}, /* Horizontal offset for valid pixels */ 217 {0x0002, 0x865b}, /* Horizontal offset for valid pixels */
326 {0x0003, 0x865c}, /* Vertical offset for valid lines */ 218 {0x0003, 0x865c}, /* Vertical offset for valid lines */
327 /***************//* sensor active */ 219 {}
328 {0x0003, 0x8801}, /* 0x03 <- 0x01 0x21 //289 */ 220};
329 {0x0021, 0x8805}, 221static const __u16 rev72a_init_sensor2[][2] = {
330 {0x0001, 0x8800}, 222 /* ms-win values */
331 {0x0004, 0x8801}, /* 0x04 <- 0x01 0x65 //357 */ 223 {0x0003, 0x0121}, /* 0x03 <- 0x01 0x21 //289 */
332 {0x0065, 0x8805}, 224 {0x0004, 0x0165}, /* 0x04 <- 0x01 0x65 //357 */
333 {0x0001, 0x8800}, 225 {0x0005, 0x002f}, /* 0x05 <- 0x2f */
334 {0x0005, 0x8801}, /* 0x05 <- 0x2f */ 226 {0x0006, 0x0000}, /* 0x06 <- 0 */
335 {0x002f, 0x8805}, 227 {0x000a, 0x0002}, /* 0x0a <- 2 */
336 {0x0000, 0x8800}, 228 {0x0009, 0x1061}, /* 0x09 <- 0x1061 */
337 {0x0006, 0x8801}, /* 0x06 <- 0 */ 229 {0x0035, 0x0014}, /* 0x35 <- 0x14 */
338 {0x0000, 0x8805}, 230 {}
339 {0x0000, 0x8800}, 231};
340 {0x000a, 0x8801}, /* 0x0a <- 2 */ 232static const __u16 rev72a_init_data3[][2] = {
341 {0x0002, 0x8805},
342 {0x0000, 0x8800},
343 {0x0009, 0x8801}, /* 0x09 <- 0x1061 */
344 {0x0061, 0x8805},
345 {0x0010, 0x8800},
346 {0x0035, 0x8801}, /* 0x35 <-0x14 */
347 {0x0014, 0x8805},
348 {0x0000, 0x8800},
349 {0x0030, 0x8112}, /* ISO and drop packet enable */ 233 {0x0030, 0x8112}, /* ISO and drop packet enable */
234/*fixme: should stop here*/
350 {0x0000, 0x8112}, /* Some kind of reset ???? */ 235 {0x0000, 0x8112}, /* Some kind of reset ???? */
351 {0x0009, 0x8118}, /* Enable sensor and set standby */ 236 {0x0009, 0x8118}, /* Enable sensor and set standby */
352 {0x0000, 0x8114}, /* Software GPIO output data */ 237 {0x0000, 0x8114}, /* Software GPIO output data */
@@ -434,7 +319,6 @@ static const __u16 spca561_init_data[][2] = {
434 {} 319 {}
435}; 320};
436 321
437
438/******************** QC Express etch2 stuff ********************/ 322/******************** QC Express etch2 stuff ********************/
439static const __u16 Pb100_1map8300[][2] = { 323static const __u16 Pb100_1map8300[][2] = {
440 /* reg, value */ 324 /* reg, value */
@@ -515,22 +399,112 @@ static const __u16 spca561_161rev12A_data2[][2] = {
515 {} 399 {}
516}; 400};
517 401
518static void sensor_mapwrite(struct gspca_dev *gspca_dev, 402static void reg_w_val(struct usb_device *dev, __u16 index, __u8 value)
519 const __u16 sensormap[][2]) 403{
404 int ret;
405
406 ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
407 0, /* request */
408 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
409 value, index, NULL, 0, 500);
410 PDEBUG(D_USBO, "reg write: 0x%02x:0x%02x", index, value);
411 if (ret < 0)
412 PDEBUG(D_ERR, "reg write: error %d", ret);
413}
414
415static void write_vector(struct gspca_dev *gspca_dev,
416 const __u16 data[][2])
520{ 417{
521 int i = 0; 418 struct usb_device *dev = gspca_dev->dev;
522 __u8 usbval[2]; 419 int i;
523 420
524 while (sensormap[i][0]) { 421 i = 0;
525 usbval[0] = sensormap[i][1]; 422 while (data[i][1] != 0) {
526 usbval[1] = sensormap[i][1] >> 8; 423 reg_w_val(dev, data[i][1], data[i][0]);
527 reg_w_buf(gspca_dev, sensormap[i][0], usbval, 2);
528 i++; 424 i++;
529 } 425 }
530} 426}
427
428/* read 'len' bytes to gspca_dev->usb_buf */
429static void reg_r(struct gspca_dev *gspca_dev,
430 __u16 index, __u16 length)
431{
432 usb_control_msg(gspca_dev->dev,
433 usb_rcvctrlpipe(gspca_dev->dev, 0),
434 0, /* request */
435 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
436 0, /* value */
437 index, gspca_dev->usb_buf, length, 500);
438}
439
440/* write 'len' bytes from gspca_dev->usb_buf */
441static void reg_w_buf(struct gspca_dev *gspca_dev,
442 __u16 index, __u16 len)
443{
444 usb_control_msg(gspca_dev->dev,
445 usb_sndctrlpipe(gspca_dev->dev, 0),
446 0, /* request */
447 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
448 0, /* value */
449 index, gspca_dev->usb_buf, len, 500);
450}
451
452static void i2c_write(struct gspca_dev *gspca_dev, __u16 value, __u16 reg)
453{
454 int retry = 60;
455
456 reg_w_val(gspca_dev->dev, 0x8801, reg);
457 reg_w_val(gspca_dev->dev, 0x8805, value);
458 reg_w_val(gspca_dev->dev, 0x8800, value >> 8);
459 do {
460 reg_r(gspca_dev, 0x8803, 1);
461 if (!gspca_dev->usb_buf[0])
462 return;
463 } while (--retry);
464}
465
466static int i2c_read(struct gspca_dev *gspca_dev, __u16 reg, __u8 mode)
467{
468 int retry = 60;
469 __u8 value;
470
471 reg_w_val(gspca_dev->dev, 0x8804, 0x92);
472 reg_w_val(gspca_dev->dev, 0x8801, reg);
473 reg_w_val(gspca_dev->dev, 0x8802, mode | 0x01);
474 do {
475 reg_r(gspca_dev, 0x8803, 1);
476 if (!gspca_dev->usb_buf[0]) {
477 reg_r(gspca_dev, 0x8800, 1);
478 value = gspca_dev->usb_buf[0];
479 reg_r(gspca_dev, 0x8805, 1);
480 return ((int) value << 8) | gspca_dev->usb_buf[0];
481 }
482 } while (--retry);
483 return -1;
484}
485
486static void sensor_mapwrite(struct gspca_dev *gspca_dev,
487 const __u16 (*sensormap)[2])
488{
489 while ((*sensormap)[0]) {
490 gspca_dev->usb_buf[0] = (*sensormap)[1];
491 gspca_dev->usb_buf[1] = (*sensormap)[1] >> 8;
492 reg_w_buf(gspca_dev, (*sensormap)[0], 2);
493 sensormap++;
494 }
495}
496
497static void write_sensor_72a(struct gspca_dev *gspca_dev,
498 const __u16 (*sensor)[2])
499{
500 while ((*sensor)[0]) {
501 i2c_write(gspca_dev, (*sensor)[1], (*sensor)[0]);
502 sensor++;
503 }
504}
505
531static void init_161rev12A(struct gspca_dev *gspca_dev) 506static void init_161rev12A(struct gspca_dev *gspca_dev)
532{ 507{
533/* sensor_reset(gspca_dev); (not in win) */
534 write_vector(gspca_dev, spca561_161rev12A_data1); 508 write_vector(gspca_dev, spca561_161rev12A_data1);
535 sensor_mapwrite(gspca_dev, Pb100_1map8300); 509 sensor_mapwrite(gspca_dev, Pb100_1map8300);
536/*fixme: should be in sd_start*/ 510/*fixme: should be in sd_start*/
@@ -598,49 +572,68 @@ static int sd_init_12a(struct gspca_dev *gspca_dev)
598static int sd_init_72a(struct gspca_dev *gspca_dev) 572static int sd_init_72a(struct gspca_dev *gspca_dev)
599{ 573{
600 PDEBUG(D_STREAM, "Chip revision: 072a"); 574 PDEBUG(D_STREAM, "Chip revision: 072a");
601 write_vector(gspca_dev, spca561_init_data); 575 write_vector(gspca_dev, rev72a_init_data1);
576 write_sensor_72a(gspca_dev, rev72a_init_sensor1);
577 write_vector(gspca_dev, rev72a_init_data2);
578 write_sensor_72a(gspca_dev, rev72a_init_sensor2);
579 write_vector(gspca_dev, rev72a_init_data3);
602 return 0; 580 return 0;
603} 581}
604 582
605static void setcontrast(struct gspca_dev *gspca_dev) 583/* rev 72a only */
584static void setbrightness(struct gspca_dev *gspca_dev)
606{ 585{
607 struct sd *sd = (struct sd *) gspca_dev; 586 struct sd *sd = (struct sd *) gspca_dev;
608 struct usb_device *dev = gspca_dev->dev; 587 struct usb_device *dev = gspca_dev->dev;
609 __u8 lowb; 588 __u8 value;
610 589
611 switch (sd->chip_revision) { 590 value = sd->brightness;
612 case Rev072A:
613 lowb = sd->contrast >> 8;
614 reg_w_val(dev, 0x8651, lowb);
615 reg_w_val(dev, 0x8652, lowb);
616 reg_w_val(dev, 0x8653, lowb);
617 reg_w_val(dev, 0x8654, lowb);
618 break;
619 default: {
620/* case Rev012A: { */
621 static const __u8 Reg8391[] =
622 { 0x92, 0x30, 0x20, 0x00, 0x0c, 0x00, 0x00, 0x00 };
623 591
624 reg_w_buf(gspca_dev, 0x8391, Reg8391, 8); 592 /* offsets for white balance */
625 reg_w_buf(gspca_dev, 0x8390, Reg8391, 8); 593 reg_w_val(dev, 0x8611, value); /* R */
626 break; 594 reg_w_val(dev, 0x8612, value); /* Gr */
627 } 595 reg_w_val(dev, 0x8613, value); /* B */
628 } 596 reg_w_val(dev, 0x8614, value); /* Gb */
629} 597}
630 598
631/* rev12a only */
632static void setwhite(struct gspca_dev *gspca_dev) 599static void setwhite(struct gspca_dev *gspca_dev)
633{ 600{
634 struct sd *sd = (struct sd *) gspca_dev; 601 struct sd *sd = (struct sd *) gspca_dev;
635 __u16 white; 602 __u16 white;
636 __u8 reg8614, reg8616; 603 __u8 blue, red;
604 __u16 reg;
637 605
638 white = sd->white;
639 /* try to emulate MS-win as possible */ 606 /* try to emulate MS-win as possible */
640 reg8616 = 0x90 - white * 5 / 8; 607 white = sd->white;
641 reg_w_val(gspca_dev->dev, 0x8616, reg8616); 608 red = 0x20 + white * 3 / 8;
642 reg8614 = 0x20 + white * 3 / 8; 609 blue = 0x90 - white * 5 / 8;
643 reg_w_val(gspca_dev->dev, 0x8614, reg8614); 610 if (sd->chip_revision == Rev012A) {
611 reg = 0x8614;
612 } else {
613 reg = 0x8651;
614 red += sd->contrast - 0x20;
615 blue += sd->contrast - 0x20;
616 }
617 reg_w_val(gspca_dev->dev, reg, red);
618 reg_w_val(gspca_dev->dev, reg + 2, blue);
619}
620
621static void setcontrast(struct gspca_dev *gspca_dev)
622{
623 struct sd *sd = (struct sd *) gspca_dev;
624 struct usb_device *dev = gspca_dev->dev;
625 __u8 value;
626
627 if (sd->chip_revision != Rev072A)
628 return;
629 value = sd->contrast + 0x20;
630
631 /* gains for white balance */
632 setwhite(gspca_dev);
633/* reg_w_val(dev, 0x8651, value); * R - done by setwhite */
634 reg_w_val(dev, 0x8652, value); /* Gr */
635/* reg_w_val(dev, 0x8653, value); * B - done by setwhite */
636 reg_w_val(dev, 0x8654, value); /* Gb */
644} 637}
645 638
646/* rev 12a only */ 639/* rev 12a only */
@@ -649,7 +642,6 @@ static void setexposure(struct gspca_dev *gspca_dev)
649 struct sd *sd = (struct sd *) gspca_dev; 642 struct sd *sd = (struct sd *) gspca_dev;
650 int expo; 643 int expo;
651 int clock_divider; 644 int clock_divider;
652 __u8 data[2];
653 645
654 /* Register 0x8309 controls exposure for the spca561, 646 /* Register 0x8309 controls exposure for the spca561,
655 the basic exposure setting goes from 1-2047, where 1 is completely 647 the basic exposure setting goes from 1-2047, where 1 is completely
@@ -673,20 +665,19 @@ static void setexposure(struct gspca_dev *gspca_dev)
673 clock_divider = 3; 665 clock_divider = 3;
674 } 666 }
675 expo |= clock_divider << 11; 667 expo |= clock_divider << 11;
676 data[0] = expo; 668 gspca_dev->usb_buf[0] = expo;
677 data[1] = expo >> 8; 669 gspca_dev->usb_buf[1] = expo >> 8;
678 reg_w_buf(gspca_dev, 0x8309, data, 2); 670 reg_w_buf(gspca_dev, 0x8309, 2);
679} 671}
680 672
681/* rev 12a only */ 673/* rev 12a only */
682static void setgain(struct gspca_dev *gspca_dev) 674static void setgain(struct gspca_dev *gspca_dev)
683{ 675{
684 struct sd *sd = (struct sd *) gspca_dev; 676 struct sd *sd = (struct sd *) gspca_dev;
685 __u8 data[2];
686 677
687 data[0] = sd->gain; 678 gspca_dev->usb_buf[0] = sd->gain;
688 data[1] = 0; 679 gspca_dev->usb_buf[1] = 0;
689 reg_w_buf(gspca_dev, 0x8335, data, 2); 680 reg_w_buf(gspca_dev, 0x8335, 2);
690} 681}
691 682
692static void setautogain(struct gspca_dev *gspca_dev) 683static void setautogain(struct gspca_dev *gspca_dev)
@@ -702,9 +693,9 @@ static void setautogain(struct gspca_dev *gspca_dev)
702static int sd_start_12a(struct gspca_dev *gspca_dev) 693static int sd_start_12a(struct gspca_dev *gspca_dev)
703{ 694{
704 struct usb_device *dev = gspca_dev->dev; 695 struct usb_device *dev = gspca_dev->dev;
705 int Clck = 0x8a; /* lower 0x8X values lead to fps > 30 */
706 __u8 Reg8307[] = { 0xaa, 0x00 };
707 int mode; 696 int mode;
697 static const __u8 Reg8391[8] =
698 {0x92, 0x30, 0x20, 0x00, 0x0c, 0x00, 0x00, 0x00};
708 699
709 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; 700 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
710 if (mode <= 1) { 701 if (mode <= 1) {
@@ -716,14 +707,21 @@ static int sd_start_12a(struct gspca_dev *gspca_dev)
716 * is sufficient to push raw frames at ~20fps */ 707 * is sufficient to push raw frames at ~20fps */
717 reg_w_val(dev, 0x8500, mode); 708 reg_w_val(dev, 0x8500, mode);
718 } /* -- qq@kuku.eu.org */ 709 } /* -- qq@kuku.eu.org */
719 reg_w_buf(gspca_dev, 0x8307, Reg8307, 2); 710
720 reg_w_val(gspca_dev->dev, 0x8700, Clck); 711 gspca_dev->usb_buf[0] = 0xaa;
712 gspca_dev->usb_buf[1] = 0x00;
713 reg_w_buf(gspca_dev, 0x8307, 2);
714 /* clock - lower 0x8X values lead to fps > 30 */
715 reg_w_val(gspca_dev->dev, 0x8700, 0x8a);
721 /* 0x8f 0x85 0x27 clock */ 716 /* 0x8f 0x85 0x27 clock */
722 reg_w_val(gspca_dev->dev, 0x8112, 0x1e | 0x20); 717 reg_w_val(gspca_dev->dev, 0x8112, 0x1e | 0x20);
723 reg_w_val(gspca_dev->dev, 0x850b, 0x03); 718 reg_w_val(gspca_dev->dev, 0x850b, 0x03);
724 setcontrast(gspca_dev); 719 memcpy(gspca_dev->usb_buf, Reg8391, 8);
720 reg_w_buf(gspca_dev, 0x8391, 8);
721 reg_w_buf(gspca_dev, 0x8390, 8);
725 setwhite(gspca_dev); 722 setwhite(gspca_dev);
726 setautogain(gspca_dev); 723 setautogain(gspca_dev);
724/* setgain(gspca_dev); */
727 setexposure(gspca_dev); 725 setexposure(gspca_dev);
728 return 0; 726 return 0;
729} 727}
@@ -750,6 +748,9 @@ static int sd_start_72a(struct gspca_dev *gspca_dev)
750 reg_w_val(dev, 0x8500, mode); /* mode */ 748 reg_w_val(dev, 0x8500, mode); /* mode */
751 reg_w_val(dev, 0x8700, Clck); /* 0x27 clock */ 749 reg_w_val(dev, 0x8700, Clck); /* 0x27 clock */
752 reg_w_val(dev, 0x8112, 0x10 | 0x20); 750 reg_w_val(dev, 0x8112, 0x10 | 0x20);
751 setcontrast(gspca_dev);
752/* setbrightness(gspca_dev); * fixme: bad values */
753 setwhite(gspca_dev);
753 setautogain(gspca_dev); 754 setautogain(gspca_dev);
754 return 0; 755 return 0;
755} 756}
@@ -791,7 +792,6 @@ static void do_autogain(struct gspca_dev *gspca_dev)
791 __u8 luma_mean = 110; 792 __u8 luma_mean = 110;
792 __u8 luma_delta = 20; 793 __u8 luma_delta = 20;
793 __u8 spring = 4; 794 __u8 spring = 4;
794 __u8 reg8339[2];
795 795
796 if (sd->ag_cnt < 0) 796 if (sd->ag_cnt < 0)
797 return; 797 return;
@@ -834,13 +834,13 @@ static void do_autogain(struct gspca_dev *gspca_dev)
834 834
835 if (gainG > 0x3f) 835 if (gainG > 0x3f)
836 gainG = 0x3f; 836 gainG = 0x3f;
837 else if (gainG < 4) 837 else if (gainG < 3)
838 gainG = 3; 838 gainG = 3;
839 i2c_write(gspca_dev, gainG, 0x35); 839 i2c_write(gspca_dev, gainG, 0x35);
840 840
841 if (expotimes >= 0x0256) 841 if (expotimes > 0x0256)
842 expotimes = 0x0256; 842 expotimes = 0x0256;
843 else if (expotimes < 4) 843 else if (expotimes < 3)
844 expotimes = 3; 844 expotimes = 3;
845 i2c_write(gspca_dev, expotimes | pixelclk, 0x09); 845 i2c_write(gspca_dev, expotimes | pixelclk, 0x09);
846 } 846 }
@@ -848,13 +848,13 @@ static void do_autogain(struct gspca_dev *gspca_dev)
848 case Rev012A: 848 case Rev012A:
849 reg_r(gspca_dev, 0x8330, 2); 849 reg_r(gspca_dev, 0x8330, 2);
850 if (gspca_dev->usb_buf[1] > 0x08) { 850 if (gspca_dev->usb_buf[1] > 0x08) {
851 reg8339[0] = ++sd->expo12a; 851 gspca_dev->usb_buf[0] = ++sd->expo12a;
852 reg8339[1] = 0; 852 gspca_dev->usb_buf[1] = 0;
853 reg_w_buf(gspca_dev, 0x8339, reg8339, 2); 853 reg_w_buf(gspca_dev, 0x8339, 2);
854 } else if (gspca_dev->usb_buf[1] < 0x02) { 854 } else if (gspca_dev->usb_buf[1] < 0x02) {
855 reg8339[0] = --sd->expo12a; 855 gspca_dev->usb_buf[0] = --sd->expo12a;
856 reg8339[1] = 0; 856 gspca_dev->usb_buf[1] = 0;
857 reg_w_buf(gspca_dev, 0x8339, reg8339, 2); 857 reg_w_buf(gspca_dev, 0x8339, 2);
858 } 858 }
859 break; 859 break;
860 } 860 }
@@ -867,8 +867,8 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
867{ 867{
868 struct sd *sd = (struct sd *) gspca_dev; 868 struct sd *sd = (struct sd *) gspca_dev;
869 869
870 switch (data[0]) { 870 switch (data[0]) { /* sequence number */
871 case 0: /* start of frame */ 871 case 0: /* start of frame */
872 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, 872 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
873 data, 0); 873 data, 0);
874 data += SPCA561_OFFSET_DATA; 874 data += SPCA561_OFFSET_DATA;
@@ -890,8 +890,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
890 frame, data, len); 890 frame, data, len);
891 } 891 }
892 return; 892 return;
893 case 0xff: /* drop */ 893 case 0xff: /* drop (empty mpackets) */
894/* gspca_dev->last_packet_type = DISCARD_PACKET; */
895 return; 894 return;
896 } 895 }
897 data++; 896 data++;
@@ -900,55 +899,6 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
900} 899}
901 900
902/* rev 72a only */ 901/* rev 72a only */
903static void setbrightness(struct gspca_dev *gspca_dev)
904{
905 struct sd *sd = (struct sd *) gspca_dev;
906 __u8 value;
907
908 value = sd->brightness;
909 reg_w_val(gspca_dev->dev, 0x8611, value);
910 reg_w_val(gspca_dev->dev, 0x8612, value);
911 reg_w_val(gspca_dev->dev, 0x8613, value);
912 reg_w_val(gspca_dev->dev, 0x8614, value);
913}
914
915static void getbrightness(struct gspca_dev *gspca_dev)
916{
917 struct sd *sd = (struct sd *) gspca_dev;
918 __u16 tot;
919
920 tot = 0;
921 reg_r(gspca_dev, 0x8611, 1);
922 tot += gspca_dev->usb_buf[0];
923 reg_r(gspca_dev, 0x8612, 1);
924 tot += gspca_dev->usb_buf[0];
925 reg_r(gspca_dev, 0x8613, 1);
926 tot += gspca_dev->usb_buf[0];
927 reg_r(gspca_dev, 0x8614, 1);
928 tot += gspca_dev->usb_buf[0];
929 sd->brightness = tot >> 2;
930}
931
932/* rev72a only */
933static void getcontrast(struct gspca_dev *gspca_dev)
934{
935 struct sd *sd = (struct sd *) gspca_dev;
936 __u16 tot;
937
938 tot = 0;
939 reg_r(gspca_dev, 0x8651, 1);
940 tot += gspca_dev->usb_buf[0];
941 reg_r(gspca_dev, 0x8652, 1);
942 tot += gspca_dev->usb_buf[0];
943 reg_r(gspca_dev, 0x8653, 1);
944 tot += gspca_dev->usb_buf[0];
945 reg_r(gspca_dev, 0x8654, 1);
946 tot += gspca_dev->usb_buf[0];
947 sd->contrast = tot << 6;
948 PDEBUG(D_CONF, "get contrast %d", sd->contrast);
949}
950
951/* rev 72a only */
952static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) 902static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
953{ 903{
954 struct sd *sd = (struct sd *) gspca_dev; 904 struct sd *sd = (struct sd *) gspca_dev;
@@ -963,7 +913,6 @@ static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
963{ 913{
964 struct sd *sd = (struct sd *) gspca_dev; 914 struct sd *sd = (struct sd *) gspca_dev;
965 915
966 getbrightness(gspca_dev);
967 *val = sd->brightness; 916 *val = sd->brightness;
968 return 0; 917 return 0;
969} 918}
@@ -983,7 +932,6 @@ static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
983{ 932{
984 struct sd *sd = (struct sd *) gspca_dev; 933 struct sd *sd = (struct sd *) gspca_dev;
985 934
986 getcontrast(gspca_dev);
987 *val = sd->contrast; 935 *val = sd->contrast;
988 return 0; 936 return 0;
989} 937}
@@ -1006,7 +954,6 @@ static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
1006 return 0; 954 return 0;
1007} 955}
1008 956
1009/* rev12a only */
1010static int sd_setwhite(struct gspca_dev *gspca_dev, __s32 val) 957static int sd_setwhite(struct gspca_dev *gspca_dev, __s32 val)
1011{ 958{
1012 struct sd *sd = (struct sd *) gspca_dev; 959 struct sd *sd = (struct sd *) gspca_dev;
@@ -1121,6 +1068,19 @@ static struct ctrl sd_ctrls_12a[] = {
1121 1068
1122static struct ctrl sd_ctrls_72a[] = { 1069static struct ctrl sd_ctrls_72a[] = {
1123 { 1070 {
1071 {
1072 .id = V4L2_CID_DO_WHITE_BALANCE,
1073 .type = V4L2_CTRL_TYPE_INTEGER,
1074 .name = "White Balance",
1075 .minimum = WHITE_MIN,
1076 .maximum = WHITE_MAX,
1077 .step = 1,
1078 .default_value = WHITE_DEF,
1079 },
1080 .set = sd_setwhite,
1081 .get = sd_getwhite,
1082 },
1083 {
1124 { 1084 {
1125 .id = V4L2_CID_BRIGHTNESS, 1085 .id = V4L2_CID_BRIGHTNESS,
1126 .type = V4L2_CTRL_TYPE_INTEGER, 1086 .type = V4L2_CTRL_TYPE_INTEGER,
diff --git a/drivers/media/video/gspca/stk014.c b/drivers/media/video/gspca/stk014.c
index d9d64911f22a..60de9af87fbb 100644
--- a/drivers/media/video/gspca/stk014.c
+++ b/drivers/media/video/gspca/stk014.c
@@ -109,7 +109,7 @@ static struct ctrl sd_ctrls[] = {
109 }, 109 },
110}; 110};
111 111
112static struct v4l2_pix_format vga_mode[] = { 112static const struct v4l2_pix_format vga_mode[] = {
113 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 113 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
114 .bytesperline = 320, 114 .bytesperline = 320,
115 .sizeimage = 320 * 240 * 3 / 8 + 590, 115 .sizeimage = 320 * 240 * 3 / 8 + 590,
@@ -424,10 +424,8 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
424 424
425 /* beginning of the frame */ 425 /* beginning of the frame */
426#define STKHDRSZ 12 426#define STKHDRSZ 12
427 gspca_frame_add(gspca_dev, INTER_PACKET, frame, 427 data += STKHDRSZ;
428 data + STKHDRSZ, len - STKHDRSZ); 428 len -= STKHDRSZ;
429#undef STKHDRSZ
430 return;
431 } 429 }
432 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); 430 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
433} 431}
diff --git a/drivers/media/video/gspca/stv06xx/Kconfig b/drivers/media/video/gspca/stv06xx/Kconfig
new file mode 100644
index 000000000000..634ad38d9fb8
--- /dev/null
+++ b/drivers/media/video/gspca/stv06xx/Kconfig
@@ -0,0 +1,9 @@
1config USB_STV06XX
2 tristate "STV06XX USB Camera Driver"
3 depends on USB_GSPCA
4 help
5 Say Y here if you want support for cameras based on
6 the ST STV06XX chip.
7
8 To compile this driver as a module, choose M here: the
9 module will be called gspca_stv06xx.
diff --git a/drivers/media/video/gspca/stv06xx/Makefile b/drivers/media/video/gspca/stv06xx/Makefile
new file mode 100644
index 000000000000..feeaa94ab588
--- /dev/null
+++ b/drivers/media/video/gspca/stv06xx/Makefile
@@ -0,0 +1,9 @@
1obj-$(CONFIG_USB_STV06XX) += gspca_stv06xx.o
2
3gspca_stv06xx-objs := stv06xx.o \
4 stv06xx_vv6410.o \
5 stv06xx_hdcs.o \
6 stv06xx_pb0100.o
7
8EXTRA_CFLAGS += -Idrivers/media/video/gspca
9
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx.c b/drivers/media/video/gspca/stv06xx/stv06xx.c
new file mode 100644
index 000000000000..13a021e3cbb7
--- /dev/null
+++ b/drivers/media/video/gspca/stv06xx/stv06xx.c
@@ -0,0 +1,522 @@
1/*
2 * Copyright (c) 2001 Jean-Fredric Clere, Nikolas Zimmermann, Georg Acher
3 * Mark Cave-Ayland, Carlo E Prelz, Dick Streefland
4 * Copyright (c) 2002, 2003 Tuukka Toivonen
5 * Copyright (c) 2008 Erik Andrén
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 *
21 * P/N 861037: Sensor HDCS1000 ASIC STV0600
22 * P/N 861050-0010: Sensor HDCS1000 ASIC STV0600
23 * P/N 861050-0020: Sensor Photobit PB100 ASIC STV0600-1 - QuickCam Express
24 * P/N 861055: Sensor ST VV6410 ASIC STV0610 - LEGO cam
25 * P/N 861075-0040: Sensor HDCS1000 ASIC
26 * P/N 961179-0700: Sensor ST VV6410 ASIC STV0602 - Dexxa WebCam USB
27 * P/N 861040-0000: Sensor ST VV6410 ASIC STV0610 - QuickCam Web
28 */
29
30#include "stv06xx_sensor.h"
31
32MODULE_AUTHOR("Erik Andrén");
33MODULE_DESCRIPTION("STV06XX USB Camera Driver");
34MODULE_LICENSE("GPL");
35
36static int dump_bridge;
37static int dump_sensor;
38
39int stv06xx_write_bridge(struct sd *sd, u16 address, u16 i2c_data)
40{
41 int err;
42 struct usb_device *udev = sd->gspca_dev.dev;
43 __u8 *buf = sd->gspca_dev.usb_buf;
44 u8 len = (i2c_data > 0xff) ? 2 : 1;
45
46 buf[0] = i2c_data & 0xff;
47 buf[1] = (i2c_data >> 8) & 0xff;
48
49 err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
50 0x04, 0x40, address, 0, buf, len,
51 STV06XX_URB_MSG_TIMEOUT);
52
53
54 PDEBUG(D_CONF, "Written 0x%x to address 0x%x, status: %d",
55 i2c_data, address, err);
56
57 return (err < 0) ? err : 0;
58}
59
60int stv06xx_read_bridge(struct sd *sd, u16 address, u8 *i2c_data)
61{
62 int err;
63 struct usb_device *udev = sd->gspca_dev.dev;
64 __u8 *buf = sd->gspca_dev.usb_buf;
65
66 err = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
67 0x04, 0xc0, address, 0, buf, 1,
68 STV06XX_URB_MSG_TIMEOUT);
69
70 *i2c_data = buf[0];
71
72 PDEBUG(D_CONF, "Read 0x%x from address 0x%x, status %d",
73 *i2c_data, address, err);
74
75 return (err < 0) ? err : 0;
76}
77
78/* Wraps the normal write sensor bytes / words functions for writing a
79 single value */
80int stv06xx_write_sensor(struct sd *sd, u8 address, u16 value)
81{
82 if (sd->sensor->i2c_len == 2) {
83 u16 data[2] = { address, value };
84 return stv06xx_write_sensor_words(sd, data, 1);
85 } else {
86 u8 data[2] = { address, value };
87 return stv06xx_write_sensor_bytes(sd, data, 1);
88 }
89}
90
91static int stv06xx_write_sensor_finish(struct sd *sd)
92{
93 int err = 0;
94
95 if (IS_850(sd)) {
96 struct usb_device *udev = sd->gspca_dev.dev;
97 __u8 *buf = sd->gspca_dev.usb_buf;
98
99 /* Quickam Web needs an extra packet */
100 buf[0] = 0;
101 err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
102 0x04, 0x40, 0x1704, 0, buf, 1,
103 STV06XX_URB_MSG_TIMEOUT);
104 }
105
106 return (err < 0) ? err : 0;
107}
108
109int stv06xx_write_sensor_bytes(struct sd *sd, const u8 *data, u8 len)
110{
111 int err, i, j;
112 struct usb_device *udev = sd->gspca_dev.dev;
113 __u8 *buf = sd->gspca_dev.usb_buf;
114
115 PDEBUG(D_USBO, "I2C: Command buffer contains %d entries", len);
116 for (i = 0; i < len;) {
117 /* Build the command buffer */
118 memset(buf, 0, I2C_BUFFER_LENGTH);
119 for (j = 0; j < I2C_MAX_BYTES && i < len; j++, i++) {
120 buf[j] = data[2*i];
121 buf[0x10 + j] = data[2*i+1];
122 PDEBUG(D_USBO, "I2C: Writing 0x%02x to reg 0x%02x",
123 data[2*i+1], data[2*i]);
124 }
125 buf[0x20] = sd->sensor->i2c_addr;
126 buf[0x21] = j - 1; /* Number of commands to send - 1 */
127 buf[0x22] = I2C_WRITE_CMD;
128 err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
129 0x04, 0x40, 0x0400, 0, buf,
130 I2C_BUFFER_LENGTH,
131 STV06XX_URB_MSG_TIMEOUT);
132 if (err < 0)
133 return err;
134 }
135 return stv06xx_write_sensor_finish(sd);
136}
137
138int stv06xx_write_sensor_words(struct sd *sd, const u16 *data, u8 len)
139{
140 int err, i, j;
141 struct usb_device *udev = sd->gspca_dev.dev;
142 __u8 *buf = sd->gspca_dev.usb_buf;
143
144 PDEBUG(D_USBO, "I2C: Command buffer contains %d entries", len);
145
146 for (i = 0; i < len;) {
147 /* Build the command buffer */
148 memset(buf, 0, I2C_BUFFER_LENGTH);
149 for (j = 0; j < I2C_MAX_WORDS && i < len; j++, i++) {
150 buf[j] = data[2*i];
151 buf[0x10 + j * 2] = data[2*i+1];
152 buf[0x10 + j * 2 + 1] = data[2*i+1] >> 8;
153 PDEBUG(D_USBO, "I2C: Writing 0x%04x to reg 0x%02x",
154 data[2*i+1], data[2*i]);
155 }
156 buf[0x20] = sd->sensor->i2c_addr;
157 buf[0x21] = j - 1; /* Number of commands to send - 1 */
158 buf[0x22] = I2C_WRITE_CMD;
159 err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
160 0x04, 0x40, 0x0400, 0, buf,
161 I2C_BUFFER_LENGTH,
162 STV06XX_URB_MSG_TIMEOUT);
163 if (err < 0)
164 return err;
165 }
166 return stv06xx_write_sensor_finish(sd);
167}
168
169int stv06xx_read_sensor(struct sd *sd, const u8 address, u16 *value)
170{
171 int err;
172 struct usb_device *udev = sd->gspca_dev.dev;
173 __u8 *buf = sd->gspca_dev.usb_buf;
174
175 err = stv06xx_write_bridge(sd, STV_I2C_FLUSH, sd->sensor->i2c_flush);
176 if (err < 0)
177 return err;
178
179 /* Clear mem */
180 memset(buf, 0, I2C_BUFFER_LENGTH);
181
182 buf[0] = address;
183 buf[0x20] = sd->sensor->i2c_addr;
184 buf[0x21] = 0;
185
186 /* Read I2C register */
187 buf[0x22] = I2C_READ_CMD;
188
189 err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
190 0x04, 0x40, 0x1400, 0, buf, I2C_BUFFER_LENGTH,
191 STV06XX_URB_MSG_TIMEOUT);
192 if (err < 0) {
193 PDEBUG(D_ERR, "I2C Read: error writing address: %d", err);
194 return err;
195 }
196
197 err = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
198 0x04, 0xc0, 0x1410, 0, buf, sd->sensor->i2c_len,
199 STV06XX_URB_MSG_TIMEOUT);
200 if (sd->sensor->i2c_len == 2)
201 *value = buf[0] | (buf[1] << 8);
202 else
203 *value = buf[0];
204
205 PDEBUG(D_USBO, "I2C: Read 0x%x from address 0x%x, status: %d",
206 *value, address, err);
207
208 return (err < 0) ? err : 0;
209}
210
211/* Dumps all bridge registers */
212static void stv06xx_dump_bridge(struct sd *sd)
213{
214 int i;
215 u8 data, buf;
216
217 info("Dumping all stv06xx bridge registers");
218 for (i = 0x1400; i < 0x160f; i++) {
219 stv06xx_read_bridge(sd, i, &data);
220
221 info("Read 0x%x from address 0x%x", data, i);
222 }
223
224 for (i = 0x1400; i < 0x160f; i++) {
225 stv06xx_read_bridge(sd, i, &data);
226 buf = data;
227
228 stv06xx_write_bridge(sd, i, 0xff);
229 stv06xx_read_bridge(sd, i, &data);
230 if (data == 0xff)
231 info("Register 0x%x is read/write", i);
232 else if (data != buf)
233 info("Register 0x%x is read/write,"
234 "but only partially", i);
235 else
236 info("Register 0x%x is read-only", i);
237
238 stv06xx_write_bridge(sd, i, buf);
239 }
240}
241
242/* this function is called at probe and resume time */
243static int stv06xx_init(struct gspca_dev *gspca_dev)
244{
245 struct sd *sd = (struct sd *) gspca_dev;
246 int err;
247
248 PDEBUG(D_PROBE, "Initializing camera");
249
250 /* Let the usb init settle for a bit
251 before performing the initialization */
252 msleep(250);
253
254 err = sd->sensor->init(sd);
255
256 if (dump_sensor)
257 sd->sensor->dump(sd);
258
259 return (err < 0) ? err : 0;
260}
261
262/* Start the camera */
263static int stv06xx_start(struct gspca_dev *gspca_dev)
264{
265 struct sd *sd = (struct sd *) gspca_dev;
266 int err;
267
268 /* Prepare the sensor for start */
269 err = sd->sensor->start(sd);
270 if (err < 0)
271 goto out;
272
273 /* Start isochronous streaming */
274 err = stv06xx_write_bridge(sd, STV_ISO_ENABLE, 1);
275
276out:
277 if (err < 0)
278 PDEBUG(D_STREAM, "Starting stream failed");
279 else
280 PDEBUG(D_STREAM, "Started streaming");
281
282 return (err < 0) ? err : 0;
283}
284
285static void stv06xx_stopN(struct gspca_dev *gspca_dev)
286{
287 int err;
288 struct sd *sd = (struct sd *) gspca_dev;
289
290 /* stop ISO-streaming */
291 err = stv06xx_write_bridge(sd, STV_ISO_ENABLE, 0);
292 if (err < 0)
293 goto out;
294
295 err = sd->sensor->stop(sd);
296 if (err < 0)
297 goto out;
298
299out:
300 if (err < 0)
301 PDEBUG(D_STREAM, "Failed to stop stream");
302 else
303 PDEBUG(D_STREAM, "Stopped streaming");
304}
305
306/*
307 * Analyse an USB packet of the data stream and store it appropriately.
308 * Each packet contains an integral number of chunks. Each chunk has
309 * 2-bytes identification, followed by 2-bytes that describe the chunk
310 * length. Known/guessed chunk identifications are:
311 * 8001/8005/C001/C005 - Begin new frame
312 * 8002/8006/C002/C006 - End frame
313 * 0200/4200 - Contains actual image data, bayer or compressed
314 * 0005 - 11 bytes of unknown data
315 * 0100 - 2 bytes of unknown data
316 * The 0005 and 0100 chunks seem to appear only in compressed stream.
317 */
318static void stv06xx_pkt_scan(struct gspca_dev *gspca_dev,
319 struct gspca_frame *frame, /* target */
320 __u8 *data, /* isoc packet */
321 int len) /* iso packet length */
322{
323 PDEBUG(D_PACK, "Packet of length %d arrived", len);
324
325 /* A packet may contain several frames
326 loop until the whole packet is reached */
327 while (len) {
328 int id, chunk_len;
329
330 if (len < 4) {
331 PDEBUG(D_PACK, "Packet is smaller than 4 bytes");
332 return;
333 }
334
335 /* Capture the id */
336 id = (data[0] << 8) | data[1];
337
338 /* Capture the chunk length */
339 chunk_len = (data[2] << 8) | data[3];
340 PDEBUG(D_PACK, "Chunk id: %x, length: %d", id, chunk_len);
341
342 data += 4;
343 len -= 4;
344
345 if (len < chunk_len) {
346 PDEBUG(D_ERR, "URB packet length is smaller"
347 " than the specified chunk length");
348 return;
349 }
350
351 switch (id) {
352 case 0x0200:
353 case 0x4200:
354 PDEBUG(D_PACK, "Frame data packet detected");
355
356 gspca_frame_add(gspca_dev, INTER_PACKET, frame,
357 data, chunk_len);
358 break;
359
360 case 0x8001:
361 case 0x8005:
362 case 0xc001:
363 case 0xc005:
364 PDEBUG(D_PACK, "Starting new frame");
365
366 /* Create a new frame, chunk length should be zero */
367 gspca_frame_add(gspca_dev, FIRST_PACKET,
368 frame, data, 0);
369
370 if (chunk_len)
371 PDEBUG(D_ERR, "Chunk length is "
372 "non-zero on a SOF");
373 break;
374
375 case 0x8002:
376 case 0x8006:
377 case 0xc002:
378 PDEBUG(D_PACK, "End of frame detected");
379
380 /* Complete the last frame (if any) */
381 gspca_frame_add(gspca_dev, LAST_PACKET, frame, data, 0);
382
383 if (chunk_len)
384 PDEBUG(D_ERR, "Chunk length is "
385 "non-zero on a EOF");
386 break;
387
388 case 0x0005:
389 PDEBUG(D_PACK, "Chunk 0x005 detected");
390 /* Unknown chunk with 11 bytes of data,
391 occurs just before end of each frame
392 in compressed mode */
393 break;
394
395 case 0x0100:
396 PDEBUG(D_PACK, "Chunk 0x0100 detected");
397 /* Unknown chunk with 2 bytes of data,
398 occurs 2-3 times per USB interrupt */
399 break;
400 default:
401 PDEBUG(D_PACK, "Unknown chunk %d detected", id);
402 /* Unknown chunk */
403 }
404 data += chunk_len;
405 len -= chunk_len;
406 }
407}
408
409static int stv06xx_config(struct gspca_dev *gspca_dev,
410 const struct usb_device_id *id);
411
412/* sub-driver description */
413static const struct sd_desc sd_desc = {
414 .name = MODULE_NAME,
415 .config = stv06xx_config,
416 .init = stv06xx_init,
417 .start = stv06xx_start,
418 .stopN = stv06xx_stopN,
419 .pkt_scan = stv06xx_pkt_scan
420};
421
422/* This function is called at probe time */
423static int stv06xx_config(struct gspca_dev *gspca_dev,
424 const struct usb_device_id *id)
425{
426 struct sd *sd = (struct sd *) gspca_dev;
427 struct cam *cam;
428
429 PDEBUG(D_PROBE, "Configuring camera");
430
431 cam = &gspca_dev->cam;
432 cam->epaddr = STV_ISOC_ENDPOINT_ADDR;
433 sd->desc = sd_desc;
434 gspca_dev->sd_desc = &sd->desc;
435
436 if (dump_bridge)
437 stv06xx_dump_bridge(sd);
438
439 sd->sensor = &stv06xx_sensor_vv6410;
440 if (!sd->sensor->probe(sd))
441 return 0;
442
443 sd->sensor = &stv06xx_sensor_hdcs1x00;
444 if (!sd->sensor->probe(sd))
445 return 0;
446
447 sd->sensor = &stv06xx_sensor_hdcs1020;
448 if (!sd->sensor->probe(sd))
449 return 0;
450
451 sd->sensor = &stv06xx_sensor_pb0100;
452 if (!sd->sensor->probe(sd))
453 return 0;
454
455 sd->sensor = NULL;
456 return -ENODEV;
457}
458
459
460
461/* -- module initialisation -- */
462static const __devinitdata struct usb_device_id device_table[] = {
463 {USB_DEVICE(0x046d, 0x0840)}, /* QuickCam Express */
464 {USB_DEVICE(0x046d, 0x0850)}, /* LEGO cam / QuickCam Web */
465 {USB_DEVICE(0x046d, 0x0870)}, /* Dexxa WebCam USB */
466 {}
467};
468MODULE_DEVICE_TABLE(usb, device_table);
469
470/* -- device connect -- */
471static int sd_probe(struct usb_interface *intf,
472 const struct usb_device_id *id)
473{
474 PDEBUG(D_PROBE, "Probing for a stv06xx device");
475 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
476 THIS_MODULE);
477}
478
479static void sd_disconnect(struct usb_interface *intf)
480{
481 struct gspca_dev *gspca_dev = usb_get_intfdata(intf);
482 struct sd *sd = (struct sd *) gspca_dev;
483 PDEBUG(D_PROBE, "Disconnecting the stv06xx device");
484
485 if (sd->sensor->disconnect)
486 sd->sensor->disconnect(sd);
487 gspca_disconnect(intf);
488}
489
490static struct usb_driver sd_driver = {
491 .name = MODULE_NAME,
492 .id_table = device_table,
493 .probe = sd_probe,
494 .disconnect = sd_disconnect,
495#ifdef CONFIG_PM
496 .suspend = gspca_suspend,
497 .resume = gspca_resume,
498#endif
499};
500
501/* -- module insert / remove -- */
502static int __init sd_mod_init(void)
503{
504 if (usb_register(&sd_driver) < 0)
505 return -1;
506 PDEBUG(D_PROBE, "registered");
507 return 0;
508}
509static void __exit sd_mod_exit(void)
510{
511 usb_deregister(&sd_driver);
512 PDEBUG(D_PROBE, "deregistered");
513}
514
515module_init(sd_mod_init);
516module_exit(sd_mod_exit);
517
518module_param(dump_bridge, bool, S_IRUGO | S_IWUSR);
519MODULE_PARM_DESC(dump_bridge, "Dumps all usb bridge registers at startup");
520
521module_param(dump_sensor, bool, S_IRUGO | S_IWUSR);
522MODULE_PARM_DESC(dump_sensor, "Dumps all sensor registers at startup");
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx.h b/drivers/media/video/gspca/stv06xx/stv06xx.h
new file mode 100644
index 000000000000..1207e7d17f14
--- /dev/null
+++ b/drivers/media/video/gspca/stv06xx/stv06xx.h
@@ -0,0 +1,107 @@
1/*
2 * Copyright (c) 2001 Jean-Fredric Clere, Nikolas Zimmermann, Georg Acher
3 * Mark Cave-Ayland, Carlo E Prelz, Dick Streefland
4 * Copyright (c) 2002, 2003 Tuukka Toivonen
5 * Copyright (c) 2008 Erik Andrén
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 *
21 * P/N 861037: Sensor HDCS1000 ASIC STV0600
22 * P/N 861050-0010: Sensor HDCS1000 ASIC STV0600
23 * P/N 861050-0020: Sensor Photobit PB100 ASIC STV0600-1 - QuickCam Express
24 * P/N 861055: Sensor ST VV6410 ASIC STV0610 - LEGO cam
25 * P/N 861075-0040: Sensor HDCS1000 ASIC
26 * P/N 961179-0700: Sensor ST VV6410 ASIC STV0602 - Dexxa WebCam USB
27 * P/N 861040-0000: Sensor ST VV6410 ASIC STV0610 - QuickCam Web
28 */
29
30#ifndef STV06XX_H_
31#define STV06XX_H_
32
33#include "gspca.h"
34
35#define MODULE_NAME "STV06xx"
36
37#define STV_ISOC_ENDPOINT_ADDR 0x81
38
39#ifndef V4L2_PIX_FMT_SGRBG8
40#define V4L2_PIX_FMT_SGRBG8 v4l2_fourcc('G', 'R', 'B', 'G')
41#endif
42
43#define STV_REG23 0x0423
44
45/* Control registers of the STV0600 ASIC */
46#define STV_I2C_PARTNER 0x1420
47#define STV_I2C_VAL_REG_VAL_PAIRS_MIN1 0x1421
48#define STV_I2C_READ_WRITE_TOGGLE 0x1422
49#define STV_I2C_FLUSH 0x1423
50#define STV_I2C_SUCC_READ_REG_VALS 0x1424
51
52#define STV_ISO_ENABLE 0x1440
53#define STV_SCAN_RATE 0x1443
54#define STV_LED_CTRL 0x1445
55#define STV_STV0600_EMULATION 0x1446
56#define STV_REG00 0x1500
57#define STV_REG01 0x1501
58#define STV_REG02 0x1502
59#define STV_REG03 0x1503
60#define STV_REG04 0x1504
61
62#define STV_ISO_SIZE_L 0x15c1
63#define STV_ISO_SIZE_H 0x15c2
64
65/* Refers to the CIF 352x288 and QCIF 176x144 */
66/* 1: 288 lines, 2: 144 lines */
67#define STV_Y_CTRL 0x15c3
68
69/* 0xa: 352 columns, 0x6: 176 columns */
70#define STV_X_CTRL 0x1680
71
72#define STV06XX_URB_MSG_TIMEOUT 5000
73
74#define I2C_MAX_BYTES 16
75#define I2C_MAX_WORDS 8
76
77#define I2C_BUFFER_LENGTH 0x23
78#define I2C_READ_CMD 3
79#define I2C_WRITE_CMD 1
80
81#define LED_ON 1
82#define LED_OFF 0
83
84/* STV06xx device descriptor */
85struct sd {
86 struct gspca_dev gspca_dev;
87
88 /* A pointer to the currently connected sensor */
89 const struct stv06xx_sensor *sensor;
90
91 /* A pointer to the sd_desc struct */
92 struct sd_desc desc;
93
94 /* Sensor private data */
95 void *sensor_priv;
96};
97
98int stv06xx_write_bridge(struct sd *sd, u16 address, u16 i2c_data);
99int stv06xx_read_bridge(struct sd *sd, u16 address, u8 *i2c_data);
100
101int stv06xx_write_sensor_bytes(struct sd *sd, const u8 *data, u8 len);
102int stv06xx_write_sensor_words(struct sd *sd, const u16 *data, u8 len);
103
104int stv06xx_read_sensor(struct sd *sd, const u8 address, u16 *value);
105int stv06xx_write_sensor(struct sd *sd, u8 address, u16 value);
106
107#endif
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c b/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c
new file mode 100644
index 000000000000..14335a9e4bb5
--- /dev/null
+++ b/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c
@@ -0,0 +1,535 @@
1/*
2 * Copyright (c) 2001 Jean-Fredric Clere, Nikolas Zimmermann, Georg Acher
3 * Mark Cave-Ayland, Carlo E Prelz, Dick Streefland
4 * Copyright (c) 2002, 2003 Tuukka Toivonen
5 * Copyright (c) 2008 Erik Andrén
6 * Copyright (c) 2008 Chia-I Wu
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 *
22 * P/N 861037: Sensor HDCS1000 ASIC STV0600
23 * P/N 861050-0010: Sensor HDCS1000 ASIC STV0600
24 * P/N 861050-0020: Sensor Photobit PB100 ASIC STV0600-1 - QuickCam Express
25 * P/N 861055: Sensor ST VV6410 ASIC STV0610 - LEGO cam
26 * P/N 861075-0040: Sensor HDCS1000 ASIC
27 * P/N 961179-0700: Sensor ST VV6410 ASIC STV0602 - Dexxa WebCam USB
28 * P/N 861040-0000: Sensor ST VV6410 ASIC STV0610 - QuickCam Web
29 */
30
31#include "stv06xx_hdcs.h"
32
33enum hdcs_power_state {
34 HDCS_STATE_SLEEP,
35 HDCS_STATE_IDLE,
36 HDCS_STATE_RUN
37};
38
39/* no lock? */
40struct hdcs {
41 enum hdcs_power_state state;
42 int w, h;
43
44 /* visible area of the sensor array */
45 struct {
46 int left, top;
47 int width, height;
48 int border;
49 } array;
50
51 struct {
52 /* Column timing overhead */
53 u8 cto;
54 /* Column processing overhead */
55 u8 cpo;
56 /* Row sample period constant */
57 u16 rs;
58 /* Exposure reset duration */
59 u16 er;
60 } exp;
61
62 int psmp;
63};
64
65static int hdcs_reg_write_seq(struct sd *sd, u8 reg, u8 *vals, u8 len)
66{
67 u8 regs[I2C_MAX_BYTES * 2];
68 int i;
69
70 if (unlikely((len <= 0) || (len >= I2C_MAX_BYTES) ||
71 (reg + len > 0xff)))
72 return -EINVAL;
73
74 for (i = 0; i < len; i++, reg++) {
75 regs[2*i] = reg;
76 regs[2*i+1] = vals[i];
77 }
78
79 return stv06xx_write_sensor_bytes(sd, regs, len);
80}
81
82static int hdcs_set_state(struct sd *sd, enum hdcs_power_state state)
83{
84 struct hdcs *hdcs = sd->sensor_priv;
85 u8 val;
86 int ret;
87
88 if (hdcs->state == state)
89 return 0;
90
91 /* we need to go idle before running or sleeping */
92 if (hdcs->state != HDCS_STATE_IDLE) {
93 ret = stv06xx_write_sensor(sd, HDCS_REG_CONTROL(sd), 0);
94 if (ret)
95 return ret;
96 }
97
98 hdcs->state = HDCS_STATE_IDLE;
99
100 if (state == HDCS_STATE_IDLE)
101 return 0;
102
103 switch (state) {
104 case HDCS_STATE_SLEEP:
105 val = HDCS_SLEEP_MODE;
106 break;
107
108 case HDCS_STATE_RUN:
109 val = HDCS_RUN_ENABLE;
110 break;
111
112 default:
113 return -EINVAL;
114 }
115
116 ret = stv06xx_write_sensor(sd, HDCS_REG_CONTROL(sd), val);
117 if (ret < 0)
118 hdcs->state = state;
119
120 return ret;
121}
122
123static int hdcs_reset(struct sd *sd)
124{
125 struct hdcs *hdcs = sd->sensor_priv;
126 int err;
127
128 err = stv06xx_write_sensor(sd, HDCS_REG_CONTROL(sd), 1);
129 if (err < 0)
130 return err;
131
132 err = stv06xx_write_sensor(sd, HDCS_REG_CONTROL(sd), 0);
133 if (err < 0)
134 hdcs->state = HDCS_STATE_IDLE;
135
136 return err;
137}
138
139static int hdcs_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
140{
141 struct sd *sd = (struct sd *) gspca_dev;
142 struct hdcs *hdcs = sd->sensor_priv;
143
144 /* Column time period */
145 int ct;
146 /* Column processing period */
147 int cp;
148 /* Row processing period */
149 int rp;
150 int cycles;
151 int err;
152 int rowexp;
153 u16 data[2];
154
155 err = stv06xx_read_sensor(sd, HDCS_ROWEXPL, &data[0]);
156 if (err < 0)
157 return err;
158
159 err = stv06xx_read_sensor(sd, HDCS_ROWEXPH, &data[1]);
160 if (err < 0)
161 return err;
162
163 rowexp = (data[1] << 8) | data[0];
164
165 ct = hdcs->exp.cto + hdcs->psmp + (HDCS_ADC_START_SIG_DUR + 2);
166 cp = hdcs->exp.cto + (hdcs->w * ct / 2);
167 rp = hdcs->exp.rs + cp;
168
169 cycles = rp * rowexp;
170 *val = cycles / HDCS_CLK_FREQ_MHZ;
171 PDEBUG(D_V4L2, "Read exposure %d", *val);
172 return 0;
173}
174
175static int hdcs_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
176{
177 struct sd *sd = (struct sd *) gspca_dev;
178 struct hdcs *hdcs = sd->sensor_priv;
179 int rowexp, srowexp;
180 int max_srowexp;
181 /* Column time period */
182 int ct;
183 /* Column processing period */
184 int cp;
185 /* Row processing period */
186 int rp;
187 /* Minimum number of column timing periods
188 within the column processing period */
189 int mnct;
190 int cycles, err;
191 u8 exp[4];
192
193 cycles = val * HDCS_CLK_FREQ_MHZ;
194
195 ct = hdcs->exp.cto + hdcs->psmp + (HDCS_ADC_START_SIG_DUR + 2);
196 cp = hdcs->exp.cto + (hdcs->w * ct / 2);
197
198 /* the cycles one row takes */
199 rp = hdcs->exp.rs + cp;
200
201 rowexp = cycles / rp;
202
203 /* the remaining cycles */
204 cycles -= rowexp * rp;
205
206 /* calculate sub-row exposure */
207 if (IS_1020(sd)) {
208 /* see HDCS-1020 datasheet 3.5.6.4, p. 63 */
209 srowexp = hdcs->w - (cycles + hdcs->exp.er + 13) / ct;
210
211 mnct = (hdcs->exp.er + 12 + ct - 1) / ct;
212 max_srowexp = hdcs->w - mnct;
213 } else {
214 /* see HDCS-1000 datasheet 3.4.5.5, p. 61 */
215 srowexp = cp - hdcs->exp.er - 6 - cycles;
216
217 mnct = (hdcs->exp.er + 5 + ct - 1) / ct;
218 max_srowexp = cp - mnct * ct - 1;
219 }
220
221 if (srowexp < 0)
222 srowexp = 0;
223 else if (srowexp > max_srowexp)
224 srowexp = max_srowexp;
225
226 if (IS_1020(sd)) {
227 exp[0] = rowexp & 0xff;
228 exp[1] = rowexp >> 8;
229 exp[2] = (srowexp >> 2) & 0xff;
230 /* this clears exposure error flag */
231 exp[3] = 0x1;
232 err = hdcs_reg_write_seq(sd, HDCS_ROWEXPL, exp, 4);
233 } else {
234 exp[0] = rowexp & 0xff;
235 exp[1] = rowexp >> 8;
236 exp[2] = srowexp & 0xff;
237 exp[3] = srowexp >> 8;
238 err = hdcs_reg_write_seq(sd, HDCS_ROWEXPL, exp, 4);
239 if (err < 0)
240 return err;
241
242 /* clear exposure error flag */
243 err = stv06xx_write_sensor(sd,
244 HDCS_STATUS, BIT(4));
245 }
246 PDEBUG(D_V4L2, "Writing exposure %d, rowexp %d, srowexp %d",
247 val, rowexp, srowexp);
248 return err;
249}
250
251static int hdcs_set_gains(struct sd *sd, u8 r, u8 g, u8 b)
252{
253 u8 gains[4];
254
255 /* the voltage gain Av = (1 + 19 * val / 127) * (1 + bit7) */
256 if (r > 127)
257 r = 0x80 | (r / 2);
258 if (g > 127)
259 g = 0x80 | (g / 2);
260 if (b > 127)
261 b = 0x80 | (b / 2);
262
263 gains[0] = g;
264 gains[1] = r;
265 gains[2] = b;
266 gains[3] = g;
267
268 return hdcs_reg_write_seq(sd, HDCS_ERECPGA, gains, 4);
269}
270
271static int hdcs_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
272{
273 struct sd *sd = (struct sd *) gspca_dev;
274 int err;
275 u16 data;
276
277 err = stv06xx_read_sensor(sd, HDCS_ERECPGA, &data);
278
279 /* Bit 7 doubles the gain */
280 if (data & 0x80)
281 *val = (data & 0x7f) * 2;
282 else
283 *val = data;
284
285 PDEBUG(D_V4L2, "Read gain %d", *val);
286 return err;
287}
288
289static int hdcs_set_gain(struct gspca_dev *gspca_dev, __s32 val)
290{
291 PDEBUG(D_V4L2, "Writing gain %d", val);
292 return hdcs_set_gains((struct sd *) gspca_dev,
293 val & 0xff, val & 0xff, val & 0xff);
294}
295
296static int hdcs_set_size(struct sd *sd,
297 unsigned int width, unsigned int height)
298{
299 struct hdcs *hdcs = sd->sensor_priv;
300 u8 win[4];
301 unsigned int x, y;
302 int err;
303
304 /* must be multiple of 4 */
305 width = (width + 3) & ~0x3;
306 height = (height + 3) & ~0x3;
307
308 if (width > hdcs->array.width)
309 width = hdcs->array.width;
310
311 if (IS_1020(sd)) {
312 /* the borders are also invalid */
313 if (height + 2 * hdcs->array.border + HDCS_1020_BOTTOM_Y_SKIP
314 > hdcs->array.height)
315 height = hdcs->array.height - 2 * hdcs->array.border -
316 HDCS_1020_BOTTOM_Y_SKIP;
317
318 y = (hdcs->array.height - HDCS_1020_BOTTOM_Y_SKIP - height) / 2
319 + hdcs->array.top;
320 } else {
321 if (height > hdcs->array.height)
322 height = hdcs->array.height;
323
324 y = hdcs->array.top + (hdcs->array.height - height) / 2;
325 }
326
327 x = hdcs->array.left + (hdcs->array.width - width) / 2;
328
329 win[0] = y / 4;
330 win[1] = x / 4;
331 win[2] = (y + height) / 4 - 1;
332 win[3] = (x + width) / 4 - 1;
333
334 err = hdcs_reg_write_seq(sd, HDCS_FWROW, win, 4);
335 if (err < 0)
336 return err;
337
338 /* Update the current width and height */
339 hdcs->w = width;
340 hdcs->h = height;
341 return err;
342}
343
344static int hdcs_probe_1x00(struct sd *sd)
345{
346 struct hdcs *hdcs;
347 u16 sensor;
348 int ret;
349
350 ret = stv06xx_read_sensor(sd, HDCS_IDENT, &sensor);
351 if (ret < 0 || sensor != 0x08)
352 return -ENODEV;
353
354 info("HDCS-1000/1100 sensor detected");
355
356 sd->gspca_dev.cam.cam_mode = stv06xx_sensor_hdcs1x00.modes;
357 sd->gspca_dev.cam.nmodes = stv06xx_sensor_hdcs1x00.nmodes;
358 sd->desc.ctrls = stv06xx_sensor_hdcs1x00.ctrls;
359 sd->desc.nctrls = stv06xx_sensor_hdcs1x00.nctrls;
360
361 hdcs = kmalloc(sizeof(struct hdcs), GFP_KERNEL);
362 if (!hdcs)
363 return -ENOMEM;
364
365 hdcs->array.left = 8;
366 hdcs->array.top = 8;
367 hdcs->array.width = HDCS_1X00_DEF_WIDTH;
368 hdcs->array.height = HDCS_1X00_DEF_HEIGHT;
369 hdcs->array.border = 4;
370
371 hdcs->exp.cto = 4;
372 hdcs->exp.cpo = 2;
373 hdcs->exp.rs = 186;
374 hdcs->exp.er = 100;
375
376 /*
377 * Frame rate on HDCS-1000 0x46D:0x840 depends on PSMP:
378 * 4 = doesn't work at all
379 * 5 = 7.8 fps,
380 * 6 = 6.9 fps,
381 * 8 = 6.3 fps,
382 * 10 = 5.5 fps,
383 * 15 = 4.4 fps,
384 * 31 = 2.8 fps
385 *
386 * Frame rate on HDCS-1000 0x46D:0x870 depends on PSMP:
387 * 15 = doesn't work at all
388 * 18 = doesn't work at all
389 * 19 = 7.3 fps
390 * 20 = 7.4 fps
391 * 21 = 7.4 fps
392 * 22 = 7.4 fps
393 * 24 = 6.3 fps
394 * 30 = 5.4 fps
395 */
396 hdcs->psmp = IS_870(sd) ? 20 : 5;
397
398 sd->sensor_priv = hdcs;
399
400 return 0;
401}
402
403static int hdcs_probe_1020(struct sd *sd)
404{
405 struct hdcs *hdcs;
406 u16 sensor;
407 int ret;
408
409 ret = stv06xx_read_sensor(sd, HDCS_IDENT, &sensor);
410 if (ret < 0 || sensor != 0x10)
411 return -ENODEV;
412
413 info("HDCS-1020 sensor detected");
414
415 sd->gspca_dev.cam.cam_mode = stv06xx_sensor_hdcs1020.modes;
416 sd->gspca_dev.cam.nmodes = stv06xx_sensor_hdcs1020.nmodes;
417 sd->desc.ctrls = stv06xx_sensor_hdcs1020.ctrls;
418 sd->desc.nctrls = stv06xx_sensor_hdcs1020.nctrls;
419
420 hdcs = kmalloc(sizeof(struct hdcs), GFP_KERNEL);
421 if (!hdcs)
422 return -ENOMEM;
423
424 /*
425 * From Andrey's test image: looks like HDCS-1020 upper-left
426 * visible pixel is at 24,8 (y maybe even smaller?) and lower-right
427 * visible pixel at 375,299 (x maybe even larger?)
428 */
429 hdcs->array.left = 24;
430 hdcs->array.top = 4;
431 hdcs->array.width = HDCS_1020_DEF_WIDTH;
432 hdcs->array.height = 304;
433 hdcs->array.border = 4;
434
435 hdcs->psmp = 6;
436
437 hdcs->exp.cto = 3;
438 hdcs->exp.cpo = 3;
439 hdcs->exp.rs = 155;
440 hdcs->exp.er = 96;
441
442 sd->sensor_priv = hdcs;
443
444 return 0;
445}
446
447static int hdcs_start(struct sd *sd)
448{
449 PDEBUG(D_STREAM, "Starting stream");
450
451 return hdcs_set_state(sd, HDCS_STATE_RUN);
452}
453
454static int hdcs_stop(struct sd *sd)
455{
456 PDEBUG(D_STREAM, "Halting stream");
457
458 return hdcs_set_state(sd, HDCS_STATE_SLEEP);
459}
460
461static void hdcs_disconnect(struct sd *sd)
462{
463 PDEBUG(D_PROBE, "Disconnecting the sensor");
464 kfree(sd->sensor_priv);
465}
466
467static int hdcs_init(struct sd *sd)
468{
469 struct hdcs *hdcs = sd->sensor_priv;
470 int i, err = 0;
471
472 /* Set the STV0602AA in STV0600 emulation mode */
473 if (IS_870(sd))
474 stv06xx_write_bridge(sd, STV_STV0600_EMULATION, 1);
475
476 /* Execute the bridge init */
477 for (i = 0; i < ARRAY_SIZE(stv_bridge_init) && !err; i++) {
478 err = stv06xx_write_bridge(sd, stv_bridge_init[i][0],
479 stv_bridge_init[i][1]);
480 }
481 if (err < 0)
482 return err;
483
484 /* sensor soft reset */
485 hdcs_reset(sd);
486
487 /* Execute the sensor init */
488 for (i = 0; i < ARRAY_SIZE(stv_sensor_init) && !err; i++) {
489 err = stv06xx_write_sensor(sd, stv_sensor_init[i][0],
490 stv_sensor_init[i][1]);
491 }
492 if (err < 0)
493 return err;
494
495 /* Enable continous frame capture, bit 2: stop when frame complete */
496 err = stv06xx_write_sensor(sd, HDCS_REG_CONFIG(sd), BIT(3));
497 if (err < 0)
498 return err;
499
500 /* Set PGA sample duration
501 (was 0x7E for IS_870, but caused slow framerate with HDCS-1020) */
502 if (IS_1020(sd))
503 err = stv06xx_write_sensor(sd, HDCS_TCTRL,
504 (HDCS_ADC_START_SIG_DUR << 6) | hdcs->psmp);
505 else
506 err = stv06xx_write_sensor(sd, HDCS_TCTRL,
507 (HDCS_ADC_START_SIG_DUR << 5) | hdcs->psmp);
508 if (err < 0)
509 return err;
510
511 err = hdcs_set_gains(sd, HDCS_DEFAULT_GAIN, HDCS_DEFAULT_GAIN,
512 HDCS_DEFAULT_GAIN);
513 if (err < 0)
514 return err;
515
516 err = hdcs_set_exposure(&sd->gspca_dev, HDCS_DEFAULT_EXPOSURE);
517 if (err < 0)
518 return err;
519
520 err = hdcs_set_size(sd, hdcs->array.width, hdcs->array.height);
521 return err;
522}
523
524static int hdcs_dump(struct sd *sd)
525{
526 u16 reg, val;
527
528 info("Dumping sensor registers:");
529
530 for (reg = HDCS_IDENT; reg <= HDCS_ROWEXPH; reg++) {
531 stv06xx_read_sensor(sd, reg, &val);
532 info("reg 0x%02x = 0x%02x", reg, val);
533 }
534 return 0;
535}
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.h b/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.h
new file mode 100644
index 000000000000..9c7279a4cd88
--- /dev/null
+++ b/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.h
@@ -0,0 +1,263 @@
1/*
2 * Copyright (c) 2001 Jean-Fredric Clere, Nikolas Zimmermann, Georg Acher
3 * Mark Cave-Ayland, Carlo E Prelz, Dick Streefland
4 * Copyright (c) 2002, 2003 Tuukka Toivonen
5 * Copyright (c) 2008 Erik Andrén
6 * Copyright (c) 2008 Chia-I Wu
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 *
22 * P/N 861037: Sensor HDCS1000 ASIC STV0600
23 * P/N 861050-0010: Sensor HDCS1000 ASIC STV0600
24 * P/N 861050-0020: Sensor Photobit PB100 ASIC STV0600-1 - QuickCam Express
25 * P/N 861055: Sensor ST VV6410 ASIC STV0610 - LEGO cam
26 * P/N 861075-0040: Sensor HDCS1000 ASIC
27 * P/N 961179-0700: Sensor ST VV6410 ASIC STV0602 - Dexxa WebCam USB
28 * P/N 861040-0000: Sensor ST VV6410 ASIC STV0610 - QuickCam Web
29 */
30
31#ifndef STV06XX_HDCS_H_
32#define STV06XX_HDCS_H_
33
34#include "stv06xx_sensor.h"
35
36#define HDCS_REG_CONFIG(sd) (IS_1020(sd) ? HDCS20_CONFIG : HDCS00_CONFIG)
37#define HDCS_REG_CONTROL(sd) (IS_1020(sd) ? HDCS20_CONTROL : HDCS00_CONTROL)
38
39#define HDCS_1X00_DEF_WIDTH 360
40#define HDCS_1X00_DEF_HEIGHT 296
41
42#define HDCS_1020_DEF_WIDTH 352
43#define HDCS_1020_DEF_HEIGHT 292
44
45#define HDCS_1020_BOTTOM_Y_SKIP 4
46
47#define HDCS_CLK_FREQ_MHZ 25
48
49#define HDCS_ADC_START_SIG_DUR 3
50
51/* LSB bit of I2C or register address signifies write (0) or read (1) */
52/* I2C Registers common for both HDCS-1000/1100 and HDCS-1020 */
53/* Identifications Register */
54#define HDCS_IDENT (0x00 << 1)
55/* Status Register */
56#define HDCS_STATUS (0x01 << 1)
57/* Interrupt Mask Register */
58#define HDCS_IMASK (0x02 << 1)
59/* Pad Control Register */
60#define HDCS_PCTRL (0x03 << 1)
61/* Pad Drive Control Register */
62#define HDCS_PDRV (0x04 << 1)
63/* Interface Control Register */
64#define HDCS_ICTRL (0x05 << 1)
65/* Interface Timing Register */
66#define HDCS_ITMG (0x06 << 1)
67/* Baud Fraction Register */
68#define HDCS_BFRAC (0x07 << 1)
69/* Baud Rate Register */
70#define HDCS_BRATE (0x08 << 1)
71/* ADC Control Register */
72#define HDCS_ADCCTRL (0x09 << 1)
73/* First Window Row Register */
74#define HDCS_FWROW (0x0a << 1)
75/* First Window Column Register */
76#define HDCS_FWCOL (0x0b << 1)
77/* Last Window Row Register */
78#define HDCS_LWROW (0x0c << 1)
79/* Last Window Column Register */
80#define HDCS_LWCOL (0x0d << 1)
81/* Timing Control Register */
82#define HDCS_TCTRL (0x0e << 1)
83/* PGA Gain Register: Even Row, Even Column */
84#define HDCS_ERECPGA (0x0f << 1)
85/* PGA Gain Register: Even Row, Odd Column */
86#define HDCS_EROCPGA (0x10 << 1)
87/* PGA Gain Register: Odd Row, Even Column */
88#define HDCS_ORECPGA (0x11 << 1)
89/* PGA Gain Register: Odd Row, Odd Column */
90#define HDCS_OROCPGA (0x12 << 1)
91/* Row Exposure Low Register */
92#define HDCS_ROWEXPL (0x13 << 1)
93/* Row Exposure High Register */
94#define HDCS_ROWEXPH (0x14 << 1)
95
96/* I2C Registers only for HDCS-1000/1100 */
97/* Sub-Row Exposure Low Register */
98#define HDCS00_SROWEXPL (0x15 << 1)
99/* Sub-Row Exposure High Register */
100#define HDCS00_SROWEXPH (0x16 << 1)
101/* Configuration Register */
102#define HDCS00_CONFIG (0x17 << 1)
103/* Control Register */
104#define HDCS00_CONTROL (0x18 << 1)
105
106/* I2C Registers only for HDCS-1020 */
107/* Sub-Row Exposure Register */
108#define HDCS20_SROWEXP (0x15 << 1)
109/* Error Control Register */
110#define HDCS20_ERROR (0x16 << 1)
111/* Interface Timing 2 Register */
112#define HDCS20_ITMG2 (0x17 << 1)
113/* Interface Control 2 Register */
114#define HDCS20_ICTRL2 (0x18 << 1)
115/* Horizontal Blank Register */
116#define HDCS20_HBLANK (0x19 << 1)
117/* Vertical Blank Register */
118#define HDCS20_VBLANK (0x1a << 1)
119/* Configuration Register */
120#define HDCS20_CONFIG (0x1b << 1)
121/* Control Register */
122#define HDCS20_CONTROL (0x1c << 1)
123
124#define HDCS_RUN_ENABLE (1 << 2)
125#define HDCS_SLEEP_MODE (1 << 1)
126
127#define HDCS_DEFAULT_EXPOSURE 5000
128#define HDCS_DEFAULT_GAIN 128
129
130static int hdcs_probe_1x00(struct sd *sd);
131static int hdcs_probe_1020(struct sd *sd);
132static int hdcs_start(struct sd *sd);
133static int hdcs_init(struct sd *sd);
134static int hdcs_stop(struct sd *sd);
135static int hdcs_dump(struct sd *sd);
136static void hdcs_disconnect(struct sd *sd);
137
138static int hdcs_get_exposure(struct gspca_dev *gspca_dev, __s32 *val);
139static int hdcs_set_exposure(struct gspca_dev *gspca_dev, __s32 val);
140static int hdcs_set_gain(struct gspca_dev *gspca_dev, __s32 val);
141static int hdcs_get_gain(struct gspca_dev *gspca_dev, __s32 *val);
142
143const struct stv06xx_sensor stv06xx_sensor_hdcs1x00 = {
144 .name = "HP HDCS-1000/1100",
145 .i2c_flush = 0,
146 .i2c_addr = (0x55 << 1),
147 .i2c_len = 1,
148
149 .init = hdcs_init,
150 .probe = hdcs_probe_1x00,
151 .start = hdcs_start,
152 .stop = hdcs_stop,
153 .disconnect = hdcs_disconnect,
154 .dump = hdcs_dump,
155
156 .nctrls = 2,
157 .ctrls = {
158 {
159 {
160 .id = V4L2_CID_EXPOSURE,
161 .type = V4L2_CTRL_TYPE_INTEGER,
162 .name = "exposure",
163 .minimum = 0x00,
164 .maximum = 0xffff,
165 .step = 0x1,
166 .default_value = HDCS_DEFAULT_EXPOSURE,
167 .flags = V4L2_CTRL_FLAG_SLIDER
168 },
169 .set = hdcs_set_exposure,
170 .get = hdcs_get_exposure
171 },
172 {
173 {
174 .id = V4L2_CID_GAIN,
175 .type = V4L2_CTRL_TYPE_INTEGER,
176 .name = "gain",
177 .minimum = 0x00,
178 .maximum = 0xff,
179 .step = 0x1,
180 .default_value = HDCS_DEFAULT_GAIN,
181 .flags = V4L2_CTRL_FLAG_SLIDER
182 },
183 .set = hdcs_set_gain,
184 .get = hdcs_get_gain
185 }
186 },
187
188 .nmodes = 1,
189 .modes = {
190 {
191 HDCS_1X00_DEF_WIDTH,
192 HDCS_1X00_DEF_HEIGHT,
193 V4L2_PIX_FMT_SBGGR8,
194 V4L2_FIELD_NONE,
195 .sizeimage =
196 HDCS_1X00_DEF_WIDTH * HDCS_1X00_DEF_HEIGHT,
197 .bytesperline = HDCS_1X00_DEF_WIDTH,
198 .colorspace = V4L2_COLORSPACE_SRGB,
199 .priv = 1
200 }
201 }
202};
203
204const struct stv06xx_sensor stv06xx_sensor_hdcs1020 = {
205 .name = "HDCS-1020",
206 .i2c_flush = 0,
207 .i2c_addr = (0x55 << 1),
208 .i2c_len = 1,
209
210 .nctrls = 0,
211 .ctrls = {},
212
213 .init = hdcs_init,
214 .probe = hdcs_probe_1020,
215 .start = hdcs_start,
216 .stop = hdcs_stop,
217 .dump = hdcs_dump,
218
219 .nmodes = 1,
220 .modes = {
221 {
222 HDCS_1020_DEF_WIDTH,
223 HDCS_1020_DEF_HEIGHT,
224 V4L2_PIX_FMT_SBGGR8,
225 V4L2_FIELD_NONE,
226 .sizeimage =
227 HDCS_1020_DEF_WIDTH * HDCS_1020_DEF_HEIGHT,
228 .bytesperline = HDCS_1020_DEF_WIDTH,
229 .colorspace = V4L2_COLORSPACE_SRGB,
230 .priv = 1
231 }
232 }
233};
234
235static const u16 stv_bridge_init[][2] = {
236 {STV_ISO_ENABLE, 0},
237 {STV_REG23, 0},
238 {STV_REG00, 0x1d},
239 {STV_REG01, 0xb5},
240 {STV_REG02, 0xa8},
241 {STV_REG03, 0x95},
242 {STV_REG04, 0x07},
243
244 {STV_SCAN_RATE, 0x20},
245 {STV_ISO_SIZE_L, 847},
246 {STV_Y_CTRL, 0x01},
247 {STV_X_CTRL, 0x0a}
248};
249
250static const u8 stv_sensor_init[][2] = {
251 /* Clear status (writing 1 will clear the corresponding status bit) */
252 {HDCS_STATUS, BIT(6) | BIT(5) | BIT(4) | BIT(3) | BIT(2) | BIT(1)},
253 /* Disable all interrupts */
254 {HDCS_IMASK, 0x00},
255 {HDCS_PCTRL, BIT(6) | BIT(5) | BIT(1) | BIT(0)},
256 {HDCS_PDRV, 0x00},
257 {HDCS_ICTRL, BIT(5)},
258 {HDCS_ITMG, BIT(4) | BIT(1)},
259 /* ADC output resolution to 10 bits */
260 {HDCS_ADCCTRL, 10}
261};
262
263#endif
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c b/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c
new file mode 100644
index 000000000000..d0a0f8596454
--- /dev/null
+++ b/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c
@@ -0,0 +1,430 @@
1/*
2 * Copyright (c) 2001 Jean-Fredric Clere, Nikolas Zimmermann, Georg Acher
3 * Mark Cave-Ayland, Carlo E Prelz, Dick Streefland
4 * Copyright (c) 2002, 2003 Tuukka Toivonen
5 * Copyright (c) 2008 Erik Andrén
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 *
21 * P/N 861037: Sensor HDCS1000 ASIC STV0600
22 * P/N 861050-0010: Sensor HDCS1000 ASIC STV0600
23 * P/N 861050-0020: Sensor Photobit PB100 ASIC STV0600-1 - QuickCam Express
24 * P/N 861055: Sensor ST VV6410 ASIC STV0610 - LEGO cam
25 * P/N 861075-0040: Sensor HDCS1000 ASIC
26 * P/N 961179-0700: Sensor ST VV6410 ASIC STV0602 - Dexxa WebCam USB
27 * P/N 861040-0000: Sensor ST VV6410 ASIC STV0610 - QuickCam Web
28 */
29
30/*
31 * The spec file for the PB-0100 suggests the following for best quality
32 * images after the sensor has been reset :
33 *
34 * PB_ADCGAINL = R60 = 0x03 (3 dec) : sets low reference of ADC
35 to produce good black level
36 * PB_PREADCTRL = R32 = 0x1400 (5120 dec) : Enables global gain changes
37 through R53
38 * PB_ADCMINGAIN = R52 = 0x10 (16 dec) : Sets the minimum gain for
39 auto-exposure
40 * PB_ADCGLOBALGAIN = R53 = 0x10 (16 dec) : Sets the global gain
41 * PB_EXPGAIN = R14 = 0x11 (17 dec) : Sets the auto-exposure value
42 * PB_UPDATEINT = R23 = 0x02 (2 dec) : Sets the speed on
43 auto-exposure routine
44 * PB_CFILLIN = R5 = 0x0E (14 dec) : Sets the frame rate
45 */
46
47#include "stv06xx_pb0100.h"
48
49static int pb0100_probe(struct sd *sd)
50{
51 u16 sensor;
52 int i, err;
53 s32 *sensor_settings;
54
55 err = stv06xx_read_sensor(sd, PB_IDENT, &sensor);
56
57 if (err < 0)
58 return -ENODEV;
59
60 if ((sensor >> 8) == 0x64) {
61 sensor_settings = kmalloc(
62 stv06xx_sensor_pb0100.nctrls * sizeof(s32),
63 GFP_KERNEL);
64 if (!sensor_settings)
65 return -ENOMEM;
66
67 info("Photobit pb0100 sensor detected");
68
69 sd->gspca_dev.cam.cam_mode = stv06xx_sensor_pb0100.modes;
70 sd->gspca_dev.cam.nmodes = stv06xx_sensor_pb0100.nmodes;
71 sd->desc.ctrls = stv06xx_sensor_pb0100.ctrls;
72 sd->desc.nctrls = stv06xx_sensor_pb0100.nctrls;
73 for (i = 0; i < stv06xx_sensor_pb0100.nctrls; i++)
74 sensor_settings[i] = stv06xx_sensor_pb0100.
75 ctrls[i].qctrl.default_value;
76 sd->sensor_priv = sensor_settings;
77
78 return 0;
79 }
80
81 return -ENODEV;
82}
83
84static int pb0100_start(struct sd *sd)
85{
86 int err;
87 struct cam *cam = &sd->gspca_dev.cam;
88 s32 *sensor_settings = sd->sensor_priv;
89 u32 mode = cam->cam_mode[sd->gspca_dev.curr_mode].priv;
90
91 /* Setup sensor window */
92 if (mode & PB0100_CROP_TO_VGA) {
93 stv06xx_write_sensor(sd, PB_RSTART, 30);
94 stv06xx_write_sensor(sd, PB_CSTART, 20);
95 stv06xx_write_sensor(sd, PB_RWSIZE, 240 - 1);
96 stv06xx_write_sensor(sd, PB_CWSIZE, 320 - 1);
97 } else {
98 stv06xx_write_sensor(sd, PB_RSTART, 8);
99 stv06xx_write_sensor(sd, PB_CSTART, 4);
100 stv06xx_write_sensor(sd, PB_RWSIZE, 288 - 1);
101 stv06xx_write_sensor(sd, PB_CWSIZE, 352 - 1);
102 }
103
104 if (mode & PB0100_SUBSAMPLE) {
105 stv06xx_write_bridge(sd, STV_Y_CTRL, 0x02); /* Wrong, FIXME */
106 stv06xx_write_bridge(sd, STV_X_CTRL, 0x06);
107
108 stv06xx_write_bridge(sd, STV_SCAN_RATE, 0x10);
109 } else {
110 stv06xx_write_bridge(sd, STV_Y_CTRL, 0x01);
111 stv06xx_write_bridge(sd, STV_X_CTRL, 0x0a);
112 /* larger -> slower */
113 stv06xx_write_bridge(sd, STV_SCAN_RATE, 0x20);
114 }
115
116 /* set_gain also sets red and blue balance */
117 pb0100_set_gain(&sd->gspca_dev, sensor_settings[GAIN_IDX]);
118 pb0100_set_exposure(&sd->gspca_dev, sensor_settings[EXPOSURE_IDX]);
119 pb0100_set_autogain_target(&sd->gspca_dev,
120 sensor_settings[AUTOGAIN_TARGET_IDX]);
121 pb0100_set_autogain(&sd->gspca_dev, sensor_settings[AUTOGAIN_IDX]);
122
123 err = stv06xx_write_sensor(sd, PB_CONTROL, BIT(5)|BIT(3)|BIT(1));
124 PDEBUG(D_STREAM, "Started stream, status: %d", err);
125
126 return (err < 0) ? err : 0;
127}
128
129static int pb0100_stop(struct sd *sd)
130{
131 int err;
132
133 err = stv06xx_write_sensor(sd, PB_ABORTFRAME, 1);
134
135 if (err < 0)
136 goto out;
137
138 /* Set bit 1 to zero */
139 err = stv06xx_write_sensor(sd, PB_CONTROL, BIT(5)|BIT(3));
140
141 PDEBUG(D_STREAM, "Halting stream");
142out:
143 return (err < 0) ? err : 0;
144}
145
146/* FIXME: Sort the init commands out and put them into tables,
147 this is only for getting the camera to work */
148/* FIXME: No error handling for now,
149 add this once the init has been converted to proper tables */
150static int pb0100_init(struct sd *sd)
151{
152 stv06xx_write_bridge(sd, STV_REG00, 1);
153 stv06xx_write_bridge(sd, STV_SCAN_RATE, 0);
154
155 /* Reset sensor */
156 stv06xx_write_sensor(sd, PB_RESET, 1);
157 stv06xx_write_sensor(sd, PB_RESET, 0);
158
159 /* Disable chip */
160 stv06xx_write_sensor(sd, PB_CONTROL, BIT(5)|BIT(3));
161
162 /* Gain stuff...*/
163 stv06xx_write_sensor(sd, PB_PREADCTRL, BIT(12)|BIT(10)|BIT(6));
164 stv06xx_write_sensor(sd, PB_ADCGLOBALGAIN, 12);
165
166 /* Set up auto-exposure */
167 /* ADC VREF_HI new setting for a transition
168 from the Expose1 to the Expose2 setting */
169 stv06xx_write_sensor(sd, PB_R28, 12);
170 /* gain max for autoexposure */
171 stv06xx_write_sensor(sd, PB_ADCMAXGAIN, 180);
172 /* gain min for autoexposure */
173 stv06xx_write_sensor(sd, PB_ADCMINGAIN, 12);
174 /* Maximum frame integration time (programmed into R8)
175 allowed for auto-exposure routine */
176 stv06xx_write_sensor(sd, PB_R54, 3);
177 /* Minimum frame integration time (programmed into R8)
178 allowed for auto-exposure routine */
179 stv06xx_write_sensor(sd, PB_R55, 0);
180 stv06xx_write_sensor(sd, PB_UPDATEINT, 1);
181 /* R15 Expose0 (maximum that auto-exposure may use) */
182 stv06xx_write_sensor(sd, PB_R15, 800);
183 /* R17 Expose2 (minimum that auto-exposure may use) */
184 stv06xx_write_sensor(sd, PB_R17, 10);
185
186 stv06xx_write_sensor(sd, PB_EXPGAIN, 0);
187
188 /* 0x14 */
189 stv06xx_write_sensor(sd, PB_VOFFSET, 0);
190 /* 0x0D */
191 stv06xx_write_sensor(sd, PB_ADCGAINH, 11);
192 /* Set black level (important!) */
193 stv06xx_write_sensor(sd, PB_ADCGAINL, 0);
194
195 /* ??? */
196 stv06xx_write_bridge(sd, STV_REG00, 0x11);
197 stv06xx_write_bridge(sd, STV_REG03, 0x45);
198 stv06xx_write_bridge(sd, STV_REG04, 0x07);
199
200 /* ISO-Size (0x27b: 635... why? - HDCS uses 847) */
201 stv06xx_write_bridge(sd, STV_ISO_SIZE_L, 847);
202
203 /* Scan/timing for the sensor */
204 stv06xx_write_sensor(sd, PB_ROWSPEED, BIT(4)|BIT(3)|BIT(1));
205 stv06xx_write_sensor(sd, PB_CFILLIN, 14);
206 stv06xx_write_sensor(sd, PB_VBL, 0);
207 stv06xx_write_sensor(sd, PB_FINTTIME, 0);
208 stv06xx_write_sensor(sd, PB_RINTTIME, 123);
209
210 stv06xx_write_bridge(sd, STV_REG01, 0xc2);
211 stv06xx_write_bridge(sd, STV_REG02, 0xb0);
212 return 0;
213}
214
215static int pb0100_dump(struct sd *sd)
216{
217 return 0;
218}
219
220static int pb0100_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
221{
222 struct sd *sd = (struct sd *) gspca_dev;
223 s32 *sensor_settings = sd->sensor_priv;
224
225 *val = sensor_settings[GAIN_IDX];
226
227 return 0;
228}
229
230static int pb0100_set_gain(struct gspca_dev *gspca_dev, __s32 val)
231{
232 int err;
233 struct sd *sd = (struct sd *) gspca_dev;
234 s32 *sensor_settings = sd->sensor_priv;
235
236 if (sensor_settings[AUTOGAIN_IDX])
237 return -EBUSY;
238
239 sensor_settings[GAIN_IDX] = val;
240 err = stv06xx_write_sensor(sd, PB_G1GAIN, val);
241 if (!err)
242 err = stv06xx_write_sensor(sd, PB_G2GAIN, val);
243 PDEBUG(D_V4L2, "Set green gain to %d, status: %d", val, err);
244
245 if (!err)
246 err = pb0100_set_red_balance(gspca_dev,
247 sensor_settings[RED_BALANCE_IDX]);
248 if (!err)
249 err = pb0100_set_blue_balance(gspca_dev,
250 sensor_settings[BLUE_BALANCE_IDX]);
251
252 return err;
253}
254
255static int pb0100_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val)
256{
257 struct sd *sd = (struct sd *) gspca_dev;
258 s32 *sensor_settings = sd->sensor_priv;
259
260 *val = sensor_settings[RED_BALANCE_IDX];
261
262 return 0;
263}
264
265static int pb0100_set_red_balance(struct gspca_dev *gspca_dev, __s32 val)
266{
267 int err;
268 struct sd *sd = (struct sd *) gspca_dev;
269 s32 *sensor_settings = sd->sensor_priv;
270
271 if (sensor_settings[AUTOGAIN_IDX])
272 return -EBUSY;
273
274 sensor_settings[RED_BALANCE_IDX] = val;
275 val += sensor_settings[GAIN_IDX];
276 if (val < 0)
277 val = 0;
278 else if (val > 255)
279 val = 255;
280
281 err = stv06xx_write_sensor(sd, PB_RGAIN, val);
282 PDEBUG(D_V4L2, "Set red gain to %d, status: %d", val, err);
283
284 return err;
285}
286
287static int pb0100_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val)
288{
289 struct sd *sd = (struct sd *) gspca_dev;
290 s32 *sensor_settings = sd->sensor_priv;
291
292 *val = sensor_settings[BLUE_BALANCE_IDX];
293
294 return 0;
295}
296
297static int pb0100_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val)
298{
299 int err;
300 struct sd *sd = (struct sd *) gspca_dev;
301 s32 *sensor_settings = sd->sensor_priv;
302
303 if (sensor_settings[AUTOGAIN_IDX])
304 return -EBUSY;
305
306 sensor_settings[BLUE_BALANCE_IDX] = val;
307 val += sensor_settings[GAIN_IDX];
308 if (val < 0)
309 val = 0;
310 else if (val > 255)
311 val = 255;
312
313 err = stv06xx_write_sensor(sd, PB_BGAIN, val);
314 PDEBUG(D_V4L2, "Set blue gain to %d, status: %d", val, err);
315
316 return err;
317}
318
319static int pb0100_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
320{
321 struct sd *sd = (struct sd *) gspca_dev;
322 s32 *sensor_settings = sd->sensor_priv;
323
324 *val = sensor_settings[EXPOSURE_IDX];
325
326 return 0;
327}
328
329static int pb0100_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
330{
331 int err;
332 struct sd *sd = (struct sd *) gspca_dev;
333 s32 *sensor_settings = sd->sensor_priv;
334
335 if (sensor_settings[AUTOGAIN_IDX])
336 return -EBUSY;
337
338 sensor_settings[EXPOSURE_IDX] = val;
339 err = stv06xx_write_sensor(sd, PB_RINTTIME, val);
340 PDEBUG(D_V4L2, "Set exposure to %d, status: %d", val, err);
341
342 return err;
343}
344
345static int pb0100_get_autogain(struct gspca_dev *gspca_dev, __s32 *val)
346{
347 struct sd *sd = (struct sd *) gspca_dev;
348 s32 *sensor_settings = sd->sensor_priv;
349
350 *val = sensor_settings[AUTOGAIN_IDX];
351
352 return 0;
353}
354
355static int pb0100_set_autogain(struct gspca_dev *gspca_dev, __s32 val)
356{
357 int err;
358 struct sd *sd = (struct sd *) gspca_dev;
359 s32 *sensor_settings = sd->sensor_priv;
360
361 sensor_settings[AUTOGAIN_IDX] = val;
362 if (sensor_settings[AUTOGAIN_IDX]) {
363 if (sensor_settings[NATURAL_IDX])
364 val = BIT(6)|BIT(4)|BIT(0);
365 else
366 val = BIT(4)|BIT(0);
367 } else
368 val = 0;
369
370 err = stv06xx_write_sensor(sd, PB_EXPGAIN, val);
371 PDEBUG(D_V4L2, "Set autogain to %d (natural: %d), status: %d",
372 sensor_settings[AUTOGAIN_IDX], sensor_settings[NATURAL_IDX],
373 err);
374
375 return err;
376}
377
378static int pb0100_get_autogain_target(struct gspca_dev *gspca_dev, __s32 *val)
379{
380 struct sd *sd = (struct sd *) gspca_dev;
381 s32 *sensor_settings = sd->sensor_priv;
382
383 *val = sensor_settings[AUTOGAIN_TARGET_IDX];
384
385 return 0;
386}
387
388static int pb0100_set_autogain_target(struct gspca_dev *gspca_dev, __s32 val)
389{
390 int err, totalpixels, brightpixels, darkpixels;
391 struct sd *sd = (struct sd *) gspca_dev;
392 s32 *sensor_settings = sd->sensor_priv;
393
394 sensor_settings[AUTOGAIN_TARGET_IDX] = val;
395
396 /* Number of pixels counted by the sensor when subsampling the pixels.
397 * Slightly larger than the real value to avoid oscillation */
398 totalpixels = gspca_dev->width * gspca_dev->height;
399 totalpixels = totalpixels/(8*8) + totalpixels/(64*64);
400
401 brightpixels = (totalpixels * val) >> 8;
402 darkpixels = totalpixels - brightpixels;
403 err = stv06xx_write_sensor(sd, PB_R21, brightpixels);
404 if (!err)
405 err = stv06xx_write_sensor(sd, PB_R22, darkpixels);
406
407 PDEBUG(D_V4L2, "Set autogain target to %d, status: %d", val, err);
408
409 return err;
410}
411
412static int pb0100_get_natural(struct gspca_dev *gspca_dev, __s32 *val)
413{
414 struct sd *sd = (struct sd *) gspca_dev;
415 s32 *sensor_settings = sd->sensor_priv;
416
417 *val = sensor_settings[NATURAL_IDX];
418
419 return 0;
420}
421
422static int pb0100_set_natural(struct gspca_dev *gspca_dev, __s32 val)
423{
424 struct sd *sd = (struct sd *) gspca_dev;
425 s32 *sensor_settings = sd->sensor_priv;
426
427 sensor_settings[NATURAL_IDX] = val;
428
429 return pb0100_set_autogain(gspca_dev, sensor_settings[AUTOGAIN_IDX]);
430}
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.h b/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.h
new file mode 100644
index 000000000000..5ea21a1154c4
--- /dev/null
+++ b/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.h
@@ -0,0 +1,275 @@
1/*
2 * Copyright (c) 2001 Jean-Fredric Clere, Nikolas Zimmermann, Georg Acher
3 * Mark Cave-Ayland, Carlo E Prelz, Dick Streefland
4 * Copyright (c) 2002, 2003 Tuukka Toivonen
5 * Copyright (c) 2008 Erik Andrén
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 *
21 * P/N 861037: Sensor HDCS1000 ASIC STV0600
22 * P/N 861050-0010: Sensor HDCS1000 ASIC STV0600
23 * P/N 861050-0020: Sensor Photobit PB100 ASIC STV0600-1 - QuickCam Express
24 * P/N 861055: Sensor ST VV6410 ASIC STV0610 - LEGO cam
25 * P/N 861075-0040: Sensor HDCS1000 ASIC
26 * P/N 961179-0700: Sensor ST VV6410 ASIC STV0602 - Dexxa WebCam USB
27 * P/N 861040-0000: Sensor ST VV6410 ASIC STV0610 - QuickCam Web
28 */
29
30#ifndef STV06XX_PB0100_H_
31#define STV06XX_PB0100_H_
32
33#include "stv06xx_sensor.h"
34
35/* mode priv field flags */
36#define PB0100_CROP_TO_VGA 0x01
37#define PB0100_SUBSAMPLE 0x02
38
39/* I2C Registers */
40#define PB_IDENT 0x00 /* Chip Version */
41#define PB_RSTART 0x01 /* Row Window Start */
42#define PB_CSTART 0x02 /* Column Window Start */
43#define PB_RWSIZE 0x03 /* Row Window Size */
44#define PB_CWSIZE 0x04 /* Column Window Size */
45#define PB_CFILLIN 0x05 /* Column Fill-In */
46#define PB_VBL 0x06 /* Vertical Blank Count */
47#define PB_CONTROL 0x07 /* Control Mode */
48#define PB_FINTTIME 0x08 /* Integration Time/Frame Unit Count */
49#define PB_RINTTIME 0x09 /* Integration Time/Row Unit Count */
50#define PB_ROWSPEED 0x0a /* Row Speed Control */
51#define PB_ABORTFRAME 0x0b /* Abort Frame */
52#define PB_R12 0x0c /* Reserved */
53#define PB_RESET 0x0d /* Reset */
54#define PB_EXPGAIN 0x0e /* Exposure Gain Command */
55#define PB_R15 0x0f /* Expose0 */
56#define PB_R16 0x10 /* Expose1 */
57#define PB_R17 0x11 /* Expose2 */
58#define PB_R18 0x12 /* Low0_DAC */
59#define PB_R19 0x13 /* Low1_DAC */
60#define PB_R20 0x14 /* Low2_DAC */
61#define PB_R21 0x15 /* Threshold11 */
62#define PB_R22 0x16 /* Threshold0x */
63#define PB_UPDATEINT 0x17 /* Update Interval */
64#define PB_R24 0x18 /* High_DAC */
65#define PB_R25 0x19 /* Trans0H */
66#define PB_R26 0x1a /* Trans1L */
67#define PB_R27 0x1b /* Trans1H */
68#define PB_R28 0x1c /* Trans2L */
69#define PB_R29 0x1d /* Reserved */
70#define PB_R30 0x1e /* Reserved */
71#define PB_R31 0x1f /* Wait to Read */
72#define PB_PREADCTRL 0x20 /* Pixel Read Control Mode */
73#define PB_R33 0x21 /* IREF_VLN */
74#define PB_R34 0x22 /* IREF_VLP */
75#define PB_R35 0x23 /* IREF_VLN_INTEG */
76#define PB_R36 0x24 /* IREF_MASTER */
77#define PB_R37 0x25 /* IDACP */
78#define PB_R38 0x26 /* IDACN */
79#define PB_R39 0x27 /* DAC_Control_Reg */
80#define PB_R40 0x28 /* VCL */
81#define PB_R41 0x29 /* IREF_VLN_ADCIN */
82#define PB_R42 0x2a /* Reserved */
83#define PB_G1GAIN 0x2b /* Green 1 Gain */
84#define PB_BGAIN 0x2c /* Blue Gain */
85#define PB_RGAIN 0x2d /* Red Gain */
86#define PB_G2GAIN 0x2e /* Green 2 Gain */
87#define PB_R47 0x2f /* Dark Row Address */
88#define PB_R48 0x30 /* Dark Row Options */
89#define PB_R49 0x31 /* Reserved */
90#define PB_R50 0x32 /* Image Test Data */
91#define PB_ADCMAXGAIN 0x33 /* Maximum Gain */
92#define PB_ADCMINGAIN 0x34 /* Minimum Gain */
93#define PB_ADCGLOBALGAIN 0x35 /* Global Gain */
94#define PB_R54 0x36 /* Maximum Frame */
95#define PB_R55 0x37 /* Minimum Frame */
96#define PB_R56 0x38 /* Reserved */
97#define PB_VOFFSET 0x39 /* VOFFSET */
98#define PB_R58 0x3a /* Snap-Shot Sequence Trigger */
99#define PB_ADCGAINH 0x3b /* VREF_HI */
100#define PB_ADCGAINL 0x3c /* VREF_LO */
101#define PB_R61 0x3d /* Reserved */
102#define PB_R62 0x3e /* Reserved */
103#define PB_R63 0x3f /* Reserved */
104#define PB_R64 0x40 /* Red/Blue Gain */
105#define PB_R65 0x41 /* Green 2/Green 1 Gain */
106#define PB_R66 0x42 /* VREF_HI/LO */
107#define PB_R67 0x43 /* Integration Time/Row Unit Count */
108#define PB_R240 0xf0 /* ADC Test */
109#define PB_R241 0xf1 /* Chip Enable */
110#define PB_R242 0xf2 /* Reserved */
111
112static int pb0100_probe(struct sd *sd);
113static int pb0100_start(struct sd *sd);
114static int pb0100_init(struct sd *sd);
115static int pb0100_stop(struct sd *sd);
116static int pb0100_dump(struct sd *sd);
117
118/* V4L2 controls supported by the driver */
119static int pb0100_get_gain(struct gspca_dev *gspca_dev, __s32 *val);
120static int pb0100_set_gain(struct gspca_dev *gspca_dev, __s32 val);
121static int pb0100_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val);
122static int pb0100_set_red_balance(struct gspca_dev *gspca_dev, __s32 val);
123static int pb0100_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val);
124static int pb0100_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val);
125static int pb0100_get_exposure(struct gspca_dev *gspca_dev, __s32 *val);
126static int pb0100_set_exposure(struct gspca_dev *gspca_dev, __s32 val);
127static int pb0100_get_autogain(struct gspca_dev *gspca_dev, __s32 *val);
128static int pb0100_set_autogain(struct gspca_dev *gspca_dev, __s32 val);
129static int pb0100_get_autogain_target(struct gspca_dev *gspca_dev, __s32 *val);
130static int pb0100_set_autogain_target(struct gspca_dev *gspca_dev, __s32 val);
131static int pb0100_get_natural(struct gspca_dev *gspca_dev, __s32 *val);
132static int pb0100_set_natural(struct gspca_dev *gspca_dev, __s32 val);
133
134const struct stv06xx_sensor stv06xx_sensor_pb0100 = {
135 .name = "PB-0100",
136 .i2c_flush = 1,
137 .i2c_addr = 0xba,
138 .i2c_len = 2,
139
140 .nctrls = 7,
141 .ctrls = {
142#define GAIN_IDX 0
143 {
144 {
145 .id = V4L2_CID_GAIN,
146 .type = V4L2_CTRL_TYPE_INTEGER,
147 .name = "Gain",
148 .minimum = 0,
149 .maximum = 255,
150 .step = 1,
151 .default_value = 128
152 },
153 .set = pb0100_set_gain,
154 .get = pb0100_get_gain
155 },
156#define RED_BALANCE_IDX 1
157 {
158 {
159 .id = V4L2_CID_RED_BALANCE,
160 .type = V4L2_CTRL_TYPE_INTEGER,
161 .name = "Red Balance",
162 .minimum = -255,
163 .maximum = 255,
164 .step = 1,
165 .default_value = 0
166 },
167 .set = pb0100_set_red_balance,
168 .get = pb0100_get_red_balance
169 },
170#define BLUE_BALANCE_IDX 2
171 {
172 {
173 .id = V4L2_CID_BLUE_BALANCE,
174 .type = V4L2_CTRL_TYPE_INTEGER,
175 .name = "Blue Balance",
176 .minimum = -255,
177 .maximum = 255,
178 .step = 1,
179 .default_value = 0
180 },
181 .set = pb0100_set_blue_balance,
182 .get = pb0100_get_blue_balance
183 },
184#define EXPOSURE_IDX 3
185 {
186 {
187 .id = V4L2_CID_EXPOSURE,
188 .type = V4L2_CTRL_TYPE_INTEGER,
189 .name = "Exposure",
190 .minimum = 0,
191 .maximum = 511,
192 .step = 1,
193 .default_value = 12
194 },
195 .set = pb0100_set_exposure,
196 .get = pb0100_get_exposure
197 },
198#define AUTOGAIN_IDX 4
199 {
200 {
201 .id = V4L2_CID_AUTOGAIN,
202 .type = V4L2_CTRL_TYPE_BOOLEAN,
203 .name = "Automatic Gain and Exposure",
204 .minimum = 0,
205 .maximum = 1,
206 .step = 1,
207 .default_value = 1
208 },
209 .set = pb0100_set_autogain,
210 .get = pb0100_get_autogain
211 },
212#define AUTOGAIN_TARGET_IDX 5
213 {
214 {
215 .id = V4L2_CTRL_CLASS_USER + 0x1000,
216 .type = V4L2_CTRL_TYPE_INTEGER,
217 .name = "Automatic Gain Target",
218 .minimum = 0,
219 .maximum = 255,
220 .step = 1,
221 .default_value = 128
222 },
223 .set = pb0100_set_autogain_target,
224 .get = pb0100_get_autogain_target
225 },
226#define NATURAL_IDX 6
227 {
228 {
229 .id = V4L2_CTRL_CLASS_USER + 0x1001,
230 .type = V4L2_CTRL_TYPE_BOOLEAN,
231 .name = "Natural Light Source",
232 .minimum = 0,
233 .maximum = 1,
234 .step = 1,
235 .default_value = 1
236 },
237 .set = pb0100_set_natural,
238 .get = pb0100_get_natural
239 },
240 },
241
242 .init = pb0100_init,
243 .probe = pb0100_probe,
244 .start = pb0100_start,
245 .stop = pb0100_stop,
246 .dump = pb0100_dump,
247
248 .nmodes = 2,
249 .modes = {
250/* low res / subsample modes disabled as they are only half res horizontal,
251 halving the vertical resolution does not seem to work */
252 {
253 320,
254 240,
255 V4L2_PIX_FMT_SGRBG8,
256 V4L2_FIELD_NONE,
257 .sizeimage = 320 * 240,
258 .bytesperline = 320,
259 .colorspace = V4L2_COLORSPACE_SRGB,
260 .priv = PB0100_CROP_TO_VGA
261 },
262 {
263 352,
264 288,
265 V4L2_PIX_FMT_SGRBG8,
266 V4L2_FIELD_NONE,
267 .sizeimage = 352 * 288,
268 .bytesperline = 352,
269 .colorspace = V4L2_COLORSPACE_SRGB,
270 .priv = 0
271 },
272 }
273};
274
275#endif
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_sensor.h b/drivers/media/video/gspca/stv06xx/stv06xx_sensor.h
new file mode 100644
index 000000000000..c726dacefa1f
--- /dev/null
+++ b/drivers/media/video/gspca/stv06xx/stv06xx_sensor.h
@@ -0,0 +1,92 @@
1/*
2 * Copyright (c) 2001 Jean-Fredric Clere, Nikolas Zimmermann, Georg Acher
3 * Mark Cave-Ayland, Carlo E Prelz, Dick Streefland
4 * Copyright (c) 2002, 2003 Tuukka Toivonen
5 * Copyright (c) 2008 Erik Andrén
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 *
21 * P/N 861037: Sensor HDCS1000 ASIC STV0600
22 * P/N 861050-0010: Sensor HDCS1000 ASIC STV0600
23 * P/N 861050-0020: Sensor Photobit PB100 ASIC STV0600-1 - QuickCam Express
24 * P/N 861055: Sensor ST VV6410 ASIC STV0610 - LEGO cam
25 * P/N 861075-0040: Sensor HDCS1000 ASIC
26 * P/N 961179-0700: Sensor ST VV6410 ASIC STV0602 - Dexxa WebCam USB
27 * P/N 861040-0000: Sensor ST VV6410 ASIC STV0610 - QuickCam Web
28 */
29
30#ifndef STV06XX_SENSOR_H_
31#define STV06XX_SENSOR_H_
32
33#include "stv06xx.h"
34
35#define IS_850(sd) ((sd)->gspca_dev.dev->descriptor.idProduct == 0x850)
36#define IS_870(sd) ((sd)->gspca_dev.dev->descriptor.idProduct == 0x870)
37#define IS_1020(sd) ((sd)->sensor == &stv06xx_sensor_hdcs1020)
38
39extern const struct stv06xx_sensor stv06xx_sensor_vv6410;
40extern const struct stv06xx_sensor stv06xx_sensor_hdcs1x00;
41extern const struct stv06xx_sensor stv06xx_sensor_hdcs1020;
42extern const struct stv06xx_sensor stv06xx_sensor_pb0100;
43
44#define STV06XX_MAX_CTRLS (V4L2_CID_LASTP1 - V4L2_CID_BASE + 10)
45
46struct stv06xx_sensor {
47 /* Defines the name of a sensor */
48 char name[32];
49
50 /* Sensor i2c address */
51 u8 i2c_addr;
52
53 /* Flush value*/
54 u8 i2c_flush;
55
56 /* length of an i2c word */
57 u8 i2c_len;
58
59 /* Probes if the sensor is connected */
60 int (*probe)(struct sd *sd);
61
62 /* Performs a initialization sequence */
63 int (*init)(struct sd *sd);
64
65 /* Executed at device disconnect */
66 void (*disconnect)(struct sd *sd);
67
68 /* Reads a sensor register */
69 int (*read_sensor)(struct sd *sd, const u8 address,
70 u8 *i2c_data, const u8 len);
71
72 /* Writes to a sensor register */
73 int (*write_sensor)(struct sd *sd, const u8 address,
74 u8 *i2c_data, const u8 len);
75
76 /* Instructs the sensor to start streaming */
77 int (*start)(struct sd *sd);
78
79 /* Instructs the sensor to stop streaming */
80 int (*stop)(struct sd *sd);
81
82 /* Instructs the sensor to dump all its contents */
83 int (*dump)(struct sd *sd);
84
85 int nctrls;
86 struct ctrl ctrls[STV06XX_MAX_CTRLS];
87
88 char nmodes;
89 struct v4l2_pix_format modes[];
90};
91
92#endif
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c b/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c
new file mode 100644
index 000000000000..1ca91f2a6dee
--- /dev/null
+++ b/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c
@@ -0,0 +1,251 @@
1/*
2 * Copyright (c) 2001 Jean-Fredric Clere, Nikolas Zimmermann, Georg Acher
3 * Mark Cave-Ayland, Carlo E Prelz, Dick Streefland
4 * Copyright (c) 2002, 2003 Tuukka Toivonen
5 * Copyright (c) 2008 Erik Andrén
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 *
21 * P/N 861037: Sensor HDCS1000 ASIC STV0600
22 * P/N 861050-0010: Sensor HDCS1000 ASIC STV0600
23 * P/N 861050-0020: Sensor Photobit PB100 ASIC STV0600-1 - QuickCam Express
24 * P/N 861055: Sensor ST VV6410 ASIC STV0610 - LEGO cam
25 * P/N 861075-0040: Sensor HDCS1000 ASIC
26 * P/N 961179-0700: Sensor ST VV6410 ASIC STV0602 - Dexxa WebCam USB
27 * P/N 861040-0000: Sensor ST VV6410 ASIC STV0610 - QuickCam Web
28 */
29
30#include "stv06xx_vv6410.h"
31
32static int vv6410_probe(struct sd *sd)
33{
34 u16 data;
35 int err;
36
37 err = stv06xx_read_sensor(sd, VV6410_DEVICEH, &data);
38
39 if (err < 0)
40 return -ENODEV;
41
42 if (data == 0x19) {
43 info("vv6410 sensor detected");
44
45 sd->gspca_dev.cam.cam_mode = stv06xx_sensor_vv6410.modes;
46 sd->gspca_dev.cam.nmodes = stv06xx_sensor_vv6410.nmodes;
47 sd->desc.ctrls = stv06xx_sensor_vv6410.ctrls;
48 sd->desc.nctrls = stv06xx_sensor_vv6410.nctrls;
49 return 0;
50 }
51
52 return -ENODEV;
53}
54
55static int vv6410_init(struct sd *sd)
56{
57 int err = 0, i;
58
59 for (i = 0; i < ARRAY_SIZE(stv_bridge_init); i++) {
60 /* if NULL then len contains single value */
61 if (stv_bridge_init[i].data == NULL) {
62 err = stv06xx_write_bridge(sd,
63 stv_bridge_init[i].start,
64 stv_bridge_init[i].len);
65 } else {
66 int j;
67 for (j = 0; j < stv_bridge_init[i].len; j++)
68 err = stv06xx_write_bridge(sd,
69 stv_bridge_init[i].start + j,
70 stv_bridge_init[i].data[j]);
71 }
72 }
73
74 if (err < 0)
75 return err;
76
77 err = stv06xx_write_sensor_bytes(sd, (u8 *) vv6410_sensor_init,
78 ARRAY_SIZE(vv6410_sensor_init));
79
80 return (err < 0) ? err : 0;
81}
82
83static int vv6410_start(struct sd *sd)
84{
85 int err;
86 struct cam *cam = &sd->gspca_dev.cam;
87 u32 priv = cam->cam_mode[sd->gspca_dev.curr_mode].priv;
88
89 if (priv & VV6410_CROP_TO_QVGA) {
90 PDEBUG(D_CONF, "Cropping to QVGA");
91 stv06xx_write_sensor(sd, VV6410_XENDH, 320 - 1);
92 stv06xx_write_sensor(sd, VV6410_YENDH, 240 - 1);
93 } else {
94 stv06xx_write_sensor(sd, VV6410_XENDH, 360 - 1);
95 stv06xx_write_sensor(sd, VV6410_YENDH, 294 - 1);
96 }
97
98 if (priv & VV6410_SUBSAMPLE) {
99 PDEBUG(D_CONF, "Enabling subsampling");
100 stv06xx_write_bridge(sd, STV_Y_CTRL, 0x02);
101 stv06xx_write_bridge(sd, STV_X_CTRL, 0x06);
102
103 stv06xx_write_bridge(sd, STV_SCAN_RATE, 0x10);
104 } else {
105 stv06xx_write_bridge(sd, STV_Y_CTRL, 0x01);
106 stv06xx_write_bridge(sd, STV_X_CTRL, 0x0a);
107
108 stv06xx_write_bridge(sd, STV_SCAN_RATE, 0x20);
109 }
110
111 /* Turn on LED */
112 err = stv06xx_write_bridge(sd, STV_LED_CTRL, LED_ON);
113 if (err < 0)
114 return err;
115
116 err = stv06xx_write_sensor(sd, VV6410_SETUP0, 0);
117 if (err < 0)
118 return err;
119
120 PDEBUG(D_STREAM, "Starting stream");
121
122 return 0;
123}
124
125static int vv6410_stop(struct sd *sd)
126{
127 int err;
128
129 /* Turn off LED */
130 err = stv06xx_write_bridge(sd, STV_LED_CTRL, LED_OFF);
131 if (err < 0)
132 return err;
133
134 err = stv06xx_write_sensor(sd, VV6410_SETUP0, VV6410_LOW_POWER_MODE);
135 if (err < 0)
136 return err;
137
138 PDEBUG(D_STREAM, "Halting stream");
139
140 return (err < 0) ? err : 0;
141}
142
143static int vv6410_dump(struct sd *sd)
144{
145 u8 i;
146 int err = 0;
147
148 info("Dumping all vv6410 sensor registers");
149 for (i = 0; i < 0xff && !err; i++) {
150 u16 data;
151 err = stv06xx_read_sensor(sd, i, &data);
152 info("Register 0x%x contained 0x%x", i, data);
153 }
154 return (err < 0) ? err : 0;
155}
156
157static int vv6410_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
158{
159 int err;
160 u16 i2c_data;
161 struct sd *sd = (struct sd *) gspca_dev;
162
163 err = stv06xx_read_sensor(sd, VV6410_DATAFORMAT, &i2c_data);
164
165 *val = (i2c_data & VV6410_HFLIP) ? 1 : 0;
166
167 PDEBUG(D_V4L2, "Read horizontal flip %d", *val);
168
169 return (err < 0) ? err : 0;
170}
171
172static int vv6410_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
173{
174 int err;
175 u16 i2c_data;
176 struct sd *sd = (struct sd *) gspca_dev;
177 err = stv06xx_read_sensor(sd, VV6410_DATAFORMAT, &i2c_data);
178 if (err < 0)
179 return err;
180
181 if (val)
182 i2c_data |= VV6410_HFLIP;
183 else
184 i2c_data &= ~VV6410_HFLIP;
185
186 PDEBUG(D_V4L2, "Set horizontal flip to %d", val);
187 err = stv06xx_write_sensor(sd, VV6410_DATAFORMAT, i2c_data);
188
189 return (err < 0) ? err : 0;
190}
191
192static int vv6410_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
193{
194 int err;
195 u16 i2c_data;
196 struct sd *sd = (struct sd *) gspca_dev;
197
198 err = stv06xx_read_sensor(sd, VV6410_DATAFORMAT, &i2c_data);
199
200 *val = (i2c_data & VV6410_VFLIP) ? 1 : 0;
201
202 PDEBUG(D_V4L2, "Read vertical flip %d", *val);
203
204 return (err < 0) ? err : 0;
205}
206
207static int vv6410_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
208{
209 int err;
210 u16 i2c_data;
211 struct sd *sd = (struct sd *) gspca_dev;
212 err = stv06xx_read_sensor(sd, VV6410_DATAFORMAT, &i2c_data);
213 if (err < 0)
214 return err;
215
216 if (val)
217 i2c_data |= VV6410_VFLIP;
218 else
219 i2c_data &= ~VV6410_VFLIP;
220
221 PDEBUG(D_V4L2, "Set vertical flip to %d", val);
222 err = stv06xx_write_sensor(sd, VV6410_DATAFORMAT, i2c_data);
223
224 return (err < 0) ? err : 0;
225}
226
227static int vv6410_get_analog_gain(struct gspca_dev *gspca_dev, __s32 *val)
228{
229 int err;
230 u16 i2c_data;
231 struct sd *sd = (struct sd *) gspca_dev;
232
233 err = stv06xx_read_sensor(sd, VV6410_ANALOGGAIN, &i2c_data);
234
235 *val = i2c_data & 0xf;
236
237 PDEBUG(D_V4L2, "Read analog gain %d", *val);
238
239 return (err < 0) ? err : 0;
240}
241
242static int vv6410_set_analog_gain(struct gspca_dev *gspca_dev, __s32 val)
243{
244 int err;
245 struct sd *sd = (struct sd *) gspca_dev;
246
247 PDEBUG(D_V4L2, "Set analog gain to %d", val);
248 err = stv06xx_write_sensor(sd, VV6410_ANALOGGAIN, 0xf0 | (val & 0xf));
249
250 return (err < 0) ? err : 0;
251}
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h b/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h
new file mode 100644
index 000000000000..3ff8c4ea3362
--- /dev/null
+++ b/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h
@@ -0,0 +1,315 @@
1/*
2 * Copyright (c) 2001 Jean-Fredric Clere, Nikolas Zimmermann, Georg Acher
3 * Mark Cave-Ayland, Carlo E Prelz, Dick Streefland
4 * Copyright (c) 2002, 2003 Tuukka Toivonen
5 * Copyright (c) 2008 Erik Andrén
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 *
21 * P/N 861037: Sensor HDCS1000 ASIC STV0600
22 * P/N 861050-0010: Sensor HDCS1000 ASIC STV0600
23 * P/N 861050-0020: Sensor Photobit PB100 ASIC STV0600-1 - QuickCam Express
24 * P/N 861055: Sensor ST VV6410 ASIC STV0610 - LEGO cam
25 * P/N 861075-0040: Sensor HDCS1000 ASIC
26 * P/N 961179-0700: Sensor ST VV6410 ASIC STV0602 - Dexxa WebCam USB
27 * P/N 861040-0000: Sensor ST VV6410 ASIC STV0610 - QuickCam Web
28 */
29
30#ifndef STV06XX_VV6410_H_
31#define STV06XX_VV6410_H_
32
33#include "stv06xx_sensor.h"
34
35#define VV6410_COLS 416
36#define VV6410_ROWS 320
37
38/* Status registers */
39/* Chip identification number including revision indicator */
40#define VV6410_DEVICEH 0x00
41#define VV6410_DEVICEL 0x01
42
43/* User can determine whether timed I2C data
44 has been consumed by interrogating flag states */
45#define VV6410_STATUS0 0x02
46
47/* Current line counter value */
48#define VV6410_LINECOUNTH 0x03
49#define VV6410_LINECOUNTL 0x04
50
51/* End x coordinate of image size */
52#define VV6410_XENDH 0x05
53#define VV6410_XENDL 0x06
54
55/* End y coordinate of image size */
56#define VV6410_YENDH 0x07
57#define VV6410_YENDL 0x08
58
59/* This is the average pixel value returned from the
60 dark line offset cancellation algorithm */
61#define VV6410_DARKAVGH 0x09
62#define VV6410_DARKAVGL 0x0a
63
64/* This is the average pixel value returned from the
65 black line offset cancellation algorithm */
66#define VV6410_BLACKAVGH 0x0b
67#define VV6410_BLACKAVGL 0x0c
68
69/* Flags to indicate whether the x or y image coordinates have been clipped */
70#define VV6410_STATUS1 0x0d
71
72/* Setup registers */
73
74/* Low-power/sleep modes & video timing */
75#define VV6410_SETUP0 0x10
76
77/* Various parameters */
78#define VV6410_SETUP1 0x11
79
80/* Contains pixel counter reset value used by external sync */
81#define VV6410_SYNCVALUE 0x12
82
83/* Frame grabbing modes (FST, LST and QCK) */
84#define VV6410_FGMODES 0x14
85
86/* FST and QCK mapping modes. */
87#define VV6410_PINMAPPING 0x15
88
89/* Data resolution */
90#define VV6410_DATAFORMAT 0x16
91
92/* Output coding formats */
93#define VV6410_OPFORMAT 0x17
94
95/* Various mode select bits */
96#define VV6410_MODESELECT 0x18
97
98/* Exposure registers */
99/* Fine exposure. */
100#define VV6410_FINEH 0x20
101#define VV6410_FINEL 0x21
102
103/* Coarse exposure */
104#define VV6410_COARSEH 0x22
105#define VV6410_COARSEL 0x23
106
107/* Analog gain setting */
108#define VV6410_ANALOGGAIN 0x24
109
110/* Clock division */
111#define VV6410_CLKDIV 0x25
112
113/* Dark line offset cancellation value */
114#define VV6410_DARKOFFSETH 0x2c
115#define VV6410_DARKOFFSETL 0x2d
116
117/* Dark line offset cancellation enable */
118#define VV6410_DARKOFFSETSETUP 0x2e
119
120/* Video timing registers */
121/* Line Length (Pixel Clocks) */
122#define VV6410_LINELENGTHH 0x52
123#define VV6410_LINELENGTHL 0x53
124
125/* X-co-ordinate of top left corner of region of interest (x-offset) */
126#define VV6410_XOFFSETH 0x57
127#define VV6410_XOFFSETL 0x58
128
129/* Y-coordinate of top left corner of region of interest (y-offset) */
130#define VV6410_YOFFSETH 0x59
131#define VV6410_YOFFSETL 0x5a
132
133/* Field length (Lines) */
134#define VV6410_FIELDLENGTHH 0x61
135#define VV6410_FIELDLENGTHL 0x62
136
137/* System registers */
138/* Black offset cancellation default value */
139#define VV6410_BLACKOFFSETH 0x70
140#define VV6410_BLACKOFFSETL 0x71
141
142/* Black offset cancellation setup */
143#define VV6410_BLACKOFFSETSETUP 0x72
144
145/* Analog Control Register 0 */
146#define VV6410_CR0 0x75
147
148/* Analog Control Register 1 */
149#define VV6410_CR1 0x76
150
151/* ADC Setup Register */
152#define VV6410_AS0 0x77
153
154/* Analog Test Register */
155#define VV6410_AT0 0x78
156
157/* Audio Amplifier Setup Register */
158#define VV6410_AT1 0x79
159
160#define VV6410_HFLIP (1 << 3)
161#define VV6410_VFLIP (1 << 4)
162
163#define VV6410_LOW_POWER_MODE (1 << 0)
164#define VV6410_SOFT_RESET (1 << 2)
165#define VV6410_PAL_25_FPS (0 << 3)
166
167#define VV6410_CLK_DIV_2 (1 << 1)
168
169#define VV6410_FINE_EXPOSURE 320
170#define VV6410_COARSE_EXPOSURE 192
171#define VV6410_DEFAULT_GAIN 5
172
173#define VV6410_SUBSAMPLE 0x01
174#define VV6410_CROP_TO_QVGA 0x02
175
176static int vv6410_probe(struct sd *sd);
177static int vv6410_start(struct sd *sd);
178static int vv6410_init(struct sd *sd);
179static int vv6410_stop(struct sd *sd);
180static int vv6410_dump(struct sd *sd);
181
182/* V4L2 controls supported by the driver */
183static int vv6410_get_hflip(struct gspca_dev *gspca_dev, __s32 *val);
184static int vv6410_set_hflip(struct gspca_dev *gspca_dev, __s32 val);
185static int vv6410_get_vflip(struct gspca_dev *gspca_dev, __s32 *val);
186static int vv6410_set_vflip(struct gspca_dev *gspca_dev, __s32 val);
187static int vv6410_get_analog_gain(struct gspca_dev *gspca_dev, __s32 *val);
188static int vv6410_set_analog_gain(struct gspca_dev *gspca_dev, __s32 val);
189
190const struct stv06xx_sensor stv06xx_sensor_vv6410 = {
191 .name = "ST VV6410",
192 .i2c_flush = 5,
193 .i2c_addr = 0x20,
194 .i2c_len = 1,
195 .init = vv6410_init,
196 .probe = vv6410_probe,
197 .start = vv6410_start,
198 .stop = vv6410_stop,
199 .dump = vv6410_dump,
200
201 .nctrls = 3,
202 .ctrls = {
203 {
204 {
205 .id = V4L2_CID_HFLIP,
206 .type = V4L2_CTRL_TYPE_BOOLEAN,
207 .name = "horizontal flip",
208 .minimum = 0,
209 .maximum = 1,
210 .step = 1,
211 .default_value = 0
212 },
213 .set = vv6410_set_hflip,
214 .get = vv6410_get_hflip
215 }, {
216 {
217 .id = V4L2_CID_VFLIP,
218 .type = V4L2_CTRL_TYPE_BOOLEAN,
219 .name = "vertical flip",
220 .minimum = 0,
221 .maximum = 1,
222 .step = 1,
223 .default_value = 0
224 },
225 .set = vv6410_set_vflip,
226 .get = vv6410_get_vflip
227 }, {
228 {
229 .id = V4L2_CID_GAIN,
230 .type = V4L2_CTRL_TYPE_INTEGER,
231 .name = "analog gain",
232 .minimum = 0,
233 .maximum = 15,
234 .step = 1,
235 .default_value = 0
236 },
237 .set = vv6410_set_analog_gain,
238 .get = vv6410_get_analog_gain
239 }
240 },
241
242 .nmodes = 1,
243 .modes = {
244 {
245 356,
246 292,
247 V4L2_PIX_FMT_SGRBG8,
248 V4L2_FIELD_NONE,
249 .sizeimage =
250 356 * 292,
251 .bytesperline = 356,
252 .colorspace = V4L2_COLORSPACE_SRGB,
253 .priv = 0
254 }
255 }
256};
257
258/* If NULL, only single value to write, stored in len */
259struct stv_init {
260 const u8 *data;
261 u16 start;
262 u8 len;
263};
264
265static const u8 x1500[] = { /* 0x1500 - 0x150f */
266 0x0b, 0xa7, 0xb7, 0x00, 0x00
267};
268
269static const u8 x1536[] = { /* 0x1536 - 0x153b */
270 0x02, 0x00, 0x60, 0x01, 0x20, 0x01
271};
272
273static const u8 x15c1[] = { /* 0x15c1 - 0x15c2 */
274 0xff, 0x03 /* Output word 0x03ff = 1023 (ISO size) */
275};
276
277static const struct stv_init stv_bridge_init[] = {
278 /* This reg is written twice. Some kind of reset? */
279 {NULL, 0x1620, 0x80},
280 {NULL, 0x1620, 0x00},
281 {NULL, 0x1423, 0x04},
282 {x1500, 0x1500, ARRAY_SIZE(x1500)},
283 {x1536, 0x1536, ARRAY_SIZE(x1536)},
284 {x15c1, 0x15c1, ARRAY_SIZE(x15c1)}
285};
286
287static const u8 vv6410_sensor_init[][2] = {
288 /* Setup registers */
289 {VV6410_SETUP0, VV6410_SOFT_RESET},
290 {VV6410_SETUP0, VV6410_LOW_POWER_MODE},
291 /* Use shuffled read-out mode */
292 {VV6410_SETUP1, BIT(6)},
293 /* All modes to 1 */
294 {VV6410_FGMODES, BIT(6) | BIT(4) | BIT(2) | BIT(0)},
295 {VV6410_PINMAPPING, 0x00},
296 /* Pre-clock generator divide off */
297 {VV6410_DATAFORMAT, BIT(7) | BIT(0)},
298
299 /* Exposure registers */
300 {VV6410_FINEH, VV6410_FINE_EXPOSURE >> 8},
301 {VV6410_FINEL, VV6410_FINE_EXPOSURE & 0xff},
302 {VV6410_COARSEH, VV6410_COARSE_EXPOSURE >> 8},
303 {VV6410_COARSEL, VV6410_COARSE_EXPOSURE & 0xff},
304 {VV6410_ANALOGGAIN, 0xf0 | VV6410_DEFAULT_GAIN},
305 {VV6410_CLKDIV, VV6410_CLK_DIV_2},
306
307 /* System registers */
308 /* Enable voltage doubler */
309 {VV6410_AS0, BIT(6) | BIT(4) | BIT(3) | BIT(2) | BIT(1)},
310 {VV6410_AT0, 0x00},
311 /* Power up audio, differential */
312 {VV6410_AT1, BIT(4)|BIT(0)},
313};
314
315#endif
diff --git a/drivers/media/video/gspca/sunplus.c b/drivers/media/video/gspca/sunplus.c
index bd9288665a80..6d904d5e4c74 100644
--- a/drivers/media/video/gspca/sunplus.c
+++ b/drivers/media/video/gspca/sunplus.c
@@ -123,7 +123,7 @@ static struct ctrl sd_ctrls[] = {
123 }, 123 },
124}; 124};
125 125
126static struct v4l2_pix_format vga_mode[] = { 126static const struct v4l2_pix_format vga_mode[] = {
127 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 127 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
128 .bytesperline = 320, 128 .bytesperline = 320,
129 .sizeimage = 320 * 240 * 3 / 8 + 590, 129 .sizeimage = 320 * 240 * 3 / 8 + 590,
@@ -136,7 +136,7 @@ static struct v4l2_pix_format vga_mode[] = {
136 .priv = 1}, 136 .priv = 1},
137}; 137};
138 138
139static struct v4l2_pix_format custom_mode[] = { 139static const struct v4l2_pix_format custom_mode[] = {
140 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 140 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
141 .bytesperline = 320, 141 .bytesperline = 320,
142 .sizeimage = 320 * 240 * 3 / 8 + 590, 142 .sizeimage = 320 * 240 * 3 / 8 + 590,
@@ -149,7 +149,7 @@ static struct v4l2_pix_format custom_mode[] = {
149 .priv = 1}, 149 .priv = 1},
150}; 150};
151 151
152static struct v4l2_pix_format vga_mode2[] = { 152static const struct v4l2_pix_format vga_mode2[] = {
153 {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 153 {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
154 .bytesperline = 176, 154 .bytesperline = 176,
155 .sizeimage = 176 * 144 * 3 / 8 + 590, 155 .sizeimage = 176 * 144 * 3 / 8 + 590,
diff --git a/drivers/media/video/gspca/t613.c b/drivers/media/video/gspca/t613.c
index eac245d7a756..6ee111a3cbd1 100644
--- a/drivers/media/video/gspca/t613.c
+++ b/drivers/media/video/gspca/t613.c
@@ -233,7 +233,7 @@ static char *effects_control[] = {
233 "Negative", 233 "Negative",
234}; 234};
235 235
236static struct v4l2_pix_format vga_mode_t16[] = { 236static const struct v4l2_pix_format vga_mode_t16[] = {
237 {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 237 {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
238 .bytesperline = 160, 238 .bytesperline = 160,
239 .sizeimage = 160 * 120 * 4 / 8 + 590, 239 .sizeimage = 160 * 120 * 4 / 8 + 590,
@@ -499,7 +499,7 @@ static void om6802_sensor_init(struct gspca_dev *gspca_dev)
499 reg_w_buf(gspca_dev, sensor_reset, sizeof sensor_reset); 499 reg_w_buf(gspca_dev, sensor_reset, sizeof sensor_reset);
500 msleep(5); 500 msleep(5);
501 i = 4; 501 i = 4;
502 while (--i < 0) { 502 while (--i > 0) {
503 byte = reg_r(gspca_dev, 0x0060); 503 byte = reg_r(gspca_dev, 0x0060);
504 if (!(byte & 0x01)) 504 if (!(byte & 0x01))
505 break; 505 break;
diff --git a/drivers/media/video/gspca/tv8532.c b/drivers/media/video/gspca/tv8532.c
index 968a5911704f..94163cceb28a 100644
--- a/drivers/media/video/gspca/tv8532.c
+++ b/drivers/media/video/gspca/tv8532.c
@@ -30,15 +30,10 @@ MODULE_LICENSE("GPL");
30struct sd { 30struct sd {
31 struct gspca_dev gspca_dev; /* !! must be the first item */ 31 struct gspca_dev gspca_dev; /* !! must be the first item */
32 32
33 int buflen; /* current length of tmpbuf */ 33 __u16 brightness;
34 __u8 tmpbuf[352 * 288 + 10 * 288]; /* no protection... */ 34 __u16 contrast;
35 __u8 tmpbuf2[352 * 288]; /* no protection... */
36 35
37 unsigned short brightness; 36 __u8 packet;
38 unsigned short contrast;
39
40 char packet;
41 char synchro;
42}; 37};
43 38
44/* V4L2 controls supported by the driver */ 39/* V4L2 controls supported by the driver */
@@ -78,7 +73,7 @@ static struct ctrl sd_ctrls[] = {
78 }, 73 },
79}; 74};
80 75
81static struct v4l2_pix_format sif_mode[] = { 76static const struct v4l2_pix_format sif_mode[] = {
82 {176, 144, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, 77 {176, 144, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
83 .bytesperline = 176, 78 .bytesperline = 176,
84 .sizeimage = 176 * 144, 79 .sizeimage = 176 * 144,
@@ -392,6 +387,8 @@ static void setbrightness(struct gspca_dev *gspca_dev)
392/* -- start the camera -- */ 387/* -- start the camera -- */
393static int sd_start(struct gspca_dev *gspca_dev) 388static int sd_start(struct gspca_dev *gspca_dev)
394{ 389{
390 struct sd *sd = (struct sd *) gspca_dev;
391
395 reg_w_1(gspca_dev, TV8532_AD_SLOPE, 0x32); 392 reg_w_1(gspca_dev, TV8532_AD_SLOPE, 0x32);
396 reg_w_1(gspca_dev, TV8532_AD_BITCTRL, 0x00); 393 reg_w_1(gspca_dev, TV8532_AD_BITCTRL, 0x00);
397 tv_8532ReadRegisters(gspca_dev); 394 tv_8532ReadRegisters(gspca_dev);
@@ -443,6 +440,10 @@ static int sd_start(struct gspca_dev *gspca_dev)
443 /************************************************/ 440 /************************************************/
444 tv_8532_PollReg(gspca_dev); 441 tv_8532_PollReg(gspca_dev);
445 reg_w_1(gspca_dev, TV8532_UDP_UPDATE, 0x00); /* 0x31 */ 442 reg_w_1(gspca_dev, TV8532_UDP_UPDATE, 0x00); /* 0x31 */
443
444 gspca_dev->empty_packet = 0; /* check the empty packets */
445 sd->packet = 0; /* ignore the first packets */
446
446 return 0; 447 return 0;
447} 448}
448 449
@@ -451,111 +452,36 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
451 reg_w_1(gspca_dev, TV8532_GPIO_OE, 0x0b); 452 reg_w_1(gspca_dev, TV8532_GPIO_OE, 0x0b);
452} 453}
453 454
454static void tv8532_preprocess(struct gspca_dev *gspca_dev)
455{
456 struct sd *sd = (struct sd *) gspca_dev;
457/* we should received a whole frame with header and EOL marker
458 * in gspca_dev->tmpbuf and return a GBRG pattern in gspca_dev->tmpbuf2
459 * sequence 2bytes header the Alternate pixels bayer GB 4 bytes
460 * Alternate pixels bayer RG 4 bytes EOL */
461 int width = gspca_dev->width;
462 int height = gspca_dev->height;
463 unsigned char *dst = sd->tmpbuf2;
464 unsigned char *data = sd->tmpbuf;
465 int i;
466
467 /* precompute where is the good bayer line */
468 if (((data[3] + data[width + 7]) >> 1)
469 + (data[4] >> 2)
470 + (data[width + 6] >> 1) >= ((data[2] + data[width + 6]) >> 1)
471 + (data[3] >> 2)
472 + (data[width + 5] >> 1))
473 data += 3;
474 else
475 data += 2;
476 for (i = 0; i < height / 2; i++) {
477 memcpy(dst, data, width);
478 data += width + 3;
479 dst += width;
480 memcpy(dst, data, width);
481 data += width + 7;
482 dst += width;
483 }
484}
485
486static void sd_pkt_scan(struct gspca_dev *gspca_dev, 455static void sd_pkt_scan(struct gspca_dev *gspca_dev,
487 struct gspca_frame *frame, /* target */ 456 struct gspca_frame *frame, /* target */
488 __u8 *data, /* isoc packet */ 457 __u8 *data, /* isoc packet */
489 int len) /* iso packet length */ 458 int len) /* iso packet length */
490{ 459{
491 struct sd *sd = (struct sd *) gspca_dev; 460 struct sd *sd = (struct sd *) gspca_dev;
492 461 int packet_type0, packet_type1;
493 if (data[0] != 0x80) { 462
494 sd->packet++; 463 packet_type0 = packet_type1 = INTER_PACKET;
495 if (sd->buflen + len > sizeof sd->tmpbuf) { 464 if (gspca_dev->empty_packet) {
496 if (gspca_dev->last_packet_type != DISCARD_PACKET) { 465 gspca_dev->empty_packet = 0;
497 PDEBUG(D_PACK, "buffer overflow"); 466 sd->packet = gspca_dev->height / 2;
498 gspca_dev->last_packet_type = DISCARD_PACKET; 467 packet_type0 = FIRST_PACKET;
499 } 468 } else if (sd->packet == 0)
500 return; 469 return; /* 2 more lines in 352x288 ! */
501 } 470 sd->packet--;
502 memcpy(&sd->tmpbuf[sd->buflen], data, len); 471 if (sd->packet == 0)
503 sd->buflen += len; 472 packet_type1 = LAST_PACKET;
504 return; 473
505 } 474 /* each packet contains:
506 475 * - header 2 bytes
507 /* here we detect 0x80 */ 476 * - RG line
508 /* counter is limited so we need few header for a frame :) */ 477 * - 4 bytes
509 478 * - GB line
510 /* header 0x80 0x80 0x80 0x80 0x80 */ 479 * - 4 bytes
511 /* packet 00 63 127 145 00 */ 480 */
512 /* sof 0 1 1 0 0 */ 481 gspca_frame_add(gspca_dev, packet_type0,
513 482 frame, data + 2, gspca_dev->width);
514 /* update sequence */ 483 gspca_frame_add(gspca_dev, packet_type1,
515 if (sd->packet == 63 || sd->packet == 127) 484 frame, data + gspca_dev->width + 6, gspca_dev->width);
516 sd->synchro = 1;
517
518 /* is there a frame start ? */
519 if (sd->packet >= (gspca_dev->height >> 1) - 1) {
520 PDEBUG(D_PACK, "SOF > %d packet %d", sd->synchro,
521 sd->packet);
522 if (!sd->synchro) { /* start of frame */
523 if (gspca_dev->last_packet_type == FIRST_PACKET) {
524 tv8532_preprocess(gspca_dev);
525 frame = gspca_frame_add(gspca_dev,
526 LAST_PACKET,
527 frame, sd->tmpbuf2,
528 gspca_dev->width *
529 gspca_dev->width);
530 }
531 gspca_frame_add(gspca_dev, FIRST_PACKET,
532 frame, data, 0);
533 memcpy(sd->tmpbuf, data, len);
534 sd->buflen = len;
535 sd->packet = 0;
536 return;
537 }
538 if (gspca_dev->last_packet_type != DISCARD_PACKET) {
539 PDEBUG(D_PACK,
540 "Warning wrong TV8532 frame detection %d",
541 sd->packet);
542 gspca_dev->last_packet_type = DISCARD_PACKET;
543 }
544 return;
545 }
546
547 if (!sd->synchro) {
548 /* Drop packet frame corrupt */
549 PDEBUG(D_PACK, "DROP SOF %d packet %d",
550 sd->synchro, sd->packet);
551 sd->packet = 0;
552 gspca_dev->last_packet_type = DISCARD_PACKET;
553 return;
554 }
555 sd->synchro = 1;
556 sd->packet++;
557 memcpy(&sd->tmpbuf[sd->buflen], data, len);
558 sd->buflen += len;
559} 485}
560 486
561static void setcontrast(struct gspca_dev *gspca_dev) 487static void setcontrast(struct gspca_dev *gspca_dev)
diff --git a/drivers/media/video/gspca/vc032x.c b/drivers/media/video/gspca/vc032x.c
index 17af353ddd1c..0525ea51a6de 100644
--- a/drivers/media/video/gspca/vc032x.c
+++ b/drivers/media/video/gspca/vc032x.c
@@ -32,44 +32,68 @@ MODULE_LICENSE("GPL");
32struct sd { 32struct sd {
33 struct gspca_dev gspca_dev; /* !! must be the first item */ 33 struct gspca_dev gspca_dev; /* !! must be the first item */
34 34
35 unsigned char autogain; 35 __u8 hflip;
36 unsigned char lightfreq; 36 __u8 vflip;
37 __u8 lightfreq;
38 __u8 sharpness;
37 39
38 char qindex;
39 char bridge; 40 char bridge;
40#define BRIDGE_VC0321 0 41#define BRIDGE_VC0321 0
41#define BRIDGE_VC0323 1 42#define BRIDGE_VC0323 1
42 char sensor; 43 char sensor;
43#define SENSOR_HV7131R 0 44#define SENSOR_HV7131R 0
44#define SENSOR_MI1320 1 45#define SENSOR_MI0360 1
45#define SENSOR_MI1310_SOC 2 46#define SENSOR_MI1320 2
46#define SENSOR_OV7660 3 47#define SENSOR_MI1310_SOC 3
47#define SENSOR_OV7670 4 48#define SENSOR_OV7660 4
48#define SENSOR_PO3130NC 5 49#define SENSOR_OV7670 5
50#define SENSOR_PO1200 6
51#define SENSOR_PO3130NC 7
49}; 52};
50 53
51/* V4L2 controls supported by the driver */ 54/* V4L2 controls supported by the driver */
52static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); 55static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val);
53static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val); 56static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val);
57static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val);
58static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val);
54static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val); 59static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val);
55static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val); 60static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val);
61static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val);
62static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val);
56 63
57static struct ctrl sd_ctrls[] = { 64static struct ctrl sd_ctrls[] = {
65/* next 2 controls work with ov7660 and ov7670 only */
66#define HFLIP_IDX 0
58 { 67 {
59 { 68 {
60 .id = V4L2_CID_AUTOGAIN, 69 .id = V4L2_CID_HFLIP,
61 .type = V4L2_CTRL_TYPE_BOOLEAN, 70 .type = V4L2_CTRL_TYPE_BOOLEAN,
62 .name = "Auto Gain", 71 .name = "Mirror",
63 .minimum = 0, 72 .minimum = 0,
64 .maximum = 1, 73 .maximum = 1,
65 .step = 1, 74 .step = 1,
66#define AUTOGAIN_DEF 1 75#define HFLIP_DEF 0
67 .default_value = AUTOGAIN_DEF, 76 .default_value = HFLIP_DEF,
68 }, 77 },
69 .set = sd_setautogain, 78 .set = sd_sethflip,
70 .get = sd_getautogain, 79 .get = sd_gethflip,
71 }, 80 },
72#define LIGHTFREQ_IDX 1 81#define VFLIP_IDX 1
82 {
83 {
84 .id = V4L2_CID_VFLIP,
85 .type = V4L2_CTRL_TYPE_BOOLEAN,
86 .name = "Vflip",
87 .minimum = 0,
88 .maximum = 1,
89 .step = 1,
90#define VFLIP_DEF 0
91 .default_value = VFLIP_DEF,
92 },
93 .set = sd_setvflip,
94 .get = sd_getvflip,
95 },
96#define LIGHTFREQ_IDX 2
73 { 97 {
74 { 98 {
75 .id = V4L2_CID_POWER_LINE_FREQUENCY, 99 .id = V4L2_CID_POWER_LINE_FREQUENCY,
@@ -84,9 +108,25 @@ static struct ctrl sd_ctrls[] = {
84 .set = sd_setfreq, 108 .set = sd_setfreq,
85 .get = sd_getfreq, 109 .get = sd_getfreq,
86 }, 110 },
111/* po1200 only */
112#define SHARPNESS_IDX 3
113 {
114 {
115 .id = V4L2_CID_SHARPNESS,
116 .type = V4L2_CTRL_TYPE_INTEGER,
117 .name = "Sharpness",
118 .minimum = 0,
119 .maximum = 2,
120 .step = 1,
121#define SHARPNESS_DEF 1
122 .default_value = SHARPNESS_DEF,
123 },
124 .set = sd_setsharpness,
125 .get = sd_getsharpness,
126 },
87}; 127};
88 128
89static struct v4l2_pix_format vc0321_mode[] = { 129static const struct v4l2_pix_format vc0321_mode[] = {
90 {320, 240, V4L2_PIX_FMT_YVYU, V4L2_FIELD_NONE, 130 {320, 240, V4L2_PIX_FMT_YVYU, V4L2_FIELD_NONE,
91 .bytesperline = 320, 131 .bytesperline = 320,
92 .sizeimage = 320 * 240 * 2, 132 .sizeimage = 320 * 240 * 2,
@@ -98,7 +138,7 @@ static struct v4l2_pix_format vc0321_mode[] = {
98 .colorspace = V4L2_COLORSPACE_SRGB, 138 .colorspace = V4L2_COLORSPACE_SRGB,
99 .priv = 0}, 139 .priv = 0},
100}; 140};
101static struct v4l2_pix_format vc0323_mode[] = { 141static const struct v4l2_pix_format vc0323_mode[] = {
102 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 142 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
103 .bytesperline = 320, 143 .bytesperline = 320,
104 .sizeimage = 320 * 240 * 3 / 8 + 590, 144 .sizeimage = 320 * 240 * 3 / 8 + 590,
@@ -111,6 +151,252 @@ static struct v4l2_pix_format vc0323_mode[] = {
111 .priv = 0}, 151 .priv = 0},
112}; 152};
113 153
154static const struct v4l2_pix_format svga_mode[] = {
155 {800, 600, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
156 .bytesperline = 800,
157 .sizeimage = 800 * 600 * 1 / 4 + 590,
158 .colorspace = V4L2_COLORSPACE_JPEG,
159 .priv = 0},
160};
161
162/* OV7660/7670 registers */
163#define OV7660_REG_MVFP 0x1e
164#define OV7660_MVFP_MIRROR 0x20
165#define OV7660_MVFP_VFLIP 0x10
166
167static const __u8 mi0360_matrix[9] = {
168 0x50, 0xf8, 0xf8, 0xf5, 0x50, 0xfb, 0xff, 0xf1, 0x50
169};
170
171static const __u8 mi0360_initVGA_JPG[][4] = {
172 {0xb0, 0x03, 0x19, 0xcc},
173 {0xb0, 0x04, 0x02, 0xcc},
174 {0xb3, 0x00, 0x24, 0xcc},
175 {0xb3, 0x00, 0x25, 0xcc},
176 {0xb3, 0x08, 0x01, 0xcc},
177 {0xb3, 0x09, 0x0c, 0xcc},
178 {0xb3, 0x05, 0x01, 0xcc},
179 {0xb3, 0x06, 0x03, 0xcc},
180 {0xb3, 0x03, 0x0a, 0xcc},
181 {0xb3, 0x20, 0x00, 0xcc},
182 {0xb3, 0x21, 0x00, 0xcc},
183 {0xb3, 0x22, 0x01, 0xcc},
184 {0xb3, 0x23, 0xe0, 0xcc},
185 {0xb3, 0x04, 0x05, 0xcc},
186 {0xb3, 0x14, 0x00, 0xcc},
187 {0xb3, 0x15, 0x00, 0xcc},
188 {0xb3, 0x16, 0x02, 0xcc},
189 {0xb3, 0x17, 0x7f, 0xcc},
190 {0xb3, 0x35, 0xdd, 0xcc},
191 {0xb3, 0x34, 0x02, 0xcc},
192 {0xb3, 0x00, 0x25, 0xcc},
193 {0xbc, 0x00, 0x71, 0xcc},
194 {0xb8, 0x00, 0x13, 0xcc},
195 {0xb8, 0x27, 0x20, 0xcc},
196 {0xb8, 0x2c, 0x50, 0xcc},
197 {0xb8, 0x2d, 0xf8, 0xcc},
198 {0xb8, 0x2e, 0xf8, 0xcc},
199 {0xb8, 0x2f, 0xf8, 0xcc},
200 {0xb8, 0x30, 0x50, 0xcc},
201 {0xb8, 0x31, 0xf8, 0xcc},
202 {0xb8, 0x32, 0xf8, 0xcc},
203 {0xb8, 0x33, 0xf8, 0xcc},
204 {0xb8, 0x34, 0x50, 0xcc},
205 {0xb8, 0x35, 0x00, 0xcc},
206 {0xb8, 0x36, 0x00, 0xcc},
207 {0xb8, 0x37, 0x00, 0xcc},
208 {0xb8, 0x01, 0x79, 0xcc},
209 {0xb8, 0x08, 0xe0, 0xcc},
210 {0xb3, 0x01, 0x41, 0xcc},
211 {0xb8, 0x01, 0x79, 0xcc},
212 {0xb8, 0x14, 0x18, 0xcc},
213 {0xb8, 0xb2, 0x0a, 0xcc},
214 {0xb8, 0xb4, 0x0a, 0xcc},
215 {0xb8, 0xb5, 0x0a, 0xcc},
216 {0xb8, 0xfe, 0x00, 0xcc},
217 {0xb8, 0xff, 0x28, 0xcc},
218 {0xb9, 0x00, 0x28, 0xcc},
219 {0xb9, 0x01, 0x28, 0xcc},
220 {0xb9, 0x02, 0x28, 0xcc},
221 {0xb9, 0x03, 0x00, 0xcc},
222 {0xb9, 0x04, 0x00, 0xcc},
223 {0xb9, 0x05, 0x3c, 0xcc},
224 {0xb9, 0x06, 0x3c, 0xcc},
225 {0xb9, 0x07, 0x3c, 0xcc},
226 {0xb9, 0x08, 0x3c, 0xcc},
227 {0xb8, 0x8e, 0x00, 0xcc},
228 {0xb8, 0x8f, 0xff, 0xcc},
229 {0xb8, 0x81, 0x09, 0xcc},
230 {0x31, 0x00, 0x00, 0xbb},
231 {0x09, 0x01, 0xc7, 0xbb},
232 {0x34, 0x01, 0x00, 0xbb},
233 {0x2b, 0x00, 0x28, 0xbb},
234 {0x2c, 0x00, 0x30, 0xbb},
235 {0x2d, 0x00, 0x30, 0xbb},
236 {0x2e, 0x00, 0x28, 0xbb},
237 {0x62, 0x04, 0x11, 0xbb},
238 {0x03, 0x01, 0xe0, 0xbb},
239 {0x2c, 0x00, 0x2c, 0xbb},
240 {0x20, 0xd0, 0x00, 0xbb},
241 {0x01, 0x00, 0x08, 0xbb},
242 {0x06, 0x00, 0x10, 0xbb},
243 {0x05, 0x00, 0x20, 0xbb},
244 {0x20, 0x00, 0x00, 0xbb},
245 {0xb6, 0x00, 0x00, 0xcc},
246 {0xb6, 0x03, 0x02, 0xcc},
247 {0xb6, 0x02, 0x80, 0xcc},
248 {0xb6, 0x05, 0x01, 0xcc},
249 {0xb6, 0x04, 0xe0, 0xcc},
250 {0xb6, 0x12, 0x78, 0xcc},
251 {0xb6, 0x18, 0x02, 0xcc},
252 {0xb6, 0x17, 0x58, 0xcc},
253 {0xb6, 0x16, 0x00, 0xcc},
254 {0xb6, 0x22, 0x12, 0xcc},
255 {0xb6, 0x23, 0x0b, 0xcc},
256 {0xb3, 0x02, 0x02, 0xcc},
257 {0xbf, 0xc0, 0x39, 0xcc},
258 {0xbf, 0xc1, 0x04, 0xcc},
259 {0xbf, 0xcc, 0x10, 0xcc},
260 {0xb9, 0x12, 0x00, 0xcc},
261 {0xb9, 0x13, 0x0a, 0xcc},
262 {0xb9, 0x14, 0x0a, 0xcc},
263 {0xb9, 0x15, 0x0a, 0xcc},
264 {0xb9, 0x16, 0x0a, 0xcc},
265 {0xb9, 0x18, 0x00, 0xcc},
266 {0xb9, 0x19, 0x0f, 0xcc},
267 {0xb9, 0x1a, 0x0f, 0xcc},
268 {0xb9, 0x1b, 0x0f, 0xcc},
269 {0xb9, 0x1c, 0x0f, 0xcc},
270 {0xb8, 0x8e, 0x00, 0xcc},
271 {0xb8, 0x8f, 0xff, 0xcc},
272 {0xb6, 0x12, 0xf8, 0xcc},
273 {0xb8, 0x0c, 0x20, 0xcc},
274 {0xb8, 0x0d, 0x70, 0xcc},
275 {0xb6, 0x13, 0x13, 0xcc},
276 {0x35, 0x00, 0x60, 0xbb},
277 {0xb3, 0x5c, 0x01, 0xcc},
278 {}
279};
280static const __u8 mi0360_initQVGA_JPG[][4] = {
281 {0xb0, 0x03, 0x19, 0xcc},
282 {0xb0, 0x04, 0x02, 0xcc},
283 {0xb3, 0x00, 0x24, 0xcc},
284 {0xb3, 0x00, 0x25, 0xcc},
285 {0xb3, 0x08, 0x01, 0xcc},
286 {0xb3, 0x09, 0x0c, 0xcc},
287 {0xb3, 0x05, 0x01, 0xcc},
288 {0xb3, 0x06, 0x03, 0xcc},
289 {0xb3, 0x03, 0x0a, 0xcc},
290 {0xb3, 0x20, 0x00, 0xcc},
291 {0xb3, 0x21, 0x00, 0xcc},
292 {0xb3, 0x22, 0x01, 0xcc},
293 {0xb3, 0x23, 0xe0, 0xcc},
294 {0xb3, 0x04, 0x05, 0xcc},
295 {0xb3, 0x14, 0x00, 0xcc},
296 {0xb3, 0x15, 0x00, 0xcc},
297 {0xb3, 0x16, 0x02, 0xcc},
298 {0xb3, 0x17, 0x7f, 0xcc},
299 {0xb3, 0x35, 0xdd, 0xcc},
300 {0xb3, 0x34, 0x02, 0xcc},
301 {0xb3, 0x00, 0x25, 0xcc},
302 {0xbc, 0x00, 0xd1, 0xcc},
303 {0xb8, 0x00, 0x13, 0xcc},
304 {0xb8, 0x27, 0x20, 0xcc},
305 {0xb8, 0x2c, 0x50, 0xcc},
306 {0xb8, 0x2d, 0xf8, 0xcc},
307 {0xb8, 0x2e, 0xf8, 0xcc},
308 {0xb8, 0x2f, 0xf8, 0xcc},
309 {0xb8, 0x30, 0x50, 0xcc},
310 {0xb8, 0x31, 0xf8, 0xcc},
311 {0xb8, 0x32, 0xf8, 0xcc},
312 {0xb8, 0x33, 0xf8, 0xcc},
313 {0xb8, 0x34, 0x50, 0xcc},
314 {0xb8, 0x35, 0x00, 0xcc},
315 {0xb8, 0x36, 0x00, 0xcc},
316 {0xb8, 0x37, 0x00, 0xcc},
317 {0xb8, 0x01, 0x79, 0xcc},
318 {0xb8, 0x08, 0xe0, 0xcc},
319 {0xb3, 0x01, 0x41, 0xcc},
320 {0xb8, 0x01, 0x79, 0xcc},
321 {0xb8, 0x14, 0x18, 0xcc},
322 {0xb8, 0xb2, 0x0a, 0xcc},
323 {0xb8, 0xb4, 0x0a, 0xcc},
324 {0xb8, 0xb5, 0x0a, 0xcc},
325 {0xb8, 0xfe, 0x00, 0xcc},
326 {0xb8, 0xff, 0x28, 0xcc},
327 {0xb9, 0x00, 0x28, 0xcc},
328 {0xb9, 0x01, 0x28, 0xcc},
329 {0xb9, 0x02, 0x28, 0xcc},
330 {0xb9, 0x03, 0x00, 0xcc},
331 {0xb9, 0x04, 0x00, 0xcc},
332 {0xb9, 0x05, 0x3c, 0xcc},
333 {0xb9, 0x06, 0x3c, 0xcc},
334 {0xb9, 0x07, 0x3c, 0xcc},
335 {0xb9, 0x08, 0x3c, 0xcc},
336 {0xb8, 0x8e, 0x00, 0xcc},
337 {0xb8, 0x8f, 0xff, 0xcc},
338 {0xb8, 0x81, 0x09, 0xcc},
339 {0x31, 0x00, 0x00, 0xbb},
340 {0x09, 0x01, 0xc7, 0xbb},
341 {0x34, 0x01, 0x00, 0xbb},
342 {0x2b, 0x00, 0x28, 0xbb},
343 {0x2c, 0x00, 0x30, 0xbb},
344 {0x2d, 0x00, 0x30, 0xbb},
345 {0x2e, 0x00, 0x28, 0xbb},
346 {0x62, 0x04, 0x11, 0xbb},
347 {0x03, 0x01, 0xe0, 0xbb},
348 {0x2c, 0x00, 0x2c, 0xbb},
349 {0x20, 0xd0, 0x00, 0xbb},
350 {0x01, 0x00, 0x08, 0xbb},
351 {0x06, 0x00, 0x10, 0xbb},
352 {0x05, 0x00, 0x20, 0xbb},
353 {0x20, 0x00, 0x00, 0xbb},
354 {0xb6, 0x00, 0x00, 0xcc},
355 {0xb6, 0x03, 0x01, 0xcc},
356 {0xb6, 0x02, 0x40, 0xcc},
357 {0xb6, 0x05, 0x00, 0xcc},
358 {0xb6, 0x04, 0xf0, 0xcc},
359 {0xb6, 0x12, 0x78, 0xcc},
360 {0xb6, 0x18, 0x00, 0xcc},
361 {0xb6, 0x17, 0x96, 0xcc},
362 {0xb6, 0x16, 0x00, 0xcc},
363 {0xb6, 0x22, 0x12, 0xcc},
364 {0xb6, 0x23, 0x0b, 0xcc},
365 {0xb3, 0x02, 0x02, 0xcc},
366 {0xbf, 0xc0, 0x39, 0xcc},
367 {0xbf, 0xc1, 0x04, 0xcc},
368 {0xbf, 0xcc, 0x10, 0xcc},
369 {0xb9, 0x12, 0x00, 0xcc},
370 {0xb9, 0x13, 0x0a, 0xcc},
371 {0xb9, 0x14, 0x0a, 0xcc},
372 {0xb9, 0x15, 0x0a, 0xcc},
373 {0xb9, 0x16, 0x0a, 0xcc},
374 {0xb9, 0x18, 0x00, 0xcc},
375 {0xb9, 0x19, 0x0f, 0xcc},
376 {0xb9, 0x1a, 0x0f, 0xcc},
377 {0xb9, 0x1b, 0x0f, 0xcc},
378 {0xb9, 0x1c, 0x0f, 0xcc},
379 {0xb8, 0x8e, 0x00, 0xcc},
380 {0xb8, 0x8f, 0xff, 0xcc},
381 {0xb6, 0x12, 0xf8, 0xcc},
382 {0xb6, 0x13, 0x13, 0xcc},
383 {0xbc, 0x02, 0x18, 0xcc},
384 {0xbc, 0x03, 0x50, 0xcc},
385 {0xbc, 0x04, 0x18, 0xcc},
386 {0xbc, 0x05, 0x00, 0xcc},
387 {0xbc, 0x06, 0x00, 0xcc},
388 {0xbc, 0x08, 0x30, 0xcc},
389 {0xbc, 0x09, 0x40, 0xcc},
390 {0xbc, 0x0a, 0x10, 0xcc},
391 {0xb8, 0x0c, 0x20, 0xcc},
392 {0xb8, 0x0d, 0x70, 0xcc},
393 {0xbc, 0x0b, 0x00, 0xcc},
394 {0xbc, 0x0c, 0x00, 0xcc},
395 {0x35, 0x00, 0xef, 0xbb},
396 {0xb3, 0x5c, 0x01, 0xcc},
397 {}
398};
399
114static const __u8 mi1310_socinitVGA_JPG[][4] = { 400static const __u8 mi1310_socinitVGA_JPG[][4] = {
115 {0xb0, 0x03, 0x19, 0xcc}, 401 {0xb0, 0x03, 0x19, 0xcc},
116 {0xb0, 0x04, 0x02, 0xcc}, 402 {0xb0, 0x04, 0x02, 0xcc},
@@ -823,7 +1109,7 @@ static const __u8 ov7660_initVGA_data[][4] = {
823 {0x00, 0x01, 0x80, 0xaa}, {0x00, 0x02, 0x80, 0xaa}, 1109 {0x00, 0x01, 0x80, 0xaa}, {0x00, 0x02, 0x80, 0xaa},
824 {0x00, 0x12, 0x80, 0xaa}, 1110 {0x00, 0x12, 0x80, 0xaa},
825 {0x00, 0x12, 0x05, 0xaa}, 1111 {0x00, 0x12, 0x05, 0xaa},
826 {0x00, 0x1e, 0x01, 0xaa}, 1112 {0x00, 0x1e, 0x01, 0xaa}, /* MVFP */
827 {0x00, 0x3d, 0x40, 0xaa}, /* 0x3d <-40 gamma 01 */ 1113 {0x00, 0x3d, 0x40, 0xaa}, /* 0x3d <-40 gamma 01 */
828 {0x00, 0x41, 0x00, 0xaa}, /* edge 00 */ 1114 {0x00, 0x41, 0x00, 0xaa}, /* edge 00 */
829 {0x00, 0x0d, 0x48, 0xaa}, {0x00, 0x0e, 0x04, 0xaa}, 1115 {0x00, 0x0d, 0x48, 0xaa}, {0x00, 0x0e, 0x04, 0xaa},
@@ -877,7 +1163,7 @@ static const __u8 ov7660_initQVGA_data[][4] = {
877 {0xb8, 0x27, 0x20, 0xcc}, {0xb8, 0x8f, 0x50, 0xcc}, 1163 {0xb8, 0x27, 0x20, 0xcc}, {0xb8, 0x8f, 0x50, 0xcc},
878 {0x00, 0x01, 0x80, 0xaa}, {0x00, 0x02, 0x80, 0xaa}, 1164 {0x00, 0x01, 0x80, 0xaa}, {0x00, 0x02, 0x80, 0xaa},
879 {0x00, 0x12, 0x80, 0xaa}, {0x00, 0x12, 0x05, 0xaa}, 1165 {0x00, 0x12, 0x80, 0xaa}, {0x00, 0x12, 0x05, 0xaa},
880 {0x00, 0x1e, 0x01, 0xaa}, 1166 {0x00, 0x1e, 0x01, 0xaa}, /* MVFP */
881 {0x00, 0x3d, 0x40, 0xaa}, /* 0x3d <-40 gamma 01 */ 1167 {0x00, 0x3d, 0x40, 0xaa}, /* 0x3d <-40 gamma 01 */
882 {0x00, 0x41, 0x00, 0xaa}, /* edge 00 */ 1168 {0x00, 0x41, 0x00, 0xaa}, /* edge 00 */
883 {0x00, 0x0d, 0x48, 0xaa}, {0x00, 0x0e, 0x04, 0xaa}, 1169 {0x00, 0x0d, 0x48, 0xaa}, {0x00, 0x0e, 0x04, 0xaa},
@@ -983,7 +1269,8 @@ static const __u8 ov7670_initVGA_JPG[][4] = {
983 {0x00, 0xa9, 0x90, 0xaa}, {0x00, 0xaa, 0x14, 0xaa}, 1269 {0x00, 0xa9, 0x90, 0xaa}, {0x00, 0xaa, 0x14, 0xaa},
984 {0x00, 0x13, 0xe5, 0xaa}, {0x00, 0x0e, 0x61, 0xaa}, 1270 {0x00, 0x13, 0xe5, 0xaa}, {0x00, 0x0e, 0x61, 0xaa},
985 {0x00, 0x0f, 0x4b, 0xaa}, {0x00, 0x16, 0x02, 0xaa}, 1271 {0x00, 0x0f, 0x4b, 0xaa}, {0x00, 0x16, 0x02, 0xaa},
986 {0x00, 0x1e, 0x07, 0xaa}, {0x00, 0x21, 0x02, 0xaa}, 1272 {0x00, 0x1e, 0x07, 0xaa}, /* MVFP */
1273 {0x00, 0x21, 0x02, 0xaa},
987 {0x00, 0x22, 0x91, 0xaa}, {0x00, 0x29, 0x07, 0xaa}, 1274 {0x00, 0x22, 0x91, 0xaa}, {0x00, 0x29, 0x07, 0xaa},
988 {0x00, 0x33, 0x0b, 0xaa}, {0x00, 0x35, 0x0b, 0xaa}, 1275 {0x00, 0x33, 0x0b, 0xaa}, {0x00, 0x35, 0x0b, 0xaa},
989 {0x00, 0x37, 0x1d, 0xaa}, {0x00, 0x38, 0x71, 0xaa}, 1276 {0x00, 0x37, 0x1d, 0xaa}, {0x00, 0x38, 0x71, 0xaa},
@@ -1048,7 +1335,8 @@ static const __u8 ov7670_initVGA_JPG[][4] = {
1048 {0x00, 0x71, 0x35, 0xaa}, {0x00, 0x72, 0x11, 0xaa}, 1335 {0x00, 0x71, 0x35, 0xaa}, {0x00, 0x72, 0x11, 0xaa},
1049 {0x00, 0x73, 0xf0, 0xaa}, {0x00, 0xa2, 0x02, 0xaa}, 1336 {0x00, 0x73, 0xf0, 0xaa}, {0x00, 0xa2, 0x02, 0xaa},
1050 {0x00, 0xb1, 0x00, 0xaa}, {0x00, 0xb1, 0x0c, 0xaa}, 1337 {0x00, 0xb1, 0x00, 0xaa}, {0x00, 0xb1, 0x0c, 0xaa},
1051 {0x00, 0x1e, 0x37, 0xaa}, {0x00, 0xaa, 0x14, 0xaa}, 1338 {0x00, 0x1e, 0x37, 0xaa}, /* MVFP */
1339 {0x00, 0xaa, 0x14, 0xaa},
1052 {0x00, 0x24, 0x80, 0xaa}, {0x00, 0x25, 0x74, 0xaa}, 1340 {0x00, 0x24, 0x80, 0xaa}, {0x00, 0x25, 0x74, 0xaa},
1053 {0x00, 0x26, 0xd3, 0xaa}, {0x00, 0x0d, 0x00, 0xaa}, 1341 {0x00, 0x26, 0xd3, 0xaa}, {0x00, 0x0d, 0x00, 0xaa},
1054 {0x00, 0x14, 0x18, 0xaa}, {0x00, 0x9d, 0x99, 0xaa}, 1342 {0x00, 0x14, 0x18, 0xaa}, {0x00, 0x9d, 0x99, 0xaa},
@@ -1110,7 +1398,8 @@ static const __u8 ov7670_initQVGA_JPG[][4] = {
1110 {0x00, 0xa9, 0x90, 0xaa}, {0x00, 0xaa, 0x14, 0xaa}, 1398 {0x00, 0xa9, 0x90, 0xaa}, {0x00, 0xaa, 0x14, 0xaa},
1111 {0x00, 0x13, 0xe5, 0xaa}, {0x00, 0x0e, 0x61, 0xaa}, 1399 {0x00, 0x13, 0xe5, 0xaa}, {0x00, 0x0e, 0x61, 0xaa},
1112 {0x00, 0x0f, 0x4b, 0xaa}, {0x00, 0x16, 0x02, 0xaa}, 1400 {0x00, 0x0f, 0x4b, 0xaa}, {0x00, 0x16, 0x02, 0xaa},
1113 {0x00, 0x1e, 0x07, 0xaa}, {0x00, 0x21, 0x02, 0xaa}, 1401 {0x00, 0x1e, 0x07, 0xaa}, /* MVFP */
1402 {0x00, 0x21, 0x02, 0xaa},
1114 {0x00, 0x22, 0x91, 0xaa}, {0x00, 0x29, 0x07, 0xaa}, 1403 {0x00, 0x22, 0x91, 0xaa}, {0x00, 0x29, 0x07, 0xaa},
1115 {0x00, 0x33, 0x0b, 0xaa}, {0x00, 0x35, 0x0b, 0xaa}, 1404 {0x00, 0x33, 0x0b, 0xaa}, {0x00, 0x35, 0x0b, 0xaa},
1116 {0x00, 0x37, 0x1d, 0xaa}, {0x00, 0x38, 0x71, 0xaa}, 1405 {0x00, 0x37, 0x1d, 0xaa}, {0x00, 0x38, 0x71, 0xaa},
@@ -1175,7 +1464,8 @@ static const __u8 ov7670_initQVGA_JPG[][4] = {
1175 {0x00, 0x71, 0x35, 0xaa}, {0x00, 0x72, 0x11, 0xaa}, 1464 {0x00, 0x71, 0x35, 0xaa}, {0x00, 0x72, 0x11, 0xaa},
1176 {0x00, 0x73, 0xf0, 0xaa}, {0x00, 0xa2, 0x02, 0xaa}, 1465 {0x00, 0x73, 0xf0, 0xaa}, {0x00, 0xa2, 0x02, 0xaa},
1177 {0x00, 0xb1, 0x00, 0xaa}, {0x00, 0xb1, 0x0c, 0xaa}, 1466 {0x00, 0xb1, 0x00, 0xaa}, {0x00, 0xb1, 0x0c, 0xaa},
1178 {0x00, 0x1e, 0x37, 0xaa}, {0x00, 0xaa, 0x14, 0xaa}, 1467 {0x00, 0x1e, 0x37, 0xaa}, /* MVFP */
1468 {0x00, 0xaa, 0x14, 0xaa},
1179 {0x00, 0x24, 0x80, 0xaa}, {0x00, 0x25, 0x74, 0xaa}, 1469 {0x00, 0x24, 0x80, 0xaa}, {0x00, 0x25, 0x74, 0xaa},
1180 {0x00, 0x26, 0xd3, 0xaa}, {0x00, 0x0d, 0x00, 0xaa}, 1470 {0x00, 0x26, 0xd3, 0xaa}, {0x00, 0x0d, 0x00, 0xaa},
1181 {0x00, 0x14, 0x18, 0xaa}, {0x00, 0x9d, 0x99, 0xaa}, 1471 {0x00, 0x14, 0x18, 0xaa}, {0x00, 0x9d, 0x99, 0xaa},
@@ -1204,6 +1494,275 @@ static const __u8 ov7670_initQVGA_JPG[][4] = {
1204 {}, 1494 {},
1205}; 1495};
1206 1496
1497/* PO1200 - values from usbvm326.inf and ms-win trace */
1498static const __u8 po1200_gamma[17] = {
1499 0x00, 0x13, 0x38, 0x59, 0x79, 0x92, 0xa7, 0xb9, 0xc8,
1500 0xd4, 0xdf, 0xe7, 0xee, 0xf4, 0xf9, 0xfc, 0xff
1501};
1502static const __u8 po1200_matrix[9] = {
1503 0x60, 0xf9, 0xe5, 0xe7, 0x50, 0x05, 0xf3, 0xe6, 0x5e
1504};
1505static const __u8 po1200_initVGA_data[][4] = {
1506 {0xb0, 0x03, 0x19, 0xcc}, /* reset? */
1507 {0xb0, 0x03, 0x19, 0xcc},
1508/* {0x00, 0x00, 0x33, 0xdd}, */
1509 {0xb0, 0x04, 0x02, 0xcc},
1510 {0xb0, 0x02, 0x02, 0xcc},
1511 {0xb3, 0x5d, 0x00, 0xcc},
1512 {0xb3, 0x01, 0x01, 0xcc},
1513 {0xb3, 0x00, 0x64, 0xcc},
1514 {0xb3, 0x00, 0x65, 0xcc},
1515 {0xb3, 0x05, 0x01, 0xcc},
1516 {0xb3, 0x06, 0x01, 0xcc},
1517 {0xb3, 0x5c, 0x01, 0xcc},
1518 {0xb3, 0x08, 0x01, 0xcc},
1519 {0xb3, 0x09, 0x0c, 0xcc},
1520 {0xb3, 0x00, 0x67, 0xcc},
1521 {0xb3, 0x02, 0xb2, 0xcc},
1522 {0xb3, 0x03, 0x18, 0xcc},
1523 {0xb3, 0x04, 0x15, 0xcc},
1524 {0xb3, 0x20, 0x00, 0xcc},
1525 {0xb3, 0x21, 0x00, 0xcc},
1526 {0xb3, 0x22, 0x02, 0xcc},
1527 {0xb3, 0x23, 0x58, 0xcc},
1528 {0xb3, 0x14, 0x00, 0xcc},
1529 {0xb3, 0x15, 0x00, 0xcc},
1530 {0xb3, 0x16, 0x03, 0xcc},
1531 {0xb3, 0x17, 0x1f, 0xcc},
1532 {0xbc, 0x00, 0x71, 0xcc},
1533 {0xbc, 0x01, 0x01, 0xcc},
1534 {0xb0, 0x54, 0x13, 0xcc},
1535 {0xb3, 0x00, 0x67, 0xcc},
1536 {0xb3, 0x34, 0x01, 0xcc},
1537 {0xb3, 0x35, 0xdc, 0xcc},
1538 {0x00, 0x03, 0x00, 0xaa},
1539 {0x00, 0x12, 0x05, 0xaa},
1540 {0x00, 0x13, 0x02, 0xaa},
1541 {0x00, 0x1e, 0xc6, 0xaa}, /* h/v flip */
1542 {0x00, 0x21, 0x00, 0xaa},
1543 {0x00, 0x25, 0x02, 0xaa},
1544 {0x00, 0x3c, 0x4f, 0xaa},
1545 {0x00, 0x3f, 0xe0, 0xaa},
1546 {0x00, 0x42, 0xff, 0xaa},
1547 {0x00, 0x45, 0x34, 0xaa},
1548 {0x00, 0x55, 0xfe, 0xaa},
1549 {0x00, 0x59, 0xd3, 0xaa},
1550 {0x00, 0x5e, 0x04, 0xaa},
1551 {0x00, 0x61, 0xb8, 0xaa}, /* sharpness */
1552 {0x00, 0x62, 0x02, 0xaa},
1553 {0x00, 0xa7, 0x31, 0xaa},
1554 {0x00, 0xa9, 0x66, 0xaa},
1555 {0x00, 0xb0, 0x00, 0xaa},
1556 {0x00, 0xb1, 0x00, 0xaa},
1557 {0x00, 0xb3, 0x11, 0xaa},
1558 {0x00, 0xb6, 0x26, 0xaa},
1559 {0x00, 0xb7, 0x20, 0xaa},
1560 {0x00, 0xba, 0x04, 0xaa},
1561 {0x00, 0x88, 0x42, 0xaa},
1562 {0x00, 0x89, 0x9a, 0xaa},
1563 {0x00, 0x8a, 0x88, 0xaa},
1564 {0x00, 0x8b, 0x8e, 0xaa},
1565 {0x00, 0x8c, 0x3e, 0xaa},
1566 {0x00, 0x8d, 0x90, 0xaa},
1567 {0x00, 0x8e, 0x87, 0xaa},
1568 {0x00, 0x8f, 0x96, 0xaa},
1569 {0x00, 0x90, 0x3d, 0xaa},
1570 {0x00, 0x64, 0x00, 0xaa},
1571 {0x00, 0x65, 0x10, 0xaa},
1572 {0x00, 0x66, 0x20, 0xaa},
1573 {0x00, 0x67, 0x2b, 0xaa},
1574 {0x00, 0x68, 0x36, 0xaa},
1575 {0x00, 0x69, 0x49, 0xaa},
1576 {0x00, 0x6a, 0x5a, 0xaa},
1577 {0x00, 0x6b, 0x7f, 0xaa},
1578 {0x00, 0x6c, 0x9b, 0xaa},
1579 {0x00, 0x6d, 0xba, 0xaa},
1580 {0x00, 0x6e, 0xd4, 0xaa},
1581 {0x00, 0x6f, 0xea, 0xaa},
1582 {0x00, 0x70, 0x00, 0xaa},
1583 {0x00, 0x71, 0x10, 0xaa},
1584 {0x00, 0x72, 0x20, 0xaa},
1585 {0x00, 0x73, 0x2b, 0xaa},
1586 {0x00, 0x74, 0x36, 0xaa},
1587 {0x00, 0x75, 0x49, 0xaa},
1588 {0x00, 0x76, 0x5a, 0xaa},
1589 {0x00, 0x77, 0x7f, 0xaa},
1590 {0x00, 0x78, 0x9b, 0xaa},
1591 {0x00, 0x79, 0xba, 0xaa},
1592 {0x00, 0x7a, 0xd4, 0xaa},
1593 {0x00, 0x7b, 0xea, 0xaa},
1594 {0x00, 0x7c, 0x00, 0xaa},
1595 {0x00, 0x7d, 0x10, 0xaa},
1596 {0x00, 0x7e, 0x20, 0xaa},
1597 {0x00, 0x7f, 0x2b, 0xaa},
1598 {0x00, 0x80, 0x36, 0xaa},
1599 {0x00, 0x81, 0x49, 0xaa},
1600 {0x00, 0x82, 0x5a, 0xaa},
1601 {0x00, 0x83, 0x7f, 0xaa},
1602 {0x00, 0x84, 0x9b, 0xaa},
1603 {0x00, 0x85, 0xba, 0xaa},
1604 {0x00, 0x86, 0xd4, 0xaa},
1605 {0x00, 0x87, 0xea, 0xaa},
1606 {0x00, 0x57, 0x2a, 0xaa},
1607 {0x00, 0x03, 0x01, 0xaa},
1608 {0x00, 0x04, 0x10, 0xaa},
1609 {0x00, 0x05, 0x10, 0xaa},
1610 {0x00, 0x06, 0x10, 0xaa},
1611 {0x00, 0x07, 0x10, 0xaa},
1612 {0x00, 0x08, 0x13, 0xaa},
1613 {0x00, 0x0a, 0x00, 0xaa},
1614 {0x00, 0x0b, 0x10, 0xaa},
1615 {0x00, 0x0c, 0x20, 0xaa},
1616 {0x00, 0x0d, 0x18, 0xaa},
1617 {0x00, 0x22, 0x01, 0xaa},
1618 {0x00, 0x23, 0x60, 0xaa},
1619 {0x00, 0x25, 0x08, 0xaa},
1620 {0x00, 0x26, 0x82, 0xaa},
1621 {0x00, 0x2e, 0x0f, 0xaa},
1622 {0x00, 0x2f, 0x1e, 0xaa},
1623 {0x00, 0x30, 0x2d, 0xaa},
1624 {0x00, 0x31, 0x3c, 0xaa},
1625 {0x00, 0x32, 0x4b, 0xaa},
1626 {0x00, 0x33, 0x5a, 0xaa},
1627 {0x00, 0x34, 0x69, 0xaa},
1628 {0x00, 0x35, 0x78, 0xaa},
1629 {0x00, 0x36, 0x87, 0xaa},
1630 {0x00, 0x37, 0x96, 0xaa},
1631 {0x00, 0x38, 0xa5, 0xaa},
1632 {0x00, 0x39, 0xb4, 0xaa},
1633 {0x00, 0x3a, 0xc3, 0xaa},
1634 {0x00, 0x3b, 0xd2, 0xaa},
1635 {0x00, 0x3c, 0xe1, 0xaa},
1636 {0x00, 0x3e, 0xff, 0xaa},
1637 {0x00, 0x3f, 0xff, 0xaa},
1638 {0x00, 0x40, 0xff, 0xaa},
1639 {0x00, 0x41, 0xff, 0xaa},
1640 {0x00, 0x42, 0xff, 0xaa},
1641 {0x00, 0x43, 0xff, 0xaa},
1642 {0x00, 0x03, 0x00, 0xaa},
1643 {0x00, 0x03, 0x00, 0xaa},
1644 {0x00, 0x20, 0xc4, 0xaa},
1645 {0x00, 0x13, 0x03, 0xaa},
1646 {0x00, 0x3c, 0x50, 0xaa},
1647 {0x00, 0x61, 0x6a, 0xaa}, /* sharpness? */
1648 {0x00, 0x51, 0x5b, 0xaa},
1649 {0x00, 0x52, 0x91, 0xaa},
1650 {0x00, 0x53, 0x4c, 0xaa},
1651 {0x00, 0x54, 0x50, 0xaa},
1652 {0x00, 0x56, 0x02, 0xaa},
1653 {0xb6, 0x00, 0x00, 0xcc},
1654 {0xb6, 0x03, 0x03, 0xcc},
1655 {0xb6, 0x02, 0x20, 0xcc},
1656 {0xb6, 0x05, 0x02, 0xcc},
1657 {0xb6, 0x04, 0x58, 0xcc},
1658 {0xb6, 0x12, 0xf8, 0xcc},
1659 {0xb6, 0x13, 0x21, 0xcc},
1660 {0xb6, 0x18, 0x03, 0xcc},
1661 {0xb6, 0x17, 0xa9, 0xcc},
1662 {0xb6, 0x16, 0x80, 0xcc},
1663 {0xb6, 0x22, 0x12, 0xcc},
1664 {0xb6, 0x23, 0x0b, 0xcc},
1665 {0xbf, 0xc0, 0x39, 0xcc},
1666 {0xbf, 0xc1, 0x04, 0xcc},
1667 {0xbf, 0xcc, 0x00, 0xcc},
1668 {0xb8, 0x06, 0x20, 0xcc},
1669 {0xb8, 0x07, 0x03, 0xcc},
1670 {0xb8, 0x08, 0x58, 0xcc},
1671 {0xb8, 0x09, 0x02, 0xcc},
1672 {0xb3, 0x01, 0x41, 0xcc},
1673 {0x00, 0x03, 0x00, 0xaa},
1674 {0x00, 0xd9, 0x0f, 0xaa},
1675 {0x00, 0xda, 0xaa, 0xaa},
1676 {0x00, 0xd9, 0x10, 0xaa},
1677 {0x00, 0xda, 0xaa, 0xaa},
1678 {0x00, 0xd9, 0x11, 0xaa},
1679 {0x00, 0xda, 0x00, 0xaa},
1680 {0x00, 0xd9, 0x12, 0xaa},
1681 {0x00, 0xda, 0xff, 0xaa},
1682 {0x00, 0xd9, 0x13, 0xaa},
1683 {0x00, 0xda, 0xff, 0xaa},
1684 {0x00, 0xe8, 0x11, 0xaa},
1685 {0x00, 0xe9, 0x12, 0xaa},
1686 {0x00, 0xea, 0x5c, 0xaa},
1687 {0x00, 0xeb, 0xff, 0xaa},
1688 {0x00, 0xd8, 0x80, 0xaa},
1689 {0x00, 0xe6, 0x02, 0xaa},
1690 {0x00, 0xd6, 0x40, 0xaa},
1691 {0x00, 0xe3, 0x05, 0xaa},
1692 {0x00, 0xe0, 0x40, 0xaa},
1693 {0x00, 0xde, 0x03, 0xaa},
1694 {0x00, 0xdf, 0x03, 0xaa},
1695 {0x00, 0xdb, 0x02, 0xaa},
1696 {0x00, 0xdc, 0x00, 0xaa},
1697 {0x00, 0xdd, 0x03, 0xaa},
1698 {0x00, 0xe1, 0x08, 0xaa},
1699 {0x00, 0xe2, 0x01, 0xaa},
1700 {0x00, 0xd6, 0x40, 0xaa},
1701 {0x00, 0xe4, 0x40, 0xaa},
1702 {0x00, 0xa8, 0x8f, 0xaa},
1703 {0x00, 0xb4, 0x16, 0xaa},
1704 {0xb0, 0x02, 0x06, 0xcc},
1705 {0xb0, 0x18, 0x06, 0xcc},
1706 {0xb0, 0x19, 0x06, 0xcc},
1707 {0xb3, 0x5d, 0x18, 0xcc},
1708 {0xb3, 0x05, 0x00, 0xcc},
1709 {0xb3, 0x06, 0x00, 0xcc},
1710 {0x00, 0xb4, 0x0e, 0xaa},
1711 {0x00, 0xb5, 0x49, 0xaa},
1712 {0x00, 0xb6, 0x1c, 0xaa},
1713 {0x00, 0xb7, 0x96, 0xaa},
1714/* end of usbvm326.inf - start of ms-win trace */
1715 {0xb6, 0x12, 0xf8, 0xcc},
1716 {0xb6, 0x13, 0x3d, 0xcc},
1717/*read b306*/
1718 {0x00, 0x03, 0x00, 0xaa},
1719 {0x00, 0x1a, 0x09, 0xaa},
1720 {0x00, 0x1b, 0x8a, 0xaa},
1721/*read b827*/
1722 {0xb8, 0x27, 0x00, 0xcc},
1723 {0xb8, 0x26, 0x60, 0xcc},
1724 {0xb8, 0x26, 0x60, 0xcc},
1725/*gamma - to do?*/
1726 {0x00, 0x03, 0x00, 0xaa},
1727 {0x00, 0xae, 0x84, 0xaa},
1728/*gamma again*/
1729 {0x00, 0x03, 0x00, 0xaa},
1730 {0x00, 0x96, 0xa0, 0xaa},
1731/*matrix*/
1732 {0x00, 0x03, 0x00, 0xaa},
1733 {0x00, 0x91, 0x35, 0xaa},
1734 {0x00, 0x92, 0x22, 0xaa},
1735/*gamma*/
1736 {0x00, 0x03, 0x00, 0xaa},
1737 {0x00, 0x95, 0x85, 0xaa},
1738/*matrix*/
1739 {0x00, 0x03, 0x00, 0xaa},
1740 {0x00, 0x4d, 0x20, 0xaa},
1741 {0xb8, 0x22, 0x40, 0xcc},
1742 {0xb8, 0x23, 0x40, 0xcc},
1743 {0xb8, 0x24, 0x40, 0xcc},
1744 {0xb8, 0x81, 0x09, 0xcc},
1745 {0x00, 0x00, 0x64, 0xdd},
1746 {0x00, 0x03, 0x01, 0xaa},
1747/*read 46*/
1748 {0x00, 0x46, 0x3c, 0xaa},
1749 {0x00, 0x03, 0x00, 0xaa},
1750 {0x00, 0x16, 0x40, 0xaa},
1751 {0x00, 0x17, 0x40, 0xaa},
1752 {0x00, 0x18, 0x40, 0xaa},
1753 {0x00, 0x19, 0x41, 0xaa},
1754 {0x00, 0x03, 0x01, 0xaa},
1755 {0x00, 0x46, 0x3c, 0xaa},
1756 {0x00, 0x00, 0x18, 0xdd},
1757/*read bfff*/
1758 {0x00, 0x03, 0x00, 0xaa},
1759 {0x00, 0xb4, 0x1c, 0xaa},
1760 {0x00, 0xb5, 0x92, 0xaa},
1761 {0x00, 0xb6, 0x39, 0xaa},
1762 {0x00, 0xb7, 0x24, 0xaa},
1763/*write 89 0400 1415*/
1764};
1765
1207struct sensor_info { 1766struct sensor_info {
1208 int sensorId; 1767 int sensorId;
1209 __u8 I2cAdd; 1768 __u8 I2cAdd;
@@ -1222,6 +1781,9 @@ static const struct sensor_info sensor_info_data[] = {
1222 {SENSOR_MI1320, 0x80 | 0xc8, 0x00, 0x148c, 0x64, 0x65, 0x01}, 1781 {SENSOR_MI1320, 0x80 | 0xc8, 0x00, 0x148c, 0x64, 0x65, 0x01},
1223 {SENSOR_OV7670, 0x80 | 0x21, 0x0a, 0x7673, 0x66, 0x67, 0x05}, 1782 {SENSOR_OV7670, 0x80 | 0x21, 0x0a, 0x7673, 0x66, 0x67, 0x05},
1224 {SENSOR_MI1310_SOC, 0x80 | 0x5d, 0x00, 0x143a, 0x24, 0x25, 0x01}, 1783 {SENSOR_MI1310_SOC, 0x80 | 0x5d, 0x00, 0x143a, 0x24, 0x25, 0x01},
1784/* (tested in vc032x_probe_sensor) */
1785/* {SENSOR_MI0360, 0x80 | 0x5d, 0x00, 0x8243, 0x24, 0x25, 0x01}, */
1786 {SENSOR_PO1200, 0x80 | 0x5c, 0x00, 0x1200, 0x67, 0x67, 0x01},
1225}; 1787};
1226 1788
1227/* read 'len' bytes in gspca_dev->usb_buf */ 1789/* read 'len' bytes in gspca_dev->usb_buf */
@@ -1278,18 +1840,18 @@ static void read_sensor_register(struct gspca_dev *gspca_dev,
1278 msleep(1); 1840 msleep(1);
1279 } 1841 }
1280 reg_r(gspca_dev, 0xa1, 0xb33e, 1); 1842 reg_r(gspca_dev, 0xa1, 0xb33e, 1);
1281 hdata = gspca_dev->usb_buf[0]; 1843 ldata = gspca_dev->usb_buf[0];
1282 reg_r(gspca_dev, 0xa1, 0xb33d, 1); 1844 reg_r(gspca_dev, 0xa1, 0xb33d, 1);
1283 mdata = gspca_dev->usb_buf[0]; 1845 mdata = gspca_dev->usb_buf[0];
1284 reg_r(gspca_dev, 0xa1, 0xb33c, 1); 1846 reg_r(gspca_dev, 0xa1, 0xb33c, 1);
1285 ldata = gspca_dev->usb_buf[0]; 1847 hdata = gspca_dev->usb_buf[0];
1286 PDEBUG(D_PROBE, "Read Sensor h (0x%02X) m (0x%02X) l (0x%02X)", 1848 PDEBUG(D_PROBE, "Read Sensor %02x%02x %02x",
1287 hdata, mdata, ldata); 1849 hdata, mdata, ldata);
1288 reg_r(gspca_dev, 0xa1, 0xb334, 1); 1850 reg_r(gspca_dev, 0xa1, 0xb334, 1);
1289 if (gspca_dev->usb_buf[0] == 0x02) 1851 if (gspca_dev->usb_buf[0] == 0x02)
1290 *value = (ldata << 8) + mdata; 1852 *value = (hdata << 8) + mdata;
1291 else 1853 else
1292 *value = ldata; 1854 *value = hdata;
1293} 1855}
1294 1856
1295static int vc032x_probe_sensor(struct gspca_dev *gspca_dev) 1857static int vc032x_probe_sensor(struct gspca_dev *gspca_dev)
@@ -1300,7 +1862,7 @@ static int vc032x_probe_sensor(struct gspca_dev *gspca_dev)
1300 const struct sensor_info *ptsensor_info; 1862 const struct sensor_info *ptsensor_info;
1301 1863
1302 reg_r(gspca_dev, 0xa1, 0xbfcf, 1); 1864 reg_r(gspca_dev, 0xa1, 0xbfcf, 1);
1303 PDEBUG(D_PROBE, "check sensor header %d", gspca_dev->usb_buf[0]); 1865 PDEBUG(D_PROBE, "check sensor header %02x", gspca_dev->usb_buf[0]);
1304 for (i = 0; i < ARRAY_SIZE(sensor_info_data); i++) { 1866 for (i = 0; i < ARRAY_SIZE(sensor_info_data); i++) {
1305 ptsensor_info = &sensor_info_data[i]; 1867 ptsensor_info = &sensor_info_data[i];
1306 reg_w(dev, 0xa0, 0x02, 0xb334); 1868 reg_w(dev, 0xa0, 0x02, 0xb334);
@@ -1309,16 +1871,15 @@ static int vc032x_probe_sensor(struct gspca_dev *gspca_dev)
1309 reg_w(dev, 0xa0, 0x01, 0xb308); 1871 reg_w(dev, 0xa0, 0x01, 0xb308);
1310 reg_w(dev, 0xa0, 0x0c, 0xb309); 1872 reg_w(dev, 0xa0, 0x0c, 0xb309);
1311 reg_w(dev, 0xa0, ptsensor_info->I2cAdd, 0xb335); 1873 reg_w(dev, 0xa0, ptsensor_info->I2cAdd, 0xb335);
1312/* PDEBUG(D_PROBE,
1313 "check sensor VC032X -> %d Add -> ox%02X!",
1314 i, ptsensor_info->I2cAdd); */
1315 reg_w(dev, 0xa0, ptsensor_info->op, 0xb301); 1874 reg_w(dev, 0xa0, ptsensor_info->op, 0xb301);
1316 read_sensor_register(gspca_dev, ptsensor_info->IdAdd, &value); 1875 read_sensor_register(gspca_dev, ptsensor_info->IdAdd, &value);
1317 if (value == ptsensor_info->VpId) { 1876 if (value == ptsensor_info->VpId)
1318/* PDEBUG(D_PROBE, "find sensor VC032X -> ox%04X!",
1319 ptsensor_info->VpId); */
1320 return ptsensor_info->sensorId; 1877 return ptsensor_info->sensorId;
1321 } 1878
1879 /* special case for MI0360 */
1880 if (ptsensor_info->sensorId == SENSOR_MI1310_SOC
1881 && value == 0x8243)
1882 return SENSOR_MI0360;
1322 } 1883 }
1323 return -1; 1884 return -1;
1324} 1885}
@@ -1420,13 +1981,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
1420 cam = &gspca_dev->cam; 1981 cam = &gspca_dev->cam;
1421 cam->epaddr = 0x02; 1982 cam->epaddr = 0x02;
1422 sd->bridge = id->driver_info; 1983 sd->bridge = id->driver_info;
1423 if (sd->bridge == BRIDGE_VC0321) {
1424 cam->cam_mode = vc0321_mode;
1425 cam->nmodes = ARRAY_SIZE(vc0321_mode);
1426 } else {
1427 cam->cam_mode = vc0323_mode;
1428 cam->nmodes = ARRAY_SIZE(vc0323_mode);
1429 }
1430 1984
1431 vc0321_reset(gspca_dev); 1985 vc0321_reset(gspca_dev);
1432 sensor = vc032x_probe_sensor(gspca_dev); 1986 sensor = vc032x_probe_sensor(gspca_dev);
@@ -1436,35 +1990,66 @@ static int sd_config(struct gspca_dev *gspca_dev,
1436 return -EINVAL; 1990 return -EINVAL;
1437 case SENSOR_HV7131R: 1991 case SENSOR_HV7131R:
1438 PDEBUG(D_PROBE, "Find Sensor HV7131R"); 1992 PDEBUG(D_PROBE, "Find Sensor HV7131R");
1439 sd->sensor = SENSOR_HV7131R; 1993 break;
1994 case SENSOR_MI0360:
1995 PDEBUG(D_PROBE, "Find Sensor MI0360");
1996 sd->bridge = BRIDGE_VC0323;
1440 break; 1997 break;
1441 case SENSOR_MI1310_SOC: 1998 case SENSOR_MI1310_SOC:
1442 PDEBUG(D_PROBE, "Find Sensor MI1310_SOC"); 1999 PDEBUG(D_PROBE, "Find Sensor MI1310_SOC");
1443 sd->sensor = SENSOR_MI1310_SOC;
1444 break; 2000 break;
1445 case SENSOR_MI1320: 2001 case SENSOR_MI1320:
1446 PDEBUG(D_PROBE, "Find Sensor MI1320"); 2002 PDEBUG(D_PROBE, "Find Sensor MI1320");
1447 sd->sensor = SENSOR_MI1320;
1448 break; 2003 break;
1449 case SENSOR_OV7660: 2004 case SENSOR_OV7660:
1450 PDEBUG(D_PROBE, "Find Sensor OV7660"); 2005 PDEBUG(D_PROBE, "Find Sensor OV7660");
1451 sd->sensor = SENSOR_OV7660;
1452 break; 2006 break;
1453 case SENSOR_OV7670: 2007 case SENSOR_OV7670:
1454 PDEBUG(D_PROBE, "Find Sensor OV7670"); 2008 PDEBUG(D_PROBE, "Find Sensor OV7670");
1455 sd->sensor = SENSOR_OV7670; 2009 break;
2010 case SENSOR_PO1200:
2011 PDEBUG(D_PROBE, "Find Sensor PO1200");
1456 break; 2012 break;
1457 case SENSOR_PO3130NC: 2013 case SENSOR_PO3130NC:
1458 PDEBUG(D_PROBE, "Find Sensor PO3130NC"); 2014 PDEBUG(D_PROBE, "Find Sensor PO3130NC");
1459 sd->sensor = SENSOR_PO3130NC;
1460 break; 2015 break;
1461 } 2016 }
2017 sd->sensor = sensor;
1462 2018
1463 sd->qindex = 7; 2019 if (sd->bridge == BRIDGE_VC0321) {
1464 sd->autogain = AUTOGAIN_DEF; 2020 cam->cam_mode = vc0321_mode;
2021 cam->nmodes = ARRAY_SIZE(vc0321_mode);
2022 } else {
2023 if (sensor != SENSOR_PO1200) {
2024 cam->cam_mode = vc0323_mode;
2025 cam->nmodes = ARRAY_SIZE(vc0323_mode);
2026 } else {
2027 cam->cam_mode = svga_mode;
2028 cam->nmodes = ARRAY_SIZE(svga_mode);
2029 }
2030 }
2031
2032 sd->hflip = HFLIP_DEF;
2033 sd->vflip = VFLIP_DEF;
2034 if (sd->sensor == SENSOR_OV7670) {
2035 sd->hflip = 1;
2036 sd->vflip = 1;
2037 }
1465 sd->lightfreq = FREQ_DEF; 2038 sd->lightfreq = FREQ_DEF;
1466 if (sd->sensor != SENSOR_OV7670) 2039 if (sd->sensor != SENSOR_OV7670)
1467 gspca_dev->ctrl_dis = (1 << LIGHTFREQ_IDX); 2040 gspca_dev->ctrl_dis = (1 << LIGHTFREQ_IDX);
2041 switch (sd->sensor) {
2042 case SENSOR_OV7660:
2043 case SENSOR_OV7670:
2044 case SENSOR_PO1200:
2045 break;
2046 default:
2047 gspca_dev->ctrl_dis = (1 << HFLIP_IDX)
2048 | (1 << VFLIP_IDX);
2049 break;
2050 }
2051
2052 sd->sharpness = SHARPNESS_DEF;
1468 2053
1469 if (sd->bridge == BRIDGE_VC0321) { 2054 if (sd->bridge == BRIDGE_VC0321) {
1470 reg_r(gspca_dev, 0x8a, 0, 3); 2055 reg_r(gspca_dev, 0x8a, 0, 3);
@@ -1482,12 +2067,33 @@ static int sd_init(struct gspca_dev *gspca_dev)
1482 return 0; 2067 return 0;
1483} 2068}
1484 2069
1485static void setquality(struct gspca_dev *gspca_dev) 2070/* for OV7660 and OV7670 only */
2071static void sethvflip(struct gspca_dev *gspca_dev)
1486{ 2072{
1487} 2073 struct sd *sd = (struct sd *) gspca_dev;
2074 __u8 data;
1488 2075
1489static void setautogain(struct gspca_dev *gspca_dev) 2076 switch (sd->sensor) {
1490{ 2077 case SENSOR_OV7660:
2078 data = 1;
2079 break;
2080 case SENSOR_OV7670:
2081 data = 7;
2082 break;
2083 case SENSOR_PO1200:
2084 data = 0;
2085 i2c_write(gspca_dev, 0x03, &data, 1);
2086 data = 0x80 * sd->hflip
2087 | 0x40 * sd->vflip
2088 | 0x06;
2089 i2c_write(gspca_dev, 0x1e, &data, 1);
2090 return;
2091 default:
2092 return;
2093 }
2094 data |= OV7660_MVFP_MIRROR * sd->hflip
2095 | OV7660_MVFP_VFLIP * sd->vflip;
2096 i2c_write(gspca_dev, OV7660_REG_MVFP, &data, 1);
1491} 2097}
1492 2098
1493static void setlightfreq(struct gspca_dev *gspca_dev) 2099static void setlightfreq(struct gspca_dev *gspca_dev)
@@ -1501,6 +2107,20 @@ static void setlightfreq(struct gspca_dev *gspca_dev)
1501 usb_exchange(gspca_dev, ov7660_freq_tb[sd->lightfreq]); 2107 usb_exchange(gspca_dev, ov7660_freq_tb[sd->lightfreq]);
1502} 2108}
1503 2109
2110/* po1200 only */
2111static void setsharpness(struct gspca_dev *gspca_dev)
2112{
2113 struct sd *sd = (struct sd *) gspca_dev;
2114 __u8 data;
2115
2116 if (sd->sensor != SENSOR_PO1200)
2117 return;
2118 data = 0;
2119 i2c_write(gspca_dev, 0x03, &data, 1);
2120 data = 0xb5 + sd->sharpness * 3;
2121 i2c_write(gspca_dev, 0x61, &data, 1);
2122}
2123
1504static int sd_start(struct gspca_dev *gspca_dev) 2124static int sd_start(struct gspca_dev *gspca_dev)
1505{ 2125{
1506 struct sd *sd = (struct sd *) gspca_dev; 2126 struct sd *sd = (struct sd *) gspca_dev;
@@ -1551,6 +2171,17 @@ static int sd_start(struct gspca_dev *gspca_dev)
1551 usb_exchange(gspca_dev, ov7670_initVGA_JPG); 2171 usb_exchange(gspca_dev, ov7670_initVGA_JPG);
1552 } 2172 }
1553 break; 2173 break;
2174 case SENSOR_MI0360:
2175 GammaT = mi1320_gamma;
2176 MatrixT = mi0360_matrix;
2177 if (mode) {
2178 /* 320x240 */
2179 usb_exchange(gspca_dev, mi0360_initQVGA_JPG);
2180 } else {
2181 /* 640x480 */
2182 usb_exchange(gspca_dev, mi0360_initVGA_JPG);
2183 }
2184 break;
1554 case SENSOR_MI1310_SOC: 2185 case SENSOR_MI1310_SOC:
1555 if (mode) { 2186 if (mode) {
1556 /* 320x240 */ 2187 /* 320x240 */
@@ -1583,6 +2214,11 @@ static int sd_start(struct gspca_dev *gspca_dev)
1583 } 2214 }
1584 usb_exchange(gspca_dev, po3130_rundata); 2215 usb_exchange(gspca_dev, po3130_rundata);
1585 break; 2216 break;
2217 case SENSOR_PO1200:
2218 GammaT = po1200_gamma;
2219 MatrixT = po1200_matrix;
2220 usb_exchange(gspca_dev, po1200_initVGA_data);
2221 break;
1586 default: 2222 default:
1587 PDEBUG(D_PROBE, "Damned !! no sensor found Bye"); 2223 PDEBUG(D_PROBE, "Damned !! no sensor found Bye");
1588 return -EMEDIUMTYPE; 2224 return -EMEDIUMTYPE;
@@ -1615,11 +2251,16 @@ static int sd_start(struct gspca_dev *gspca_dev)
1615 reg_w(gspca_dev->dev, 0xa0, 0x23, 0xb800); * ISP CTRL_BAS 2251 reg_w(gspca_dev->dev, 0xa0, 0x23, 0xb800); * ISP CTRL_BAS
1616 */ 2252 */
1617 /* set the led on 0x0892 0x0896 */ 2253 /* set the led on 0x0892 0x0896 */
1618 reg_w(gspca_dev->dev, 0x89, 0xffff, 0xfdff); 2254 if (sd->sensor != SENSOR_PO1200) {
1619 msleep(100); 2255 reg_w(gspca_dev->dev, 0x89, 0xffff, 0xfdff);
1620 setquality(gspca_dev); 2256 msleep(100);
1621 setautogain(gspca_dev); 2257 sethvflip(gspca_dev);
1622 setlightfreq(gspca_dev); 2258 setlightfreq(gspca_dev);
2259 } else {
2260 setsharpness(gspca_dev);
2261 sethvflip(gspca_dev);
2262 reg_w(gspca_dev->dev, 0x89, 0x0400, 0x1415);
2263 }
1623 } 2264 }
1624 return 0; 2265 return 0;
1625} 2266}
@@ -1665,24 +2306,48 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1665 data, len); 2306 data, len);
1666 return; 2307 return;
1667 } 2308 }
2309
2310 /* The vc0321 sends some additional data after sending the complete
2311 * frame, we ignore this. */
2312 if (sd->bridge == BRIDGE_VC0321
2313 && len > frame->v4l2_buf.length - (frame->data_end - frame->data))
2314 len = frame->v4l2_buf.length - (frame->data_end - frame->data);
1668 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); 2315 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
1669} 2316}
1670 2317
1671static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val) 2318static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val)
2319{
2320 struct sd *sd = (struct sd *) gspca_dev;
2321
2322 sd->hflip = val;
2323 if (gspca_dev->streaming)
2324 sethvflip(gspca_dev);
2325 return 0;
2326}
2327
2328static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val)
2329{
2330 struct sd *sd = (struct sd *) gspca_dev;
2331
2332 *val = sd->hflip;
2333 return 0;
2334}
2335
2336static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val)
1672{ 2337{
1673 struct sd *sd = (struct sd *) gspca_dev; 2338 struct sd *sd = (struct sd *) gspca_dev;
1674 2339
1675 sd->autogain = val; 2340 sd->vflip = val;
1676 if (gspca_dev->streaming) 2341 if (gspca_dev->streaming)
1677 setautogain(gspca_dev); 2342 sethvflip(gspca_dev);
1678 return 0; 2343 return 0;
1679} 2344}
1680 2345
1681static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val) 2346static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val)
1682{ 2347{
1683 struct sd *sd = (struct sd *) gspca_dev; 2348 struct sd *sd = (struct sd *) gspca_dev;
1684 2349
1685 *val = sd->autogain; 2350 *val = sd->vflip;
1686 return 0; 2351 return 0;
1687} 2352}
1688 2353
@@ -1704,6 +2369,24 @@ static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val)
1704 return 0; 2369 return 0;
1705} 2370}
1706 2371
2372static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val)
2373{
2374 struct sd *sd = (struct sd *) gspca_dev;
2375
2376 sd->sharpness = val;
2377 if (gspca_dev->streaming)
2378 setsharpness(gspca_dev);
2379 return 0;
2380}
2381
2382static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val)
2383{
2384 struct sd *sd = (struct sd *) gspca_dev;
2385
2386 *val = sd->sharpness;
2387 return 0;
2388}
2389
1707static int sd_querymenu(struct gspca_dev *gspca_dev, 2390static int sd_querymenu(struct gspca_dev *gspca_dev,
1708 struct v4l2_querymenu *menu) 2391 struct v4l2_querymenu *menu)
1709{ 2392{
@@ -1743,11 +2426,13 @@ static const struct sd_desc sd_desc = {
1743static const __devinitdata struct usb_device_id device_table[] = { 2426static const __devinitdata struct usb_device_id device_table[] = {
1744 {USB_DEVICE(0x046d, 0x0892), .driver_info = BRIDGE_VC0321}, 2427 {USB_DEVICE(0x046d, 0x0892), .driver_info = BRIDGE_VC0321},
1745 {USB_DEVICE(0x046d, 0x0896), .driver_info = BRIDGE_VC0321}, 2428 {USB_DEVICE(0x046d, 0x0896), .driver_info = BRIDGE_VC0321},
2429 {USB_DEVICE(0x046d, 0x0897), .driver_info = BRIDGE_VC0321},
1746 {USB_DEVICE(0x0ac8, 0x0321), .driver_info = BRIDGE_VC0321}, 2430 {USB_DEVICE(0x0ac8, 0x0321), .driver_info = BRIDGE_VC0321},
1747 {USB_DEVICE(0x0ac8, 0x0323), .driver_info = BRIDGE_VC0323}, 2431 {USB_DEVICE(0x0ac8, 0x0323), .driver_info = BRIDGE_VC0323},
1748 {USB_DEVICE(0x0ac8, 0x0328), .driver_info = BRIDGE_VC0321}, 2432 {USB_DEVICE(0x0ac8, 0x0328), .driver_info = BRIDGE_VC0321},
1749 {USB_DEVICE(0x0ac8, 0xc001), .driver_info = BRIDGE_VC0321}, 2433 {USB_DEVICE(0x0ac8, 0xc001), .driver_info = BRIDGE_VC0321},
1750 {USB_DEVICE(0x0ac8, 0xc002), .driver_info = BRIDGE_VC0321}, 2434 {USB_DEVICE(0x0ac8, 0xc002), .driver_info = BRIDGE_VC0321},
2435 {USB_DEVICE(0x15b8, 0x6002), .driver_info = BRIDGE_VC0323},
1751 {USB_DEVICE(0x17ef, 0x4802), .driver_info = BRIDGE_VC0323}, 2436 {USB_DEVICE(0x17ef, 0x4802), .driver_info = BRIDGE_VC0323},
1752 {} 2437 {}
1753}; 2438};
diff --git a/drivers/media/video/gspca/zc3xx-reg.h b/drivers/media/video/gspca/zc3xx-reg.h
index f52e09c2cc19..bfb559c3b713 100644
--- a/drivers/media/video/gspca/zc3xx-reg.h
+++ b/drivers/media/video/gspca/zc3xx-reg.h
@@ -244,14 +244,6 @@
244#define ZC3XX_R1CA_SHARPNESS04 0x01ca 244#define ZC3XX_R1CA_SHARPNESS04 0x01ca
245#define ZC3XX_R1CB_SHARPNESS05 0x01cb 245#define ZC3XX_R1CB_SHARPNESS05 0x01cb
246 246
247/* Synchronization */
248#define ZC3XX_R190_SYNC00LOW 0x0190
249#define ZC3XX_R191_SYNC00MID 0x0191
250#define ZC3XX_R192_SYNC00HIGH 0x0192
251#define ZC3XX_R195_SYNC01LOW 0x0195
252#define ZC3XX_R196_SYNC01MID 0x0196
253#define ZC3XX_R197_SYNC01HIGH 0x0197
254
255/* Dead pixels */ 247/* Dead pixels */
256#define ZC3XX_R250_DEADPIXELSMODE 0x0250 248#define ZC3XX_R250_DEADPIXELSMODE 0x0250
257 249
diff --git a/drivers/media/video/gspca/zc3xx.c b/drivers/media/video/gspca/zc3xx.c
index 0befacf49855..ec2a53d53fe2 100644
--- a/drivers/media/video/gspca/zc3xx.c
+++ b/drivers/media/video/gspca/zc3xx.c
@@ -51,16 +51,16 @@ struct sd {
51#define SENSOR_CS2102 0 51#define SENSOR_CS2102 0
52#define SENSOR_CS2102K 1 52#define SENSOR_CS2102K 1
53#define SENSOR_GC0305 2 53#define SENSOR_GC0305 2
54#define SENSOR_HDCS2020 3 54#define SENSOR_HDCS2020b 3
55#define SENSOR_HDCS2020b 4 55#define SENSOR_HV7131B 4
56#define SENSOR_HV7131B 5 56#define SENSOR_HV7131C 5
57#define SENSOR_HV7131C 6 57#define SENSOR_ICM105A 6
58#define SENSOR_ICM105A 7 58#define SENSOR_MC501CB 7
59#define SENSOR_MC501CB 8 59#define SENSOR_OV7620 8
60#define SENSOR_OV7620 9 60/*#define SENSOR_OV7648 8 - same values */
61/*#define SENSOR_OV7648 9 - same values */ 61#define SENSOR_OV7630C 9
62#define SENSOR_OV7630C 10 62#define SENSOR_PAS106 10
63#define SENSOR_PAS106 11 63#define SENSOR_PAS202B 11
64#define SENSOR_PB0330 12 64#define SENSOR_PB0330 12
65#define SENSOR_PO2030 13 65#define SENSOR_PO2030 13
66#define SENSOR_TAS5130CK 14 66#define SENSOR_TAS5130CK 14
@@ -173,7 +173,7 @@ static struct ctrl sd_ctrls[] = {
173 }, 173 },
174}; 174};
175 175
176static struct v4l2_pix_format vga_mode[] = { 176static const struct v4l2_pix_format vga_mode[] = {
177 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 177 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
178 .bytesperline = 320, 178 .bytesperline = 320,
179 .sizeimage = 320 * 240 * 3 / 8 + 590, 179 .sizeimage = 320 * 240 * 3 / 8 + 590,
@@ -186,7 +186,7 @@ static struct v4l2_pix_format vga_mode[] = {
186 .priv = 0}, 186 .priv = 0},
187}; 187};
188 188
189static struct v4l2_pix_format sif_mode[] = { 189static const struct v4l2_pix_format sif_mode[] = {
190 {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 190 {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
191 .bytesperline = 176, 191 .bytesperline = 176,
192 .sizeimage = 176 * 144 * 3 / 8 + 590, 192 .sizeimage = 176 * 144 * 3 / 8 + 590,
@@ -1653,295 +1653,6 @@ static const struct usb_action gc0305_NoFliker[] = {
1653 {} 1653 {}
1654}; 1654};
1655 1655
1656/* play poker with registers at your own risk !! */
1657static const struct usb_action hdcs2020xx_Initial[] = {
1658 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
1659 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
1660 {0xa0, 0x0e, ZC3XX_R010_CMOSSENSORSELECT},
1661 {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT},
1662 {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH},
1663 {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW},
1664 {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH},
1665 {0xa0, 0xd0, ZC3XX_R006_FRAMEHEIGHTLOW},
1666 /* D0 ?? E0 did not start */
1667 {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING},
1668 {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC},
1669 {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC},
1670 {0xa0, 0x08, ZC3XX_R08D_COMPABILITYMODE},
1671 {0xa0, 0x08, ZC3XX_R098_WINYSTARTLOW},
1672 {0xa0, 0x02, ZC3XX_R09A_WINXSTARTLOW},
1673 {0xa0, 0x08, ZC3XX_R11A_FIRSTYLOW},
1674 {0xa0, 0x02, ZC3XX_R11C_FIRSTXLOW},
1675 {0xa0, 0x01, ZC3XX_R09B_WINHEIGHTHIGH},
1676 {0xa0, 0xd8, ZC3XX_R09C_WINHEIGHTLOW},
1677 {0xa0, 0x02, ZC3XX_R09D_WINWIDTHHIGH},
1678 {0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW},
1679 {0xaa, 0x02, 0x0002},
1680 {0xaa, 0x07, 0x0006},
1681 {0xaa, 0x08, 0x0002},
1682 {0xaa, 0x09, 0x0006},
1683 {0xaa, 0x0a, 0x0001},
1684 {0xaa, 0x0b, 0x0001},
1685 {0xaa, 0x0c, 0x0008},
1686 {0xaa, 0x0d, 0x0000},
1687 {0xaa, 0x10, 0x0000},
1688 {0xaa, 0x12, 0x0005},
1689 {0xaa, 0x13, 0x0063},
1690 {0xaa, 0x15, 0x0070},
1691 {0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION},
1692 {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE},
1693 {0xa0, 0x06, ZC3XX_R189_AWBSTATUS},
1694 {0xa0, 0x00, 0x01ad},
1695 {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE},
1696 {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05},
1697 {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},
1698 {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
1699 {0xa0, 0x70, ZC3XX_R18D_YTARGET},
1700 {0xa1, 0x01, 0x0002},
1701 {0xa1, 0x01, 0x0008},
1702 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */
1703 {0xa0, 0x04, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */
1704 {0xa1, 0x01, 0x01c8},
1705 {0xa1, 0x01, 0x01c9},
1706 {0xa1, 0x01, 0x01ca},
1707 {0xa0, 0x07, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */
1708 {0xa0, 0x11, ZC3XX_R120_GAMMA00}, /* gamma ~4 */
1709 {0xa0, 0x37, ZC3XX_R121_GAMMA01},
1710 {0xa0, 0x58, ZC3XX_R122_GAMMA02},
1711 {0xa0, 0x79, ZC3XX_R123_GAMMA03},
1712 {0xa0, 0x91, ZC3XX_R124_GAMMA04},
1713 {0xa0, 0xa6, ZC3XX_R125_GAMMA05},
1714 {0xa0, 0xb8, ZC3XX_R126_GAMMA06},
1715 {0xa0, 0xc7, ZC3XX_R127_GAMMA07},
1716 {0xa0, 0xd3, ZC3XX_R128_GAMMA08},
1717 {0xa0, 0xde, ZC3XX_R129_GAMMA09},
1718 {0xa0, 0xe6, ZC3XX_R12A_GAMMA0A},
1719 {0xa0, 0xed, ZC3XX_R12B_GAMMA0B},
1720 {0xa0, 0xf3, ZC3XX_R12C_GAMMA0C},
1721 {0xa0, 0xf8, ZC3XX_R12D_GAMMA0D},
1722 {0xa0, 0xfb, ZC3XX_R12E_GAMMA0E},
1723 {0xa0, 0xff, ZC3XX_R12F_GAMMA0F},
1724 {0xa0, 0x26, ZC3XX_R130_GAMMA10},
1725 {0xa0, 0x23, ZC3XX_R131_GAMMA11},
1726 {0xa0, 0x20, ZC3XX_R132_GAMMA12},
1727 {0xa0, 0x1c, ZC3XX_R133_GAMMA13},
1728 {0xa0, 0x16, ZC3XX_R134_GAMMA14},
1729 {0xa0, 0x13, ZC3XX_R135_GAMMA15},
1730 {0xa0, 0x10, ZC3XX_R136_GAMMA16},
1731 {0xa0, 0x0d, ZC3XX_R137_GAMMA17},
1732 {0xa0, 0x0b, ZC3XX_R138_GAMMA18},
1733 {0xa0, 0x09, ZC3XX_R139_GAMMA19},
1734 {0xa0, 0x07, ZC3XX_R13A_GAMMA1A},
1735 {0xa0, 0x06, ZC3XX_R13B_GAMMA1B},
1736 {0xa0, 0x05, ZC3XX_R13C_GAMMA1C},
1737 {0xa0, 0x04, ZC3XX_R13D_GAMMA1D},
1738 {0xa0, 0x03, ZC3XX_R13E_GAMMA1E},
1739 {0xa0, 0x02, ZC3XX_R13F_GAMMA1F},
1740
1741 {0xa0, 0x4c, ZC3XX_R10A_RGB00}, /* matrix */
1742 {0xa0, 0xf5, ZC3XX_R10B_RGB01},
1743 {0xa0, 0xff, ZC3XX_R10C_RGB02},
1744 {0xa0, 0xf9, ZC3XX_R10D_RGB10},
1745 {0xa0, 0x51, ZC3XX_R10E_RGB11},
1746 {0xa0, 0xf5, ZC3XX_R10F_RGB12},
1747 {0xa0, 0xfb, ZC3XX_R110_RGB20},
1748 {0xa0, 0xed, ZC3XX_R111_RGB21},
1749 {0xa0, 0x5f, ZC3XX_R112_RGB22},
1750
1751 {0xa1, 0x01, 0x0180},
1752 {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
1753 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
1754 {0xa0, 0x20, ZC3XX_R087_EXPTIMEMID},
1755 {0xa0, 0x21, ZC3XX_R088_EXPTIMELOW},
1756 {0xaa, 0x20, 0x0004},
1757 {0xaa, 0x21, 0x003d},
1758 {0xaa, 0x03, 0x0041},
1759 {0xaa, 0x04, 0x0010},
1760 {0xaa, 0x05, 0x003d},
1761 {0xaa, 0x0e, 0x0001},
1762 {0xaa, 0x0f, 0x0000},
1763 {0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF},
1764 {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP},
1765 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
1766 {0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID},
1767 {0xa0, 0x3d, ZC3XX_R192_EXPOSURELIMITLOW},
1768 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
1769 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
1770 {0xa0, 0x9b, ZC3XX_R197_ANTIFLICKERLOW},
1771 {0xa0, 0x10, ZC3XX_R18C_AEFREEZE},
1772 {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE},
1773 {0xa0, 0x41, ZC3XX_R01D_HSYNC_0},
1774 {0xa0, 0x6f, ZC3XX_R01E_HSYNC_1},
1775 {0xa0, 0xad, ZC3XX_R01F_HSYNC_2},
1776 {0xa0, 0xff, ZC3XX_R020_HSYNC_3},
1777 {0xa0, 0x0f, ZC3XX_R087_EXPTIMEMID},
1778 {0xa0, 0x0e, ZC3XX_R088_EXPTIMELOW},
1779 {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE},
1780 {0xa1, 0x01, 0x0195},
1781 {0xa1, 0x01, 0x0196},
1782 {0xa1, 0x01, 0x0197},
1783 {0xa0, 0x3d, ZC3XX_R192_EXPOSURELIMITLOW},
1784 {0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID},
1785 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
1786 {0xa0, 0x1d, ZC3XX_R116_RGAIN},
1787 {0xa0, 0x40, ZC3XX_R117_GGAIN},
1788 {0xa0, 0x85, ZC3XX_R118_BGAIN},
1789 {0xa1, 0x01, 0x0116},
1790 {0xa1, 0x01, 0x0118},
1791 {0xa1, 0x01, 0x0180},
1792 {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
1793 {0xa0, 0x1d, ZC3XX_R116_RGAIN},
1794 {0xa0, 0x40, ZC3XX_R117_GGAIN},
1795 {0xa0, 0x85, ZC3XX_R118_BGAIN},
1796 {0xa1, 0x01, 0x0116},
1797 {0xa1, 0x01, 0x0118},
1798/* {0xa0, 0x02, ZC3XX_R008_CLOCKSETTING}, */
1799 {0xa0, 0x00, 0x0007},
1800 {}
1801};
1802
1803static const struct usb_action hdcs2020xx_InitialScale[] = {
1804 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
1805 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
1806 {0xa0, 0x0e, ZC3XX_R010_CMOSSENSORSELECT},
1807 {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT},
1808 {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH},
1809 {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW},
1810 {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH},
1811 {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW},
1812 {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING},
1813 {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC},
1814 {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC},
1815 {0xa0, 0x08, ZC3XX_R08D_COMPABILITYMODE},
1816 {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW},
1817 {0xa0, 0x03, ZC3XX_R09A_WINXSTARTLOW},
1818 {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW},
1819 {0xa0, 0x03, ZC3XX_R11C_FIRSTXLOW},
1820 {0xa0, 0x01, ZC3XX_R09B_WINHEIGHTHIGH},
1821 {0xa0, 0xe6, ZC3XX_R09C_WINHEIGHTLOW},
1822 {0xa0, 0x02, ZC3XX_R09D_WINWIDTHHIGH},
1823 {0xa0, 0x86, ZC3XX_R09E_WINWIDTHLOW},
1824 {0xaa, 0x02, 0x0002},
1825 {0xaa, 0x07, 0x0006},
1826 {0xaa, 0x08, 0x0002},
1827 {0xaa, 0x09, 0x0006},
1828 {0xaa, 0x0a, 0x0001},
1829 {0xaa, 0x0b, 0x0001},
1830 {0xaa, 0x0c, 0x0008},
1831 {0xaa, 0x0d, 0x0000},
1832 {0xaa, 0x10, 0x0000},
1833 {0xaa, 0x12, 0x0005},
1834 {0xaa, 0x13, 0x0063},
1835 {0xaa, 0x15, 0x0070},
1836 {0xa0, 0xb7, ZC3XX_R101_SENSORCORRECTION},
1837 {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE},
1838 {0xa0, 0x06, ZC3XX_R189_AWBSTATUS},
1839 {0xa0, 0x00, 0x01ad},
1840 {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE},
1841 {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05},
1842 {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},
1843 {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
1844 {0xa0, 0x70, ZC3XX_R18D_YTARGET},
1845 {0xa1, 0x01, 0x0002},
1846 {0xa1, 0x01, 0x0008},
1847 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */
1848 {0xa0, 0x04, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */
1849 {0xa1, 0x01, 0x01c8},
1850 {0xa1, 0x01, 0x01c9},
1851 {0xa1, 0x01, 0x01ca},
1852 {0xa0, 0x07, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */
1853 {0xa0, 0x11, ZC3XX_R120_GAMMA00}, /* gamma ~4*/
1854 {0xa0, 0x37, ZC3XX_R121_GAMMA01},
1855 {0xa0, 0x58, ZC3XX_R122_GAMMA02},
1856 {0xa0, 0x79, ZC3XX_R123_GAMMA03},
1857 {0xa0, 0x91, ZC3XX_R124_GAMMA04},
1858 {0xa0, 0xa6, ZC3XX_R125_GAMMA05},
1859 {0xa0, 0xb8, ZC3XX_R126_GAMMA06},
1860 {0xa0, 0xc7, ZC3XX_R127_GAMMA07},
1861 {0xa0, 0xd3, ZC3XX_R128_GAMMA08},
1862 {0xa0, 0xde, ZC3XX_R129_GAMMA09},
1863 {0xa0, 0xe6, ZC3XX_R12A_GAMMA0A},
1864 {0xa0, 0xed, ZC3XX_R12B_GAMMA0B},
1865 {0xa0, 0xf3, ZC3XX_R12C_GAMMA0C},
1866 {0xa0, 0xf8, ZC3XX_R12D_GAMMA0D},
1867 {0xa0, 0xfb, ZC3XX_R12E_GAMMA0E},
1868 {0xa0, 0xff, ZC3XX_R12F_GAMMA0F},
1869 {0xa0, 0x26, ZC3XX_R130_GAMMA10},
1870 {0xa0, 0x23, ZC3XX_R131_GAMMA11},
1871 {0xa0, 0x20, ZC3XX_R132_GAMMA12},
1872 {0xa0, 0x1c, ZC3XX_R133_GAMMA13},
1873 {0xa0, 0x16, ZC3XX_R134_GAMMA14},
1874 {0xa0, 0x13, ZC3XX_R135_GAMMA15},
1875 {0xa0, 0x10, ZC3XX_R136_GAMMA16},
1876 {0xa0, 0x0d, ZC3XX_R137_GAMMA17},
1877 {0xa0, 0x0b, ZC3XX_R138_GAMMA18},
1878 {0xa0, 0x09, ZC3XX_R139_GAMMA19},
1879 {0xa0, 0x07, ZC3XX_R13A_GAMMA1A},
1880 {0xa0, 0x06, ZC3XX_R13B_GAMMA1B},
1881 {0xa0, 0x05, ZC3XX_R13C_GAMMA1C},
1882 {0xa0, 0x04, ZC3XX_R13D_GAMMA1D},
1883 {0xa0, 0x03, ZC3XX_R13E_GAMMA1E},
1884 {0xa0, 0x02, ZC3XX_R13F_GAMMA1F},
1885 {0xa0, 0x60, ZC3XX_R10A_RGB00}, /* matrix */
1886 {0xa0, 0xff, ZC3XX_R10B_RGB01},
1887 {0xa0, 0xff, ZC3XX_R10C_RGB02},
1888 {0xa0, 0xff, ZC3XX_R10D_RGB10},
1889 {0xa0, 0x60, ZC3XX_R10E_RGB11},
1890 {0xa0, 0xff, ZC3XX_R10F_RGB12},
1891 {0xa0, 0xff, ZC3XX_R110_RGB20},
1892 {0xa0, 0xff, ZC3XX_R111_RGB21},
1893 {0xa0, 0x60, ZC3XX_R112_RGB22},
1894
1895 {0xa1, 0x01, 0x0180},
1896 {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
1897 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
1898 {0xa0, 0x20, ZC3XX_R087_EXPTIMEMID},
1899 {0xa0, 0x21, ZC3XX_R088_EXPTIMELOW},
1900 {0xaa, 0x20, 0x0002},
1901 {0xaa, 0x21, 0x001b},
1902 {0xaa, 0x03, 0x0044},
1903 {0xaa, 0x04, 0x0008},
1904 {0xaa, 0x05, 0x001b},
1905 {0xaa, 0x0e, 0x0001},
1906 {0xaa, 0x0f, 0x0000},
1907 {0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF},
1908 {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP},
1909 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
1910 {0xa0, 0x02, ZC3XX_R191_EXPOSURELIMITMID},
1911 {0xa0, 0x1b, ZC3XX_R192_EXPOSURELIMITLOW},
1912 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
1913 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
1914 {0xa0, 0x4d, ZC3XX_R197_ANTIFLICKERLOW},
1915 {0xa0, 0x10, ZC3XX_R18C_AEFREEZE},
1916 {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE},
1917 {0xa0, 0x44, ZC3XX_R01D_HSYNC_0},
1918 {0xa0, 0x6f, ZC3XX_R01E_HSYNC_1},
1919 {0xa0, 0xad, ZC3XX_R01F_HSYNC_2},
1920 {0xa0, 0xeb, ZC3XX_R020_HSYNC_3},
1921 {0xa0, 0x0f, ZC3XX_R087_EXPTIMEMID},
1922 {0xa0, 0x0e, ZC3XX_R088_EXPTIMELOW},
1923 {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE},
1924 {0xa1, 0x01, 0x0195},
1925 {0xa1, 0x01, 0x0196},
1926 {0xa1, 0x01, 0x0197},
1927 {0xa0, 0x1b, ZC3XX_R192_EXPOSURELIMITLOW},
1928 {0xa0, 0x02, ZC3XX_R191_EXPOSURELIMITMID},
1929 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
1930 {0xa0, 0x1d, ZC3XX_R116_RGAIN},
1931 {0xa0, 0x40, ZC3XX_R117_GGAIN},
1932 {0xa0, 0x99, ZC3XX_R118_BGAIN},
1933 {0xa1, 0x01, 0x0116},
1934 {0xa1, 0x01, 0x0118},
1935 {0xa1, 0x01, 0x0180},
1936 {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
1937 {0xa0, 0x1d, ZC3XX_R116_RGAIN},
1938 {0xa0, 0x40, ZC3XX_R117_GGAIN},
1939 {0xa0, 0x99, ZC3XX_R118_BGAIN},
1940/* {0xa0, 0x02, ZC3XX_R008_CLOCKSETTING}, */
1941 {0xa0, 0x00, 0x0007},
1942/* {0xa0, 0x18, 0x00fe}, */
1943 {}
1944};
1945static const struct usb_action hdcs2020xb_Initial[] = { 1656static const struct usb_action hdcs2020xb_Initial[] = {
1946 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, 1657 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
1947 {0xa0, 0x11, ZC3XX_R002_CLOCKSELECT}, 1658 {0xa0, 0x11, ZC3XX_R002_CLOCKSELECT},
@@ -2310,67 +2021,6 @@ static const struct usb_action hv7131bxx_Initial[] = { /* 320x240 */
2310 {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, 2021 {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},
2311 {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, 2022 {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
2312 {0xaa, 0x02, 0x0090}, /* 00,02,80,aa */ 2023 {0xaa, 0x02, 0x0090}, /* 00,02,80,aa */
2313 {0xa1, 0x01, 0x0002},
2314 {0xa0, 0x00, ZC3XX_R092_I2CADDRESSSELECT},
2315 {0xa0, 0x02, ZC3XX_R090_I2CCOMMAND},
2316 {0xa1, 0x01, 0x0091},
2317 {0xa1, 0x01, 0x0095},
2318 {0xa1, 0x01, 0x0096},
2319
2320 {0xa1, 0x01, 0x0008},
2321 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */
2322 {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */
2323 {0xa1, 0x01, 0x01c8},
2324 {0xa1, 0x01, 0x01c9},
2325 {0xa1, 0x01, 0x01ca},
2326 {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */
2327
2328 {0xa0, 0x50, ZC3XX_R10A_RGB00}, /* matrix */
2329 {0xa0, 0xf8, ZC3XX_R10B_RGB01},
2330 {0xa0, 0xf8, ZC3XX_R10C_RGB02},
2331 {0xa0, 0xf8, ZC3XX_R10D_RGB10},
2332 {0xa0, 0x50, ZC3XX_R10E_RGB11},
2333 {0xa0, 0xf8, ZC3XX_R10F_RGB12},
2334 {0xa0, 0xf8, ZC3XX_R110_RGB20},
2335 {0xa0, 0xf8, ZC3XX_R111_RGB21},
2336 {0xa0, 0x50, ZC3XX_R112_RGB22},
2337 {0xa1, 0x01, 0x0180},
2338 {0xa0, 0x10, ZC3XX_R180_AUTOCORRECTENABLE},
2339 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
2340 {0xaa, 0x25, 0x0007},
2341 {0xaa, 0x26, 0x00a1},
2342 {0xaa, 0x27, 0x0020},
2343 {0xaa, 0x20, 0x0000},
2344 {0xaa, 0x21, 0x00a0},
2345 {0xaa, 0x22, 0x0016},
2346 {0xaa, 0x23, 0x0040},
2347
2348 {0xa0, 0x10, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 2F */
2349 {0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID}, /* 4d */
2350 {0xa0, 0x60, ZC3XX_R192_EXPOSURELIMITLOW},
2351 {0xa0, 0x01, ZC3XX_R195_ANTIFLICKERHIGH},
2352 {0xa0, 0x86, ZC3XX_R196_ANTIFLICKERMID},
2353 {0xa0, 0xa0, ZC3XX_R197_ANTIFLICKERLOW},
2354 {0xa0, 0x07, ZC3XX_R18C_AEFREEZE},
2355 {0xa0, 0x0f, ZC3XX_R18F_AEUNFREEZE},
2356 {0xa0, 0x18, ZC3XX_R1A9_DIGITALLIMITDIFF},
2357 {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP},
2358 {0xa0, 0x00, ZC3XX_R01D_HSYNC_0},
2359 {0xa0, 0xa0, ZC3XX_R01E_HSYNC_1},
2360 {0xa0, 0x16, ZC3XX_R01F_HSYNC_2},
2361 {0xa0, 0x40, ZC3XX_R020_HSYNC_3},
2362 {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN},
2363 {0xa1, 0x01, 0x001d},
2364 {0xa1, 0x01, 0x001e},
2365 {0xa1, 0x01, 0x001f},
2366 {0xa1, 0x01, 0x0020},
2367 {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE},
2368 {0xa1, 0x01, 0x0180},
2369 {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
2370 {0xa0, 0x40, ZC3XX_R116_RGAIN},
2371 {0xa0, 0x40, ZC3XX_R117_GGAIN},
2372 {0xa0, 0x40, ZC3XX_R118_BGAIN},
2373/* {0xa0, 0x02, ZC3XX_R008_CLOCKSETTING}, */
2374 {} 2024 {}
2375}; 2025};
2376 2026
@@ -2418,65 +2068,156 @@ static const struct usb_action hv7131bxx_InitialScale[] = { /* 640x480*/
2418 {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, 2068 {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},
2419 {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, 2069 {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
2420 {0xaa, 0x02, 0x0090}, /* {0xaa, 0x02, 0x0080}, */ 2070 {0xaa, 0x02, 0x0090}, /* {0xaa, 0x02, 0x0080}, */
2421 {0xa1, 0x01, 0x0002}, 2071 {}
2422 {0xa0, 0x00, ZC3XX_R092_I2CADDRESSSELECT}, 2072};
2423 {0xa0, 0x02, ZC3XX_R090_I2CCOMMAND}, 2073static const struct usb_action hv7131b_50HZ[] = { /* 640x480*/
2424 {0xa1, 0x01, 0x0091}, 2074 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
2425 {0xa1, 0x01, 0x0095}, 2075 {0xaa, 0x25, 0x0007}, /* 00,25,07,aa */
2426 {0xa1, 0x01, 0x0096}, 2076 {0xaa, 0x26, 0x0053}, /* 00,26,53,aa */
2427 {0xa1, 0x01, 0x0008}, 2077 {0xaa, 0x27, 0x0000}, /* 00,27,00,aa */
2428 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */ 2078 {0xaa, 0x20, 0x0000}, /* 00,20,00,aa */
2429 {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */ 2079 {0xaa, 0x21, 0x0050}, /* 00,21,50,aa */
2430 {0xa1, 0x01, 0x01c8}, 2080 {0xaa, 0x22, 0x001b}, /* 00,22,1b,aa */
2431 {0xa1, 0x01, 0x01c9}, 2081 {0xaa, 0x23, 0x00fc}, /* 00,23,fc,aa */
2432 {0xa1, 0x01, 0x01ca}, 2082 {0xa0, 0x2f, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,2f,cc */
2433 {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */ 2083 {0xa0, 0x9b, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,9b,cc */
2434 2084 {0xa0, 0x80, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,80,cc */
2435 {0xa0, 0x50, ZC3XX_R10A_RGB00}, /* matrix */ 2085 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
2436 {0xa0, 0xf8, ZC3XX_R10B_RGB01}, 2086 {0xa0, 0xea, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,ea,cc */
2437 {0xa0, 0xf8, ZC3XX_R10C_RGB02}, 2087 {0xa0, 0x60, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,60,cc */
2438 {0xa0, 0xf8, ZC3XX_R10D_RGB10}, 2088 {0xa0, 0x0c, ZC3XX_R18C_AEFREEZE}, /* 01,8c,0c,cc */
2439 {0xa0, 0x50, ZC3XX_R10E_RGB11}, 2089 {0xa0, 0x18, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,18,cc */
2440 {0xa0, 0xf8, ZC3XX_R10F_RGB12}, 2090 {0xa0, 0x18, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,18,cc */
2441 {0xa0, 0xf8, ZC3XX_R110_RGB20}, 2091 {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc */
2442 {0xa0, 0xf8, ZC3XX_R111_RGB21}, 2092 {0xa0, 0x00, ZC3XX_R01D_HSYNC_0}, /* 00,1d,00,cc */
2443 {0xa0, 0x50, ZC3XX_R112_RGB22}, 2093 {0xa0, 0x50, ZC3XX_R01E_HSYNC_1}, /* 00,1e,50,cc */
2444 {0xa1, 0x01, 0x0180}, 2094 {0xa0, 0x1b, ZC3XX_R01F_HSYNC_2}, /* 00,1f,1b,cc */
2445 {0xa0, 0x10, ZC3XX_R180_AUTOCORRECTENABLE}, 2095 {0xa0, 0xfc, ZC3XX_R020_HSYNC_3}, /* 00,20,fc,cc */
2446 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, 2096 {}
2447 {0xaa, 0x25, 0x0007}, 2097};
2448 {0xaa, 0x26, 0x00a1}, 2098static const struct usb_action hv7131b_50HZScale[] = { /* 320x240 */
2449 {0xaa, 0x27, 0x0020}, 2099 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
2450 {0xaa, 0x20, 0x0000}, 2100 {0xaa, 0x25, 0x0007}, /* 00,25,07,aa */
2451 {0xaa, 0x21, 0x0040}, 2101 {0xaa, 0x26, 0x0053}, /* 00,26,53,aa */
2452 {0xaa, 0x22, 0x0013}, 2102 {0xaa, 0x27, 0x0000}, /* 00,27,00,aa */
2453 {0xaa, 0x23, 0x004c}, 2103 {0xaa, 0x20, 0x0000}, /* 00,20,00,aa */
2454 {0xa0, 0x10, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 2f */ 2104 {0xaa, 0x21, 0x0050}, /* 00,21,50,aa */
2455 {0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID}, /* 4d */ 2105 {0xaa, 0x22, 0x0012}, /* 00,22,12,aa */
2456 {0xa0, 0x60, ZC3XX_R192_EXPOSURELIMITLOW}, /* 60 */ 2106 {0xaa, 0x23, 0x0080}, /* 00,23,80,aa */
2457 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, 2107 {0xa0, 0x2f, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,2f,cc */
2458 {0xa0, 0xc3, ZC3XX_R196_ANTIFLICKERMID}, 2108 {0xa0, 0x9b, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,9b,cc */
2459 {0xa0, 0x50, ZC3XX_R197_ANTIFLICKERLOW}, 2109 {0xa0, 0x80, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,80,cc */
2460 {0xa0, 0x0c, ZC3XX_R18C_AEFREEZE}, 2110 {0xa0, 0x01, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,01,cc */
2461 {0xa0, 0x18, ZC3XX_R18F_AEUNFREEZE}, 2111 {0xa0, 0xd4, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,d4,cc */
2462 {0xa0, 0x18, ZC3XX_R1A9_DIGITALLIMITDIFF}, 2112 {0xa0, 0xc0, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,c0,cc */
2463 {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, 2113 {0xa0, 0x07, ZC3XX_R18C_AEFREEZE}, /* 01,8c,07,cc */
2464 {0xa0, 0x00, ZC3XX_R01D_HSYNC_0}, 2114 {0xa0, 0x0f, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,0f,cc */
2465 {0xa0, 0x40, ZC3XX_R01E_HSYNC_1}, 2115 {0xa0, 0x18, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,18,cc */
2466 {0xa0, 0x13, ZC3XX_R01F_HSYNC_2}, 2116 {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc */
2467 {0xa0, 0x4c, ZC3XX_R020_HSYNC_3}, 2117 {0xa0, 0x00, ZC3XX_R01D_HSYNC_0}, /* 00,1d,00,cc */
2468 {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN}, 2118 {0xa0, 0x50, ZC3XX_R01E_HSYNC_1}, /* 00,1e,50,cc */
2469 {0xa1, 0x01, 0x001d}, 2119 {0xa0, 0x12, ZC3XX_R01F_HSYNC_2}, /* 00,1f,12,cc */
2470 {0xa1, 0x01, 0x001e}, 2120 {0xa0, 0x80, ZC3XX_R020_HSYNC_3}, /* 00,20,80,cc */
2471 {0xa1, 0x01, 0x001f}, 2121 {}
2472 {0xa1, 0x01, 0x0020}, 2122};
2473 {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE}, 2123static const struct usb_action hv7131b_60HZ[] = { /* 640x480*/
2474 {0xa1, 0x01, 0x0180}, 2124 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
2475 {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, 2125 {0xaa, 0x25, 0x0007}, /* 00,25,07,aa */
2476 {0xa0, 0x40, ZC3XX_R116_RGAIN}, 2126 {0xaa, 0x26, 0x00a1}, /* 00,26,a1,aa */
2477 {0xa0, 0x40, ZC3XX_R117_GGAIN}, 2127 {0xaa, 0x27, 0x0020}, /* 00,27,20,aa */
2478 {0xa0, 0x40, ZC3XX_R118_BGAIN}, 2128 {0xaa, 0x20, 0x0000}, /* 00,20,00,aa */
2479/* {0xa0, 0x02, ZC3XX_R008_CLOCKSETTING}, */ 2129 {0xaa, 0x21, 0x0040}, /* 00,21,40,aa */
2130 {0xaa, 0x22, 0x0013}, /* 00,22,13,aa */
2131 {0xaa, 0x23, 0x004c}, /* 00,23,4c,aa */
2132 {0xa0, 0x2f, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,2f,cc */
2133 {0xa0, 0x4d, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,4d,cc */
2134 {0xa0, 0x60, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,60,cc */
2135 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
2136 {0xa0, 0xc3, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,c3,cc */
2137 {0xa0, 0x50, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,50,cc */
2138 {0xa0, 0x0c, ZC3XX_R18C_AEFREEZE}, /* 01,8c,0c,cc */
2139 {0xa0, 0x18, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,18,cc */
2140 {0xa0, 0x18, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,18,cc */
2141 {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc */
2142 {0xa0, 0x00, ZC3XX_R01D_HSYNC_0}, /* 00,1d,00,cc */
2143 {0xa0, 0x40, ZC3XX_R01E_HSYNC_1}, /* 00,1e,40,cc */
2144 {0xa0, 0x13, ZC3XX_R01F_HSYNC_2}, /* 00,1f,13,cc */
2145 {0xa0, 0x4c, ZC3XX_R020_HSYNC_3}, /* 00,20,4c,cc */
2146 {}
2147};
2148static const struct usb_action hv7131b_60HZScale[] = { /* 320x240 */
2149 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
2150 {0xaa, 0x25, 0x0007}, /* 00,25,07,aa */
2151 {0xaa, 0x26, 0x00a1}, /* 00,26,a1,aa */
2152 {0xaa, 0x27, 0x0020}, /* 00,27,20,aa */
2153 {0xaa, 0x20, 0x0000}, /* 00,20,00,aa */
2154 {0xaa, 0x21, 0x00a0}, /* 00,21,a0,aa */
2155 {0xaa, 0x22, 0x0016}, /* 00,22,16,aa */
2156 {0xaa, 0x23, 0x0040}, /* 00,23,40,aa */
2157 {0xa0, 0x2f, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,2f,cc */
2158 {0xa0, 0x4d, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,4d,cc */
2159 {0xa0, 0x60, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,60,cc */
2160 {0xa0, 0x01, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,01,cc */
2161 {0xa0, 0x86, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,86,cc */
2162 {0xa0, 0xa0, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,a0,cc */
2163 {0xa0, 0x07, ZC3XX_R18C_AEFREEZE}, /* 01,8c,07,cc */
2164 {0xa0, 0x0f, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,0f,cc */
2165 {0xa0, 0x18, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,18,cc */
2166 {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc */
2167 {0xa0, 0x00, ZC3XX_R01D_HSYNC_0}, /* 00,1d,00,cc */
2168 {0xa0, 0xa0, ZC3XX_R01E_HSYNC_1}, /* 00,1e,a0,cc */
2169 {0xa0, 0x16, ZC3XX_R01F_HSYNC_2}, /* 00,1f,16,cc */
2170 {0xa0, 0x40, ZC3XX_R020_HSYNC_3}, /* 00,20,40,cc */
2171 {}
2172};
2173static const struct usb_action hv7131b_NoFliker[] = { /* 640x480*/
2174 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
2175 {0xaa, 0x25, 0x0003}, /* 00,25,03,aa */
2176 {0xaa, 0x26, 0x0000}, /* 00,26,00,aa */
2177 {0xaa, 0x27, 0x0000}, /* 00,27,00,aa */
2178 {0xaa, 0x20, 0x0000}, /* 00,20,00,aa */
2179 {0xaa, 0x21, 0x0010}, /* 00,21,10,aa */
2180 {0xaa, 0x22, 0x0000}, /* 00,22,00,aa */
2181 {0xaa, 0x23, 0x0003}, /* 00,23,03,aa */
2182 {0xa0, 0x2f, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,2f,cc */
2183 {0xa0, 0xf8, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,f8,cc */
2184 {0xa0, 0x00, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,00,cc */
2185 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
2186 {0xa0, 0x02, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,02,cc */
2187 {0xa0, 0x00, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,00,cc */
2188 {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
2189 {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
2190 {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,00,cc */
2191 {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,00,cc */
2192 {0xa0, 0x00, ZC3XX_R01D_HSYNC_0}, /* 00,1d,00,cc */
2193 {0xa0, 0x10, ZC3XX_R01E_HSYNC_1}, /* 00,1e,10,cc */
2194 {0xa0, 0x00, ZC3XX_R01F_HSYNC_2}, /* 00,1f,00,cc */
2195 {0xa0, 0x03, ZC3XX_R020_HSYNC_3}, /* 00,20,03,cc */
2196 {}
2197};
2198static const struct usb_action hv7131b_NoFlikerScale[] = { /* 320x240 */
2199 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
2200 {0xaa, 0x25, 0x0003}, /* 00,25,03,aa */
2201 {0xaa, 0x26, 0x0000}, /* 00,26,00,aa */
2202 {0xaa, 0x27, 0x0000}, /* 00,27,00,aa */
2203 {0xaa, 0x20, 0x0000}, /* 00,20,00,aa */
2204 {0xaa, 0x21, 0x00a0}, /* 00,21,a0,aa */
2205 {0xaa, 0x22, 0x0016}, /* 00,22,16,aa */
2206 {0xaa, 0x23, 0x0040}, /* 00,23,40,aa */
2207 {0xa0, 0x2f, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,2f,cc */
2208 {0xa0, 0xf8, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,f8,cc */
2209 {0xa0, 0x00, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,00,cc */
2210 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
2211 {0xa0, 0x02, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,02,cc */
2212 {0xa0, 0x00, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,00,cc */
2213 {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
2214 {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
2215 {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,00,cc */
2216 {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,00,cc */
2217 {0xa0, 0x00, ZC3XX_R01D_HSYNC_0}, /* 00,1d,00,cc */
2218 {0xa0, 0xa0, ZC3XX_R01E_HSYNC_1}, /* 00,1e,a0,cc */
2219 {0xa0, 0x16, ZC3XX_R01F_HSYNC_2}, /* 00,1f,16,cc */
2220 {0xa0, 0x40, ZC3XX_R020_HSYNC_3}, /* 00,20,40,cc */
2480 {} 2221 {}
2481}; 2222};
2482 2223
@@ -4389,6 +4130,270 @@ static const struct usb_action pas106b_NoFliker[] = {
4389 {} 4130 {}
4390}; 4131};
4391 4132
4133/* from usbvm31b.inf */
4134static const struct usb_action pas202b_Initial[] = { /* 640x480 */
4135 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc */
4136 {0xa0, 0x00, ZC3XX_R008_CLOCKSETTING}, /* 00,08,00,cc */
4137 {0xa0, 0x0e, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0e,cc */
4138 {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, /* 00,02,00,cc */
4139 {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, /* 00,03,02,cc */
4140 {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, /* 00,04,80,cc */
4141 {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, /* 00,05,01,cc */
4142 {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, /* 00,06,e0,cc */
4143 {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, /* 00,01,01,cc */
4144 {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,03,cc */
4145 {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,01,cc */
4146 {0xa0, 0x08, ZC3XX_R08D_COMPABILITYMODE}, /* 00,8d,08,cc */
4147 {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, /* 00,98,00,cc */
4148 {0xa0, 0x03, ZC3XX_R09A_WINXSTARTLOW}, /* 00,9a,03,cc */
4149 {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, /* 01,1a,00,cc */
4150 {0xa0, 0x03, ZC3XX_R11C_FIRSTXLOW}, /* 01,1c,03,cc */
4151 {0xa0, 0x01, ZC3XX_R09B_WINHEIGHTHIGH}, /* 00,9b,01,cc */
4152 {0xa0, 0xe6, ZC3XX_R09C_WINHEIGHTLOW}, /* 00,9c,e6,cc */
4153 {0xa0, 0x02, ZC3XX_R09D_WINWIDTHHIGH}, /* 00,9d,02,cc */
4154 {0xa0, 0x86, ZC3XX_R09E_WINWIDTHLOW}, /* 00,9e,86,cc */
4155 {0xaa, 0x02, 0x0002}, /* 00,02,04,aa --> 02 */
4156 {0xaa, 0x07, 0x0006}, /* 00,07,06,aa */
4157 {0xaa, 0x08, 0x0002}, /* 00,08,02,aa */
4158 {0xaa, 0x09, 0x0006}, /* 00,09,06,aa */
4159 {0xaa, 0x0a, 0x0001}, /* 00,0a,01,aa */
4160 {0xaa, 0x0b, 0x0001}, /* 00,0b,01,aa */
4161 {0xaa, 0x0c, 0x0008}, /* 00,0c,08,aa */
4162 {0xaa, 0x0d, 0x0000}, /* 00,0d,00,aa */
4163 {0xaa, 0x10, 0x0000}, /* 00,10,00,aa */
4164 {0xaa, 0x12, 0x0005}, /* 00,12,05,aa */
4165 {0xaa, 0x13, 0x0063}, /* 00,13,63,aa */
4166 {0xaa, 0x15, 0x0070}, /* 00,15,70,aa */
4167 {0xa0, 0xb7, ZC3XX_R101_SENSORCORRECTION}, /* 01,01,b7,cc */
4168 {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0d,cc */
4169 {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, /* 01,89,06,cc */
4170 {0xa0, 0x00, 0x01ad}, /* 01,ad,00,cc */
4171 {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, /* 01,c5,03,cc */
4172 {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, /* 01,cb,13,cc */
4173 {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* 02,50,08,cc */
4174 {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* 03,01,08,cc */
4175 {0xa0, 0x70, ZC3XX_R18D_YTARGET}, /* 01,8d,70,cc */
4176 {}
4177};
4178static const struct usb_action pas202b_InitialScale[] = { /* 320x240 */
4179 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc */
4180 {0xa0, 0x00, ZC3XX_R008_CLOCKSETTING}, /* 00,08,00,cc */
4181 {0xa0, 0x0e, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0e,cc */
4182 {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, /* 00,02,10,cc */
4183 {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, /* 00,03,02,cc */
4184 {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, /* 00,04,80,cc */
4185 {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, /* 00,05,01,cc */
4186 {0xa0, 0xd0, ZC3XX_R006_FRAMEHEIGHTLOW}, /* 00,06,d0,cc */
4187 {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, /* 00,01,01,cc */
4188 {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,03,cc */
4189 {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,01,cc */
4190 {0xa0, 0x08, ZC3XX_R08D_COMPABILITYMODE}, /* 00,8d,08,cc */
4191 {0xa0, 0x08, ZC3XX_R098_WINYSTARTLOW}, /* 00,98,08,cc */
4192 {0xa0, 0x02, ZC3XX_R09A_WINXSTARTLOW}, /* 00,9a,02,cc */
4193 {0xa0, 0x08, ZC3XX_R11A_FIRSTYLOW}, /* 01,1a,08,cc */
4194 {0xa0, 0x02, ZC3XX_R11C_FIRSTXLOW}, /* 01,1c,02,cc */
4195 {0xa0, 0x01, ZC3XX_R09B_WINHEIGHTHIGH}, /* 00,9b,01,cc */
4196 {0xa0, 0xd8, ZC3XX_R09C_WINHEIGHTLOW}, /* 00,9c,d8,cc */
4197 {0xa0, 0x02, ZC3XX_R09D_WINWIDTHHIGH}, /* 00,9d,02,cc */
4198 {0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW}, /* 00,9e,88,cc */
4199 {0xaa, 0x02, 0x0002}, /* 00,02,02,aa */
4200 {0xaa, 0x07, 0x0006}, /* 00,07,06,aa */
4201 {0xaa, 0x08, 0x0002}, /* 00,08,02,aa */
4202 {0xaa, 0x09, 0x0006}, /* 00,09,06,aa */
4203 {0xaa, 0x0a, 0x0001}, /* 00,0a,01,aa */
4204 {0xaa, 0x0b, 0x0001}, /* 00,0b,01,aa */
4205 {0xaa, 0x0c, 0x0008}, /* 00,0c,08,aa */
4206 {0xaa, 0x0d, 0x0000}, /* 00,0d,00,aa */
4207 {0xaa, 0x10, 0x0000}, /* 00,10,00,aa */
4208 {0xaa, 0x12, 0x0005}, /* 00,12,05,aa */
4209 {0xaa, 0x13, 0x0063}, /* 00,13,63,aa */
4210 {0xaa, 0x15, 0x0070}, /* 00,15,70,aa */
4211 {0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION}, /* 01,01,37,cc */
4212 {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0d,cc */
4213 {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, /* 01,89,06,cc */
4214 {0xa0, 0x00, 0x01ad}, /* 01,ad,00,cc */
4215 {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, /* 01,c5,03,cc */
4216 {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, /* 01,cb,13,cc */
4217 {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* 02,50,08,cc */
4218 {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* 03,01,08,cc */
4219 {0xa0, 0x70, ZC3XX_R18D_YTARGET}, /* 01,8d,70,cc */
4220 {}
4221};
4222static const struct usb_action pas202b_50HZ[] = {
4223 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
4224 {0xa0, 0x20, ZC3XX_R087_EXPTIMEMID}, /* 00,87,20,cc */
4225 {0xa0, 0x21, ZC3XX_R088_EXPTIMELOW}, /* 00,88,21,cc */
4226 {0xaa, 0x20, 0x0002}, /* 00,20,02,aa */
4227 {0xaa, 0x21, 0x0068}, /* 00,21,68,aa */
4228 {0xaa, 0x03, 0x0044}, /* 00,03,44,aa */
4229 {0xaa, 0x04, 0x0009}, /* 00,04,09,aa */
4230 {0xaa, 0x05, 0x0028}, /* 00,05,28,aa */
4231 {0xaa, 0x0e, 0x0001}, /* 00,0e,01,aa */
4232 {0xaa, 0x0f, 0x0000}, /* 00,0f,00,aa */
4233 {0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,14,cc */
4234 {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc */
4235 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
4236 {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,07,cc */
4237 {0xa0, 0xd2, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,d2,cc */
4238 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
4239 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
4240 {0xa0, 0x4d, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,4d,cc */
4241 {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
4242 {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
4243 {0xa0, 0x44, ZC3XX_R01D_HSYNC_0}, /* 00,1d,44,cc */
4244 {0xa0, 0x6f, ZC3XX_R01E_HSYNC_1}, /* 00,1e,6f,cc */
4245 {0xa0, 0xad, ZC3XX_R01F_HSYNC_2}, /* 00,1f,ad,cc */
4246 {0xa0, 0xeb, ZC3XX_R020_HSYNC_3}, /* 00,20,eb,cc */
4247 {0xa0, 0x0f, ZC3XX_R087_EXPTIMEMID}, /* 00,87,0f,cc */
4248 {0xa0, 0x0e, ZC3XX_R088_EXPTIMELOW}, /* 00,88,0e,cc */
4249 {}
4250};
4251static const struct usb_action pas202b_50HZScale[] = {
4252 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
4253 {0xa0, 0x20, ZC3XX_R087_EXPTIMEMID}, /* 00,87,20,cc */
4254 {0xa0, 0x21, ZC3XX_R088_EXPTIMELOW}, /* 00,88,21,cc */
4255 {0xaa, 0x20, 0x0002}, /* 00,20,02,aa */
4256 {0xaa, 0x21, 0x006c}, /* 00,21,6c,aa */
4257 {0xaa, 0x03, 0x0041}, /* 00,03,41,aa */
4258 {0xaa, 0x04, 0x0009}, /* 00,04,09,aa */
4259 {0xaa, 0x05, 0x002c}, /* 00,05,2c,aa */
4260 {0xaa, 0x0e, 0x0001}, /* 00,0e,01,aa */
4261 {0xaa, 0x0f, 0x0000}, /* 00,0f,00,aa */
4262 {0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,14,cc */
4263 {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc */
4264 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
4265 {0xa0, 0x0f, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,0f,cc */
4266 {0xa0, 0xbe, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,be,cc */
4267 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
4268 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
4269 {0xa0, 0x9b, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,9b,cc */
4270 {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
4271 {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
4272 {0xa0, 0x41, ZC3XX_R01D_HSYNC_0}, /* 00,1d,41,cc */
4273 {0xa0, 0x6f, ZC3XX_R01E_HSYNC_1}, /* 00,1e,6f,cc */
4274 {0xa0, 0xad, ZC3XX_R01F_HSYNC_2}, /* 00,1f,ad,cc */
4275 {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */
4276 {0xa0, 0x0f, ZC3XX_R087_EXPTIMEMID}, /* 00,87,0f,cc */
4277 {0xa0, 0x0e, ZC3XX_R088_EXPTIMELOW}, /* 00,88,0e,cc */
4278 {}
4279};
4280static const struct usb_action pas202b_60HZ[] = {
4281 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
4282 {0xa0, 0x20, ZC3XX_R087_EXPTIMEMID}, /* 00,87,20,cc */
4283 {0xa0, 0x21, ZC3XX_R088_EXPTIMELOW}, /* 00,88,21,cc */
4284 {0xaa, 0x20, 0x0002}, /* 00,20,02,aa */
4285 {0xaa, 0x21, 0x0000}, /* 00,21,00,aa */
4286 {0xaa, 0x03, 0x0045}, /* 00,03,45,aa */
4287 {0xaa, 0x04, 0x0008}, /* 00,04,08,aa */
4288 {0xaa, 0x05, 0x0000}, /* 00,05,00,aa */
4289 {0xaa, 0x0e, 0x0001}, /* 00,0e,01,aa */
4290 {0xaa, 0x0f, 0x0000}, /* 00,0f,00,aa */
4291 {0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,14,cc */
4292 {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc */
4293 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
4294 {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,07,cc */
4295 {0xa0, 0xc0, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,c0,cc */
4296 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
4297 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
4298 {0xa0, 0x40, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,40,cc */
4299 {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
4300 {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
4301 {0xa0, 0x45, ZC3XX_R01D_HSYNC_0}, /* 00,1d,45,cc */
4302 {0xa0, 0x8e, ZC3XX_R01E_HSYNC_1}, /* 00,1e,8e,cc */
4303 {0xa0, 0xc1, ZC3XX_R01F_HSYNC_2}, /* 00,1f,c1,cc */
4304 {0xa0, 0xf5, ZC3XX_R020_HSYNC_3}, /* 00,20,f5,cc */
4305 {0xa0, 0x0f, ZC3XX_R087_EXPTIMEMID}, /* 00,87,0f,cc */
4306 {0xa0, 0x0e, ZC3XX_R088_EXPTIMELOW}, /* 00,88,0e,cc */
4307 {}
4308};
4309static const struct usb_action pas202b_60HZScale[] = {
4310 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
4311 {0xa0, 0x20, ZC3XX_R087_EXPTIMEMID}, /* 00,87,20,cc */
4312 {0xa0, 0x21, ZC3XX_R088_EXPTIMELOW}, /* 00,88,21,cc */
4313 {0xaa, 0x20, 0x0002}, /* 00,20,02,aa */
4314 {0xaa, 0x21, 0x0004}, /* 00,21,04,aa */
4315 {0xaa, 0x03, 0x0042}, /* 00,03,42,aa */
4316 {0xaa, 0x04, 0x0008}, /* 00,04,08,aa */
4317 {0xaa, 0x05, 0x0004}, /* 00,05,04,aa */
4318 {0xaa, 0x0e, 0x0001}, /* 00,0e,01,aa */
4319 {0xaa, 0x0f, 0x0000}, /* 00,0f,00,aa */
4320 {0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,14,cc */
4321 {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc */
4322 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
4323 {0xa0, 0x0f, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,0f,cc */
4324 {0xa0, 0x9f, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,9f,cc */
4325 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
4326 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
4327 {0xa0, 0x81, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,81,cc */
4328 {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
4329 {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
4330 {0xa0, 0x42, ZC3XX_R01D_HSYNC_0}, /* 00,1d,42,cc */
4331 {0xa0, 0x6f, ZC3XX_R01E_HSYNC_1}, /* 00,1e,6f,cc */
4332 {0xa0, 0xaf, ZC3XX_R01F_HSYNC_2}, /* 00,1f,af,cc */
4333 {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */
4334 {0xa0, 0x0f, ZC3XX_R087_EXPTIMEMID}, /* 00,87,0f,cc */
4335 {0xa0, 0x0e, ZC3XX_R088_EXPTIMELOW}, /* 00,88,0e,cc */
4336 {}
4337};
4338static const struct usb_action pas202b_NoFliker[] = {
4339 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
4340 {0xa0, 0x20, ZC3XX_R087_EXPTIMEMID}, /* 00,87,20,cc */
4341 {0xa0, 0x21, ZC3XX_R088_EXPTIMELOW}, /* 00,88,21,cc */
4342 {0xaa, 0x20, 0x0002}, /* 00,20,02,aa */
4343 {0xaa, 0x21, 0x0020}, /* 00,21,20,aa */
4344 {0xaa, 0x03, 0x0040}, /* 00,03,40,aa */
4345 {0xaa, 0x04, 0x0008}, /* 00,04,08,aa */
4346 {0xaa, 0x05, 0x0020}, /* 00,05,20,aa */
4347 {0xaa, 0x0e, 0x0001}, /* 00,0e,01,aa */
4348 {0xaa, 0x0f, 0x0000}, /* 00,0f,00,aa */
4349 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
4350 {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,07,cc */
4351 {0xa0, 0xf0, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,f0,cc */
4352 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
4353 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
4354 {0xa0, 0x02, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,02,cc */
4355 {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
4356 {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
4357 {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,00,cc */
4358 {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,00,cc */
4359 {0xa0, 0x40, ZC3XX_R01D_HSYNC_0}, /* 00,1d,40,cc */
4360 {0xa0, 0x60, ZC3XX_R01E_HSYNC_1}, /* 00,1e,60,cc */
4361 {0xa0, 0x90, ZC3XX_R01F_HSYNC_2}, /* 00,1f,90,cc */
4362 {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */
4363 {0xa0, 0x0f, ZC3XX_R087_EXPTIMEMID}, /* 00,87,0f,cc */
4364 {0xa0, 0x0e, ZC3XX_R088_EXPTIMELOW}, /* 00,88,0e,cc */
4365 {}
4366};
4367static const struct usb_action pas202b_NoFlikerScale[] = {
4368 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
4369 {0xa0, 0x20, ZC3XX_R087_EXPTIMEMID}, /* 00,87,20,cc */
4370 {0xa0, 0x21, ZC3XX_R088_EXPTIMELOW}, /* 00,88,21,cc */
4371 {0xaa, 0x20, 0x0002}, /* 00,20,02,aa */
4372 {0xaa, 0x21, 0x0010}, /* 00,21,10,aa */
4373 {0xaa, 0x03, 0x0040}, /* 00,03,40,aa */
4374 {0xaa, 0x04, 0x0008}, /* 00,04,08,aa */
4375 {0xaa, 0x05, 0x0010}, /* 00,05,10,aa */
4376 {0xaa, 0x0e, 0x0001}, /* 00,0e,01,aa */
4377 {0xaa, 0x0f, 0x0000}, /* 00,0f,00,aa */
4378 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
4379 {0xa0, 0x0f, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,0f,cc */
4380 {0xa0, 0xf0, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,f0,cc */
4381 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
4382 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
4383 {0xa0, 0x02, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,02,cc */
4384 {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
4385 {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
4386 {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,00,cc */
4387 {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,00,cc */
4388 {0xa0, 0x40, ZC3XX_R01D_HSYNC_0}, /* 00,1d,40,cc */
4389 {0xa0, 0x60, ZC3XX_R01E_HSYNC_1}, /* 00,1e,60,cc */
4390 {0xa0, 0x90, ZC3XX_R01F_HSYNC_2}, /* 00,1f,90,cc */
4391 {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */
4392 {0xa0, 0x0f, ZC3XX_R087_EXPTIMEMID}, /* 00,87,0f,cc */
4393 {0xa0, 0x0e, ZC3XX_R088_EXPTIMELOW}, /* 00,88,0e,cc */
4394 {}
4395};
4396
4392static const struct usb_action pb03303x_Initial[] = { 4397static const struct usb_action pb03303x_Initial[] = {
4393 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, 4398 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
4394 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, 4399 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
@@ -5725,7 +5730,7 @@ static const struct usb_action tas5130cxx_Initial[] = {
5725 {} 5730 {}
5726}; 5731};
5727static const struct usb_action tas5130cxx_InitialScale[] = { 5732static const struct usb_action tas5130cxx_InitialScale[] = {
5728 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, 5733/*?? {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, */
5729 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, 5734 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
5730 {0xa0, 0x40, ZC3XX_R002_CLOCKSELECT}, 5735 {0xa0, 0x40, ZC3XX_R002_CLOCKSELECT},
5731 5736
@@ -6049,7 +6054,7 @@ static const struct usb_action tas5130c_vf0250_InitialScale[] = {
6049 {0xaa, 0x1b, 0x0000}, /* 00,1b,00,aa, */ 6054 {0xaa, 0x1b, 0x0000}, /* 00,1b,00,aa, */
6050 {0xaa, 0x13, 0x0002}, /* 00,13,02,aa, */ 6055 {0xaa, 0x13, 0x0002}, /* 00,13,02,aa, */
6051 {0xaa, 0x15, 0x0004}, /* 00,15,04,aa */ 6056 {0xaa, 0x15, 0x0004}, /* 00,15,04,aa */
6052 {0xaa, 0x01, 0x0000}, 6057/*?? {0xaa, 0x01, 0x0000}, */
6053 {0xaa, 0x01, 0x0000}, 6058 {0xaa, 0x01, 0x0000},
6054 {0xaa, 0x1a, 0x0000}, /* 00,1a,00,aa, */ 6059 {0xaa, 0x1a, 0x0000}, /* 00,1a,00,aa, */
6055 {0xaa, 0x1c, 0x0017}, /* 00,1c,17,aa, */ 6060 {0xaa, 0x1c, 0x0017}, /* 00,1c,17,aa, */
@@ -6065,8 +6070,8 @@ static const struct usb_action tas5130c_vf0250_InitialScale[] = {
6065 {0xaa, 0x0f, 0x00a0}, /* 00,0f,a0,aa, */ 6070 {0xaa, 0x0f, 0x00a0}, /* 00,0f,a0,aa, */
6066 {0xaa, 0x10, 0x0000}, /* 00,10,00,aa, */ 6071 {0xaa, 0x10, 0x0000}, /* 00,10,00,aa, */
6067 {0xaa, 0x11, 0x00a0}, /* 00,11,a0,aa, */ 6072 {0xaa, 0x11, 0x00a0}, /* 00,11,a0,aa, */
6068 {0xa0, 0x00, 0x0039}, 6073/*?? {0xa0, 0x00, 0x0039},
6069 {0xa1, 0x01, 0x0037}, 6074 {0xa1, 0x01, 0x0037}, */
6070 {0xaa, 0x16, 0x0001}, /* 00,16,01,aa, */ 6075 {0xaa, 0x16, 0x0001}, /* 00,16,01,aa, */
6071 {0xaa, 0x17, 0x00e8}, /* 00,17,e6,aa (e6 -> e8) */ 6076 {0xaa, 0x17, 0x00e8}, /* 00,17,e6,aa (e6 -> e8) */
6072 {0xaa, 0x18, 0x0002}, /* 00,18,02,aa, */ 6077 {0xaa, 0x18, 0x0002}, /* 00,18,02,aa, */
@@ -6303,7 +6308,7 @@ static __u8 i2c_write(struct gspca_dev *gspca_dev,
6303 reg_w_i(gspca_dev->dev, valL, 0x93); 6308 reg_w_i(gspca_dev->dev, valL, 0x93);
6304 reg_w_i(gspca_dev->dev, valH, 0x94); 6309 reg_w_i(gspca_dev->dev, valH, 0x94);
6305 reg_w_i(gspca_dev->dev, 0x01, 0x90); /* <- write command */ 6310 reg_w_i(gspca_dev->dev, 0x01, 0x90); /* <- write command */
6306 msleep(5); 6311 msleep(15);
6307 retbyte = reg_r_i(gspca_dev, 0x0091); /* read status */ 6312 retbyte = reg_r_i(gspca_dev, 0x0091); /* read status */
6308 PDEBUG(D_USBO, "i2c w [%02x] = %02x%02x (%02x)", 6313 PDEBUG(D_USBO, "i2c w [%02x] = %02x%02x (%02x)",
6309 reg, valH, valL, retbyte); 6314 reg, valH, valL, retbyte);
@@ -6346,30 +6351,35 @@ static void setmatrix(struct gspca_dev *gspca_dev)
6346 {0x50, 0xf8, 0xf8, 0xf8, 0x50, 0xf8, 0xf8, 0xf8, 0x50}; 6351 {0x50, 0xf8, 0xf8, 0xf8, 0x50, 0xf8, 0xf8, 0xf8, 0x50};
6347 static const __u8 ov7620_matrix[9] = 6352 static const __u8 ov7620_matrix[9] =
6348 {0x58, 0xf4, 0xf4, 0xf4, 0x58, 0xf4, 0xf4, 0xf4, 0x58}; 6353 {0x58, 0xf4, 0xf4, 0xf4, 0x58, 0xf4, 0xf4, 0xf4, 0x58};
6354 static const __u8 pas202b_matrix[9] =
6355 {0x4c, 0xf5, 0xff, 0xf9, 0x51, 0xf5, 0xfb, 0xed, 0x5f};
6349 static const __u8 po2030_matrix[9] = 6356 static const __u8 po2030_matrix[9] =
6350 {0x60, 0xf0, 0xf0, 0xf0, 0x60, 0xf0, 0xf0, 0xf0, 0x60}; 6357 {0x60, 0xf0, 0xf0, 0xf0, 0x60, 0xf0, 0xf0, 0xf0, 0x60};
6351 static const __u8 vf0250_matrix[9] = 6358 static const __u8 vf0250_matrix[9] =
6352 {0x7b, 0xea, 0xea, 0xea, 0x7b, 0xea, 0xea, 0xea, 0x7b}; 6359 {0x7b, 0xea, 0xea, 0xea, 0x7b, 0xea, 0xea, 0xea, 0x7b};
6360 static const __u8 *matrix_tb[SENSOR_MAX] = {
6361 NULL, /* SENSOR_CS2102 0 */
6362 NULL, /* SENSOR_CS2102K 1 */
6363 gc0305_matrix, /* SENSOR_GC0305 2 */
6364 NULL, /* SENSOR_HDCS2020b 3 */
6365 NULL, /* SENSOR_HV7131B 4 */
6366 NULL, /* SENSOR_HV7131C 5 */
6367 NULL, /* SENSOR_ICM105A 6 */
6368 NULL, /* SENSOR_MC501CB 7 */
6369 ov7620_matrix, /* SENSOR_OV7620 8 */
6370 NULL, /* SENSOR_OV7630C 9 */
6371 NULL, /* SENSOR_PAS106 10 */
6372 pas202b_matrix, /* SENSOR_PAS202B 11 */
6373 NULL, /* SENSOR_PB0330 12 */
6374 po2030_matrix, /* SENSOR_PO2030 13 */
6375 NULL, /* SENSOR_TAS5130CK 14 */
6376 NULL, /* SENSOR_TAS5130CXX 15 */
6377 vf0250_matrix, /* SENSOR_TAS5130C_VF0250 16 */
6378 };
6353 6379
6354 switch (sd->sensor) { 6380 matrix = matrix_tb[sd->sensor];
6355 case SENSOR_GC0305: 6381 if (matrix == NULL)
6356 matrix = gc0305_matrix; 6382 return; /* matrix already loaded */
6357 break;
6358 case SENSOR_MC501CB:
6359 return; /* no matrix? */
6360 case SENSOR_OV7620:
6361/* case SENSOR_OV7648: */
6362 matrix = ov7620_matrix;
6363 break;
6364 case SENSOR_PO2030:
6365 matrix = po2030_matrix;
6366 break;
6367 case SENSOR_TAS5130C_VF0250:
6368 matrix = vf0250_matrix;
6369 break;
6370 default: /* matrix already loaded */
6371 return;
6372 }
6373 for (i = 0; i < ARRAY_SIZE(ov7620_matrix); i++) 6383 for (i = 0; i < ARRAY_SIZE(ov7620_matrix); i++)
6374 reg_w(gspca_dev->dev, matrix[i], 0x010a + i); 6384 reg_w(gspca_dev->dev, matrix[i], 0x010a + i);
6375} 6385}
@@ -6585,42 +6595,42 @@ static int setlightfreq(struct gspca_dev *gspca_dev)
6585 {gc0305_NoFliker, gc0305_NoFliker, 6595 {gc0305_NoFliker, gc0305_NoFliker,
6586 gc0305_50HZ, gc0305_50HZ, 6596 gc0305_50HZ, gc0305_50HZ,
6587 gc0305_60HZ, gc0305_60HZ}, 6597 gc0305_60HZ, gc0305_60HZ},
6588/* SENSOR_HDCS2020 3 */ 6598/* SENSOR_HDCS2020b 3 */
6589 {NULL, NULL,
6590 NULL, NULL,
6591 NULL, NULL},
6592/* SENSOR_HDCS2020b 4 */
6593 {hdcs2020b_NoFliker, hdcs2020b_NoFliker, 6599 {hdcs2020b_NoFliker, hdcs2020b_NoFliker,
6594 hdcs2020b_50HZ, hdcs2020b_50HZ, 6600 hdcs2020b_50HZ, hdcs2020b_50HZ,
6595 hdcs2020b_60HZ, hdcs2020b_60HZ}, 6601 hdcs2020b_60HZ, hdcs2020b_60HZ},
6596/* SENSOR_HV7131B 5 */ 6602/* SENSOR_HV7131B 4 */
6603 {hv7131b_NoFlikerScale, hv7131b_NoFliker,
6604 hv7131b_50HZScale, hv7131b_50HZ,
6605 hv7131b_60HZScale, hv7131b_60HZ},
6606/* SENSOR_HV7131C 5 */
6597 {NULL, NULL, 6607 {NULL, NULL,
6598 NULL, NULL, 6608 NULL, NULL,
6599 NULL, NULL}, 6609 NULL, NULL},
6600/* SENSOR_HV7131C 6 */ 6610/* SENSOR_ICM105A 6 */
6601 {NULL, NULL,
6602 NULL, NULL,
6603 NULL, NULL},
6604/* SENSOR_ICM105A 7 */
6605 {icm105a_NoFliker, icm105a_NoFlikerScale, 6611 {icm105a_NoFliker, icm105a_NoFlikerScale,
6606 icm105a_50HZ, icm105a_50HZScale, 6612 icm105a_50HZ, icm105a_50HZScale,
6607 icm105a_60HZ, icm105a_60HZScale}, 6613 icm105a_60HZ, icm105a_60HZScale},
6608/* SENSOR_MC501CB 8 */ 6614/* SENSOR_MC501CB 7 */
6609 {MC501CB_NoFliker, MC501CB_NoFlikerScale, 6615 {MC501CB_NoFliker, MC501CB_NoFlikerScale,
6610 MC501CB_50HZ, MC501CB_50HZScale, 6616 MC501CB_50HZ, MC501CB_50HZScale,
6611 MC501CB_60HZ, MC501CB_60HZScale}, 6617 MC501CB_60HZ, MC501CB_60HZScale},
6612/* SENSOR_OV7620 9 */ 6618/* SENSOR_OV7620 8 */
6613 {OV7620_NoFliker, OV7620_NoFliker, 6619 {OV7620_NoFliker, OV7620_NoFliker,
6614 OV7620_50HZ, OV7620_50HZ, 6620 OV7620_50HZ, OV7620_50HZ,
6615 OV7620_60HZ, OV7620_60HZ}, 6621 OV7620_60HZ, OV7620_60HZ},
6616/* SENSOR_OV7630C 10 */ 6622/* SENSOR_OV7630C 9 */
6617 {NULL, NULL, 6623 {NULL, NULL,
6618 NULL, NULL, 6624 NULL, NULL,
6619 NULL, NULL}, 6625 NULL, NULL},
6620/* SENSOR_PAS106 11 */ 6626/* SENSOR_PAS106 10 */
6621 {pas106b_NoFliker, pas106b_NoFliker, 6627 {pas106b_NoFliker, pas106b_NoFliker,
6622 pas106b_50HZ, pas106b_50HZ, 6628 pas106b_50HZ, pas106b_50HZ,
6623 pas106b_60HZ, pas106b_60HZ}, 6629 pas106b_60HZ, pas106b_60HZ},
6630/* SENSOR_PAS202B 11 */
6631 {pas202b_NoFlikerScale, pas202b_NoFliker,
6632 pas202b_50HZScale, pas202b_50HZ,
6633 pas202b_60HZScale, pas202b_60HZ},
6624/* SENSOR_PB0330 12 */ 6634/* SENSOR_PB0330 12 */
6625 {pb0330_NoFliker, pb0330_NoFlikerScale, 6635 {pb0330_NoFliker, pb0330_NoFlikerScale,
6626 pb0330_50HZ, pb0330_50HZScale, 6636 pb0330_50HZ, pb0330_50HZScale,
@@ -7002,15 +7012,15 @@ static int sd_config(struct gspca_dev *gspca_dev,
7002 5, /* SENSOR_CS2102 0 */ 7012 5, /* SENSOR_CS2102 0 */
7003 5, /* SENSOR_CS2102K 1 */ 7013 5, /* SENSOR_CS2102K 1 */
7004 4, /* SENSOR_GC0305 2 */ 7014 4, /* SENSOR_GC0305 2 */
7005 4, /* SENSOR_HDCS2020 3 */ 7015 4, /* SENSOR_HDCS2020b 3 */
7006 4, /* SENSOR_HDCS2020b 4 */ 7016 4, /* SENSOR_HV7131B 4 */
7007 4, /* SENSOR_HV7131B 5 */ 7017 4, /* SENSOR_HV7131C 5 */
7008 4, /* SENSOR_HV7131C 6 */ 7018 4, /* SENSOR_ICM105A 6 */
7009 4, /* SENSOR_ICM105A 7 */ 7019 4, /* SENSOR_MC501CB 7 */
7010 4, /* SENSOR_MC501CB 8 */ 7020 3, /* SENSOR_OV7620 8 */
7011 3, /* SENSOR_OV7620 9 */ 7021 4, /* SENSOR_OV7630C 9 */
7012 4, /* SENSOR_OV7630C 10 */ 7022 4, /* SENSOR_PAS106 10 */
7013 4, /* SENSOR_PAS106 11 */ 7023 4, /* SENSOR_PAS202B 11 */
7014 4, /* SENSOR_PB0330 12 */ 7024 4, /* SENSOR_PB0330 12 */
7015 4, /* SENSOR_PO2030 13 */ 7025 4, /* SENSOR_PO2030 13 */
7016 4, /* SENSOR_TAS5130CK 14 */ 7026 4, /* SENSOR_TAS5130CK 14 */
@@ -7066,8 +7076,8 @@ static int sd_config(struct gspca_dev *gspca_dev,
7066 sd->sensor = SENSOR_ICM105A; 7076 sd->sensor = SENSOR_ICM105A;
7067 break; 7077 break;
7068 case 0x0e: 7078 case 0x0e:
7069 PDEBUG(D_PROBE, "Find Sensor HDCS2020"); 7079 PDEBUG(D_PROBE, "Find Sensor PAS202B");
7070 sd->sensor = SENSOR_HDCS2020; 7080 sd->sensor = SENSOR_PAS202B;
7071 sd->sharpness = 1; 7081 sd->sharpness = 1;
7072 break; 7082 break;
7073 case 0x0f: 7083 case 0x0f:
@@ -7153,7 +7163,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
7153 sd->gamma = gamma[(int) sd->sensor]; 7163 sd->gamma = gamma[(int) sd->sensor];
7154 sd->autogain = sd_ctrls[SD_AUTOGAIN].qctrl.default_value; 7164 sd->autogain = sd_ctrls[SD_AUTOGAIN].qctrl.default_value;
7155 sd->lightfreq = sd_ctrls[SD_FREQ].qctrl.default_value; 7165 sd->lightfreq = sd_ctrls[SD_FREQ].qctrl.default_value;
7156 sd->sharpness = sd_ctrls[SD_SHARPNESS].qctrl.default_value;
7157 7166
7158 switch (sd->sensor) { 7167 switch (sd->sensor) {
7159 case SENSOR_GC0305: 7168 case SENSOR_GC0305:
@@ -7161,7 +7170,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
7161 case SENSOR_PO2030: 7170 case SENSOR_PO2030:
7162 gspca_dev->ctrl_dis = (1 << BRIGHTNESS_IDX); 7171 gspca_dev->ctrl_dis = (1 << BRIGHTNESS_IDX);
7163 break; 7172 break;
7164 case SENSOR_HDCS2020:
7165 case SENSOR_HV7131B: 7173 case SENSOR_HV7131B:
7166 case SENSOR_HV7131C: 7174 case SENSOR_HV7131C:
7167 case SENSOR_OV7630C: 7175 case SENSOR_OV7630C:
@@ -7191,15 +7199,15 @@ static int sd_start(struct gspca_dev *gspca_dev)
7191 {cs2102_InitialScale, cs2102_Initial}, /* 0 */ 7199 {cs2102_InitialScale, cs2102_Initial}, /* 0 */
7192 {cs2102K_InitialScale, cs2102K_Initial}, /* 1 */ 7200 {cs2102K_InitialScale, cs2102K_Initial}, /* 1 */
7193 {gc0305_Initial, gc0305_InitialScale}, /* 2 */ 7201 {gc0305_Initial, gc0305_InitialScale}, /* 2 */
7194 {hdcs2020xx_InitialScale, hdcs2020xx_Initial}, /* 3 */ 7202 {hdcs2020xb_InitialScale, hdcs2020xb_Initial}, /* 3 */
7195 {hdcs2020xb_InitialScale, hdcs2020xb_Initial}, /* 4 */ 7203 {hv7131bxx_InitialScale, hv7131bxx_Initial}, /* 4 */
7196 {hv7131bxx_InitialScale, hv7131bxx_Initial}, /* 5 */ 7204 {hv7131cxx_InitialScale, hv7131cxx_Initial}, /* 5 */
7197 {hv7131cxx_InitialScale, hv7131cxx_Initial}, /* 6 */ 7205 {icm105axx_InitialScale, icm105axx_Initial}, /* 6 */
7198 {icm105axx_InitialScale, icm105axx_Initial}, /* 7 */ 7206 {MC501CB_InitialScale, MC501CB_Initial}, /* 7 */
7199 {MC501CB_InitialScale, MC501CB_Initial}, /* 9 */ 7207 {OV7620_mode0, OV7620_mode1}, /* 8 */
7200 {OV7620_mode0, OV7620_mode1}, /* 9 */ 7208 {ov7630c_InitialScale, ov7630c_Initial}, /* 9 */
7201 {ov7630c_InitialScale, ov7630c_Initial}, /* 10 */ 7209 {pas106b_InitialScale, pas106b_Initial}, /* 10 */
7202 {pas106b_InitialScale, pas106b_Initial}, /* 11 */ 7210 {pas202b_Initial, pas202b_InitialScale}, /* 11 */
7203 {pb0330xx_InitialScale, pb0330xx_Initial}, /* 12 */ 7211 {pb0330xx_InitialScale, pb0330xx_Initial}, /* 12 */
7204/* or {pb03303x_InitialScale, pb03303x_Initial}, */ 7212/* or {pb03303x_InitialScale, pb03303x_Initial}, */
7205 {PO2030_mode0, PO2030_mode1}, /* 13 */ 7213 {PO2030_mode0, PO2030_mode1}, /* 13 */
@@ -7256,6 +7264,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
7256 reg_r(gspca_dev, 0x0008); 7264 reg_r(gspca_dev, 0x0008);
7257 reg_w(dev, 0x00, 0x0008); 7265 reg_w(dev, 0x00, 0x0008);
7258 break; 7266 break;
7267 case SENSOR_PAS202B:
7259 case SENSOR_GC0305: 7268 case SENSOR_GC0305:
7260 reg_r(gspca_dev, 0x0008); 7269 reg_r(gspca_dev, 0x0008);
7261 /* fall thru */ 7270 /* fall thru */
@@ -7269,7 +7278,6 @@ static int sd_start(struct gspca_dev *gspca_dev)
7269 switch (sd->sensor) { 7278 switch (sd->sensor) {
7270 case SENSOR_CS2102: /* gamma set in xxx_Initial */ 7279 case SENSOR_CS2102: /* gamma set in xxx_Initial */
7271 case SENSOR_CS2102K: 7280 case SENSOR_CS2102K:
7272 case SENSOR_HDCS2020:
7273 case SENSOR_HDCS2020b: 7281 case SENSOR_HDCS2020b:
7274 case SENSOR_PB0330: /* pb with chip_revision - see above */ 7282 case SENSOR_PB0330: /* pb with chip_revision - see above */
7275 case SENSOR_OV7630C: 7283 case SENSOR_OV7630C:
@@ -7282,6 +7290,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
7282 setmatrix(gspca_dev); /* one more time? */ 7290 setmatrix(gspca_dev); /* one more time? */
7283 switch (sd->sensor) { 7291 switch (sd->sensor) {
7284 case SENSOR_OV7620: 7292 case SENSOR_OV7620:
7293 case SENSOR_PAS202B:
7285 reg_r(gspca_dev, 0x0180); /* from win */ 7294 reg_r(gspca_dev, 0x0180); /* from win */
7286 reg_w(dev, 0x00, 0x0180); 7295 reg_w(dev, 0x00, 0x0180);
7287 break; 7296 break;
@@ -7293,37 +7302,29 @@ static int sd_start(struct gspca_dev *gspca_dev)
7293 7302
7294 switch (sd->sensor) { 7303 switch (sd->sensor) {
7295 case SENSOR_GC0305: 7304 case SENSOR_GC0305:
7296 case SENSOR_OV7620:
7297 reg_w(dev, 0x09, 0x01ad); /* (from win traces) */ 7305 reg_w(dev, 0x09, 0x01ad); /* (from win traces) */
7298 reg_w(dev, 0x15, 0x01ae); 7306 reg_w(dev, 0x15, 0x01ae);
7299 sd->autogain = 0; 7307 /* fall thru */
7300 break; 7308 case SENSOR_PAS202B:
7301 case SENSOR_PO2030: 7309 case SENSOR_PO2030:
7302 reg_w(dev, 0x40, 0x0117); /* (from win traces) */ 7310/* reg_w(dev, 0x40, ZC3XX_R117_GGAIN); * (from win traces) */
7303 reg_r(gspca_dev, 0x0180); 7311 reg_r(gspca_dev, 0x0180);
7304 break; 7312 break;
7305 }
7306
7307 setautogain(gspca_dev);
7308 switch (sd->sensor) {
7309 case SENSOR_GC0305:
7310/* setlightfreq(gspca_dev); ?? (end: 80 -> [18d]) */
7311 reg_w(dev, 0x09, 0x01ad); /* (from win traces) */
7312 reg_w(dev, 0x15, 0x01ae);
7313 reg_w(dev, 0x40, 0x0180);
7314 reg_w(dev, 0x40, 0x0117);
7315 reg_r(gspca_dev, 0x0180);
7316 sd->autogain = 1;
7317 setautogain(gspca_dev);
7318 break;
7319 case SENSOR_OV7620: 7313 case SENSOR_OV7620:
7314 reg_w(dev, 0x09, 0x01ad);
7315 reg_w(dev, 0x15, 0x01ae);
7320 i2c_read(gspca_dev, 0x13); /*fixme: returns 0xa3 */ 7316 i2c_read(gspca_dev, 0x13); /*fixme: returns 0xa3 */
7321 i2c_write(gspca_dev, 0x13, 0xa3, 0x00); 7317 i2c_write(gspca_dev, 0x13, 0xa3, 0x00);
7322 /*fixme: returned value to send? */ 7318 /*fixme: returned value to send? */
7323 reg_w(dev, 0x40, 0x0117); /* (from win traces) */ 7319 reg_w(dev, 0x40, 0x0117);
7324 reg_r(gspca_dev, 0x0180); 7320 reg_r(gspca_dev, 0x0180);
7325 setautogain(gspca_dev); 7321 break;
7326 msleep(500); 7322 }
7323
7324 setautogain(gspca_dev);
7325 switch (sd->sensor) {
7326 case SENSOR_PAS202B:
7327 reg_w(dev, 0x00, 0x0007); /* (from win traces) */
7327 break; 7328 break;
7328 case SENSOR_PO2030: 7329 case SENSOR_PO2030:
7329 msleep(500); 7330 msleep(500);
@@ -7333,6 +7334,8 @@ static int sd_start(struct gspca_dev *gspca_dev)
7333 reg_w(dev, 0x02, 0x0008); 7334 reg_w(dev, 0x02, 0x0008);
7334 break; 7335 break;
7335 } 7336 }
7337 if (sd->sensor == SENSOR_PAS202B)
7338 reg_w(dev, 0x02, ZC3XX_R008_CLOCKSETTING);
7336 return 0; 7339 return 0;
7337} 7340}
7338 7341
@@ -7530,6 +7533,7 @@ static const __devinitdata struct usb_device_id device_table[] = {
7530 {USB_DEVICE(0x0458, 0x700c)}, 7533 {USB_DEVICE(0x0458, 0x700c)},
7531 {USB_DEVICE(0x0458, 0x700f)}, 7534 {USB_DEVICE(0x0458, 0x700f)},
7532 {USB_DEVICE(0x0461, 0x0a00)}, 7535 {USB_DEVICE(0x0461, 0x0a00)},
7536 {USB_DEVICE(0x046d, 0x089d), .driver_info = SENSOR_MC501CB},
7533 {USB_DEVICE(0x046d, 0x08a0)}, 7537 {USB_DEVICE(0x046d, 0x08a0)},
7534 {USB_DEVICE(0x046d, 0x08a1)}, 7538 {USB_DEVICE(0x046d, 0x08a1)},
7535 {USB_DEVICE(0x046d, 0x08a2)}, 7539 {USB_DEVICE(0x046d, 0x08a2)},
diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c
index efe849981ab7..d4658c56eddc 100644
--- a/drivers/media/video/ir-kbd-i2c.c
+++ b/drivers/media/video/ir-kbd-i2c.c
@@ -385,10 +385,10 @@ static int ir_attach(struct i2c_adapter *adap, int addr,
385 goto err_out_detach; 385 goto err_out_detach;
386 } 386 }
387 387
388 /* Phys addr can only be set after attaching (for ir->c.dev.bus_id) */ 388 /* Phys addr can only be set after attaching (for ir->c.dev) */
389 snprintf(ir->phys, sizeof(ir->phys), "%s/%s/ir0", 389 snprintf(ir->phys, sizeof(ir->phys), "%s/%s/ir0",
390 ir->c.adapter->dev.bus_id, 390 dev_name(&ir->c.adapter->dev),
391 ir->c.dev.bus_id); 391 dev_name(&ir->c.dev));
392 392
393 /* init + register input device */ 393 /* init + register input device */
394 ir_input_init(input_dev, &ir->ir, ir_type, ir->ir_codes); 394 ir_input_init(input_dev, &ir->ir, ir_type, ir->ir_codes);
diff --git a/drivers/media/video/ivtv/ivtv-cards.c b/drivers/media/video/ivtv/ivtv-cards.c
index 4e05f91a9100..2883c8780760 100644
--- a/drivers/media/video/ivtv/ivtv-cards.c
+++ b/drivers/media/video/ivtv/ivtv-cards.c
@@ -877,20 +877,28 @@ static const struct ivtv_card_pci_info ivtv_pci_pg600v2[] = {
877static const struct ivtv_card ivtv_card_pg600v2 = { 877static const struct ivtv_card ivtv_card_pg600v2 = {
878 .type = IVTV_CARD_PG600V2, 878 .type = IVTV_CARD_PG600V2,
879 .name = "Yuan PG600-2, GotView PCI DVD Lite", 879 .name = "Yuan PG600-2, GotView PCI DVD Lite",
880 .comment = "only Composite and S-Video inputs are supported, not the tuner\n",
881 .v4l2_capabilities = IVTV_CAP_ENCODER, 880 .v4l2_capabilities = IVTV_CAP_ENCODER,
882 .hw_video = IVTV_HW_CX25840, 881 .hw_video = IVTV_HW_CX25840,
883 .hw_audio = IVTV_HW_CX25840, 882 .hw_audio = IVTV_HW_CX25840,
884 .hw_audio_ctrl = IVTV_HW_CX25840, 883 .hw_audio_ctrl = IVTV_HW_CX25840,
885 .hw_all = IVTV_HW_CX25840, 884 .hw_all = IVTV_HW_CX25840 | IVTV_HW_TUNER,
885 /* XC2028 support apparently works for the Yuan, it's still
886 uncertain whether it also works with the GotView. */
886 .video_inputs = { 887 .video_inputs = {
887 { IVTV_CARD_INPUT_SVIDEO1, 0, 888 { IVTV_CARD_INPUT_VID_TUNER, 0, CX25840_COMPOSITE2 },
889 { IVTV_CARD_INPUT_SVIDEO1, 1,
888 CX25840_SVIDEO_LUMA3 | CX25840_SVIDEO_CHROMA4 }, 890 CX25840_SVIDEO_LUMA3 | CX25840_SVIDEO_CHROMA4 },
889 { IVTV_CARD_INPUT_COMPOSITE1, 0, CX25840_COMPOSITE1 }, 891 { IVTV_CARD_INPUT_COMPOSITE1, 1, CX25840_COMPOSITE1 },
890 }, 892 },
891 .audio_inputs = { 893 .audio_inputs = {
894 { IVTV_CARD_INPUT_AUD_TUNER, CX25840_AUDIO5 },
892 { IVTV_CARD_INPUT_LINE_IN1, CX25840_AUDIO_SERIAL }, 895 { IVTV_CARD_INPUT_LINE_IN1, CX25840_AUDIO_SERIAL },
893 }, 896 },
897 .radio_input = { IVTV_CARD_INPUT_AUD_TUNER, CX25840_AUDIO5 },
898 .xceive_pin = 12,
899 .tuners = {
900 { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 },
901 },
894 .pci_list = ivtv_pci_pg600v2, 902 .pci_list = ivtv_pci_pg600v2,
895 .i2c = &ivtv_i2c_std, 903 .i2c = &ivtv_i2c_std,
896}; 904};
diff --git a/drivers/media/video/ivtv/ivtv-controls.c b/drivers/media/video/ivtv/ivtv-controls.c
index 48e103be7183..62aa06f5d168 100644
--- a/drivers/media/video/ivtv/ivtv-controls.c
+++ b/drivers/media/video/ivtv/ivtv-controls.c
@@ -63,7 +63,7 @@ int ivtv_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *qctrl)
63 case V4L2_CID_HUE: 63 case V4L2_CID_HUE:
64 case V4L2_CID_SATURATION: 64 case V4L2_CID_SATURATION:
65 case V4L2_CID_CONTRAST: 65 case V4L2_CID_CONTRAST:
66 if (itv->video_dec_func(itv, VIDIOC_QUERYCTRL, qctrl)) 66 if (v4l2_subdev_call(itv->sd_video, core, queryctrl, qctrl))
67 qctrl->flags |= V4L2_CTRL_FLAG_DISABLED; 67 qctrl->flags |= V4L2_CTRL_FLAG_DISABLED;
68 return 0; 68 return 0;
69 69
@@ -73,7 +73,7 @@ int ivtv_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *qctrl)
73 case V4L2_CID_AUDIO_BASS: 73 case V4L2_CID_AUDIO_BASS:
74 case V4L2_CID_AUDIO_TREBLE: 74 case V4L2_CID_AUDIO_TREBLE:
75 case V4L2_CID_AUDIO_LOUDNESS: 75 case V4L2_CID_AUDIO_LOUDNESS:
76 if (ivtv_i2c_hw(itv, itv->card->hw_audio_ctrl, VIDIOC_QUERYCTRL, qctrl)) 76 if (v4l2_subdev_call(itv->sd_audio, core, queryctrl, qctrl))
77 qctrl->flags |= V4L2_CTRL_FLAG_DISABLED; 77 qctrl->flags |= V4L2_CTRL_FLAG_DISABLED;
78 return 0; 78 return 0;
79 79
@@ -122,7 +122,7 @@ static int ivtv_s_ctrl(struct ivtv *itv, struct v4l2_control *vctrl)
122 case V4L2_CID_HUE: 122 case V4L2_CID_HUE:
123 case V4L2_CID_SATURATION: 123 case V4L2_CID_SATURATION:
124 case V4L2_CID_CONTRAST: 124 case V4L2_CID_CONTRAST:
125 return itv->video_dec_func(itv, VIDIOC_S_CTRL, vctrl); 125 return v4l2_subdev_call(itv->sd_video, core, s_ctrl, vctrl);
126 126
127 case V4L2_CID_AUDIO_VOLUME: 127 case V4L2_CID_AUDIO_VOLUME:
128 case V4L2_CID_AUDIO_MUTE: 128 case V4L2_CID_AUDIO_MUTE:
@@ -130,7 +130,7 @@ static int ivtv_s_ctrl(struct ivtv *itv, struct v4l2_control *vctrl)
130 case V4L2_CID_AUDIO_BASS: 130 case V4L2_CID_AUDIO_BASS:
131 case V4L2_CID_AUDIO_TREBLE: 131 case V4L2_CID_AUDIO_TREBLE:
132 case V4L2_CID_AUDIO_LOUDNESS: 132 case V4L2_CID_AUDIO_LOUDNESS:
133 return ivtv_i2c_hw(itv, itv->card->hw_audio_ctrl, VIDIOC_S_CTRL, vctrl); 133 return v4l2_subdev_call(itv->sd_audio, core, s_ctrl, vctrl);
134 134
135 default: 135 default:
136 IVTV_DEBUG_IOCTL("invalid control 0x%x\n", vctrl->id); 136 IVTV_DEBUG_IOCTL("invalid control 0x%x\n", vctrl->id);
@@ -147,7 +147,7 @@ static int ivtv_g_ctrl(struct ivtv *itv, struct v4l2_control *vctrl)
147 case V4L2_CID_HUE: 147 case V4L2_CID_HUE:
148 case V4L2_CID_SATURATION: 148 case V4L2_CID_SATURATION:
149 case V4L2_CID_CONTRAST: 149 case V4L2_CID_CONTRAST:
150 return itv->video_dec_func(itv, VIDIOC_G_CTRL, vctrl); 150 return v4l2_subdev_call(itv->sd_video, core, g_ctrl, vctrl);
151 151
152 case V4L2_CID_AUDIO_VOLUME: 152 case V4L2_CID_AUDIO_VOLUME:
153 case V4L2_CID_AUDIO_MUTE: 153 case V4L2_CID_AUDIO_MUTE:
@@ -155,7 +155,7 @@ static int ivtv_g_ctrl(struct ivtv *itv, struct v4l2_control *vctrl)
155 case V4L2_CID_AUDIO_BASS: 155 case V4L2_CID_AUDIO_BASS:
156 case V4L2_CID_AUDIO_TREBLE: 156 case V4L2_CID_AUDIO_TREBLE:
157 case V4L2_CID_AUDIO_LOUDNESS: 157 case V4L2_CID_AUDIO_LOUDNESS:
158 return ivtv_i2c_hw(itv, itv->card->hw_audio_ctrl, VIDIOC_G_CTRL, vctrl); 158 return v4l2_subdev_call(itv->sd_audio, core, g_ctrl, vctrl);
159 default: 159 default:
160 IVTV_DEBUG_IOCTL("invalid control 0x%x\n", vctrl->id); 160 IVTV_DEBUG_IOCTL("invalid control 0x%x\n", vctrl->id);
161 return -EINVAL; 161 return -EINVAL;
@@ -268,7 +268,7 @@ int ivtv_s_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *c)
268 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 268 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
269 fmt.fmt.pix.width = itv->params.width / (is_mpeg1 ? 2 : 1); 269 fmt.fmt.pix.width = itv->params.width / (is_mpeg1 ? 2 : 1);
270 fmt.fmt.pix.height = itv->params.height; 270 fmt.fmt.pix.height = itv->params.height;
271 itv->video_dec_func(itv, VIDIOC_S_FMT, &fmt); 271 v4l2_subdev_call(itv->sd_video, video, s_fmt, &fmt);
272 } 272 }
273 err = cx2341x_update(itv, ivtv_api_func, &itv->params, &p); 273 err = cx2341x_update(itv, ivtv_api_func, &itv->params, &p);
274 if (!err && itv->params.stream_vbi_fmt != p.stream_vbi_fmt) 274 if (!err && itv->params.stream_vbi_fmt != p.stream_vbi_fmt)
@@ -279,7 +279,7 @@ int ivtv_s_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *c)
279 /* The audio clock of the digitizer must match the codec sample 279 /* The audio clock of the digitizer must match the codec sample
280 rate otherwise you get some very strange effects. */ 280 rate otherwise you get some very strange effects. */
281 if (idx < sizeof(freqs)) 281 if (idx < sizeof(freqs))
282 ivtv_call_i2c_clients(itv, VIDIOC_INT_AUDIO_CLOCK_FREQ, &freqs[idx]); 282 ivtv_call_all(itv, audio, s_clock_freq, freqs[idx]);
283 return err; 283 return err;
284 } 284 }
285 return -EINVAL; 285 return -EINVAL;
diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c
index b69cc1d55e5b..08b762951759 100644
--- a/drivers/media/video/ivtv/ivtv-driver.c
+++ b/drivers/media/video/ivtv/ivtv-driver.c
@@ -60,9 +60,6 @@
60#include <media/v4l2-chip-ident.h> 60#include <media/v4l2-chip-ident.h>
61#include "tuner-xc2028.h" 61#include "tuner-xc2028.h"
62 62
63/* var to keep track of the number of array elements in use */
64int ivtv_cards_active;
65
66/* If you have already X v4l cards, then set this to X. This way 63/* If you have already X v4l cards, then set this to X. This way
67 the device numbers stay matched. Example: you have a WinTV card 64 the device numbers stay matched. Example: you have a WinTV card
68 without radio and a PVR-350 with. Normally this would give a 65 without radio and a PVR-350 with. Normally this would give a
@@ -70,12 +67,6 @@ int ivtv_cards_active;
70 setting this to 1 you ensure that radio0 is now also radio1. */ 67 setting this to 1 you ensure that radio0 is now also radio1. */
71int ivtv_first_minor; 68int ivtv_first_minor;
72 69
73/* Master variable for all ivtv info */
74struct ivtv *ivtv_cards[IVTV_MAX_CARDS];
75
76/* Protects ivtv_cards_active */
77DEFINE_SPINLOCK(ivtv_cards_lock);
78
79/* add your revision and whatnot here */ 70/* add your revision and whatnot here */
80static struct pci_device_id ivtv_pci_tbl[] __devinitdata = { 71static struct pci_device_id ivtv_pci_tbl[] __devinitdata = {
81 {PCI_VENDOR_ID_ICOMP, PCI_DEVICE_ID_IVTV15, 72 {PCI_VENDOR_ID_ICOMP, PCI_DEVICE_ID_IVTV15,
@@ -87,6 +78,9 @@ static struct pci_device_id ivtv_pci_tbl[] __devinitdata = {
87 78
88MODULE_DEVICE_TABLE(pci,ivtv_pci_tbl); 79MODULE_DEVICE_TABLE(pci,ivtv_pci_tbl);
89 80
81/* ivtv instance counter */
82static atomic_t ivtv_instance = ATOMIC_INIT(0);
83
90/* Parameter declarations */ 84/* Parameter declarations */
91static int cardtype[IVTV_MAX_CARDS]; 85static int cardtype[IVTV_MAX_CARDS];
92static int tuner[IVTV_MAX_CARDS] = { -1, -1, -1, -1, -1, -1, -1, -1, 86static int tuner[IVTV_MAX_CARDS] = { -1, -1, -1, -1, -1, -1, -1, -1,
@@ -599,9 +593,9 @@ static void ivtv_process_options(struct ivtv *itv)
599 itv->options.kilobytes[IVTV_DEC_STREAM_TYPE_MPG] = dec_mpg_buffers * 1024; 593 itv->options.kilobytes[IVTV_DEC_STREAM_TYPE_MPG] = dec_mpg_buffers * 1024;
600 itv->options.kilobytes[IVTV_DEC_STREAM_TYPE_YUV] = dec_yuv_buffers * 1024; 594 itv->options.kilobytes[IVTV_DEC_STREAM_TYPE_YUV] = dec_yuv_buffers * 1024;
601 itv->options.kilobytes[IVTV_DEC_STREAM_TYPE_VBI] = dec_vbi_buffers; 595 itv->options.kilobytes[IVTV_DEC_STREAM_TYPE_VBI] = dec_vbi_buffers;
602 itv->options.cardtype = cardtype[itv->num]; 596 itv->options.cardtype = cardtype[itv->instance];
603 itv->options.tuner = tuner[itv->num]; 597 itv->options.tuner = tuner[itv->instance];
604 itv->options.radio = radio[itv->num]; 598 itv->options.radio = radio[itv->instance];
605 itv->options.newi2c = newi2c; 599 itv->options.newi2c = newi2c;
606 if (tunertype < -1 || tunertype > 1) { 600 if (tunertype < -1 || tunertype > 1) {
607 IVTV_WARN("Invalid tunertype argument, will autodetect instead\n"); 601 IVTV_WARN("Invalid tunertype argument, will autodetect instead\n");
@@ -688,7 +682,7 @@ static int __devinit ivtv_init_struct1(struct ivtv *itv)
688 spin_lock_init(&itv->lock); 682 spin_lock_init(&itv->lock);
689 spin_lock_init(&itv->dma_reg_lock); 683 spin_lock_init(&itv->dma_reg_lock);
690 684
691 itv->irq_work_queues = create_singlethread_workqueue(itv->name); 685 itv->irq_work_queues = create_singlethread_workqueue(itv->device.name);
692 if (itv->irq_work_queues == NULL) { 686 if (itv->irq_work_queues == NULL) {
693 IVTV_ERR("Could not create ivtv workqueue\n"); 687 IVTV_ERR("Could not create ivtv workqueue\n");
694 return -1; 688 return -1;
@@ -770,12 +764,6 @@ static void __devinit ivtv_init_struct2(struct ivtv *itv)
770 i = 0; 764 i = 0;
771 itv->active_input = i; 765 itv->active_input = i;
772 itv->audio_input = itv->card->video_inputs[i].audio_index; 766 itv->audio_input = itv->card->video_inputs[i].audio_index;
773 if (itv->card->hw_all & IVTV_HW_CX25840)
774 itv->video_dec_func = ivtv_cx25840;
775 else if (itv->card->hw_all & IVTV_HW_SAA717X)
776 itv->video_dec_func = ivtv_saa717x;
777 else
778 itv->video_dec_func = ivtv_saa7115;
779} 767}
780 768
781static int ivtv_setup_pci(struct ivtv *itv, struct pci_dev *dev, 769static int ivtv_setup_pci(struct ivtv *itv, struct pci_dev *dev,
@@ -788,21 +776,21 @@ static int ivtv_setup_pci(struct ivtv *itv, struct pci_dev *dev,
788 IVTV_DEBUG_INFO("Enabling pci device\n"); 776 IVTV_DEBUG_INFO("Enabling pci device\n");
789 777
790 if (pci_enable_device(dev)) { 778 if (pci_enable_device(dev)) {
791 IVTV_ERR("Can't enable device %d!\n", itv->num); 779 IVTV_ERR("Can't enable device!\n");
792 return -EIO; 780 return -EIO;
793 } 781 }
794 if (pci_set_dma_mask(dev, 0xffffffff)) { 782 if (pci_set_dma_mask(dev, 0xffffffff)) {
795 IVTV_ERR("No suitable DMA available on card %d.\n", itv->num); 783 IVTV_ERR("No suitable DMA available.\n");
796 return -EIO; 784 return -EIO;
797 } 785 }
798 if (!request_mem_region(itv->base_addr, IVTV_ENCODER_SIZE, "ivtv encoder")) { 786 if (!request_mem_region(itv->base_addr, IVTV_ENCODER_SIZE, "ivtv encoder")) {
799 IVTV_ERR("Cannot request encoder memory region on card %d.\n", itv->num); 787 IVTV_ERR("Cannot request encoder memory region.\n");
800 return -EIO; 788 return -EIO;
801 } 789 }
802 790
803 if (!request_mem_region(itv->base_addr + IVTV_REG_OFFSET, 791 if (!request_mem_region(itv->base_addr + IVTV_REG_OFFSET,
804 IVTV_REG_SIZE, "ivtv registers")) { 792 IVTV_REG_SIZE, "ivtv registers")) {
805 IVTV_ERR("Cannot request register memory region on card %d.\n", itv->num); 793 IVTV_ERR("Cannot request register memory region.\n");
806 release_mem_region(itv->base_addr, IVTV_ENCODER_SIZE); 794 release_mem_region(itv->base_addr, IVTV_ENCODER_SIZE);
807 return -EIO; 795 return -EIO;
808 } 796 }
@@ -810,7 +798,7 @@ static int ivtv_setup_pci(struct ivtv *itv, struct pci_dev *dev,
810 if (itv->has_cx23415 && 798 if (itv->has_cx23415 &&
811 !request_mem_region(itv->base_addr + IVTV_DECODER_OFFSET, 799 !request_mem_region(itv->base_addr + IVTV_DECODER_OFFSET,
812 IVTV_DECODER_SIZE, "ivtv decoder")) { 800 IVTV_DECODER_SIZE, "ivtv decoder")) {
813 IVTV_ERR("Cannot request decoder memory region on card %d.\n", itv->num); 801 IVTV_ERR("Cannot request decoder memory region.\n");
814 release_mem_region(itv->base_addr, IVTV_ENCODER_SIZE); 802 release_mem_region(itv->base_addr, IVTV_ENCODER_SIZE);
815 release_mem_region(itv->base_addr + IVTV_REG_OFFSET, IVTV_REG_SIZE); 803 release_mem_region(itv->base_addr + IVTV_REG_OFFSET, IVTV_REG_SIZE);
816 return -EIO; 804 return -EIO;
@@ -853,69 +841,11 @@ static int ivtv_setup_pci(struct ivtv *itv, struct pci_dev *dev,
853 return 0; 841 return 0;
854} 842}
855 843
856#ifdef MODULE
857static u32 ivtv_request_module(struct ivtv *itv, u32 hw,
858 const char *name, u32 id)
859{
860 if ((hw & id) == 0)
861 return hw;
862 if (request_module(name) != 0) {
863 IVTV_ERR("Failed to load module %s\n", name);
864 return hw & ~id;
865 }
866 IVTV_DEBUG_INFO("Loaded module %s\n", name);
867 return hw;
868}
869#endif
870
871static void ivtv_load_and_init_modules(struct ivtv *itv) 844static void ivtv_load_and_init_modules(struct ivtv *itv)
872{ 845{
873 u32 hw = itv->card->hw_all; 846 u32 hw = itv->card->hw_all;
874 unsigned i; 847 unsigned i;
875 848
876#ifdef MODULE
877 /* load modules */
878#ifdef CONFIG_MEDIA_TUNER_MODULE
879 hw = ivtv_request_module(itv, hw, "tuner", IVTV_HW_TUNER);
880#endif
881#ifdef CONFIG_VIDEO_CX25840_MODULE
882 hw = ivtv_request_module(itv, hw, "cx25840", IVTV_HW_CX25840);
883#endif
884#ifdef CONFIG_VIDEO_SAA711X_MODULE
885 hw = ivtv_request_module(itv, hw, "saa7115", IVTV_HW_SAA711X);
886#endif
887#ifdef CONFIG_VIDEO_SAA7127_MODULE
888 hw = ivtv_request_module(itv, hw, "saa7127", IVTV_HW_SAA7127);
889#endif
890#ifdef CONFIG_VIDEO_SAA717X_MODULE
891 hw = ivtv_request_module(itv, hw, "saa717x", IVTV_HW_SAA717X);
892#endif
893#ifdef CONFIG_VIDEO_UPD64031A_MODULE
894 hw = ivtv_request_module(itv, hw, "upd64031a", IVTV_HW_UPD64031A);
895#endif
896#ifdef CONFIG_VIDEO_UPD64083_MODULE
897 hw = ivtv_request_module(itv, hw, "upd64083", IVTV_HW_UPD6408X);
898#endif
899#ifdef CONFIG_VIDEO_MSP3400_MODULE
900 hw = ivtv_request_module(itv, hw, "msp3400", IVTV_HW_MSP34XX);
901#endif
902#ifdef CONFIG_VIDEO_VP27SMPX_MODULE
903 hw = ivtv_request_module(itv, hw, "vp27smpx", IVTV_HW_VP27SMPX);
904#endif
905#ifdef CONFIG_VIDEO_WM8775_MODULE
906 hw = ivtv_request_module(itv, hw, "wm8775", IVTV_HW_WM8775);
907#endif
908#ifdef CONFIG_VIDEO_WM8739_MODULE
909 hw = ivtv_request_module(itv, hw, "wm8739", IVTV_HW_WM8739);
910#endif
911#ifdef CONFIG_VIDEO_CS53L32A_MODULE
912 hw = ivtv_request_module(itv, hw, "cs53l32a", IVTV_HW_CS53L32A);
913#endif
914#ifdef CONFIG_VIDEO_M52790_MODULE
915 hw = ivtv_request_module(itv, hw, "m52790", IVTV_HW_M52790);
916#endif
917#endif
918
919 /* check which i2c devices are actually found */ 849 /* check which i2c devices are actually found */
920 for (i = 0; i < 32; i++) { 850 for (i = 0; i < 32; i++) {
921 u32 device = 1 << i; 851 u32 device = 1 << i;
@@ -927,11 +857,21 @@ static void ivtv_load_and_init_modules(struct ivtv *itv)
927 itv->hw_flags |= device; 857 itv->hw_flags |= device;
928 continue; 858 continue;
929 } 859 }
930 ivtv_i2c_register(itv, i); 860 if (ivtv_i2c_register(itv, i) == 0)
931 if (ivtv_i2c_hw_addr(itv, device) > 0)
932 itv->hw_flags |= device; 861 itv->hw_flags |= device;
933 } 862 }
934 863
864 if (itv->card->hw_all & IVTV_HW_CX25840)
865 itv->sd_video = ivtv_find_hw(itv, IVTV_HW_CX25840);
866 else if (itv->card->hw_all & IVTV_HW_SAA717X)
867 itv->sd_video = ivtv_find_hw(itv, IVTV_HW_SAA717X);
868 else if (itv->card->hw_all & IVTV_HW_SAA7114)
869 itv->sd_video = ivtv_find_hw(itv, IVTV_HW_SAA7114);
870 else
871 itv->sd_video = ivtv_find_hw(itv, IVTV_HW_SAA7115);
872 itv->sd_audio = ivtv_find_hw(itv, itv->card->hw_audio_ctrl);
873 itv->sd_muxer = ivtv_find_hw(itv, itv->card->hw_muxer);
874
935 hw = itv->hw_flags; 875 hw = itv->hw_flags;
936 876
937 if (itv->card->type == IVTV_CARD_CX23416GYC) { 877 if (itv->card->type == IVTV_CARD_CX23416GYC) {
@@ -949,7 +889,7 @@ static void ivtv_load_and_init_modules(struct ivtv *itv)
949 /* The crystal frequency of GVMVPRX is 24.576MHz */ 889 /* The crystal frequency of GVMVPRX is 24.576MHz */
950 crystal_freq.freq = SAA7115_FREQ_24_576_MHZ; 890 crystal_freq.freq = SAA7115_FREQ_24_576_MHZ;
951 crystal_freq.flags = SAA7115_FREQ_FL_UCGC; 891 crystal_freq.flags = SAA7115_FREQ_FL_UCGC;
952 itv->video_dec_func(itv, VIDIOC_INT_S_CRYSTAL_FREQ, &crystal_freq); 892 v4l2_subdev_call(itv->sd_video, video, s_crystal_freq, &crystal_freq);
953 } 893 }
954 894
955 if (hw & IVTV_HW_CX25840) { 895 if (hw & IVTV_HW_CX25840) {
@@ -967,7 +907,7 @@ static void ivtv_load_and_init_modules(struct ivtv *itv)
967 /* determine the exact saa711x model */ 907 /* determine the exact saa711x model */
968 itv->hw_flags &= ~IVTV_HW_SAA711X; 908 itv->hw_flags &= ~IVTV_HW_SAA711X;
969 909
970 ivtv_saa7115(itv, VIDIOC_G_CHIP_IDENT, &v); 910 ivtv_call_hw(itv, IVTV_HW_SAA711X, core, g_chip_ident, &v);
971 if (v.ident == V4L2_IDENT_SAA7114) { 911 if (v.ident == V4L2_IDENT_SAA7114) {
972 itv->hw_flags |= IVTV_HW_SAA7114; 912 itv->hw_flags |= IVTV_HW_SAA7114;
973 /* VBI is not yet supported by the saa7114 driver. */ 913 /* VBI is not yet supported by the saa7114 driver. */
@@ -1001,28 +941,20 @@ static int __devinit ivtv_probe(struct pci_dev *dev,
1001 int vbi_buf_size; 941 int vbi_buf_size;
1002 struct ivtv *itv; 942 struct ivtv *itv;
1003 943
1004 spin_lock(&ivtv_cards_lock);
1005
1006 /* Make sure we've got a place for this card */
1007 if (ivtv_cards_active == IVTV_MAX_CARDS) {
1008 printk(KERN_ERR "ivtv: Maximum number of cards detected (%d)\n",
1009 ivtv_cards_active);
1010 spin_unlock(&ivtv_cards_lock);
1011 return -ENOMEM;
1012 }
1013
1014 itv = kzalloc(sizeof(struct ivtv), GFP_ATOMIC); 944 itv = kzalloc(sizeof(struct ivtv), GFP_ATOMIC);
1015 if (itv == NULL) { 945 if (itv == NULL)
1016 spin_unlock(&ivtv_cards_lock);
1017 return -ENOMEM; 946 return -ENOMEM;
1018 }
1019 ivtv_cards[ivtv_cards_active] = itv;
1020 itv->dev = dev; 947 itv->dev = dev;
1021 itv->num = ivtv_cards_active++; 948 itv->instance = atomic_inc_return(&ivtv_instance) - 1;
1022 snprintf(itv->name, sizeof(itv->name), "ivtv%d", itv->num);
1023 IVTV_INFO("Initializing card #%d\n", itv->num);
1024 949
1025 spin_unlock(&ivtv_cards_lock); 950 retval = v4l2_device_register(&dev->dev, &itv->device);
951 if (retval)
952 return retval;
953 /* "ivtv + PCI ID" is a bit of a mouthful, so use
954 "ivtv + instance" instead. */
955 snprintf(itv->device.name, sizeof(itv->device.name),
956 "ivtv%d", itv->instance);
957 IVTV_INFO("Initializing card %d\n", itv->instance);
1026 958
1027 ivtv_process_options(itv); 959 ivtv_process_options(itv);
1028 if (itv->options.cardtype == -1) { 960 if (itv->options.cardtype == -1) {
@@ -1043,8 +975,6 @@ static int __devinit ivtv_probe(struct pci_dev *dev,
1043 else if (retval == -ENXIO) 975 else if (retval == -ENXIO)
1044 goto free_mem; 976 goto free_mem;
1045 } 977 }
1046 /* save itv in the pci struct for later use */
1047 pci_set_drvdata(dev, itv);
1048 978
1049 /* map io memory */ 979 /* map io memory */
1050 IVTV_DEBUG_INFO("attempting ioremap at 0x%08x len 0x%08x\n", 980 IVTV_DEBUG_INFO("attempting ioremap at 0x%08x len 0x%08x\n",
@@ -1086,7 +1016,9 @@ static int __devinit ivtv_probe(struct pci_dev *dev,
1086 goto free_io; 1016 goto free_io;
1087 } 1017 }
1088 1018
1089 ivtv_gpio_init(itv); 1019 retval = ivtv_gpio_init(itv);
1020 if (retval)
1021 goto free_io;
1090 1022
1091 /* active i2c */ 1023 /* active i2c */
1092 IVTV_DEBUG_INFO("activating i2c...\n"); 1024 IVTV_DEBUG_INFO("activating i2c...\n");
@@ -1095,8 +1027,6 @@ static int __devinit ivtv_probe(struct pci_dev *dev,
1095 goto free_io; 1027 goto free_io;
1096 } 1028 }
1097 1029
1098 IVTV_DEBUG_INFO("Active card count: %d.\n", ivtv_cards_active);
1099
1100 if (itv->card->hw_all & IVTV_HW_TVEEPROM) { 1030 if (itv->card->hw_all & IVTV_HW_TVEEPROM) {
1101 /* Based on the model number the cardtype may be changed. 1031 /* Based on the model number the cardtype may be changed.
1102 The PCI IDs are not always reliable. */ 1032 The PCI IDs are not always reliable. */
@@ -1191,7 +1121,7 @@ static int __devinit ivtv_probe(struct pci_dev *dev,
1191 setup.mode_mask = T_ANALOG_TV; /* matches TV tuners */ 1121 setup.mode_mask = T_ANALOG_TV; /* matches TV tuners */
1192 setup.tuner_callback = (setup.type == TUNER_XC2028) ? 1122 setup.tuner_callback = (setup.type == TUNER_XC2028) ?
1193 ivtv_reset_tuner_gpio : NULL; 1123 ivtv_reset_tuner_gpio : NULL;
1194 ivtv_call_i2c_clients(itv, TUNER_SET_TYPE_ADDR, &setup); 1124 ivtv_call_all(itv, tuner, s_type_addr, &setup);
1195 if (setup.type == TUNER_XC2028) { 1125 if (setup.type == TUNER_XC2028) {
1196 static struct xc2028_ctrl ctrl = { 1126 static struct xc2028_ctrl ctrl = {
1197 .fname = XC2028_DEFAULT_FIRMWARE, 1127 .fname = XC2028_DEFAULT_FIRMWARE,
@@ -1201,7 +1131,7 @@ static int __devinit ivtv_probe(struct pci_dev *dev,
1201 .tuner = itv->options.tuner, 1131 .tuner = itv->options.tuner,
1202 .priv = &ctrl, 1132 .priv = &ctrl,
1203 }; 1133 };
1204 ivtv_call_i2c_clients(itv, TUNER_SET_CONFIG, &cfg); 1134 ivtv_call_all(itv, tuner, s_config, &cfg);
1205 } 1135 }
1206 } 1136 }
1207 1137
@@ -1210,11 +1140,11 @@ static int __devinit ivtv_probe(struct pci_dev *dev,
1210 itv->tuner_std = itv->std; 1140 itv->tuner_std = itv->std;
1211 1141
1212 if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) { 1142 if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) {
1213 ivtv_call_i2c_clients(itv, VIDIOC_INT_S_STD_OUTPUT, &itv->std); 1143 ivtv_call_all(itv, video, s_std_output, itv->std);
1214 /* Turn off the output signal. The mpeg decoder is not yet 1144 /* Turn off the output signal. The mpeg decoder is not yet
1215 active so without this you would get a green image until the 1145 active so without this you would get a green image until the
1216 mpeg decoder becomes active. */ 1146 mpeg decoder becomes active. */
1217 ivtv_saa7127(itv, VIDIOC_STREAMOFF, NULL); 1147 ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_stream, 0);
1218 } 1148 }
1219 1149
1220 /* clear interrupt mask, effectively disabling interrupts */ 1150 /* clear interrupt mask, effectively disabling interrupts */
@@ -1222,7 +1152,7 @@ static int __devinit ivtv_probe(struct pci_dev *dev,
1222 1152
1223 /* Register IRQ */ 1153 /* Register IRQ */
1224 retval = request_irq(itv->dev->irq, ivtv_irq_handler, 1154 retval = request_irq(itv->dev->irq, ivtv_irq_handler,
1225 IRQF_SHARED | IRQF_DISABLED, itv->name, (void *)itv); 1155 IRQF_SHARED | IRQF_DISABLED, itv->device.name, (void *)itv);
1226 if (retval) { 1156 if (retval) {
1227 IVTV_ERR("Failed to register irq %d\n", retval); 1157 IVTV_ERR("Failed to register irq %d\n", retval);
1228 goto free_i2c; 1158 goto free_i2c;
@@ -1238,7 +1168,7 @@ static int __devinit ivtv_probe(struct pci_dev *dev,
1238 IVTV_ERR("Error %d registering devices\n", retval); 1168 IVTV_ERR("Error %d registering devices\n", retval);
1239 goto free_streams; 1169 goto free_streams;
1240 } 1170 }
1241 IVTV_INFO("Initialized card #%d: %s\n", itv->num, itv->card_name); 1171 IVTV_INFO("Initialized card: %s\n", itv->card_name);
1242 return 0; 1172 return 0;
1243 1173
1244free_streams: 1174free_streams:
@@ -1261,10 +1191,8 @@ err:
1261 retval = -ENODEV; 1191 retval = -ENODEV;
1262 IVTV_ERR("Error %d on initialization\n", retval); 1192 IVTV_ERR("Error %d on initialization\n", retval);
1263 1193
1264 spin_lock(&ivtv_cards_lock); 1194 v4l2_device_unregister(&itv->device);
1265 kfree(ivtv_cards[ivtv_cards_active]); 1195 kfree(itv);
1266 ivtv_cards[ivtv_cards_active] = NULL;
1267 spin_unlock(&ivtv_cards_lock);
1268 return retval; 1196 return retval;
1269} 1197}
1270 1198
@@ -1304,10 +1232,11 @@ int ivtv_init_on_first_open(struct ivtv *itv)
1304 if (itv->card->hw_all & IVTV_HW_CX25840) { 1232 if (itv->card->hw_all & IVTV_HW_CX25840) {
1305 struct v4l2_control ctrl; 1233 struct v4l2_control ctrl;
1306 1234
1235 v4l2_subdev_call(itv->sd_video, core, init, 0);
1307 /* CX25840_CID_ENABLE_PVR150_WORKAROUND */ 1236 /* CX25840_CID_ENABLE_PVR150_WORKAROUND */
1308 ctrl.id = V4L2_CID_PRIVATE_BASE; 1237 ctrl.id = V4L2_CID_PRIVATE_BASE;
1309 ctrl.value = itv->pvr150_workaround; 1238 ctrl.value = itv->pvr150_workaround;
1310 itv->video_dec_func(itv, VIDIOC_S_CTRL, &ctrl); 1239 v4l2_subdev_call(itv->sd_video, core, s_ctrl, &ctrl);
1311 } 1240 }
1312 1241
1313 vf.tuner = 0; 1242 vf.tuner = 0;
@@ -1337,7 +1266,7 @@ int ivtv_init_on_first_open(struct ivtv *itv)
1337 /* Turn on the TV-out: ivtv_init_mpeg_decoder() initializes 1266 /* Turn on the TV-out: ivtv_init_mpeg_decoder() initializes
1338 the mpeg decoder so now the saa7127 receives a proper 1267 the mpeg decoder so now the saa7127 receives a proper
1339 signal. */ 1268 signal. */
1340 ivtv_saa7127(itv, VIDIOC_STREAMON, NULL); 1269 ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_stream, 1);
1341 ivtv_init_mpeg_decoder(itv); 1270 ivtv_init_mpeg_decoder(itv);
1342 } 1271 }
1343 ivtv_s_std(NULL, &fh, &itv->tuner_std); 1272 ivtv_s_std(NULL, &fh, &itv->tuner_std);
@@ -1362,9 +1291,11 @@ int ivtv_init_on_first_open(struct ivtv *itv)
1362 1291
1363static void ivtv_remove(struct pci_dev *pci_dev) 1292static void ivtv_remove(struct pci_dev *pci_dev)
1364{ 1293{
1365 struct ivtv *itv = pci_get_drvdata(pci_dev); 1294 struct v4l2_device *dev = dev_get_drvdata(&pci_dev->dev);
1295 struct ivtv *itv = to_ivtv(dev);
1296 int i;
1366 1297
1367 IVTV_DEBUG_INFO("Removing Card #%d\n", itv->num); 1298 IVTV_DEBUG_INFO("Removing card\n");
1368 1299
1369 if (test_bit(IVTV_F_I_INITED, &itv->i_flags)) { 1300 if (test_bit(IVTV_F_I_INITED, &itv->i_flags)) {
1370 /* Stop all captures */ 1301 /* Stop all captures */
@@ -1377,7 +1308,7 @@ static void ivtv_remove(struct pci_dev *pci_dev)
1377 1308
1378 /* Turn off the TV-out */ 1309 /* Turn off the TV-out */
1379 if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) 1310 if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)
1380 ivtv_saa7127(itv, VIDIOC_STREAMOFF, NULL); 1311 ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_stream, 0);
1381 if (atomic_read(&itv->decoding) > 0) { 1312 if (atomic_read(&itv->decoding) > 0) {
1382 int type; 1313 int type;
1383 1314
@@ -1402,6 +1333,8 @@ static void ivtv_remove(struct pci_dev *pci_dev)
1402 ivtv_streams_cleanup(itv, 1); 1333 ivtv_streams_cleanup(itv, 1);
1403 ivtv_udma_free(itv); 1334 ivtv_udma_free(itv);
1404 1335
1336 v4l2_device_unregister(&itv->device);
1337
1405 exit_ivtv_i2c(itv); 1338 exit_ivtv_i2c(itv);
1406 1339
1407 free_irq(itv->dev->irq, (void *)itv); 1340 free_irq(itv->dev->irq, (void *)itv);
@@ -1413,8 +1346,11 @@ static void ivtv_remove(struct pci_dev *pci_dev)
1413 release_mem_region(itv->base_addr + IVTV_DECODER_OFFSET, IVTV_DECODER_SIZE); 1346 release_mem_region(itv->base_addr + IVTV_DECODER_OFFSET, IVTV_DECODER_SIZE);
1414 1347
1415 pci_disable_device(itv->dev); 1348 pci_disable_device(itv->dev);
1349 for (i = 0; i < IVTV_VBI_FRAMES; i++)
1350 kfree(itv->vbi.sliced_mpeg_data[i]);
1416 1351
1417 IVTV_INFO("Removed %s, card #%d\n", itv->card_name, itv->num); 1352 printk(KERN_INFO "ivtv: Removed %s\n", itv->card_name);
1353 kfree(itv);
1418} 1354}
1419 1355
1420/* define a pci_driver for card detection */ 1356/* define a pci_driver for card detection */
@@ -1427,54 +1363,36 @@ static struct pci_driver ivtv_pci_driver = {
1427 1363
1428static int module_start(void) 1364static int module_start(void)
1429{ 1365{
1430 printk(KERN_INFO "ivtv: Start initialization, version %s\n", IVTV_VERSION); 1366 printk(KERN_INFO "ivtv: Start initialization, version %s\n", IVTV_VERSION);
1431
1432 memset(ivtv_cards, 0, sizeof(ivtv_cards));
1433 1367
1434 /* Validate parameters */ 1368 /* Validate parameters */
1435 if (ivtv_first_minor < 0 || ivtv_first_minor >= IVTV_MAX_CARDS) { 1369 if (ivtv_first_minor < 0 || ivtv_first_minor >= IVTV_MAX_CARDS) {
1436 printk(KERN_ERR "ivtv: Exiting, ivtv_first_minor must be between 0 and %d\n", 1370 printk(KERN_ERR "ivtv: Exiting, ivtv_first_minor must be between 0 and %d\n",
1437 IVTV_MAX_CARDS - 1); 1371 IVTV_MAX_CARDS - 1);
1438 return -1; 1372 return -1;
1439 } 1373 }
1440 1374
1441 if (ivtv_debug < 0 || ivtv_debug > 2047) { 1375 if (ivtv_debug < 0 || ivtv_debug > 2047) {
1442 ivtv_debug = 0; 1376 ivtv_debug = 0;
1443 printk(KERN_INFO "ivtv: Debug value must be >= 0 and <= 2047\n"); 1377 printk(KERN_INFO "ivtv: Debug value must be >= 0 and <= 2047\n");
1444 } 1378 }
1445 1379
1446 if (pci_register_driver(&ivtv_pci_driver)) { 1380 if (pci_register_driver(&ivtv_pci_driver)) {
1447 printk(KERN_ERR "ivtv: Error detecting PCI card\n"); 1381 printk(KERN_ERR "ivtv: Error detecting PCI card\n");
1448 return -ENODEV; 1382 return -ENODEV;
1449 } 1383 }
1450 printk(KERN_INFO "ivtv: End initialization\n"); 1384 printk(KERN_INFO "ivtv: End initialization\n");
1451 return 0; 1385 return 0;
1452} 1386}
1453 1387
1454static void module_cleanup(void) 1388static void module_cleanup(void)
1455{ 1389{
1456 int i, j;
1457
1458 pci_unregister_driver(&ivtv_pci_driver); 1390 pci_unregister_driver(&ivtv_pci_driver);
1459
1460 spin_lock(&ivtv_cards_lock);
1461 for (i = 0; i < ivtv_cards_active; i++) {
1462 if (ivtv_cards[i] == NULL)
1463 continue;
1464 for (j = 0; j < IVTV_VBI_FRAMES; j++) {
1465 kfree(ivtv_cards[i]->vbi.sliced_mpeg_data[j]);
1466 }
1467 kfree(ivtv_cards[i]);
1468 }
1469 spin_unlock(&ivtv_cards_lock);
1470} 1391}
1471 1392
1472/* Note: These symbols are exported because they are used by the ivtvfb 1393/* Note: These symbols are exported because they are used by the ivtvfb
1473 framebuffer module and an infrared module for the IR-blaster. */ 1394 framebuffer module and an infrared module for the IR-blaster. */
1474EXPORT_SYMBOL(ivtv_set_irq_mask); 1395EXPORT_SYMBOL(ivtv_set_irq_mask);
1475EXPORT_SYMBOL(ivtv_cards_active);
1476EXPORT_SYMBOL(ivtv_cards);
1477EXPORT_SYMBOL(ivtv_cards_lock);
1478EXPORT_SYMBOL(ivtv_api); 1396EXPORT_SYMBOL(ivtv_api);
1479EXPORT_SYMBOL(ivtv_vapi); 1397EXPORT_SYMBOL(ivtv_vapi);
1480EXPORT_SYMBOL(ivtv_vapi_result); 1398EXPORT_SYMBOL(ivtv_vapi_result);
diff --git a/drivers/media/video/ivtv/ivtv-driver.h b/drivers/media/video/ivtv/ivtv-driver.h
index 3733b2afec5f..ce8d9b74357e 100644
--- a/drivers/media/video/ivtv/ivtv-driver.h
+++ b/drivers/media/video/ivtv/ivtv-driver.h
@@ -61,6 +61,7 @@
61#include <linux/dvb/audio.h> 61#include <linux/dvb/audio.h>
62#include <media/v4l2-common.h> 62#include <media/v4l2-common.h>
63#include <media/v4l2-ioctl.h> 63#include <media/v4l2-ioctl.h>
64#include <media/v4l2-device.h>
64#include <media/tuner.h> 65#include <media/tuner.h>
65#include <media/cx2341x.h> 66#include <media/cx2341x.h>
66 67
@@ -113,9 +114,6 @@
113#define IVTV_REG_VPU (0x9058) 114#define IVTV_REG_VPU (0x9058)
114#define IVTV_REG_APU (0xA064) 115#define IVTV_REG_APU (0xA064)
115 116
116/* i2c stuff */
117#define I2C_CLIENTS_MAX 16
118
119/* debugging */ 117/* debugging */
120extern int ivtv_debug; 118extern int ivtv_debug;
121 119
@@ -132,12 +130,10 @@ extern int ivtv_debug;
132/* Flag to turn on high volume debugging */ 130/* Flag to turn on high volume debugging */
133#define IVTV_DBGFLG_HIGHVOL (1 << 10) 131#define IVTV_DBGFLG_HIGHVOL (1 << 10)
134 132
135/* NOTE: extra space before comma in 'itv->num , ## args' is required for
136 gcc-2.95, otherwise it won't compile. */
137#define IVTV_DEBUG(x, type, fmt, args...) \ 133#define IVTV_DEBUG(x, type, fmt, args...) \
138 do { \ 134 do { \
139 if ((x) & ivtv_debug) \ 135 if ((x) & ivtv_debug) \
140 printk(KERN_INFO "ivtv%d " type ": " fmt, itv->num , ## args); \ 136 v4l2_info(&itv->device, " " type ": " fmt , ##args); \
141 } while (0) 137 } while (0)
142#define IVTV_DEBUG_WARN(fmt, args...) IVTV_DEBUG(IVTV_DBGFLG_WARN, "warn", fmt , ## args) 138#define IVTV_DEBUG_WARN(fmt, args...) IVTV_DEBUG(IVTV_DBGFLG_WARN, "warn", fmt , ## args)
143#define IVTV_DEBUG_INFO(fmt, args...) IVTV_DEBUG(IVTV_DBGFLG_INFO, "info", fmt , ## args) 139#define IVTV_DEBUG_INFO(fmt, args...) IVTV_DEBUG(IVTV_DBGFLG_INFO, "info", fmt , ## args)
@@ -152,8 +148,8 @@ extern int ivtv_debug;
152 148
153#define IVTV_DEBUG_HIGH_VOL(x, type, fmt, args...) \ 149#define IVTV_DEBUG_HIGH_VOL(x, type, fmt, args...) \
154 do { \ 150 do { \
155 if (((x) & ivtv_debug) && (ivtv_debug & IVTV_DBGFLG_HIGHVOL)) \ 151 if (((x) & ivtv_debug) && (ivtv_debug & IVTV_DBGFLG_HIGHVOL)) \
156 printk(KERN_INFO "ivtv%d " type ": " fmt, itv->num , ## args); \ 152 v4l2_info(&itv->device, " " type ": " fmt , ##args); \
157 } while (0) 153 } while (0)
158#define IVTV_DEBUG_HI_WARN(fmt, args...) IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_WARN, "warn", fmt , ## args) 154#define IVTV_DEBUG_HI_WARN(fmt, args...) IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_WARN, "warn", fmt , ## args)
159#define IVTV_DEBUG_HI_INFO(fmt, args...) IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_INFO, "info", fmt , ## args) 155#define IVTV_DEBUG_HI_INFO(fmt, args...) IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_INFO, "info", fmt , ## args)
@@ -167,9 +163,9 @@ extern int ivtv_debug;
167#define IVTV_DEBUG_HI_YUV(fmt, args...) IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_YUV, "yuv", fmt , ## args) 163#define IVTV_DEBUG_HI_YUV(fmt, args...) IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_YUV, "yuv", fmt , ## args)
168 164
169/* Standard kernel messages */ 165/* Standard kernel messages */
170#define IVTV_ERR(fmt, args...) printk(KERN_ERR "ivtv%d: " fmt, itv->num , ## args) 166#define IVTV_ERR(fmt, args...) v4l2_err(&itv->device, fmt , ## args)
171#define IVTV_WARN(fmt, args...) printk(KERN_WARNING "ivtv%d: " fmt, itv->num , ## args) 167#define IVTV_WARN(fmt, args...) v4l2_warn(&itv->device, fmt , ## args)
172#define IVTV_INFO(fmt, args...) printk(KERN_INFO "ivtv%d: " fmt, itv->num , ## args) 168#define IVTV_INFO(fmt, args...) v4l2_info(&itv->device, fmt , ## args)
173 169
174/* output modes (cx23415 only) */ 170/* output modes (cx23415 only) */
175#define OUT_NONE 0 171#define OUT_NONE 0
@@ -596,8 +592,6 @@ struct ivtv_card;
596/* Struct to hold info about ivtv cards */ 592/* Struct to hold info about ivtv cards */
597struct ivtv { 593struct ivtv {
598 /* General fixed card data */ 594 /* General fixed card data */
599 int num; /* board number, -1 during init! */
600 char name[8]; /* board name for printk and interrupts (e.g. 'ivtv0') */
601 struct pci_dev *dev; /* PCI device */ 595 struct pci_dev *dev; /* PCI device */
602 const struct ivtv_card *card; /* card information */ 596 const struct ivtv_card *card; /* card information */
603 const char *card_name; /* full name of the card */ 597 const char *card_name; /* full name of the card */
@@ -609,14 +603,18 @@ struct ivtv {
609 u32 v4l2_cap; /* V4L2 capabilities of card */ 603 u32 v4l2_cap; /* V4L2 capabilities of card */
610 u32 hw_flags; /* hardware description of the board */ 604 u32 hw_flags; /* hardware description of the board */
611 v4l2_std_id tuner_std; /* the norm of the card's tuner (fixed) */ 605 v4l2_std_id tuner_std; /* the norm of the card's tuner (fixed) */
612 /* controlling video decoder function */ 606 struct v4l2_subdev *sd_video; /* controlling video decoder subdev */
613 int (*video_dec_func)(struct ivtv *, unsigned int, void *); 607 struct v4l2_subdev *sd_audio; /* controlling audio subdev */
608 struct v4l2_subdev *sd_muxer; /* controlling audio muxer subdev */
614 u32 base_addr; /* PCI resource base address */ 609 u32 base_addr; /* PCI resource base address */
615 volatile void __iomem *enc_mem; /* pointer to mapped encoder memory */ 610 volatile void __iomem *enc_mem; /* pointer to mapped encoder memory */
616 volatile void __iomem *dec_mem; /* pointer to mapped decoder memory */ 611 volatile void __iomem *dec_mem; /* pointer to mapped decoder memory */
617 volatile void __iomem *reg_mem; /* pointer to mapped registers */ 612 volatile void __iomem *reg_mem; /* pointer to mapped registers */
618 struct ivtv_options options; /* user options */ 613 struct ivtv_options options; /* user options */
619 614
615 struct v4l2_device device;
616 struct v4l2_subdev sd_gpio; /* GPIO sub-device */
617 u16 instance;
620 618
621 /* High-level state info */ 619 /* High-level state info */
622 unsigned long i_flags; /* global ivtv flags */ 620 unsigned long i_flags; /* global ivtv flags */
@@ -676,7 +674,6 @@ struct ivtv {
676 struct i2c_adapter i2c_adap; 674 struct i2c_adapter i2c_adap;
677 struct i2c_algo_bit_data i2c_algo; 675 struct i2c_algo_bit_data i2c_algo;
678 struct i2c_client i2c_client; 676 struct i2c_client i2c_client;
679 struct i2c_client *i2c_clients[I2C_CLIENTS_MAX];/* pointers to all I2C clients */
680 int i2c_state; /* i2c bit state */ 677 int i2c_state; /* i2c bit state */
681 struct mutex i2c_bus_lock; /* lock i2c bus */ 678 struct mutex i2c_bus_lock; /* lock i2c bus */
682 679
@@ -722,11 +719,13 @@ struct ivtv {
722 struct osd_info *osd_info; /* ivtvfb private OSD info */ 719 struct osd_info *osd_info; /* ivtvfb private OSD info */
723}; 720};
724 721
722static inline struct ivtv *to_ivtv(struct v4l2_device *dev)
723{
724 return container_of(dev, struct ivtv, device);
725}
726
725/* Globals */ 727/* Globals */
726extern struct ivtv *ivtv_cards[];
727extern int ivtv_cards_active;
728extern int ivtv_first_minor; 728extern int ivtv_first_minor;
729extern spinlock_t ivtv_cards_lock;
730 729
731/*==============Prototypes==================*/ 730/*==============Prototypes==================*/
732 731
@@ -786,4 +785,19 @@ static inline int ivtv_raw_vbi(const struct ivtv *itv)
786#define write_dec_sync(val, addr) \ 785#define write_dec_sync(val, addr) \
787 do { write_dec(val, addr); read_dec(addr); } while (0) 786 do { write_dec(val, addr); read_dec(addr); } while (0)
788 787
788/* Call the specified callback for all subdevs matching hw (if 0, then
789 match them all). Ignore any errors. */
790#define ivtv_call_hw(itv, hw, o, f, args...) \
791 __v4l2_device_call_subdevs(&(itv)->device, !(hw) || (sd->grp_id & (hw)), o, f , ##args)
792
793#define ivtv_call_all(itv, o, f, args...) ivtv_call_hw(itv, 0, o, f , ##args)
794
795/* Call the specified callback for all subdevs matching hw (if 0, then
796 match them all). If the callback returns an error other than 0 or
797 -ENOIOCTLCMD, then return with that error code. */
798#define ivtv_call_hw_err(itv, hw, o, f, args...) \
799 __v4l2_device_call_subdevs_until_err(&(itv)->device, !(hw) || (sd->grp_id & (hw)), o, f , ##args)
800
801#define ivtv_call_all_err(itv, o, f, args...) ivtv_call_hw_err(itv, 0, o, f , ##args)
802
789#endif 803#endif
diff --git a/drivers/media/video/ivtv/ivtv-fileops.c b/drivers/media/video/ivtv/ivtv-fileops.c
index 1c404e454a36..5eb587592e9d 100644
--- a/drivers/media/video/ivtv/ivtv-fileops.c
+++ b/drivers/media/video/ivtv/ivtv-fileops.c
@@ -155,7 +155,7 @@ static void ivtv_dualwatch(struct ivtv *itv)
155 155
156 new_stereo_mode = itv->params.audio_properties & stereo_mask; 156 new_stereo_mode = itv->params.audio_properties & stereo_mask;
157 memset(&vt, 0, sizeof(vt)); 157 memset(&vt, 0, sizeof(vt));
158 ivtv_call_i2c_clients(itv, VIDIOC_G_TUNER, &vt); 158 ivtv_call_all(itv, tuner, g_tuner, &vt);
159 if (vt.audmode == V4L2_TUNER_MODE_LANG1_LANG2 && (vt.rxsubchans & V4L2_TUNER_SUB_LANG2)) 159 if (vt.audmode == V4L2_TUNER_MODE_LANG1_LANG2 && (vt.rxsubchans & V4L2_TUNER_SUB_LANG2))
160 new_stereo_mode = dual; 160 new_stereo_mode = dual;
161 161
@@ -857,7 +857,7 @@ int ivtv_v4l2_close(struct inode *inode, struct file *filp)
857 /* Mark that the radio is no longer in use */ 857 /* Mark that the radio is no longer in use */
858 clear_bit(IVTV_F_I_RADIO_USER, &itv->i_flags); 858 clear_bit(IVTV_F_I_RADIO_USER, &itv->i_flags);
859 /* Switch tuner to TV */ 859 /* Switch tuner to TV */
860 ivtv_call_i2c_clients(itv, VIDIOC_S_STD, &itv->std); 860 ivtv_call_all(itv, tuner, s_std, itv->std);
861 /* Select correct audio input (i.e. TV tuner or Line in) */ 861 /* Select correct audio input (i.e. TV tuner or Line in) */
862 ivtv_audio_set_io(itv); 862 ivtv_audio_set_io(itv);
863 if (itv->hw_flags & IVTV_HW_SAA711X) 863 if (itv->hw_flags & IVTV_HW_SAA711X)
@@ -865,7 +865,7 @@ int ivtv_v4l2_close(struct inode *inode, struct file *filp)
865 struct v4l2_crystal_freq crystal_freq; 865 struct v4l2_crystal_freq crystal_freq;
866 crystal_freq.freq = SAA7115_FREQ_32_11_MHZ; 866 crystal_freq.freq = SAA7115_FREQ_32_11_MHZ;
867 crystal_freq.flags = 0; 867 crystal_freq.flags = 0;
868 ivtv_saa7115(itv, VIDIOC_INT_S_CRYSTAL_FREQ, &crystal_freq); 868 ivtv_call_hw(itv, IVTV_HW_SAA711X, video, s_crystal_freq, &crystal_freq);
869 } 869 }
870 if (atomic_read(&itv->capturing) > 0) { 870 if (atomic_read(&itv->capturing) > 0) {
871 /* Undo video mute */ 871 /* Undo video mute */
@@ -952,15 +952,14 @@ static int ivtv_serialized_open(struct ivtv_stream *s, struct file *filp)
952 /* We have the radio */ 952 /* We have the radio */
953 ivtv_mute(itv); 953 ivtv_mute(itv);
954 /* Switch tuner to radio */ 954 /* Switch tuner to radio */
955 ivtv_call_i2c_clients(itv, AUDC_SET_RADIO, NULL); 955 ivtv_call_all(itv, tuner, s_radio);
956 /* Select the correct audio input (i.e. radio tuner) */ 956 /* Select the correct audio input (i.e. radio tuner) */
957 ivtv_audio_set_io(itv); 957 ivtv_audio_set_io(itv);
958 if (itv->hw_flags & IVTV_HW_SAA711X) 958 if (itv->hw_flags & IVTV_HW_SAA711X) {
959 {
960 struct v4l2_crystal_freq crystal_freq; 959 struct v4l2_crystal_freq crystal_freq;
961 crystal_freq.freq = SAA7115_FREQ_32_11_MHZ; 960 crystal_freq.freq = SAA7115_FREQ_32_11_MHZ;
962 crystal_freq.flags = SAA7115_FREQ_FL_APLL; 961 crystal_freq.flags = SAA7115_FREQ_FL_APLL;
963 ivtv_saa7115(itv, VIDIOC_INT_S_CRYSTAL_FREQ, &crystal_freq); 962 ivtv_call_hw(itv, IVTV_HW_SAA711X, video, s_crystal_freq, &crystal_freq);
964 } 963 }
965 /* Done! Unmute and continue. */ 964 /* Done! Unmute and continue. */
966 ivtv_unmute(itv); 965 ivtv_unmute(itv);
@@ -981,37 +980,18 @@ static int ivtv_serialized_open(struct ivtv_stream *s, struct file *filp)
981 980
982int ivtv_v4l2_open(struct inode *inode, struct file *filp) 981int ivtv_v4l2_open(struct inode *inode, struct file *filp)
983{ 982{
984 int res, x, y = 0; 983 int res;
985 struct ivtv *itv = NULL; 984 struct ivtv *itv = NULL;
986 struct ivtv_stream *s = NULL; 985 struct ivtv_stream *s = NULL;
987 int minor = iminor(inode); 986 struct video_device *vdev = video_devdata(filp);
988
989 /* Find which card this open was on */
990 spin_lock(&ivtv_cards_lock);
991 for (x = 0; itv == NULL && x < ivtv_cards_active; x++) {
992 if (ivtv_cards[x] == NULL)
993 continue;
994 /* find out which stream this open was on */
995 for (y = 0; y < IVTV_MAX_STREAMS; y++) {
996 s = &ivtv_cards[x]->streams[y];
997 if (s->v4l2dev && s->v4l2dev->minor == minor) {
998 itv = ivtv_cards[x];
999 break;
1000 }
1001 }
1002 }
1003 spin_unlock(&ivtv_cards_lock);
1004 987
1005 if (itv == NULL) { 988 s = video_get_drvdata(vdev);
1006 /* Couldn't find a device registered 989 itv = s->itv;
1007 on that minor, shouldn't happen! */
1008 printk(KERN_WARNING "No ivtv device found on minor %d\n", minor);
1009 return -ENXIO;
1010 }
1011 990
1012 mutex_lock(&itv->serialize_lock); 991 mutex_lock(&itv->serialize_lock);
1013 if (ivtv_init_on_first_open(itv)) { 992 if (ivtv_init_on_first_open(itv)) {
1014 IVTV_ERR("Failed to initialize on minor %d\n", minor); 993 IVTV_ERR("Failed to initialize on minor %d\n",
994 s->v4l2dev->minor);
1015 mutex_unlock(&itv->serialize_lock); 995 mutex_unlock(&itv->serialize_lock);
1016 return -ENXIO; 996 return -ENXIO;
1017 } 997 }
diff --git a/drivers/media/video/ivtv/ivtv-gpio.c b/drivers/media/video/ivtv/ivtv-gpio.c
index 74a44844ccaf..dc2850e87a7e 100644
--- a/drivers/media/video/ivtv/ivtv-gpio.c
+++ b/drivers/media/video/ivtv/ivtv-gpio.c
@@ -144,22 +144,9 @@ int ivtv_reset_tuner_gpio(void *dev, int component, int cmd, int value)
144 return 0; 144 return 0;
145} 145}
146 146
147void ivtv_gpio_init(struct ivtv *itv) 147static inline struct ivtv *sd_to_ivtv(struct v4l2_subdev *sd)
148{ 148{
149 u16 pin = 0; 149 return container_of(sd, struct ivtv, sd_gpio);
150
151 if (itv->card->xceive_pin)
152 pin = 1 << itv->card->xceive_pin;
153
154 if ((itv->card->gpio_init.direction | pin) == 0)
155 return;
156
157 IVTV_DEBUG_INFO("GPIO initial dir: %08x out: %08x\n",
158 read_reg(IVTV_REG_GPIO_DIR), read_reg(IVTV_REG_GPIO_OUT));
159
160 /* init output data then direction */
161 write_reg(itv->card->gpio_init.initial_value | pin, IVTV_REG_GPIO_OUT);
162 write_reg(itv->card->gpio_init.direction | pin, IVTV_REG_GPIO_DIR);
163} 150}
164 151
165static struct v4l2_queryctrl gpio_ctrl_mute = { 152static struct v4l2_queryctrl gpio_ctrl_mute = {
@@ -173,134 +160,231 @@ static struct v4l2_queryctrl gpio_ctrl_mute = {
173 .flags = 0, 160 .flags = 0,
174}; 161};
175 162
176int ivtv_gpio(struct ivtv *itv, unsigned int command, void *arg) 163static int subdev_s_clock_freq(struct v4l2_subdev *sd, u32 freq)
177{ 164{
178 struct v4l2_tuner *tuner = arg; 165 struct ivtv *itv = sd_to_ivtv(sd);
179 struct v4l2_control *ctrl = arg;
180 struct v4l2_routing *route = arg;
181 u16 mask, data; 166 u16 mask, data;
182 167
183 switch (command) { 168 mask = itv->card->gpio_audio_freq.mask;
184 case VIDIOC_INT_AUDIO_CLOCK_FREQ: 169 switch (freq) {
185 mask = itv->card->gpio_audio_freq.mask; 170 case 32000:
186 switch (*(u32 *)arg) { 171 data = itv->card->gpio_audio_freq.f32000;
187 case 32000: 172 break;
188 data = itv->card->gpio_audio_freq.f32000; 173 case 44100:
189 break; 174 data = itv->card->gpio_audio_freq.f44100;
190 case 44100: 175 break;
191 data = itv->card->gpio_audio_freq.f44100; 176 case 48000:
192 break; 177 default:
193 case 48000: 178 data = itv->card->gpio_audio_freq.f48000;
194 default:
195 data = itv->card->gpio_audio_freq.f48000;
196 break;
197 }
198 break; 179 break;
180 }
181 if (mask)
182 write_reg((read_reg(IVTV_REG_GPIO_OUT) & ~mask) | (data & mask), IVTV_REG_GPIO_OUT);
183 return 0;
184}
199 185
200 case VIDIOC_G_TUNER: 186static int subdev_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
201 mask = itv->card->gpio_audio_detect.mask; 187{
202 if (mask == 0 || (read_reg(IVTV_REG_GPIO_IN) & mask)) 188 struct ivtv *itv = sd_to_ivtv(sd);
203 tuner->rxsubchans = V4L2_TUNER_MODE_STEREO | 189 u16 mask;
204 V4L2_TUNER_MODE_LANG1 | V4L2_TUNER_MODE_LANG2; 190
205 else 191 mask = itv->card->gpio_audio_detect.mask;
206 tuner->rxsubchans = V4L2_TUNER_SUB_MONO; 192 if (mask == 0 || (read_reg(IVTV_REG_GPIO_IN) & mask))
207 return 0; 193 vt->rxsubchans = V4L2_TUNER_MODE_STEREO |
194 V4L2_TUNER_MODE_LANG1 | V4L2_TUNER_MODE_LANG2;
195 else
196 vt->rxsubchans = V4L2_TUNER_SUB_MONO;
197 return 0;
198}
208 199
209 case VIDIOC_S_TUNER: 200static int subdev_s_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
210 mask = itv->card->gpio_audio_mode.mask; 201{
211 switch (tuner->audmode) { 202 struct ivtv *itv = sd_to_ivtv(sd);
212 case V4L2_TUNER_MODE_LANG1: 203 u16 mask, data;
213 data = itv->card->gpio_audio_mode.lang1;
214 break;
215 case V4L2_TUNER_MODE_LANG2:
216 data = itv->card->gpio_audio_mode.lang2;
217 break;
218 case V4L2_TUNER_MODE_MONO:
219 data = itv->card->gpio_audio_mode.mono;
220 break;
221 case V4L2_TUNER_MODE_STEREO:
222 case V4L2_TUNER_MODE_LANG1_LANG2:
223 default:
224 data = itv->card->gpio_audio_mode.stereo;
225 break;
226 }
227 break;
228 204
229 case AUDC_SET_RADIO: 205 mask = itv->card->gpio_audio_mode.mask;
230 mask = itv->card->gpio_audio_input.mask; 206 switch (vt->audmode) {
231 data = itv->card->gpio_audio_input.radio; 207 case V4L2_TUNER_MODE_LANG1:
208 data = itv->card->gpio_audio_mode.lang1;
209 break;
210 case V4L2_TUNER_MODE_LANG2:
211 data = itv->card->gpio_audio_mode.lang2;
212 break;
213 case V4L2_TUNER_MODE_MONO:
214 data = itv->card->gpio_audio_mode.mono;
232 break; 215 break;
216 case V4L2_TUNER_MODE_STEREO:
217 case V4L2_TUNER_MODE_LANG1_LANG2:
218 default:
219 data = itv->card->gpio_audio_mode.stereo;
220 break;
221 }
222 if (mask)
223 write_reg((read_reg(IVTV_REG_GPIO_OUT) & ~mask) | (data & mask), IVTV_REG_GPIO_OUT);
224 return 0;
225}
226
227static int subdev_s_radio(struct v4l2_subdev *sd)
228{
229 struct ivtv *itv = sd_to_ivtv(sd);
230 u16 mask, data;
231
232 mask = itv->card->gpio_audio_input.mask;
233 data = itv->card->gpio_audio_input.radio;
234 if (mask)
235 write_reg((read_reg(IVTV_REG_GPIO_OUT) & ~mask) | (data & mask), IVTV_REG_GPIO_OUT);
236 return 0;
237}
233 238
234 case VIDIOC_S_STD: 239static int subdev_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
235 mask = itv->card->gpio_audio_input.mask; 240{
241 struct ivtv *itv = sd_to_ivtv(sd);
242 u16 mask, data;
243
244 mask = itv->card->gpio_audio_input.mask;
245 data = itv->card->gpio_audio_input.tuner;
246 if (mask)
247 write_reg((read_reg(IVTV_REG_GPIO_OUT) & ~mask) | (data & mask), IVTV_REG_GPIO_OUT);
248 return 0;
249}
250
251static int subdev_s_audio_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
252{
253 struct ivtv *itv = sd_to_ivtv(sd);
254 u16 mask, data;
255
256 if (route->input > 2)
257 return -EINVAL;
258 mask = itv->card->gpio_audio_input.mask;
259 switch (route->input) {
260 case 0:
236 data = itv->card->gpio_audio_input.tuner; 261 data = itv->card->gpio_audio_input.tuner;
237 break; 262 break;
238 263 case 1:
239 case VIDIOC_INT_S_AUDIO_ROUTING: 264 data = itv->card->gpio_audio_input.linein;
240 if (route->input > 2) 265 break;
241 return -EINVAL; 266 case 2:
242 mask = itv->card->gpio_audio_input.mask; 267 default:
243 switch (route->input) { 268 data = itv->card->gpio_audio_input.radio;
244 case 0:
245 data = itv->card->gpio_audio_input.tuner;
246 break;
247 case 1:
248 data = itv->card->gpio_audio_input.linein;
249 break;
250 case 2:
251 default:
252 data = itv->card->gpio_audio_input.radio;
253 break;
254 }
255 break; 269 break;
270 }
271 if (mask)
272 write_reg((read_reg(IVTV_REG_GPIO_OUT) & ~mask) | (data & mask), IVTV_REG_GPIO_OUT);
273 return 0;
274}
256 275
257 case VIDIOC_G_CTRL: 276static int subdev_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
258 if (ctrl->id != V4L2_CID_AUDIO_MUTE) 277{
259 return -EINVAL; 278 struct ivtv *itv = sd_to_ivtv(sd);
260 mask = itv->card->gpio_audio_mute.mask; 279 u16 mask, data;
261 data = itv->card->gpio_audio_mute.mute;
262 ctrl->value = (read_reg(IVTV_REG_GPIO_OUT) & mask) == data;
263 return 0;
264 280
265 case VIDIOC_S_CTRL: 281 if (ctrl->id != V4L2_CID_AUDIO_MUTE)
266 if (ctrl->id != V4L2_CID_AUDIO_MUTE) 282 return -EINVAL;
267 return -EINVAL; 283 mask = itv->card->gpio_audio_mute.mask;
268 mask = itv->card->gpio_audio_mute.mask; 284 data = itv->card->gpio_audio_mute.mute;
269 data = ctrl->value ? itv->card->gpio_audio_mute.mute : 0; 285 ctrl->value = (read_reg(IVTV_REG_GPIO_OUT) & mask) == data;
270 break; 286 return 0;
287}
271 288
272 case VIDIOC_QUERYCTRL: 289static int subdev_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
273 { 290{
274 struct v4l2_queryctrl *qc = arg; 291 struct ivtv *itv = sd_to_ivtv(sd);
292 u16 mask, data;
275 293
276 if (qc->id != V4L2_CID_AUDIO_MUTE) 294 if (ctrl->id != V4L2_CID_AUDIO_MUTE)
277 return -EINVAL; 295 return -EINVAL;
278 *qc = gpio_ctrl_mute; 296 mask = itv->card->gpio_audio_mute.mask;
279 return 0; 297 data = ctrl->value ? itv->card->gpio_audio_mute.mute : 0;
280 } 298 if (mask)
299 write_reg((read_reg(IVTV_REG_GPIO_OUT) & ~mask) | (data & mask), IVTV_REG_GPIO_OUT);
300 return 0;
301}
302
303static int subdev_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
304{
305 if (qc->id != V4L2_CID_AUDIO_MUTE)
306 return -EINVAL;
307 *qc = gpio_ctrl_mute;
308 return 0;
309}
310
311static int subdev_log_status(struct v4l2_subdev *sd)
312{
313 struct ivtv *itv = sd_to_ivtv(sd);
281 314
282 case VIDIOC_LOG_STATUS: 315 IVTV_INFO("GPIO status: DIR=0x%04x OUT=0x%04x IN=0x%04x\n",
283 IVTV_INFO("GPIO status: DIR=0x%04x OUT=0x%04x IN=0x%04x\n",
284 read_reg(IVTV_REG_GPIO_DIR), read_reg(IVTV_REG_GPIO_OUT), 316 read_reg(IVTV_REG_GPIO_DIR), read_reg(IVTV_REG_GPIO_OUT),
285 read_reg(IVTV_REG_GPIO_IN)); 317 read_reg(IVTV_REG_GPIO_IN));
286 return 0; 318 return 0;
319}
287 320
288 case VIDIOC_INT_S_VIDEO_ROUTING: 321static int subdev_s_video_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
289 if (route->input > 2) /* 0:Tuner 1:Composite 2:S-Video */ 322{
290 return -EINVAL; 323 struct ivtv *itv = sd_to_ivtv(sd);
291 mask = itv->card->gpio_video_input.mask; 324 u16 mask, data;
292 if (route->input == 0)
293 data = itv->card->gpio_video_input.tuner;
294 else if (route->input == 1)
295 data = itv->card->gpio_video_input.composite;
296 else
297 data = itv->card->gpio_video_input.svideo;
298 break;
299 325
300 default: 326 if (route->input > 2) /* 0:Tuner 1:Composite 2:S-Video */
301 return -EINVAL; 327 return -EINVAL;
302 } 328 mask = itv->card->gpio_video_input.mask;
329 if (route->input == 0)
330 data = itv->card->gpio_video_input.tuner;
331 else if (route->input == 1)
332 data = itv->card->gpio_video_input.composite;
333 else
334 data = itv->card->gpio_video_input.svideo;
303 if (mask) 335 if (mask)
304 write_reg((read_reg(IVTV_REG_GPIO_OUT) & ~mask) | (data & mask), IVTV_REG_GPIO_OUT); 336 write_reg((read_reg(IVTV_REG_GPIO_OUT) & ~mask) | (data & mask), IVTV_REG_GPIO_OUT);
305 return 0; 337 return 0;
306} 338}
339
340static const struct v4l2_subdev_core_ops subdev_core_ops = {
341 .log_status = subdev_log_status,
342 .g_ctrl = subdev_g_ctrl,
343 .s_ctrl = subdev_s_ctrl,
344 .queryctrl = subdev_queryctrl,
345};
346
347static const struct v4l2_subdev_tuner_ops subdev_tuner_ops = {
348 .s_std = subdev_s_std,
349 .s_radio = subdev_s_radio,
350 .g_tuner = subdev_g_tuner,
351 .s_tuner = subdev_s_tuner,
352};
353
354static const struct v4l2_subdev_audio_ops subdev_audio_ops = {
355 .s_clock_freq = subdev_s_clock_freq,
356 .s_routing = subdev_s_audio_routing,
357};
358
359static const struct v4l2_subdev_video_ops subdev_video_ops = {
360 .s_routing = subdev_s_video_routing,
361};
362
363static const struct v4l2_subdev_ops subdev_ops = {
364 .core = &subdev_core_ops,
365 .tuner = &subdev_tuner_ops,
366 .audio = &subdev_audio_ops,
367 .video = &subdev_video_ops,
368};
369
370int ivtv_gpio_init(struct ivtv *itv)
371{
372 u16 pin = 0;
373
374 if (itv->card->xceive_pin)
375 pin = 1 << itv->card->xceive_pin;
376
377 if ((itv->card->gpio_init.direction | pin) == 0)
378 return 0;
379
380 IVTV_DEBUG_INFO("GPIO initial dir: %08x out: %08x\n",
381 read_reg(IVTV_REG_GPIO_DIR), read_reg(IVTV_REG_GPIO_OUT));
382
383 /* init output data then direction */
384 write_reg(itv->card->gpio_init.initial_value | pin, IVTV_REG_GPIO_OUT);
385 write_reg(itv->card->gpio_init.direction | pin, IVTV_REG_GPIO_DIR);
386 v4l2_subdev_init(&itv->sd_gpio, &subdev_ops);
387 snprintf(itv->sd_gpio.name, sizeof(itv->sd_gpio.name), "%s-gpio", itv->device.name);
388 itv->sd_gpio.grp_id = IVTV_HW_GPIO;
389 return v4l2_device_register_subdev(&itv->device, &itv->sd_gpio);
390}
diff --git a/drivers/media/video/ivtv/ivtv-gpio.h b/drivers/media/video/ivtv/ivtv-gpio.h
index 48b6291613a2..0b5d19c8ecb4 100644
--- a/drivers/media/video/ivtv/ivtv-gpio.h
+++ b/drivers/media/video/ivtv/ivtv-gpio.h
@@ -22,9 +22,8 @@
22#define IVTV_GPIO_H 22#define IVTV_GPIO_H
23 23
24/* GPIO stuff */ 24/* GPIO stuff */
25void ivtv_gpio_init(struct ivtv *itv); 25int ivtv_gpio_init(struct ivtv *itv);
26void ivtv_reset_ir_gpio(struct ivtv *itv); 26void ivtv_reset_ir_gpio(struct ivtv *itv);
27int ivtv_reset_tuner_gpio(void *dev, int component, int cmd, int value); 27int ivtv_reset_tuner_gpio(void *dev, int component, int cmd, int value);
28int ivtv_gpio(struct ivtv *itv, unsigned int command, void *arg);
29 28
30#endif 29#endif
diff --git a/drivers/media/video/ivtv/ivtv-i2c.c b/drivers/media/video/ivtv/ivtv-i2c.c
index 41dbbe9621a1..ca1d9557945e 100644
--- a/drivers/media/video/ivtv/ivtv-i2c.c
+++ b/drivers/media/video/ivtv/ivtv-i2c.c
@@ -90,26 +90,6 @@
90#define IVTV_M52790_I2C_ADDR 0x48 90#define IVTV_M52790_I2C_ADDR 0x48
91 91
92/* This array should match the IVTV_HW_ defines */ 92/* This array should match the IVTV_HW_ defines */
93static const u8 hw_driverids[] = {
94 I2C_DRIVERID_CX25840,
95 I2C_DRIVERID_SAA711X,
96 I2C_DRIVERID_SAA7127,
97 I2C_DRIVERID_MSP3400,
98 I2C_DRIVERID_TUNER,
99 I2C_DRIVERID_WM8775,
100 I2C_DRIVERID_CS53L32A,
101 I2C_DRIVERID_TVEEPROM,
102 I2C_DRIVERID_SAA711X,
103 I2C_DRIVERID_UPD64031A,
104 I2C_DRIVERID_UPD64083,
105 I2C_DRIVERID_SAA717X,
106 I2C_DRIVERID_WM8739,
107 I2C_DRIVERID_VP27SMPX,
108 I2C_DRIVERID_M52790,
109 0 /* IVTV_HW_GPIO dummy driver ID */
110};
111
112/* This array should match the IVTV_HW_ defines */
113static const u8 hw_addrs[] = { 93static const u8 hw_addrs[] = {
114 IVTV_CX25840_I2C_ADDR, 94 IVTV_CX25840_I2C_ADDR,
115 IVTV_SAA7115_I2C_ADDR, 95 IVTV_SAA7115_I2C_ADDR,
@@ -130,6 +110,26 @@ static const u8 hw_addrs[] = {
130}; 110};
131 111
132/* This array should match the IVTV_HW_ defines */ 112/* This array should match the IVTV_HW_ defines */
113static const char *hw_modules[] = {
114 "cx25840",
115 "saa7115",
116 "saa7127",
117 "msp3400",
118 "tuner",
119 "wm8775",
120 "cs53l32a",
121 NULL,
122 "saa7115",
123 "upd64031a",
124 "upd64083",
125 "saa717x",
126 "wm8739",
127 "vp27smpx",
128 "m52790",
129 NULL
130};
131
132/* This array should match the IVTV_HW_ defines */
133static const char * const hw_devicenames[] = { 133static const char * const hw_devicenames[] = {
134 "cx25840", 134 "cx25840",
135 "saa7115", 135 "saa7115",
@@ -151,80 +151,58 @@ static const char * const hw_devicenames[] = {
151 151
152int ivtv_i2c_register(struct ivtv *itv, unsigned idx) 152int ivtv_i2c_register(struct ivtv *itv, unsigned idx)
153{ 153{
154 struct i2c_board_info info; 154 struct v4l2_subdev *sd;
155 struct i2c_client *c; 155 struct i2c_adapter *adap = &itv->i2c_adap;
156 u8 id; 156 const char *mod = hw_modules[idx];
157 int i; 157 const char *type = hw_devicenames[idx];
158 u32 hw = 1 << idx;
158 159
159 IVTV_DEBUG_I2C("i2c client register\n"); 160 if (idx >= ARRAY_SIZE(hw_addrs))
160 if (idx >= ARRAY_SIZE(hw_driverids) || hw_driverids[idx] == 0)
161 return -1; 161 return -1;
162 id = hw_driverids[idx]; 162 if (hw == IVTV_HW_TUNER) {
163 memset(&info, 0, sizeof(info)); 163 /* special tuner handling */
164 strlcpy(info.type, hw_devicenames[idx], sizeof(info.type)); 164 sd = v4l2_i2c_new_probed_subdev(adap, mod, type,
165 info.addr = hw_addrs[idx]; 165 itv->card_i2c->radio);
166 for (i = 0; itv->i2c_clients[i] && i < I2C_CLIENTS_MAX; i++) {} 166 if (sd)
167 167 sd->grp_id = 1 << idx;
168 if (i == I2C_CLIENTS_MAX) { 168 sd = v4l2_i2c_new_probed_subdev(adap, mod, type,
169 IVTV_ERR("insufficient room for new I2C client!\n"); 169 itv->card_i2c->demod);
170 return -ENOMEM; 170 if (sd)
171 sd->grp_id = 1 << idx;
172 sd = v4l2_i2c_new_probed_subdev(adap, mod, type,
173 itv->card_i2c->tv);
174 if (sd)
175 sd->grp_id = 1 << idx;
176 return sd ? 0 : -1;
171 } 177 }
178 if (!hw_addrs[idx])
179 return -1;
180 if (hw == IVTV_HW_UPD64031A || hw == IVTV_HW_UPD6408X) {
181 unsigned short addrs[2] = { hw_addrs[idx], I2C_CLIENT_END };
172 182
173 if (id != I2C_DRIVERID_TUNER) { 183 sd = v4l2_i2c_new_probed_subdev(adap, mod, type, addrs);
174 if (id == I2C_DRIVERID_UPD64031A || 184 } else {
175 id == I2C_DRIVERID_UPD64083) { 185 sd = v4l2_i2c_new_subdev(adap, mod, type, hw_addrs[idx]);
176 unsigned short addrs[2] = { info.addr, I2C_CLIENT_END };
177
178 c = i2c_new_probed_device(&itv->i2c_adap, &info, addrs);
179 } else
180 c = i2c_new_device(&itv->i2c_adap, &info);
181 if (c && c->driver == NULL)
182 i2c_unregister_device(c);
183 else if (c)
184 itv->i2c_clients[i] = c;
185 return itv->i2c_clients[i] ? 0 : -ENODEV;
186 } 186 }
187 187 if (sd)
188 /* special tuner handling */ 188 sd->grp_id = 1 << idx;
189 c = i2c_new_probed_device(&itv->i2c_adap, &info, itv->card_i2c->radio); 189 return sd ? 0 : -1;
190 if (c && c->driver == NULL)
191 i2c_unregister_device(c);
192 else if (c)
193 itv->i2c_clients[i++] = c;
194 c = i2c_new_probed_device(&itv->i2c_adap, &info, itv->card_i2c->demod);
195 if (c && c->driver == NULL)
196 i2c_unregister_device(c);
197 else if (c)
198 itv->i2c_clients[i++] = c;
199 c = i2c_new_probed_device(&itv->i2c_adap, &info, itv->card_i2c->tv);
200 if (c && c->driver == NULL)
201 i2c_unregister_device(c);
202 else if (c)
203 itv->i2c_clients[i++] = c;
204 return 0;
205}
206
207static int attach_inform(struct i2c_client *client)
208{
209 return 0;
210} 190}
211 191
212static int detach_inform(struct i2c_client *client) 192struct v4l2_subdev *ivtv_find_hw(struct ivtv *itv, u32 hw)
213{ 193{
214 int i; 194 struct v4l2_subdev *result = NULL;
215 struct ivtv *itv = (struct ivtv *)i2c_get_adapdata(client->adapter); 195 struct v4l2_subdev *sd;
216 196
217 IVTV_DEBUG_I2C("i2c client detach\n"); 197 spin_lock(&itv->device.lock);
218 for (i = 0; i < I2C_CLIENTS_MAX; i++) { 198 v4l2_device_for_each_subdev(sd, &itv->device) {
219 if (itv->i2c_clients[i] == client) { 199 if (sd->grp_id == hw) {
220 itv->i2c_clients[i] = NULL; 200 result = sd;
221 break; 201 break;
222 } 202 }
223 } 203 }
224 IVTV_DEBUG_I2C("i2c detach [client=%s,%s]\n", 204 spin_unlock(&itv->device.lock);
225 client->name, (i < I2C_CLIENTS_MAX) ? "ok" : "failed"); 205 return result;
226
227 return 0;
228} 206}
229 207
230/* Set the serial clock line to the desired state */ 208/* Set the serial clock line to the desired state */
@@ -494,7 +472,8 @@ static int ivtv_read(struct ivtv *itv, unsigned char addr, unsigned char *data,
494 intervening stop condition */ 472 intervening stop condition */
495static int ivtv_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int num) 473static int ivtv_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int num)
496{ 474{
497 struct ivtv *itv = i2c_get_adapdata(i2c_adap); 475 struct v4l2_device *drv = i2c_get_adapdata(i2c_adap);
476 struct ivtv *itv = to_ivtv(drv);
498 int retval; 477 int retval;
499 int i; 478 int i;
500 479
@@ -530,8 +509,6 @@ static struct i2c_adapter ivtv_i2c_adap_hw_template = {
530 .id = I2C_HW_B_CX2341X, 509 .id = I2C_HW_B_CX2341X,
531 .algo = &ivtv_algo, 510 .algo = &ivtv_algo,
532 .algo_data = NULL, /* filled from template */ 511 .algo_data = NULL, /* filled from template */
533 .client_register = attach_inform,
534 .client_unregister = detach_inform,
535 .owner = THIS_MODULE, 512 .owner = THIS_MODULE,
536}; 513};
537 514
@@ -583,8 +560,6 @@ static struct i2c_adapter ivtv_i2c_adap_template = {
583 .id = I2C_HW_B_CX2341X, 560 .id = I2C_HW_B_CX2341X,
584 .algo = NULL, /* set by i2c-algo-bit */ 561 .algo = NULL, /* set by i2c-algo-bit */
585 .algo_data = NULL, /* filled from template */ 562 .algo_data = NULL, /* filled from template */
586 .client_register = attach_inform,
587 .client_unregister = detach_inform,
588 .owner = THIS_MODULE, 563 .owner = THIS_MODULE,
589}; 564};
590 565
@@ -601,160 +576,6 @@ static struct i2c_client ivtv_i2c_client_template = {
601 .name = "ivtv internal", 576 .name = "ivtv internal",
602}; 577};
603 578
604int ivtv_call_i2c_client(struct ivtv *itv, int addr, unsigned int cmd, void *arg)
605{
606 struct i2c_client *client;
607 int retval;
608 int i;
609
610 IVTV_DEBUG_I2C("call_i2c_client addr=%02x\n", addr);
611 for (i = 0; i < I2C_CLIENTS_MAX; i++) {
612 client = itv->i2c_clients[i];
613 if (client == NULL || client->driver == NULL ||
614 client->driver->command == NULL)
615 continue;
616 if (addr == client->addr) {
617 retval = client->driver->command(client, cmd, arg);
618 return retval;
619 }
620 }
621 if (cmd != VIDIOC_G_CHIP_IDENT)
622 IVTV_ERR("i2c addr 0x%02x not found for command 0x%x\n", addr, cmd);
623 return -ENODEV;
624}
625
626/* Find the i2c device based on the driver ID and return
627 its i2c address or -ENODEV if no matching device was found. */
628static int ivtv_i2c_id_addr(struct ivtv *itv, u32 id)
629{
630 struct i2c_client *client;
631 int retval = -ENODEV;
632 int i;
633
634 for (i = 0; i < I2C_CLIENTS_MAX; i++) {
635 client = itv->i2c_clients[i];
636 if (client == NULL || client->driver == NULL)
637 continue;
638 if (id == client->driver->id) {
639 retval = client->addr;
640 break;
641 }
642 }
643 return retval;
644}
645
646/* Find the i2c device name matching the DRIVERID */
647static const char *ivtv_i2c_id_name(u32 id)
648{
649 int i;
650
651 for (i = 0; i < ARRAY_SIZE(hw_driverids); i++)
652 if (hw_driverids[i] == id)
653 return hw_devicenames[i];
654 return "unknown device";
655}
656
657/* Find the i2c device name matching the IVTV_HW_ flag */
658static const char *ivtv_i2c_hw_name(u32 hw)
659{
660 int i;
661
662 for (i = 0; i < ARRAY_SIZE(hw_driverids); i++)
663 if (1 << i == hw)
664 return hw_devicenames[i];
665 return "unknown device";
666}
667
668/* Find the i2c device matching the IVTV_HW_ flag and return
669 its i2c address or -ENODEV if no matching device was found. */
670int ivtv_i2c_hw_addr(struct ivtv *itv, u32 hw)
671{
672 int i;
673
674 for (i = 0; i < ARRAY_SIZE(hw_driverids); i++)
675 if (1 << i == hw)
676 return ivtv_i2c_id_addr(itv, hw_driverids[i]);
677 return -ENODEV;
678}
679
680/* Calls i2c device based on IVTV_HW_ flag. If hw == 0, then do nothing.
681 If hw == IVTV_HW_GPIO then call the gpio handler. */
682int ivtv_i2c_hw(struct ivtv *itv, u32 hw, unsigned int cmd, void *arg)
683{
684 int addr;
685
686 if (hw == IVTV_HW_GPIO)
687 return ivtv_gpio(itv, cmd, arg);
688 if (hw == 0)
689 return 0;
690
691 addr = ivtv_i2c_hw_addr(itv, hw);
692 if (addr < 0) {
693 IVTV_ERR("i2c hardware 0x%08x (%s) not found for command 0x%x\n",
694 hw, ivtv_i2c_hw_name(hw), cmd);
695 return addr;
696 }
697 return ivtv_call_i2c_client(itv, addr, cmd, arg);
698}
699
700/* Calls i2c device based on I2C driver ID. */
701int ivtv_i2c_id(struct ivtv *itv, u32 id, unsigned int cmd, void *arg)
702{
703 int addr;
704
705 addr = ivtv_i2c_id_addr(itv, id);
706 if (addr < 0) {
707 if (cmd != VIDIOC_G_CHIP_IDENT)
708 IVTV_ERR("i2c ID 0x%08x (%s) not found for command 0x%x\n",
709 id, ivtv_i2c_id_name(id), cmd);
710 return addr;
711 }
712 return ivtv_call_i2c_client(itv, addr, cmd, arg);
713}
714
715int ivtv_cx25840(struct ivtv *itv, unsigned int cmd, void *arg)
716{
717 return ivtv_call_i2c_client(itv, IVTV_CX25840_I2C_ADDR, cmd, arg);
718}
719
720int ivtv_saa7115(struct ivtv *itv, unsigned int cmd, void *arg)
721{
722 return ivtv_call_i2c_client(itv, IVTV_SAA7115_I2C_ADDR, cmd, arg);
723}
724
725int ivtv_saa7127(struct ivtv *itv, unsigned int cmd, void *arg)
726{
727 return ivtv_call_i2c_client(itv, IVTV_SAA7127_I2C_ADDR, cmd, arg);
728}
729EXPORT_SYMBOL(ivtv_saa7127);
730
731int ivtv_saa717x(struct ivtv *itv, unsigned int cmd, void *arg)
732{
733 return ivtv_call_i2c_client(itv, IVTV_SAA717x_I2C_ADDR, cmd, arg);
734}
735
736int ivtv_upd64031a(struct ivtv *itv, unsigned int cmd, void *arg)
737{
738 return ivtv_call_i2c_client(itv, IVTV_UPD64031A_I2C_ADDR, cmd, arg);
739}
740
741int ivtv_upd64083(struct ivtv *itv, unsigned int cmd, void *arg)
742{
743 return ivtv_call_i2c_client(itv, IVTV_UPD64083_I2C_ADDR, cmd, arg);
744}
745
746/* broadcast cmd for all I2C clients and for the gpio subsystem */
747void ivtv_call_i2c_clients(struct ivtv *itv, unsigned int cmd, void *arg)
748{
749 if (itv->i2c_adap.algo == NULL) {
750 IVTV_ERR("Adapter is not set");
751 return;
752 }
753 i2c_clients_command(&itv->i2c_adap, cmd, arg);
754 if (itv->hw_flags & IVTV_HW_GPIO)
755 ivtv_gpio(itv, cmd, arg);
756}
757
758/* init + register i2c algo-bit adapter */ 579/* init + register i2c algo-bit adapter */
759int init_ivtv_i2c(struct ivtv *itv) 580int init_ivtv_i2c(struct ivtv *itv)
760{ 581{
@@ -763,10 +584,9 @@ int init_ivtv_i2c(struct ivtv *itv)
763 /* Sanity checks for the I2C hardware arrays. They must be the 584 /* Sanity checks for the I2C hardware arrays. They must be the
764 * same size and GPIO must be the last entry. 585 * same size and GPIO must be the last entry.
765 */ 586 */
766 if (ARRAY_SIZE(hw_driverids) != ARRAY_SIZE(hw_addrs) || 587 if (ARRAY_SIZE(hw_devicenames) != ARRAY_SIZE(hw_addrs) ||
767 ARRAY_SIZE(hw_devicenames) != ARRAY_SIZE(hw_addrs) || 588 ARRAY_SIZE(hw_devicenames) != ARRAY_SIZE(hw_modules) ||
768 IVTV_HW_GPIO != (1 << (ARRAY_SIZE(hw_addrs) - 1)) || 589 IVTV_HW_GPIO != (1 << (ARRAY_SIZE(hw_addrs) - 1))) {
769 hw_driverids[ARRAY_SIZE(hw_addrs) - 1]) {
770 IVTV_ERR("Mismatched I2C hardware arrays\n"); 590 IVTV_ERR("Mismatched I2C hardware arrays\n");
771 return -ENODEV; 591 return -ENODEV;
772 } 592 }
@@ -783,8 +603,8 @@ int init_ivtv_i2c(struct ivtv *itv)
783 itv->i2c_adap.algo_data = &itv->i2c_algo; 603 itv->i2c_adap.algo_data = &itv->i2c_algo;
784 604
785 sprintf(itv->i2c_adap.name + strlen(itv->i2c_adap.name), " #%d", 605 sprintf(itv->i2c_adap.name + strlen(itv->i2c_adap.name), " #%d",
786 itv->num); 606 itv->instance);
787 i2c_set_adapdata(&itv->i2c_adap, itv); 607 i2c_set_adapdata(&itv->i2c_adap, &itv->device);
788 608
789 memcpy(&itv->i2c_client, &ivtv_i2c_client_template, 609 memcpy(&itv->i2c_client, &ivtv_i2c_client_template,
790 sizeof(struct i2c_client)); 610 sizeof(struct i2c_client));
diff --git a/drivers/media/video/ivtv/ivtv-i2c.h b/drivers/media/video/ivtv/ivtv-i2c.h
index 022978cf533d..396928a06a54 100644
--- a/drivers/media/video/ivtv/ivtv-i2c.h
+++ b/drivers/media/video/ivtv/ivtv-i2c.h
@@ -21,19 +21,8 @@
21#ifndef IVTV_I2C_H 21#ifndef IVTV_I2C_H
22#define IVTV_I2C_H 22#define IVTV_I2C_H
23 23
24int ivtv_cx25840(struct ivtv *itv, unsigned int cmd, void *arg);
25int ivtv_saa7115(struct ivtv *itv, unsigned int cmd, void *arg);
26int ivtv_saa7127(struct ivtv *itv, unsigned int cmd, void *arg);
27int ivtv_saa717x(struct ivtv *itv, unsigned int cmd, void *arg);
28int ivtv_upd64031a(struct ivtv *itv, unsigned int cmd, void *arg);
29int ivtv_upd64083(struct ivtv *itv, unsigned int cmd, void *arg);
30
31int ivtv_i2c_hw_addr(struct ivtv *itv, u32 hw);
32int ivtv_i2c_hw(struct ivtv *itv, u32 hw, unsigned int cmd, void *arg);
33int ivtv_i2c_id(struct ivtv *itv, u32 id, unsigned int cmd, void *arg);
34int ivtv_call_i2c_client(struct ivtv *itv, int addr, unsigned int cmd, void *arg);
35void ivtv_call_i2c_clients(struct ivtv *itv, unsigned int cmd, void *arg);
36int ivtv_i2c_register(struct ivtv *itv, unsigned idx); 24int ivtv_i2c_register(struct ivtv *itv, unsigned idx);
25struct v4l2_subdev *ivtv_find_hw(struct ivtv *itv, u32 hw);
37 26
38/* init + register i2c algo-bit adapter */ 27/* init + register i2c algo-bit adapter */
39int init_ivtv_i2c(struct ivtv *itv); 28int init_ivtv_i2c(struct ivtv *itv);
diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c
index 4bae38d21ef6..cd990a4b81a9 100644
--- a/drivers/media/video/ivtv/ivtv-ioctl.c
+++ b/drivers/media/video/ivtv/ivtv-ioctl.c
@@ -393,7 +393,7 @@ static int ivtv_g_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_fo
393 return 0; 393 return 0;
394 } 394 }
395 395
396 itv->video_dec_func(itv, VIDIOC_G_FMT, fmt); 396 v4l2_subdev_call(itv->sd_video, video, s_fmt, fmt);
397 vbifmt->service_set = ivtv_get_service_set(vbifmt); 397 vbifmt->service_set = ivtv_get_service_set(vbifmt);
398 return 0; 398 return 0;
399} 399}
@@ -581,7 +581,7 @@ static int ivtv_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f
581 p->height = h; 581 p->height = h;
582 if (p->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1) 582 if (p->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1)
583 fmt->fmt.pix.width /= 2; 583 fmt->fmt.pix.width /= 2;
584 itv->video_dec_func(itv, VIDIOC_S_FMT, fmt); 584 v4l2_subdev_call(itv->sd_video, video, s_fmt, fmt);
585 return ivtv_g_fmt_vid_cap(file, fh, fmt); 585 return ivtv_g_fmt_vid_cap(file, fh, fmt);
586} 586}
587 587
@@ -593,7 +593,7 @@ static int ivtv_s_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *f
593 return -EBUSY; 593 return -EBUSY;
594 itv->vbi.sliced_in->service_set = 0; 594 itv->vbi.sliced_in->service_set = 0;
595 itv->vbi.in.type = V4L2_BUF_TYPE_VBI_CAPTURE; 595 itv->vbi.in.type = V4L2_BUF_TYPE_VBI_CAPTURE;
596 itv->video_dec_func(itv, VIDIOC_S_FMT, fmt); 596 v4l2_subdev_call(itv->sd_video, video, s_fmt, fmt);
597 return ivtv_g_fmt_vbi_cap(file, fh, fmt); 597 return ivtv_g_fmt_vbi_cap(file, fh, fmt);
598} 598}
599 599
@@ -611,7 +611,7 @@ static int ivtv_s_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_fo
611 if (ivtv_raw_vbi(itv) && atomic_read(&itv->capturing) > 0) 611 if (ivtv_raw_vbi(itv) && atomic_read(&itv->capturing) > 0)
612 return -EBUSY; 612 return -EBUSY;
613 itv->vbi.in.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE; 613 itv->vbi.in.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE;
614 itv->video_dec_func(itv, VIDIOC_S_FMT, fmt); 614 v4l2_subdev_call(itv->sd_video, video, s_fmt, fmt);
615 memcpy(itv->vbi.sliced_in, vbifmt, sizeof(*itv->vbi.sliced_in)); 615 memcpy(itv->vbi.sliced_in, vbifmt, sizeof(*itv->vbi.sliced_in));
616 return 0; 616 return 0;
617} 617}
@@ -685,18 +685,17 @@ static int ivtv_g_chip_ident(struct file *file, void *fh, struct v4l2_chip_ident
685 chip->ident = itv->has_cx23415 ? V4L2_IDENT_CX23415 : V4L2_IDENT_CX23416; 685 chip->ident = itv->has_cx23415 ? V4L2_IDENT_CX23415 : V4L2_IDENT_CX23416;
686 return 0; 686 return 0;
687 } 687 }
688 if (chip->match_type == V4L2_CHIP_MATCH_I2C_DRIVER) 688 if (chip->match_type != V4L2_CHIP_MATCH_I2C_DRIVER &&
689 return ivtv_i2c_id(itv, chip->match_chip, VIDIOC_G_CHIP_IDENT, chip); 689 chip->match_type != V4L2_CHIP_MATCH_I2C_ADDR)
690 if (chip->match_type == V4L2_CHIP_MATCH_I2C_ADDR) 690 return -EINVAL;
691 return ivtv_call_i2c_client(itv, chip->match_chip, VIDIOC_G_CHIP_IDENT, chip); 691 /* TODO: is this correct? */
692 return -EINVAL; 692 return ivtv_call_all_err(itv, core, g_chip_ident, chip);
693} 693}
694 694
695#ifdef CONFIG_VIDEO_ADV_DEBUG 695#ifdef CONFIG_VIDEO_ADV_DEBUG
696static int ivtv_itvc(struct ivtv *itv, unsigned int cmd, void *arg) 696static int ivtv_itvc(struct ivtv *itv, unsigned int cmd, void *arg)
697{ 697{
698 struct v4l2_register *regs = arg; 698 struct v4l2_register *regs = arg;
699 unsigned long flags;
700 volatile u8 __iomem *reg_start; 699 volatile u8 __iomem *reg_start;
701 700
702 if (!capable(CAP_SYS_ADMIN)) 701 if (!capable(CAP_SYS_ADMIN))
@@ -711,12 +710,10 @@ static int ivtv_itvc(struct ivtv *itv, unsigned int cmd, void *arg)
711 else 710 else
712 return -EINVAL; 711 return -EINVAL;
713 712
714 spin_lock_irqsave(&ivtv_cards_lock, flags);
715 if (cmd == VIDIOC_DBG_G_REGISTER) 713 if (cmd == VIDIOC_DBG_G_REGISTER)
716 regs->val = readl(regs->reg + reg_start); 714 regs->val = readl(regs->reg + reg_start);
717 else 715 else
718 writel(regs->val, regs->reg + reg_start); 716 writel(regs->val, regs->reg + reg_start);
719 spin_unlock_irqrestore(&ivtv_cards_lock, flags);
720 return 0; 717 return 0;
721} 718}
722 719
@@ -726,9 +723,10 @@ static int ivtv_g_register(struct file *file, void *fh, struct v4l2_register *re
726 723
727 if (v4l2_chip_match_host(reg->match_type, reg->match_chip)) 724 if (v4l2_chip_match_host(reg->match_type, reg->match_chip))
728 return ivtv_itvc(itv, VIDIOC_DBG_G_REGISTER, reg); 725 return ivtv_itvc(itv, VIDIOC_DBG_G_REGISTER, reg);
729 if (reg->match_type == V4L2_CHIP_MATCH_I2C_DRIVER) 726 /* TODO: subdev errors should not be ignored, this should become a
730 return ivtv_i2c_id(itv, reg->match_chip, VIDIOC_DBG_G_REGISTER, reg); 727 subdev helper function. */
731 return ivtv_call_i2c_client(itv, reg->match_chip, VIDIOC_DBG_G_REGISTER, reg); 728 ivtv_call_all(itv, core, g_register, reg);
729 return 0;
732} 730}
733 731
734static int ivtv_s_register(struct file *file, void *fh, struct v4l2_register *reg) 732static int ivtv_s_register(struct file *file, void *fh, struct v4l2_register *reg)
@@ -737,9 +735,10 @@ static int ivtv_s_register(struct file *file, void *fh, struct v4l2_register *re
737 735
738 if (v4l2_chip_match_host(reg->match_type, reg->match_chip)) 736 if (v4l2_chip_match_host(reg->match_type, reg->match_chip))
739 return ivtv_itvc(itv, VIDIOC_DBG_S_REGISTER, reg); 737 return ivtv_itvc(itv, VIDIOC_DBG_S_REGISTER, reg);
740 if (reg->match_type == V4L2_CHIP_MATCH_I2C_DRIVER) 738 /* TODO: subdev errors should not be ignored, this should become a
741 return ivtv_i2c_id(itv, reg->match_chip, VIDIOC_DBG_S_REGISTER, reg); 739 subdev helper function. */
742 return ivtv_call_i2c_client(itv, reg->match_chip, VIDIOC_DBG_S_REGISTER, reg); 740 ivtv_call_all(itv, core, s_register, reg);
741 return 0;
743} 742}
744#endif 743#endif
745 744
@@ -884,12 +883,6 @@ static int ivtv_s_crop(struct file *file, void *fh, struct v4l2_crop *crop)
884 883
885 streamtype = id->type; 884 streamtype = id->type;
886 885
887 if (ivtv_debug & IVTV_DBGFLG_IOCTL) {
888 printk(KERN_INFO "ivtv%d ioctl: ", itv->num);
889 /* Should be replaced */
890 /* v4l_printk_ioctl(VIDIOC_S_CROP); */
891 }
892
893 if (crop->type == V4L2_BUF_TYPE_VIDEO_OUTPUT && 886 if (crop->type == V4L2_BUF_TYPE_VIDEO_OUTPUT &&
894 (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) { 887 (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) {
895 if (streamtype == IVTV_DEC_STREAM_TYPE_YUV) { 888 if (streamtype == IVTV_DEC_STREAM_TYPE_YUV) {
@@ -1050,7 +1043,7 @@ static int ivtv_s_output(struct file *file, void *fh, unsigned int outp)
1050 itv->active_output = outp; 1043 itv->active_output = outp;
1051 route.input = SAA7127_INPUT_TYPE_NORMAL; 1044 route.input = SAA7127_INPUT_TYPE_NORMAL;
1052 route.output = itv->card->video_outputs[outp].video_output; 1045 route.output = itv->card->video_outputs[outp].video_output;
1053 ivtv_saa7127(itv, VIDIOC_INT_S_VIDEO_ROUTING, &route); 1046 ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_routing, &route);
1054 1047
1055 return 0; 1048 return 0;
1056} 1049}
@@ -1062,7 +1055,7 @@ static int ivtv_g_frequency(struct file *file, void *fh, struct v4l2_frequency *
1062 if (vf->tuner != 0) 1055 if (vf->tuner != 0)
1063 return -EINVAL; 1056 return -EINVAL;
1064 1057
1065 ivtv_call_i2c_clients(itv, VIDIOC_G_FREQUENCY, vf); 1058 ivtv_call_all(itv, tuner, g_frequency, vf);
1066 return 0; 1059 return 0;
1067} 1060}
1068 1061
@@ -1075,7 +1068,7 @@ int ivtv_s_frequency(struct file *file, void *fh, struct v4l2_frequency *vf)
1075 1068
1076 ivtv_mute(itv); 1069 ivtv_mute(itv);
1077 IVTV_DEBUG_INFO("v4l2 ioctl: set frequency %d\n", vf->frequency); 1070 IVTV_DEBUG_INFO("v4l2 ioctl: set frequency %d\n", vf->frequency);
1078 ivtv_call_i2c_clients(itv, VIDIOC_S_FREQUENCY, vf); 1071 ivtv_call_all(itv, tuner, s_frequency, vf);
1079 ivtv_unmute(itv); 1072 ivtv_unmute(itv);
1080 return 0; 1073 return 0;
1081} 1074}
@@ -1123,14 +1116,14 @@ int ivtv_s_std(struct file *file, void *fh, v4l2_std_id *std)
1123 IVTV_DEBUG_INFO("Switching standard to %llx.\n", (unsigned long long)itv->std); 1116 IVTV_DEBUG_INFO("Switching standard to %llx.\n", (unsigned long long)itv->std);
1124 1117
1125 /* Tuner */ 1118 /* Tuner */
1126 ivtv_call_i2c_clients(itv, VIDIOC_S_STD, &itv->std); 1119 ivtv_call_all(itv, tuner, s_std, itv->std);
1127 1120
1128 if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) { 1121 if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) {
1129 /* set display standard */ 1122 /* set display standard */
1130 itv->std_out = *std; 1123 itv->std_out = *std;
1131 itv->is_out_60hz = itv->is_60hz; 1124 itv->is_out_60hz = itv->is_60hz;
1132 itv->is_out_50hz = itv->is_50hz; 1125 itv->is_out_50hz = itv->is_50hz;
1133 ivtv_call_i2c_clients(itv, VIDIOC_INT_S_STD_OUTPUT, &itv->std_out); 1126 ivtv_call_all(itv, video, s_std_output, itv->std_out);
1134 ivtv_vapi(itv, CX2341X_DEC_SET_STANDARD, 1, itv->is_out_50hz); 1127 ivtv_vapi(itv, CX2341X_DEC_SET_STANDARD, 1, itv->is_out_50hz);
1135 itv->main_rect.left = itv->main_rect.top = 0; 1128 itv->main_rect.left = itv->main_rect.top = 0;
1136 itv->main_rect.width = 720; 1129 itv->main_rect.width = 720;
@@ -1154,7 +1147,7 @@ static int ivtv_s_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
1154 if (vt->index != 0) 1147 if (vt->index != 0)
1155 return -EINVAL; 1148 return -EINVAL;
1156 1149
1157 ivtv_call_i2c_clients(itv, VIDIOC_S_TUNER, vt); 1150 ivtv_call_all(itv, tuner, s_tuner, vt);
1158 1151
1159 return 0; 1152 return 0;
1160} 1153}
@@ -1166,7 +1159,7 @@ static int ivtv_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
1166 if (vt->index != 0) 1159 if (vt->index != 0)
1167 return -EINVAL; 1160 return -EINVAL;
1168 1161
1169 ivtv_call_i2c_clients(itv, VIDIOC_G_TUNER, vt); 1162 ivtv_call_all(itv, tuner, g_tuner, vt);
1170 1163
1171 if (test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags)) { 1164 if (test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags)) {
1172 strlcpy(vt->name, "ivtv Radio Tuner", sizeof(vt->name)); 1165 strlcpy(vt->name, "ivtv Radio Tuner", sizeof(vt->name));
@@ -1444,14 +1437,15 @@ static int ivtv_log_status(struct file *file, void *fh)
1444 struct v4l2_audio audin; 1437 struct v4l2_audio audin;
1445 int i; 1438 int i;
1446 1439
1447 IVTV_INFO("================= START STATUS CARD #%d =================\n", itv->num); 1440 IVTV_INFO("================= START STATUS CARD #%d =================\n",
1441 itv->instance);
1448 IVTV_INFO("Version: %s Card: %s\n", IVTV_VERSION, itv->card_name); 1442 IVTV_INFO("Version: %s Card: %s\n", IVTV_VERSION, itv->card_name);
1449 if (itv->hw_flags & IVTV_HW_TVEEPROM) { 1443 if (itv->hw_flags & IVTV_HW_TVEEPROM) {
1450 struct tveeprom tv; 1444 struct tveeprom tv;
1451 1445
1452 ivtv_read_eeprom(itv, &tv); 1446 ivtv_read_eeprom(itv, &tv);
1453 } 1447 }
1454 ivtv_call_i2c_clients(itv, VIDIOC_LOG_STATUS, NULL); 1448 ivtv_call_all(itv, core, log_status);
1455 ivtv_get_input(itv, itv->active_input, &vidin); 1449 ivtv_get_input(itv, itv->active_input, &vidin);
1456 ivtv_get_audio_input(itv, itv->audio_input, &audin); 1450 ivtv_get_audio_input(itv, itv->audio_input, &audin);
1457 IVTV_INFO("Video Input: %s\n", vidin.name); 1451 IVTV_INFO("Video Input: %s\n", vidin.name);
@@ -1518,7 +1512,7 @@ static int ivtv_log_status(struct file *file, void *fh)
1518 } 1512 }
1519 IVTV_INFO("Tuner: %s\n", 1513 IVTV_INFO("Tuner: %s\n",
1520 test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags) ? "Radio" : "TV"); 1514 test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags) ? "Radio" : "TV");
1521 cx2341x_log_status(&itv->params, itv->name); 1515 cx2341x_log_status(&itv->params, itv->device.name);
1522 IVTV_INFO("Status flags: 0x%08lx\n", itv->i_flags); 1516 IVTV_INFO("Status flags: 0x%08lx\n", itv->i_flags);
1523 for (i = 0; i < IVTV_MAX_STREAMS; i++) { 1517 for (i = 0; i < IVTV_MAX_STREAMS; i++) {
1524 struct ivtv_stream *s = &itv->streams[i]; 1518 struct ivtv_stream *s = &itv->streams[i];
@@ -1530,8 +1524,11 @@ static int ivtv_log_status(struct file *file, void *fh)
1530 (s->buffers * s->buf_size) / 1024, s->buffers); 1524 (s->buffers * s->buf_size) / 1024, s->buffers);
1531 } 1525 }
1532 1526
1533 IVTV_INFO("Read MPG/VBI: %lld/%lld bytes\n", (long long)itv->mpg_data_received, (long long)itv->vbi_data_inserted); 1527 IVTV_INFO("Read MPG/VBI: %lld/%lld bytes\n",
1534 IVTV_INFO("================== END STATUS CARD #%d ==================\n", itv->num); 1528 (long long)itv->mpg_data_received,
1529 (long long)itv->vbi_data_inserted);
1530 IVTV_INFO("================== END STATUS CARD #%d ==================\n",
1531 itv->instance);
1535 1532
1536 return 0; 1533 return 0;
1537} 1534}
@@ -1736,7 +1733,7 @@ static int ivtv_default(struct file *file, void *fh, int cmd, void *arg)
1736 case VIDIOC_INT_S_AUDIO_ROUTING: { 1733 case VIDIOC_INT_S_AUDIO_ROUTING: {
1737 struct v4l2_routing *route = arg; 1734 struct v4l2_routing *route = arg;
1738 1735
1739 ivtv_i2c_hw(itv, itv->card->hw_audio, VIDIOC_INT_S_AUDIO_ROUTING, route); 1736 ivtv_call_hw(itv, itv->card->hw_audio, audio, s_routing, route);
1740 break; 1737 break;
1741 } 1738 }
1742 1739
@@ -1746,7 +1743,7 @@ static int ivtv_default(struct file *file, void *fh, int cmd, void *arg)
1746 if ((val == 0 && itv->options.newi2c) || (val & 0x01)) 1743 if ((val == 0 && itv->options.newi2c) || (val & 0x01))
1747 ivtv_reset_ir_gpio(itv); 1744 ivtv_reset_ir_gpio(itv);
1748 if (val & 0x02) 1745 if (val & 0x02)
1749 itv->video_dec_func(itv, cmd, NULL); 1746 v4l2_subdev_call(itv->sd_video, core, reset, 0);
1750 break; 1747 break;
1751 } 1748 }
1752 1749
diff --git a/drivers/media/video/ivtv/ivtv-routing.c b/drivers/media/video/ivtv/ivtv-routing.c
index 05564919b57f..3fd302294497 100644
--- a/drivers/media/video/ivtv/ivtv-routing.c
+++ b/drivers/media/video/ivtv/ivtv-routing.c
@@ -47,13 +47,13 @@ void ivtv_audio_set_io(struct ivtv *itv)
47 route.output = 0; 47 route.output = 0;
48 if (itv->card->hw_muxer & IVTV_HW_M52790) 48 if (itv->card->hw_muxer & IVTV_HW_M52790)
49 route.output = M52790_OUT_STEREO; 49 route.output = M52790_OUT_STEREO;
50 ivtv_i2c_hw(itv, itv->card->hw_muxer, VIDIOC_INT_S_AUDIO_ROUTING, &route); 50 v4l2_subdev_call(itv->sd_muxer, audio, s_routing, &route);
51 51
52 route.input = in->audio_input; 52 route.input = in->audio_input;
53 route.output = 0; 53 route.output = 0;
54 if (itv->card->hw_audio & IVTV_HW_MSP34XX) 54 if (itv->card->hw_audio & IVTV_HW_MSP34XX)
55 route.output = MSP_OUTPUT(MSP_SC_IN_DSP_SCART1); 55 route.output = MSP_OUTPUT(MSP_SC_IN_DSP_SCART1);
56 ivtv_i2c_hw(itv, itv->card->hw_audio, VIDIOC_INT_S_AUDIO_ROUTING, &route); 56 ivtv_call_hw(itv, itv->card->hw_audio, audio, s_routing, &route);
57} 57}
58 58
59/* Selects the video input and output according to the current 59/* Selects the video input and output according to the current
@@ -66,7 +66,7 @@ void ivtv_video_set_io(struct ivtv *itv)
66 66
67 route.input = itv->card->video_inputs[inp].video_input; 67 route.input = itv->card->video_inputs[inp].video_input;
68 route.output = 0; 68 route.output = 0;
69 itv->video_dec_func(itv, VIDIOC_INT_S_VIDEO_ROUTING, &route); 69 v4l2_subdev_call(itv->sd_video, video, s_routing, &route);
70 70
71 type = itv->card->video_inputs[inp].video_type; 71 type = itv->card->video_inputs[inp].video_type;
72 72
@@ -79,7 +79,7 @@ void ivtv_video_set_io(struct ivtv *itv)
79 } 79 }
80 80
81 if (itv->card->hw_video & IVTV_HW_GPIO) 81 if (itv->card->hw_video & IVTV_HW_GPIO)
82 ivtv_gpio(itv, VIDIOC_INT_S_VIDEO_ROUTING, &route); 82 ivtv_call_hw(itv, IVTV_HW_GPIO, video, s_routing, &route);
83 83
84 if (itv->card->hw_video & IVTV_HW_UPD64031A) { 84 if (itv->card->hw_video & IVTV_HW_UPD64031A) {
85 if (type == IVTV_CARD_INPUT_VID_TUNER || 85 if (type == IVTV_CARD_INPUT_VID_TUNER ||
@@ -92,7 +92,7 @@ void ivtv_video_set_io(struct ivtv *itv)
92 } 92 }
93 route.input |= itv->card->gr_config; 93 route.input |= itv->card->gr_config;
94 94
95 ivtv_upd64031a(itv, VIDIOC_INT_S_VIDEO_ROUTING, &route); 95 ivtv_call_hw(itv, IVTV_HW_UPD64031A, video, s_routing, &route);
96 } 96 }
97 97
98 if (itv->card->hw_video & IVTV_HW_UPD6408X) { 98 if (itv->card->hw_video & IVTV_HW_UPD6408X) {
@@ -110,6 +110,6 @@ void ivtv_video_set_io(struct ivtv *itv)
110 route.input |= UPD64083_EXT_Y_ADC; 110 route.input |= UPD64083_EXT_Y_ADC;
111 } 111 }
112 } 112 }
113 ivtv_upd64083(itv, VIDIOC_INT_S_VIDEO_ROUTING, &route); 113 ivtv_call_hw(itv, IVTV_HW_UPD6408X, video, s_routing, &route);
114 } 114 }
115} 115}
diff --git a/drivers/media/video/ivtv/ivtv-streams.c b/drivers/media/video/ivtv/ivtv-streams.c
index 9b7aa79eb267..f77d764707b2 100644
--- a/drivers/media/video/ivtv/ivtv-streams.c
+++ b/drivers/media/video/ivtv/ivtv-streams.c
@@ -172,7 +172,7 @@ static int ivtv_prep_dev(struct ivtv *itv, int type)
172{ 172{
173 struct ivtv_stream *s = &itv->streams[type]; 173 struct ivtv_stream *s = &itv->streams[type];
174 int num_offset = ivtv_stream_info[type].num_offset; 174 int num_offset = ivtv_stream_info[type].num_offset;
175 int num = itv->num + ivtv_first_minor + num_offset; 175 int num = itv->instance + ivtv_first_minor + num_offset;
176 176
177 /* These four fields are always initialized. If v4l2dev == NULL, then 177 /* These four fields are always initialized. If v4l2dev == NULL, then
178 this stream is not in use. In that case no other fields but these 178 this stream is not in use. In that case no other fields but these
@@ -205,11 +205,11 @@ static int ivtv_prep_dev(struct ivtv *itv, int type)
205 return -ENOMEM; 205 return -ENOMEM;
206 } 206 }
207 207
208 snprintf(s->v4l2dev->name, sizeof(s->v4l2dev->name), "ivtv%d %s", 208 snprintf(s->v4l2dev->name, sizeof(s->v4l2dev->name), "%s %s",
209 itv->num, s->name); 209 itv->device.name, s->name);
210 210
211 s->v4l2dev->num = num; 211 s->v4l2dev->num = num;
212 s->v4l2dev->parent = &itv->dev->dev; 212 s->v4l2dev->v4l2_dev = &itv->device;
213 s->v4l2dev->fops = ivtv_stream_info[type].fops; 213 s->v4l2dev->fops = ivtv_stream_info[type].fops;
214 s->v4l2dev->release = video_device_release; 214 s->v4l2dev->release = video_device_release;
215 s->v4l2dev->tvnorms = V4L2_STD_ALL; 215 s->v4l2dev->tvnorms = V4L2_STD_ALL;
@@ -260,6 +260,7 @@ static int ivtv_reg_dev(struct ivtv *itv, int type)
260 if (s_mpg->v4l2dev) 260 if (s_mpg->v4l2dev)
261 num = s_mpg->v4l2dev->num + ivtv_stream_info[type].num_offset; 261 num = s_mpg->v4l2dev->num + ivtv_stream_info[type].num_offset;
262 } 262 }
263 video_set_drvdata(s->v4l2dev, s);
263 264
264 /* Register device. First try the desired minor, then any free one. */ 265 /* Register device. First try the desired minor, then any free one. */
265 if (video_register_device(s->v4l2dev, vfl_type, num)) { 266 if (video_register_device(s->v4l2dev, vfl_type, num)) {
@@ -343,7 +344,7 @@ static void ivtv_vbi_setup(struct ivtv *itv)
343 ivtv_vapi(itv, CX2341X_ENC_SET_VBI_LINE, 5, 0xffff , 0, 0, 0, 0); 344 ivtv_vapi(itv, CX2341X_ENC_SET_VBI_LINE, 5, 0xffff , 0, 0, 0, 0);
344 345
345 /* setup VBI registers */ 346 /* setup VBI registers */
346 itv->video_dec_func(itv, VIDIOC_S_FMT, &itv->vbi.in); 347 v4l2_subdev_call(itv->sd_video, video, s_fmt, &itv->vbi.in);
347 348
348 /* determine number of lines and total number of VBI bytes. 349 /* determine number of lines and total number of VBI bytes.
349 A raw line takes 1443 bytes: 2 * 720 + 4 byte frame header - 1 350 A raw line takes 1443 bytes: 2 * 720 + 4 byte frame header - 1
@@ -577,10 +578,10 @@ int ivtv_start_v4l2_encode_stream(struct ivtv_stream *s)
577 clear_bit(IVTV_F_I_EOS, &itv->i_flags); 578 clear_bit(IVTV_F_I_EOS, &itv->i_flags);
578 579
579 /* Initialize Digitizer for Capture */ 580 /* Initialize Digitizer for Capture */
580 itv->video_dec_func(itv, VIDIOC_STREAMOFF, NULL); 581 v4l2_subdev_call(itv->sd_video, video, s_stream, 0);
581 ivtv_msleep_timeout(300, 1); 582 ivtv_msleep_timeout(300, 1);
582 ivtv_vapi(itv, CX2341X_ENC_INITIALIZE_INPUT, 0); 583 ivtv_vapi(itv, CX2341X_ENC_INITIALIZE_INPUT, 0);
583 itv->video_dec_func(itv, VIDIOC_STREAMON, NULL); 584 v4l2_subdev_call(itv->sd_video, video, s_stream, 1);
584 } 585 }
585 586
586 /* begin_capture */ 587 /* begin_capture */
diff --git a/drivers/media/video/ivtv/ivtv-vbi.c b/drivers/media/video/ivtv/ivtv-vbi.c
index 4a37a7d2e69d..5c5d1c462fef 100644
--- a/drivers/media/video/ivtv/ivtv-vbi.c
+++ b/drivers/media/video/ivtv/ivtv-vbi.c
@@ -21,6 +21,7 @@
21#include "ivtv-i2c.h" 21#include "ivtv-i2c.h"
22#include "ivtv-ioctl.h" 22#include "ivtv-ioctl.h"
23#include "ivtv-queue.h" 23#include "ivtv-queue.h"
24#include "ivtv-cards.h"
24#include "ivtv-vbi.h" 25#include "ivtv-vbi.h"
25 26
26static void ivtv_set_vps(struct ivtv *itv, int enabled) 27static void ivtv_set_vps(struct ivtv *itv, int enabled)
@@ -37,7 +38,7 @@ static void ivtv_set_vps(struct ivtv *itv, int enabled)
37 data.data[9] = itv->vbi.vps_payload.data[2]; 38 data.data[9] = itv->vbi.vps_payload.data[2];
38 data.data[10] = itv->vbi.vps_payload.data[3]; 39 data.data[10] = itv->vbi.vps_payload.data[3];
39 data.data[11] = itv->vbi.vps_payload.data[4]; 40 data.data[11] = itv->vbi.vps_payload.data[4];
40 ivtv_saa7127(itv, VIDIOC_INT_S_VBI_DATA, &data); 41 ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_vbi_data, &data);
41} 42}
42 43
43static void ivtv_set_cc(struct ivtv *itv, int mode, const struct vbi_cc *cc) 44static void ivtv_set_cc(struct ivtv *itv, int mode, const struct vbi_cc *cc)
@@ -51,12 +52,12 @@ static void ivtv_set_cc(struct ivtv *itv, int mode, const struct vbi_cc *cc)
51 data.line = (mode & 1) ? 21 : 0; 52 data.line = (mode & 1) ? 21 : 0;
52 data.data[0] = cc->odd[0]; 53 data.data[0] = cc->odd[0];
53 data.data[1] = cc->odd[1]; 54 data.data[1] = cc->odd[1];
54 ivtv_saa7127(itv, VIDIOC_INT_S_VBI_DATA, &data); 55 ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_vbi_data, &data);
55 data.field = 1; 56 data.field = 1;
56 data.line = (mode & 2) ? 21 : 0; 57 data.line = (mode & 2) ? 21 : 0;
57 data.data[0] = cc->even[0]; 58 data.data[0] = cc->even[0];
58 data.data[1] = cc->even[1]; 59 data.data[1] = cc->even[1];
59 ivtv_saa7127(itv, VIDIOC_INT_S_VBI_DATA, &data); 60 ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_vbi_data, &data);
60} 61}
61 62
62static void ivtv_set_wss(struct ivtv *itv, int enabled, int mode) 63static void ivtv_set_wss(struct ivtv *itv, int enabled, int mode)
@@ -79,7 +80,7 @@ static void ivtv_set_wss(struct ivtv *itv, int enabled, int mode)
79 data.line = enabled ? 23 : 0; 80 data.line = enabled ? 23 : 0;
80 data.data[0] = mode & 0xff; 81 data.data[0] = mode & 0xff;
81 data.data[1] = (mode >> 8) & 0xff; 82 data.data[1] = (mode >> 8) & 0xff;
82 ivtv_saa7127(itv, VIDIOC_INT_S_VBI_DATA, &data); 83 ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_vbi_data, &data);
83} 84}
84 85
85static int odd_parity(u8 c) 86static int odd_parity(u8 c)
@@ -313,7 +314,7 @@ static u32 compress_sliced_buf(struct ivtv *itv, u32 line, u8 *buf, u32 size, u8
313 continue; 314 continue;
314 } 315 }
315 vbi.p = p + 4; 316 vbi.p = p + 4;
316 itv->video_dec_func(itv, VIDIOC_INT_DECODE_VBI_LINE, &vbi); 317 v4l2_subdev_call(itv->sd_video, video, decode_vbi_line, &vbi);
317 if (vbi.type && !(lines & (1 << vbi.line))) { 318 if (vbi.type && !(lines & (1 << vbi.line))) {
318 lines |= 1 << vbi.line; 319 lines |= 1 << vbi.line;
319 itv->vbi.sliced_data[line].id = vbi.type; 320 itv->vbi.sliced_data[line].id = vbi.type;
@@ -437,7 +438,7 @@ void ivtv_vbi_work_handler(struct ivtv *itv)
437 data.id = V4L2_SLICED_WSS_625; 438 data.id = V4L2_SLICED_WSS_625;
438 data.field = 0; 439 data.field = 0;
439 440
440 if (itv->video_dec_func(itv, VIDIOC_INT_G_VBI_DATA, &data) == 0) { 441 if (v4l2_subdev_call(itv->sd_video, video, g_vbi_data, &data) == 0) {
441 ivtv_set_wss(itv, 1, data.data[0] & 0xf); 442 ivtv_set_wss(itv, 1, data.data[0] & 0xf);
442 vi->wss_missing_cnt = 0; 443 vi->wss_missing_cnt = 0;
443 } else if (vi->wss_missing_cnt == 4) { 444 } else if (vi->wss_missing_cnt == 4) {
@@ -451,13 +452,13 @@ void ivtv_vbi_work_handler(struct ivtv *itv)
451 452
452 data.id = V4L2_SLICED_CAPTION_525; 453 data.id = V4L2_SLICED_CAPTION_525;
453 data.field = 0; 454 data.field = 0;
454 if (itv->video_dec_func(itv, VIDIOC_INT_G_VBI_DATA, &data) == 0) { 455 if (v4l2_subdev_call(itv->sd_video, video, g_vbi_data, &data) == 0) {
455 mode |= 1; 456 mode |= 1;
456 cc.odd[0] = data.data[0]; 457 cc.odd[0] = data.data[0];
457 cc.odd[1] = data.data[1]; 458 cc.odd[1] = data.data[1];
458 } 459 }
459 data.field = 1; 460 data.field = 1;
460 if (itv->video_dec_func(itv, VIDIOC_INT_G_VBI_DATA, &data) == 0) { 461 if (v4l2_subdev_call(itv->sd_video, video, g_vbi_data, &data) == 0) {
461 mode |= 2; 462 mode |= 2;
462 cc.even[0] = data.data[0]; 463 cc.even[0] = data.data[0];
463 cc.even[1] = data.data[1]; 464 cc.even[1] = data.data[1];
diff --git a/drivers/media/video/ivtv/ivtvfb.c b/drivers/media/video/ivtv/ivtvfb.c
index 921e281876f8..36abd2aef6f1 100644
--- a/drivers/media/video/ivtv/ivtvfb.c
+++ b/drivers/media/video/ivtv/ivtvfb.c
@@ -48,6 +48,7 @@
48#endif 48#endif
49 49
50#include "ivtv-driver.h" 50#include "ivtv-driver.h"
51#include "ivtv-cards.h"
51#include "ivtv-i2c.h" 52#include "ivtv-i2c.h"
52#include "ivtv-udma.h" 53#include "ivtv-udma.h"
53#include "ivtv-mailbox.h" 54#include "ivtv-mailbox.h"
@@ -121,15 +122,15 @@ MODULE_LICENSE("GPL");
121#define IVTVFB_DEBUG(x, type, fmt, args...) \ 122#define IVTVFB_DEBUG(x, type, fmt, args...) \
122 do { \ 123 do { \
123 if ((x) & ivtvfb_debug) \ 124 if ((x) & ivtvfb_debug) \
124 printk(KERN_INFO "ivtvfb%d " type ": " fmt, itv->num , ## args); \ 125 printk(KERN_INFO "ivtvfb%d " type ": " fmt, itv->instance , ## args); \
125 } while (0) 126 } while (0)
126#define IVTVFB_DEBUG_WARN(fmt, args...) IVTVFB_DEBUG(IVTVFB_DBGFLG_WARN, "warning", fmt , ## args) 127#define IVTVFB_DEBUG_WARN(fmt, args...) IVTVFB_DEBUG(IVTVFB_DBGFLG_WARN, "warning", fmt , ## args)
127#define IVTVFB_DEBUG_INFO(fmt, args...) IVTVFB_DEBUG(IVTVFB_DBGFLG_INFO, "info", fmt , ## args) 128#define IVTVFB_DEBUG_INFO(fmt, args...) IVTVFB_DEBUG(IVTVFB_DBGFLG_INFO, "info", fmt , ## args)
128 129
129/* Standard kernel messages */ 130/* Standard kernel messages */
130#define IVTVFB_ERR(fmt, args...) printk(KERN_ERR "ivtvfb%d: " fmt, itv->num , ## args) 131#define IVTVFB_ERR(fmt, args...) printk(KERN_ERR "ivtvfb%d: " fmt, itv->instance , ## args)
131#define IVTVFB_WARN(fmt, args...) printk(KERN_WARNING "ivtvfb%d: " fmt, itv->num , ## args) 132#define IVTVFB_WARN(fmt, args...) printk(KERN_WARNING "ivtvfb%d: " fmt, itv->instance , ## args)
132#define IVTVFB_INFO(fmt, args...) printk(KERN_INFO "ivtvfb%d: " fmt, itv->num , ## args) 133#define IVTVFB_INFO(fmt, args...) printk(KERN_INFO "ivtvfb%d: " fmt, itv->instance , ## args)
133 134
134/* --------------------------------------------------------------------- */ 135/* --------------------------------------------------------------------- */
135 136
@@ -895,16 +896,16 @@ static int ivtvfb_blank(int blank_mode, struct fb_info *info)
895 switch (blank_mode) { 896 switch (blank_mode) {
896 case FB_BLANK_UNBLANK: 897 case FB_BLANK_UNBLANK:
897 ivtv_vapi(itv, CX2341X_OSD_SET_STATE, 1, 1); 898 ivtv_vapi(itv, CX2341X_OSD_SET_STATE, 1, 1);
898 ivtv_saa7127(itv, VIDIOC_STREAMON, NULL); 899 ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_stream, 1);
899 break; 900 break;
900 case FB_BLANK_NORMAL: 901 case FB_BLANK_NORMAL:
901 case FB_BLANK_HSYNC_SUSPEND: 902 case FB_BLANK_HSYNC_SUSPEND:
902 case FB_BLANK_VSYNC_SUSPEND: 903 case FB_BLANK_VSYNC_SUSPEND:
903 ivtv_vapi(itv, CX2341X_OSD_SET_STATE, 1, 0); 904 ivtv_vapi(itv, CX2341X_OSD_SET_STATE, 1, 0);
904 ivtv_saa7127(itv, VIDIOC_STREAMON, NULL); 905 ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_stream, 1);
905 break; 906 break;
906 case FB_BLANK_POWERDOWN: 907 case FB_BLANK_POWERDOWN:
907 ivtv_saa7127(itv, VIDIOC_STREAMOFF, NULL); 908 ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_stream, 0);
908 ivtv_vapi(itv, CX2341X_OSD_SET_STATE, 1, 0); 909 ivtv_vapi(itv, CX2341X_OSD_SET_STATE, 1, 0);
909 break; 910 break;
910 } 911 }
@@ -1188,10 +1189,45 @@ static int ivtvfb_init_card(struct ivtv *itv)
1188 1189
1189} 1190}
1190 1191
1192static int __init ivtvfb_callback_init(struct device *dev, void *p)
1193{
1194 struct v4l2_device *v4l2_dev = dev_get_drvdata(dev);
1195 struct ivtv *itv = container_of(v4l2_dev, struct ivtv, device);
1196
1197 if (itv && (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) {
1198 if (ivtvfb_init_card(itv) == 0) {
1199 IVTVFB_INFO("Framebuffer registered on %s\n",
1200 itv->device.name);
1201 (*(int *)p)++;
1202 }
1203 }
1204 return 0;
1205}
1206
1207static int ivtvfb_callback_cleanup(struct device *dev, void *p)
1208{
1209 struct v4l2_device *v4l2_dev = dev_get_drvdata(dev);
1210 struct ivtv *itv = container_of(v4l2_dev, struct ivtv, device);
1211
1212 if (itv && (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) {
1213 if (unregister_framebuffer(&itv->osd_info->ivtvfb_info)) {
1214 IVTVFB_WARN("Framebuffer %d is in use, cannot unload\n",
1215 itv->instance);
1216 return 0;
1217 }
1218 IVTVFB_INFO("Unregister framebuffer %d\n", itv->instance);
1219 ivtvfb_blank(FB_BLANK_POWERDOWN, &itv->osd_info->ivtvfb_info);
1220 ivtvfb_release_buffers(itv);
1221 itv->osd_video_pbase = 0;
1222 }
1223 return 0;
1224}
1225
1191static int __init ivtvfb_init(void) 1226static int __init ivtvfb_init(void)
1192{ 1227{
1193 struct ivtv *itv; 1228 struct device_driver *drv;
1194 int i, registered = 0; 1229 int registered = 0;
1230 int err;
1195 1231
1196 if (ivtvfb_card_id < -1 || ivtvfb_card_id >= IVTV_MAX_CARDS) { 1232 if (ivtvfb_card_id < -1 || ivtvfb_card_id >= IVTV_MAX_CARDS) {
1197 printk(KERN_ERR "ivtvfb: ivtvfb_card_id parameter is out of range (valid range: -1 - %d)\n", 1233 printk(KERN_ERR "ivtvfb: ivtvfb_card_id parameter is out of range (valid range: -1 - %d)\n",
@@ -1199,20 +1235,11 @@ static int __init ivtvfb_init(void)
1199 return -EINVAL; 1235 return -EINVAL;
1200 } 1236 }
1201 1237
1202 /* Locate & initialise all cards supporting an OSD. */ 1238 drv = driver_find("ivtv", &pci_bus_type);
1203 for (i = 0; i < ivtv_cards_active; i++) { 1239 err = driver_for_each_device(drv, NULL, &registered, ivtvfb_callback_init);
1204 if (ivtvfb_card_id != -1 && i != ivtvfb_card_id) 1240 put_driver(drv);
1205 continue;
1206 itv = ivtv_cards[i];
1207 if (itv && (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) {
1208 if (ivtvfb_init_card(itv) == 0) {
1209 IVTVFB_INFO("Framebuffer registered on ivtv card id %d\n", i);
1210 registered++;
1211 }
1212 }
1213 }
1214 if (!registered) { 1241 if (!registered) {
1215 printk(KERN_ERR "ivtvfb: no cards found"); 1242 printk(KERN_ERR "ivtvfb: no cards found\n");
1216 return -ENODEV; 1243 return -ENODEV;
1217 } 1244 }
1218 return 0; 1245 return 0;
@@ -1220,24 +1247,14 @@ static int __init ivtvfb_init(void)
1220 1247
1221static void ivtvfb_cleanup(void) 1248static void ivtvfb_cleanup(void)
1222{ 1249{
1223 struct ivtv *itv; 1250 struct device_driver *drv;
1224 int i; 1251 int err;
1225 1252
1226 printk(KERN_INFO "ivtvfb: Unloading framebuffer module\n"); 1253 printk(KERN_INFO "ivtvfb: Unloading framebuffer module\n");
1227 1254
1228 for (i = 0; i < ivtv_cards_active; i++) { 1255 drv = driver_find("ivtv", &pci_bus_type);
1229 itv = ivtv_cards[i]; 1256 err = driver_for_each_device(drv, NULL, NULL, ivtvfb_callback_cleanup);
1230 if (itv && (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) && itv->osd_info) { 1257 put_driver(drv);
1231 if (unregister_framebuffer(&itv->osd_info->ivtvfb_info)) {
1232 IVTVFB_WARN("Framebuffer %d is in use, cannot unload\n", i);
1233 return;
1234 }
1235 IVTVFB_DEBUG_INFO("Unregister framebuffer %d\n", i);
1236 ivtvfb_blank(FB_BLANK_POWERDOWN, &itv->osd_info->ivtvfb_info);
1237 ivtvfb_release_buffers(itv);
1238 itv->osd_video_pbase = 0;
1239 }
1240 }
1241} 1258}
1242 1259
1243module_init(ivtvfb_init); 1260module_init(ivtvfb_init);
diff --git a/drivers/media/video/m52790.c b/drivers/media/video/m52790.c
index 89a781c6929d..07be14a9fe7b 100644
--- a/drivers/media/video/m52790.c
+++ b/drivers/media/video/m52790.c
@@ -28,7 +28,7 @@
28#include <linux/i2c-id.h> 28#include <linux/i2c-id.h>
29#include <linux/videodev2.h> 29#include <linux/videodev2.h>
30#include <media/m52790.h> 30#include <media/m52790.h>
31#include <media/v4l2-common.h> 31#include <media/v4l2-device.h>
32#include <media/v4l2-chip-ident.h> 32#include <media/v4l2-chip-ident.h>
33#include <media/v4l2-i2c-drv.h> 33#include <media/v4l2-i2c-drv.h>
34 34
@@ -38,89 +38,130 @@ MODULE_LICENSE("GPL");
38 38
39 39
40struct m52790_state { 40struct m52790_state {
41 struct v4l2_subdev sd;
41 u16 input; 42 u16 input;
42 u16 output; 43 u16 output;
43}; 44};
44 45
46static inline struct m52790_state *to_state(struct v4l2_subdev *sd)
47{
48 return container_of(sd, struct m52790_state, sd);
49}
50
45/* ----------------------------------------------------------------------- */ 51/* ----------------------------------------------------------------------- */
46 52
47static int m52790_write(struct i2c_client *client) 53static int m52790_write(struct v4l2_subdev *sd)
48{ 54{
49 struct m52790_state *state = i2c_get_clientdata(client); 55 struct m52790_state *state = to_state(sd);
56 struct i2c_client *client = v4l2_get_subdevdata(sd);
57
50 u8 sw1 = (state->input | state->output) & 0xff; 58 u8 sw1 = (state->input | state->output) & 0xff;
51 u8 sw2 = (state->input | state->output) >> 8; 59 u8 sw2 = (state->input | state->output) >> 8;
52 60
53 return i2c_smbus_write_byte_data(client, sw1, sw2); 61 return i2c_smbus_write_byte_data(client, sw1, sw2);
54} 62}
55 63
56static int m52790_command(struct i2c_client *client, unsigned int cmd, 64/* Note: audio and video are linked and cannot be switched separately.
57 void *arg) 65 So audio and video routing commands are identical for this chip.
66 In theory the video amplifier and audio modes could be handled
67 separately for the output, but that seems to be overkill right now.
68 The same holds for implementing an audio mute control, this is now
69 part of the audio output routing. The normal case is that another
70 chip takes care of the actual muting so making it part of the
71 output routing seems to be the right thing to do for now. */
72static int m52790_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
58{ 73{
59 struct m52790_state *state = i2c_get_clientdata(client); 74 struct m52790_state *state = to_state(sd);
60 struct v4l2_routing *route = arg; 75
61 76 state->input = route->input;
62 /* Note: audio and video are linked and cannot be switched separately. 77 state->output = route->output;
63 So audio and video routing commands are identical for this chip. 78 m52790_write(sd);
64 In theory the video amplifier and audio modes could be handled 79 return 0;
65 separately for the output, but that seems to be overkill right now. 80}
66 The same holds for implementing an audio mute control, this is now
67 part of the audio output routing. The normal case is that another
68 chip takes care of the actual muting so making it part of the
69 output routing seems to be the right thing to do for now. */
70 switch (cmd) {
71 case VIDIOC_INT_G_AUDIO_ROUTING:
72 case VIDIOC_INT_G_VIDEO_ROUTING:
73 route->input = state->input;
74 route->output = state->output;
75 break;
76
77 case VIDIOC_INT_S_AUDIO_ROUTING:
78 case VIDIOC_INT_S_VIDEO_ROUTING:
79 state->input = route->input;
80 state->output = route->output;
81 m52790_write(client);
82 break;
83 81
84#ifdef CONFIG_VIDEO_ADV_DEBUG 82#ifdef CONFIG_VIDEO_ADV_DEBUG
85 case VIDIOC_DBG_G_REGISTER: 83static int m52790_g_register(struct v4l2_subdev *sd, struct v4l2_register *reg)
86 case VIDIOC_DBG_S_REGISTER: 84{
87 { 85 struct m52790_state *state = to_state(sd);
88 struct v4l2_register *reg = arg; 86 struct i2c_client *client = v4l2_get_subdevdata(sd);
89
90 if (!v4l2_chip_match_i2c_client(client,
91 reg->match_type, reg->match_chip))
92 return -EINVAL;
93 if (!capable(CAP_SYS_ADMIN))
94 return -EPERM;
95 if (reg->reg != 0)
96 return -EINVAL;
97 if (cmd == VIDIOC_DBG_G_REGISTER)
98 reg->val = state->input | state->output;
99 else {
100 state->input = reg->val & 0x0303;
101 state->output = reg->val & ~0x0303;
102 m52790_write(client);
103 }
104 break;
105 }
106#endif
107 87
108 case VIDIOC_G_CHIP_IDENT: 88 if (!v4l2_chip_match_i2c_client(client,
109 return v4l2_chip_ident_i2c_client(client, arg, 89 reg->match_type, reg->match_chip))
110 V4L2_IDENT_M52790, 0); 90 return -EINVAL;
91 if (!capable(CAP_SYS_ADMIN))
92 return -EPERM;
93 if (reg->reg != 0)
94 return -EINVAL;
95 reg->val = state->input | state->output;
96 return 0;
97}
111 98
112 case VIDIOC_LOG_STATUS: 99static int m52790_s_register(struct v4l2_subdev *sd, struct v4l2_register *reg)
113 v4l_info(client, "Switch 1: %02x\n", 100{
114 (state->input | state->output) & 0xff); 101 struct m52790_state *state = to_state(sd);
115 v4l_info(client, "Switch 2: %02x\n", 102 struct i2c_client *client = v4l2_get_subdevdata(sd);
116 (state->input | state->output) >> 8);
117 break;
118 103
119 default: 104 if (!v4l2_chip_match_i2c_client(client,
105 reg->match_type, reg->match_chip))
120 return -EINVAL; 106 return -EINVAL;
121 } 107 if (!capable(CAP_SYS_ADMIN))
108 return -EPERM;
109 if (reg->reg != 0)
110 return -EINVAL;
111 state->input = reg->val & 0x0303;
112 state->output = reg->val & ~0x0303;
113 m52790_write(sd);
122 return 0; 114 return 0;
123} 115}
116#endif
117
118static int m52790_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_chip_ident *chip)
119{
120 struct i2c_client *client = v4l2_get_subdevdata(sd);
121
122 return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_M52790, 0);
123}
124
125static int m52790_log_status(struct v4l2_subdev *sd)
126{
127 struct m52790_state *state = to_state(sd);
128
129 v4l2_info(sd, "Switch 1: %02x\n",
130 (state->input | state->output) & 0xff);
131 v4l2_info(sd, "Switch 2: %02x\n",
132 (state->input | state->output) >> 8);
133 return 0;
134}
135
136static int m52790_command(struct i2c_client *client, unsigned cmd, void *arg)
137{
138 return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
139}
140
141/* ----------------------------------------------------------------------- */
142
143static const struct v4l2_subdev_core_ops m52790_core_ops = {
144 .log_status = m52790_log_status,
145 .g_chip_ident = m52790_g_chip_ident,
146#ifdef CONFIG_VIDEO_ADV_DEBUG
147 .g_register = m52790_g_register,
148 .s_register = m52790_s_register,
149#endif
150};
151
152static const struct v4l2_subdev_audio_ops m52790_audio_ops = {
153 .s_routing = m52790_s_routing,
154};
155
156static const struct v4l2_subdev_video_ops m52790_video_ops = {
157 .s_routing = m52790_s_routing,
158};
159
160static const struct v4l2_subdev_ops m52790_ops = {
161 .core = &m52790_core_ops,
162 .audio = &m52790_audio_ops,
163 .video = &m52790_video_ops,
164};
124 165
125/* ----------------------------------------------------------------------- */ 166/* ----------------------------------------------------------------------- */
126 167
@@ -130,6 +171,7 @@ static int m52790_probe(struct i2c_client *client,
130 const struct i2c_device_id *id) 171 const struct i2c_device_id *id)
131{ 172{
132 struct m52790_state *state; 173 struct m52790_state *state;
174 struct v4l2_subdev *sd;
133 175
134 /* Check if the adapter supports the needed features */ 176 /* Check if the adapter supports the needed features */
135 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) 177 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
@@ -142,16 +184,20 @@ static int m52790_probe(struct i2c_client *client,
142 if (state == NULL) 184 if (state == NULL)
143 return -ENOMEM; 185 return -ENOMEM;
144 186
187 sd = &state->sd;
188 v4l2_i2c_subdev_init(sd, client, &m52790_ops);
145 state->input = M52790_IN_TUNER; 189 state->input = M52790_IN_TUNER;
146 state->output = M52790_OUT_STEREO; 190 state->output = M52790_OUT_STEREO;
147 i2c_set_clientdata(client, state); 191 m52790_write(sd);
148 m52790_write(client);
149 return 0; 192 return 0;
150} 193}
151 194
152static int m52790_remove(struct i2c_client *client) 195static int m52790_remove(struct i2c_client *client)
153{ 196{
154 kfree(i2c_get_clientdata(client)); 197 struct v4l2_subdev *sd = i2c_get_clientdata(client);
198
199 v4l2_device_unregister_subdev(sd);
200 kfree(to_state(sd));
155 return 0; 201 return 0;
156} 202}
157 203
diff --git a/drivers/media/video/msp3400-driver.c b/drivers/media/video/msp3400-driver.c
index 3da74dcee902..a622dbb72ed8 100644
--- a/drivers/media/video/msp3400-driver.c
+++ b/drivers/media/video/msp3400-driver.c
@@ -51,14 +51,14 @@
51#include <linux/module.h> 51#include <linux/module.h>
52#include <linux/slab.h> 52#include <linux/slab.h>
53#include <linux/i2c.h> 53#include <linux/i2c.h>
54#include <linux/kthread.h>
55#include <linux/freezer.h>
54#include <linux/videodev2.h> 56#include <linux/videodev2.h>
55#include <media/v4l2-common.h> 57#include <media/v4l2-device.h>
56#include <media/v4l2-ioctl.h> 58#include <media/v4l2-ioctl.h>
57#include <media/v4l2-i2c-drv-legacy.h> 59#include <media/v4l2-i2c-drv-legacy.h>
58#include <media/tvaudio.h>
59#include <media/msp3400.h> 60#include <media/msp3400.h>
60#include <linux/kthread.h> 61#include <media/tvaudio.h>
61#include <linux/freezer.h>
62#include "msp3400-driver.h" 62#include "msp3400-driver.h"
63 63
64/* ---------------------------------------------------------------------- */ 64/* ---------------------------------------------------------------------- */
@@ -265,7 +265,7 @@ static char *scart_names[] = {
265 265
266void msp_set_scart(struct i2c_client *client, int in, int out) 266void msp_set_scart(struct i2c_client *client, int in, int out)
267{ 267{
268 struct msp_state *state = i2c_get_clientdata(client); 268 struct msp_state *state = to_state(i2c_get_clientdata(client));
269 269
270 state->in_scart = in; 270 state->in_scart = in;
271 271
@@ -289,7 +289,7 @@ void msp_set_scart(struct i2c_client *client, int in, int out)
289 289
290void msp_set_audio(struct i2c_client *client) 290void msp_set_audio(struct i2c_client *client)
291{ 291{
292 struct msp_state *state = i2c_get_clientdata(client); 292 struct msp_state *state = to_state(i2c_get_clientdata(client));
293 int bal = 0, bass, treble, loudness; 293 int bal = 0, bass, treble, loudness;
294 int val = 0; 294 int val = 0;
295 int reallymuted = state->muted | state->scan_in_progress; 295 int reallymuted = state->muted | state->scan_in_progress;
@@ -336,7 +336,7 @@ void msp_set_audio(struct i2c_client *client)
336 336
337static void msp_wake_thread(struct i2c_client *client) 337static void msp_wake_thread(struct i2c_client *client)
338{ 338{
339 struct msp_state *state = i2c_get_clientdata(client); 339 struct msp_state *state = to_state(i2c_get_clientdata(client));
340 340
341 if (NULL == state->kthread) 341 if (NULL == state->kthread)
342 return; 342 return;
@@ -390,9 +390,9 @@ static int msp_mode_v4l1_to_v4l2(int mode)
390} 390}
391#endif 391#endif
392 392
393static int msp_get_ctrl(struct i2c_client *client, struct v4l2_control *ctrl) 393static int msp_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
394{ 394{
395 struct msp_state *state = i2c_get_clientdata(client); 395 struct msp_state *state = to_state(sd);
396 396
397 switch (ctrl->id) { 397 switch (ctrl->id) {
398 case V4L2_CID_AUDIO_VOLUME: 398 case V4L2_CID_AUDIO_VOLUME:
@@ -433,9 +433,10 @@ static int msp_get_ctrl(struct i2c_client *client, struct v4l2_control *ctrl)
433 return 0; 433 return 0;
434} 434}
435 435
436static int msp_set_ctrl(struct i2c_client *client, struct v4l2_control *ctrl) 436static int msp_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
437{ 437{
438 struct msp_state *state = i2c_get_clientdata(client); 438 struct msp_state *state = to_state(sd);
439 struct i2c_client *client = v4l2_get_subdevdata(sd);
439 440
440 switch (ctrl->id) { 441 switch (ctrl->id) {
441 case V4L2_CID_AUDIO_VOLUME: 442 case V4L2_CID_AUDIO_VOLUME:
@@ -481,40 +482,16 @@ static int msp_set_ctrl(struct i2c_client *client, struct v4l2_control *ctrl)
481 return 0; 482 return 0;
482} 483}
483 484
484static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) 485#ifdef CONFIG_VIDEO_ALLOW_V4L1
486static int msp_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
485{ 487{
486 struct msp_state *state = i2c_get_clientdata(client); 488 struct msp_state *state = to_state(sd);
487 489 struct i2c_client *client = v4l2_get_subdevdata(sd);
488 if (msp_debug >= 2)
489 v4l_i2c_print_ioctl(client, cmd);
490 490
491 switch (cmd) { 491 switch (cmd) {
492 case AUDC_SET_RADIO:
493 if (state->radio)
494 return 0;
495 state->radio = 1;
496 v4l_dbg(1, msp_debug, client, "switching to radio mode\n");
497 state->watch_stereo = 0;
498 switch (state->opmode) {
499 case OPMODE_MANUAL:
500 /* set msp3400 to FM radio mode */
501 msp3400c_set_mode(client, MSP_MODE_FM_RADIO);
502 msp3400c_set_carrier(client, MSP_CARRIER(10.7),
503 MSP_CARRIER(10.7));
504 msp_set_audio(client);
505 break;
506 case OPMODE_AUTODETECT:
507 case OPMODE_AUTOSELECT:
508 /* the thread will do for us */
509 msp_wake_thread(client);
510 break;
511 }
512 break;
513
514 /* --- v4l ioctls --- */ 492 /* --- v4l ioctls --- */
515 /* take care: bttv does userspace copying, we'll get a 493 /* take care: bttv does userspace copying, we'll get a
516 kernel pointer here... */ 494 kernel pointer here... */
517#ifdef CONFIG_VIDEO_ALLOW_V4L1
518 case VIDIOCGAUDIO: 495 case VIDIOCGAUDIO:
519 { 496 {
520 struct video_audio *va = arg; 497 struct video_audio *va = arg;
@@ -588,105 +565,137 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
588 msp_wake_thread(client); 565 msp_wake_thread(client);
589 break; 566 break;
590 } 567 }
591#endif 568 default:
592 case VIDIOC_S_FREQUENCY: 569 return -ENOIOCTLCMD;
593 {
594 /* new channel -- kick audio carrier scan */
595 msp_wake_thread(client);
596 break;
597 } 570 }
571 return 0;
572}
573#endif
598 574
599 /* --- v4l2 ioctls --- */ 575/* --- v4l2 ioctls --- */
600 case VIDIOC_S_STD: 576static int msp_s_radio(struct v4l2_subdev *sd)
601 { 577{
602 v4l2_std_id *id = arg; 578 struct msp_state *state = to_state(sd);
603 int update = state->radio || state->v4l2_std != *id; 579 struct i2c_client *client = v4l2_get_subdevdata(sd);
604 580
605 state->v4l2_std = *id; 581 if (state->radio)
606 state->radio = 0;
607 if (update)
608 msp_wake_thread(client);
609 return 0; 582 return 0;
583 state->radio = 1;
584 v4l_dbg(1, msp_debug, client, "switching to radio mode\n");
585 state->watch_stereo = 0;
586 switch (state->opmode) {
587 case OPMODE_MANUAL:
588 /* set msp3400 to FM radio mode */
589 msp3400c_set_mode(client, MSP_MODE_FM_RADIO);
590 msp3400c_set_carrier(client, MSP_CARRIER(10.7),
591 MSP_CARRIER(10.7));
592 msp_set_audio(client);
593 break;
594 case OPMODE_AUTODETECT:
595 case OPMODE_AUTOSELECT:
596 /* the thread will do for us */
597 msp_wake_thread(client);
598 break;
610 } 599 }
600 return 0;
601}
611 602
612 case VIDIOC_INT_G_AUDIO_ROUTING: 603static int msp_s_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *freq)
613 { 604{
614 struct v4l2_routing *rt = arg; 605 struct i2c_client *client = v4l2_get_subdevdata(sd);
615 606
616 *rt = state->routing; 607 /* new channel -- kick audio carrier scan */
617 break; 608 msp_wake_thread(client);
618 } 609 return 0;
610}
619 611
620 case VIDIOC_INT_S_AUDIO_ROUTING: 612static int msp_s_std(struct v4l2_subdev *sd, v4l2_std_id id)
621 { 613{
622 struct v4l2_routing *rt = arg; 614 struct msp_state *state = to_state(sd);
623 int tuner = (rt->input >> 3) & 1; 615 struct i2c_client *client = v4l2_get_subdevdata(sd);
624 int sc_in = rt->input & 0x7; 616 int update = state->radio || state->v4l2_std != id;
625 int sc1_out = rt->output & 0xf; 617
626 int sc2_out = (rt->output >> 4) & 0xf; 618 state->v4l2_std = id;
627 u16 val, reg; 619 state->radio = 0;
628 int i; 620 if (update)
629 int extern_input = 1;
630
631 if (state->routing.input == rt->input &&
632 state->routing.output == rt->output)
633 break;
634 state->routing = *rt;
635 /* check if the tuner input is used */
636 for (i = 0; i < 5; i++) {
637 if (((rt->input >> (4 + i * 4)) & 0xf) == 0)
638 extern_input = 0;
639 }
640 state->mode = extern_input ? MSP_MODE_EXTERN : MSP_MODE_AM_DETECT;
641 state->rxsubchans = V4L2_TUNER_SUB_STEREO;
642 msp_set_scart(client, sc_in, 0);
643 msp_set_scart(client, sc1_out, 1);
644 msp_set_scart(client, sc2_out, 2);
645 msp_set_audmode(client);
646 reg = (state->opmode == OPMODE_AUTOSELECT) ? 0x30 : 0xbb;
647 val = msp_read_dem(client, reg);
648 msp_write_dem(client, reg, (val & ~0x100) | (tuner << 8));
649 /* wake thread when a new input is chosen */
650 msp_wake_thread(client); 621 msp_wake_thread(client);
651 break; 622 return 0;
623}
624
625static int msp_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *rt)
626{
627 struct msp_state *state = to_state(sd);
628 struct i2c_client *client = v4l2_get_subdevdata(sd);
629 int tuner = (rt->input >> 3) & 1;
630 int sc_in = rt->input & 0x7;
631 int sc1_out = rt->output & 0xf;
632 int sc2_out = (rt->output >> 4) & 0xf;
633 u16 val, reg;
634 int i;
635 int extern_input = 1;
636
637 if (state->routing.input == rt->input &&
638 state->routing.output == rt->output)
639 return 0;
640 state->routing = *rt;
641 /* check if the tuner input is used */
642 for (i = 0; i < 5; i++) {
643 if (((rt->input >> (4 + i * 4)) & 0xf) == 0)
644 extern_input = 0;
652 } 645 }
646 state->mode = extern_input ? MSP_MODE_EXTERN : MSP_MODE_AM_DETECT;
647 state->rxsubchans = V4L2_TUNER_SUB_STEREO;
648 msp_set_scart(client, sc_in, 0);
649 msp_set_scart(client, sc1_out, 1);
650 msp_set_scart(client, sc2_out, 2);
651 msp_set_audmode(client);
652 reg = (state->opmode == OPMODE_AUTOSELECT) ? 0x30 : 0xbb;
653 val = msp_read_dem(client, reg);
654 msp_write_dem(client, reg, (val & ~0x100) | (tuner << 8));
655 /* wake thread when a new input is chosen */
656 msp_wake_thread(client);
657 return 0;
658}
653 659
654 case VIDIOC_G_TUNER: 660static int msp_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
655 { 661{
656 struct v4l2_tuner *vt = arg; 662 struct msp_state *state = to_state(sd);
663 struct i2c_client *client = v4l2_get_subdevdata(sd);
657 664
658 if (state->radio) 665 if (state->radio)
659 break; 666 return 0;
660 if (state->opmode == OPMODE_AUTOSELECT) 667 if (state->opmode == OPMODE_AUTOSELECT)
661 msp_detect_stereo(client); 668 msp_detect_stereo(client);
662 vt->audmode = state->audmode; 669 vt->audmode = state->audmode;
663 vt->rxsubchans = state->rxsubchans; 670 vt->rxsubchans = state->rxsubchans;
664 vt->capability |= V4L2_TUNER_CAP_STEREO | 671 vt->capability |= V4L2_TUNER_CAP_STEREO |
665 V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2; 672 V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2;
666 break; 673 return 0;
667 } 674}
668 675
669 case VIDIOC_S_TUNER: 676static int msp_s_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
670 { 677{
671 struct v4l2_tuner *vt = (struct v4l2_tuner *)arg; 678 struct msp_state *state = to_state(sd);
679 struct i2c_client *client = v4l2_get_subdevdata(sd);
672 680
673 if (state->radio) /* TODO: add mono/stereo support for radio */ 681 if (state->radio) /* TODO: add mono/stereo support for radio */
674 break; 682 return 0;
675 if (state->audmode == vt->audmode) 683 if (state->audmode == vt->audmode)
676 break; 684 return 0;
677 state->audmode = vt->audmode; 685 state->audmode = vt->audmode;
678 /* only set audmode */ 686 /* only set audmode */
679 msp_set_audmode(client); 687 msp_set_audmode(client);
680 break; 688 return 0;
681 } 689}
682 690
683 case VIDIOC_INT_I2S_CLOCK_FREQ: 691static int msp_s_i2s_clock_freq(struct v4l2_subdev *sd, u32 freq)
684 { 692{
685 u32 *a = (u32 *)arg; 693 struct msp_state *state = to_state(sd);
694 struct i2c_client *client = v4l2_get_subdevdata(sd);
686 695
687 v4l_dbg(1, msp_debug, client, "Setting I2S speed to %d\n", *a); 696 v4l_dbg(1, msp_debug, client, "Setting I2S speed to %d\n", freq);
688 697
689 switch (*a) { 698 switch (freq) {
690 case 1024000: 699 case 1024000:
691 state->i2s_mode = 0; 700 state->i2s_mode = 0;
692 break; 701 break;
@@ -695,24 +704,24 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
695 break; 704 break;
696 default: 705 default:
697 return -EINVAL; 706 return -EINVAL;
698 }
699 break;
700 } 707 }
708 return 0;
709}
701 710
702 case VIDIOC_QUERYCTRL: 711static int msp_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
703 { 712{
704 struct v4l2_queryctrl *qc = arg; 713 struct msp_state *state = to_state(sd);
705 714
706 switch (qc->id) { 715 switch (qc->id) {
707 case V4L2_CID_AUDIO_VOLUME: 716 case V4L2_CID_AUDIO_VOLUME:
708 case V4L2_CID_AUDIO_MUTE: 717 case V4L2_CID_AUDIO_MUTE:
709 return v4l2_ctrl_query_fill_std(qc); 718 return v4l2_ctrl_query_fill_std(qc);
710 default: 719 default:
711 break; 720 break;
712 } 721 }
713 if (!state->has_sound_processing) 722 if (!state->has_sound_processing)
714 return -EINVAL; 723 return -EINVAL;
715 switch (qc->id) { 724 switch (qc->id) {
716 case V4L2_CID_AUDIO_LOUDNESS: 725 case V4L2_CID_AUDIO_LOUDNESS:
717 case V4L2_CID_AUDIO_BALANCE: 726 case V4L2_CID_AUDIO_BALANCE:
718 case V4L2_CID_AUDIO_BASS: 727 case V4L2_CID_AUDIO_BASS:
@@ -720,32 +729,38 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
720 return v4l2_ctrl_query_fill_std(qc); 729 return v4l2_ctrl_query_fill_std(qc);
721 default: 730 default:
722 return -EINVAL; 731 return -EINVAL;
723 }
724 } 732 }
733 return 0;
734}
725 735
726 case VIDIOC_G_CTRL: 736static int msp_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_chip_ident *chip)
727 return msp_get_ctrl(client, arg); 737{
728 738 struct msp_state *state = to_state(sd);
729 case VIDIOC_S_CTRL: 739 struct i2c_client *client = v4l2_get_subdevdata(sd);
730 return msp_set_ctrl(client, arg);
731 740
732 case VIDIOC_LOG_STATUS: 741 return v4l2_chip_ident_i2c_client(client, chip, state->ident,
733 { 742 (state->rev1 << 16) | state->rev2);
734 const char *p; 743}
735 744
736 if (state->opmode == OPMODE_AUTOSELECT) 745static int msp_log_status(struct v4l2_subdev *sd)
737 msp_detect_stereo(client); 746{
738 v4l_info(client, "%s rev1 = 0x%04x rev2 = 0x%04x\n", 747 struct msp_state *state = to_state(sd);
739 client->name, state->rev1, state->rev2); 748 struct i2c_client *client = v4l2_get_subdevdata(sd);
740 v4l_info(client, "Audio: volume %d%s\n", 749 const char *p;
741 state->volume, state->muted ? " (muted)" : ""); 750
742 if (state->has_sound_processing) { 751 if (state->opmode == OPMODE_AUTOSELECT)
743 v4l_info(client, "Audio: balance %d bass %d treble %d loudness %s\n", 752 msp_detect_stereo(client);
744 state->balance, state->bass, 753 v4l_info(client, "%s rev1 = 0x%04x rev2 = 0x%04x\n",
745 state->treble, 754 client->name, state->rev1, state->rev2);
746 state->loudness ? "on" : "off"); 755 v4l_info(client, "Audio: volume %d%s\n",
747 } 756 state->volume, state->muted ? " (muted)" : "");
748 switch (state->mode) { 757 if (state->has_sound_processing) {
758 v4l_info(client, "Audio: balance %d bass %d treble %d loudness %s\n",
759 state->balance, state->bass,
760 state->treble,
761 state->loudness ? "on" : "off");
762 }
763 switch (state->mode) {
749 case MSP_MODE_AM_DETECT: p = "AM (for carrier detect)"; break; 764 case MSP_MODE_AM_DETECT: p = "AM (for carrier detect)"; break;
750 case MSP_MODE_FM_RADIO: p = "FM Radio"; break; 765 case MSP_MODE_FM_RADIO: p = "FM Radio"; break;
751 case MSP_MODE_FM_TERRA: p = "Terrestial FM-mono/stereo"; break; 766 case MSP_MODE_FM_TERRA: p = "Terrestial FM-mono/stereo"; break;
@@ -756,36 +771,25 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
756 case MSP_MODE_BTSC: p = "BTSC"; break; 771 case MSP_MODE_BTSC: p = "BTSC"; break;
757 case MSP_MODE_EXTERN: p = "External input"; break; 772 case MSP_MODE_EXTERN: p = "External input"; break;
758 default: p = "unknown"; break; 773 default: p = "unknown"; break;
759 } 774 }
760 if (state->mode == MSP_MODE_EXTERN) { 775 if (state->mode == MSP_MODE_EXTERN) {
761 v4l_info(client, "Mode: %s\n", p); 776 v4l_info(client, "Mode: %s\n", p);
762 } else if (state->opmode == OPMODE_MANUAL) { 777 } else if (state->opmode == OPMODE_MANUAL) {
763 v4l_info(client, "Mode: %s (%s%s)\n", p, 778 v4l_info(client, "Mode: %s (%s%s)\n", p,
764 (state->rxsubchans & V4L2_TUNER_SUB_STEREO) ? "stereo" : "mono", 779 (state->rxsubchans & V4L2_TUNER_SUB_STEREO) ? "stereo" : "mono",
765 (state->rxsubchans & V4L2_TUNER_SUB_LANG2) ? ", dual" : ""); 780 (state->rxsubchans & V4L2_TUNER_SUB_LANG2) ? ", dual" : "");
766 } else { 781 } else {
767 if (state->opmode == OPMODE_AUTODETECT) 782 if (state->opmode == OPMODE_AUTODETECT)
768 v4l_info(client, "Mode: %s\n", p); 783 v4l_info(client, "Mode: %s\n", p);
769 v4l_info(client, "Standard: %s (%s%s)\n", 784 v4l_info(client, "Standard: %s (%s%s)\n",
770 msp_standard_std_name(state->std), 785 msp_standard_std_name(state->std),
771 (state->rxsubchans & V4L2_TUNER_SUB_STEREO) ? "stereo" : "mono", 786 (state->rxsubchans & V4L2_TUNER_SUB_STEREO) ? "stereo" : "mono",
772 (state->rxsubchans & V4L2_TUNER_SUB_LANG2) ? ", dual" : ""); 787 (state->rxsubchans & V4L2_TUNER_SUB_LANG2) ? ", dual" : "");
773 }
774 v4l_info(client, "Audmode: 0x%04x\n", state->audmode);
775 v4l_info(client, "Routing: 0x%08x (input) 0x%08x (output)\n",
776 state->routing.input, state->routing.output);
777 v4l_info(client, "ACB: 0x%04x\n", state->acb);
778 break;
779 }
780
781 case VIDIOC_G_CHIP_IDENT:
782 return v4l2_chip_ident_i2c_client(client, arg, state->ident,
783 (state->rev1 << 16) | state->rev2);
784
785 default:
786 /* unknown */
787 return -EINVAL;
788 } 788 }
789 v4l_info(client, "Audmode: 0x%04x\n", state->audmode);
790 v4l_info(client, "Routing: 0x%08x (input) 0x%08x (output)\n",
791 state->routing.input, state->routing.output);
792 v4l_info(client, "ACB: 0x%04x\n", state->acb);
789 return 0; 793 return 0;
790} 794}
791 795
@@ -803,11 +807,49 @@ static int msp_resume(struct i2c_client *client)
803 return 0; 807 return 0;
804} 808}
805 809
810static int msp_command(struct i2c_client *client, unsigned cmd, void *arg)
811{
812 return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
813}
814
815/* ----------------------------------------------------------------------- */
816
817static const struct v4l2_subdev_core_ops msp_core_ops = {
818 .log_status = msp_log_status,
819 .g_chip_ident = msp_g_chip_ident,
820 .g_ctrl = msp_g_ctrl,
821 .s_ctrl = msp_s_ctrl,
822 .queryctrl = msp_queryctrl,
823#ifdef CONFIG_VIDEO_ALLOW_V4L1
824 .ioctl = msp_ioctl,
825#endif
826};
827
828static const struct v4l2_subdev_tuner_ops msp_tuner_ops = {
829 .s_frequency = msp_s_frequency,
830 .g_tuner = msp_g_tuner,
831 .s_tuner = msp_s_tuner,
832 .s_radio = msp_s_radio,
833 .s_std = msp_s_std,
834};
835
836static const struct v4l2_subdev_audio_ops msp_audio_ops = {
837 .s_routing = msp_s_routing,
838 .s_i2s_clock_freq = msp_s_i2s_clock_freq,
839};
840
841static const struct v4l2_subdev_ops msp_ops = {
842 .core = &msp_core_ops,
843 .tuner = &msp_tuner_ops,
844 .audio = &msp_audio_ops,
845};
846
806/* ----------------------------------------------------------------------- */ 847/* ----------------------------------------------------------------------- */
807 848
808static int msp_probe(struct i2c_client *client, const struct i2c_device_id *id) 849static int msp_probe(struct i2c_client *client, const struct i2c_device_id *id)
809{ 850{
810 struct msp_state *state; 851 struct msp_state *state;
852 struct v4l2_subdev *sd;
811 int (*thread_func)(void *data) = NULL; 853 int (*thread_func)(void *data) = NULL;
812 int msp_hard; 854 int msp_hard;
813 int msp_family; 855 int msp_family;
@@ -827,7 +869,8 @@ static int msp_probe(struct i2c_client *client, const struct i2c_device_id *id)
827 if (!state) 869 if (!state)
828 return -ENOMEM; 870 return -ENOMEM;
829 871
830 i2c_set_clientdata(client, state); 872 sd = &state->sd;
873 v4l2_i2c_subdev_init(sd, client, &msp_ops);
831 874
832 state->v4l2_std = V4L2_STD_NTSC; 875 state->v4l2_std = V4L2_STD_NTSC;
833 state->audmode = V4L2_TUNER_MODE_STEREO; 876 state->audmode = V4L2_TUNER_MODE_STEREO;
@@ -972,8 +1015,9 @@ static int msp_probe(struct i2c_client *client, const struct i2c_device_id *id)
972 1015
973static int msp_remove(struct i2c_client *client) 1016static int msp_remove(struct i2c_client *client)
974{ 1017{
975 struct msp_state *state = i2c_get_clientdata(client); 1018 struct msp_state *state = to_state(i2c_get_clientdata(client));
976 1019
1020 v4l2_device_unregister_subdev(&state->sd);
977 /* shutdown control thread */ 1021 /* shutdown control thread */
978 if (state->kthread) { 1022 if (state->kthread) {
979 state->restart = 1; 1023 state->restart = 1;
diff --git a/drivers/media/video/msp3400-driver.h b/drivers/media/video/msp3400-driver.h
index ab69a290e5dc..3fe1c1b10f53 100644
--- a/drivers/media/video/msp3400-driver.h
+++ b/drivers/media/video/msp3400-driver.h
@@ -5,6 +5,7 @@
5#define MSP3400_DRIVER_H 5#define MSP3400_DRIVER_H
6 6
7#include <media/msp3400.h> 7#include <media/msp3400.h>
8#include <media/v4l2-device.h>
8 9
9/* ---------------------------------------------------------------------- */ 10/* ---------------------------------------------------------------------- */
10 11
@@ -49,6 +50,7 @@ extern int msp_dolby;
49extern int msp_stereo_thresh; 50extern int msp_stereo_thresh;
50 51
51struct msp_state { 52struct msp_state {
53 struct v4l2_subdev sd;
52 int rev1, rev2; 54 int rev1, rev2;
53 int ident; 55 int ident;
54 u8 has_nicam; 56 u8 has_nicam;
@@ -96,6 +98,11 @@ struct msp_state {
96 unsigned int watch_stereo:1; 98 unsigned int watch_stereo:1;
97}; 99};
98 100
101static inline struct msp_state *to_state(struct v4l2_subdev *sd)
102{
103 return container_of(sd, struct msp_state, sd);
104}
105
99/* msp3400-driver.c */ 106/* msp3400-driver.c */
100int msp_write_dem(struct i2c_client *client, int addr, int val); 107int msp_write_dem(struct i2c_client *client, int addr, int val);
101int msp_write_dsp(struct i2c_client *client, int addr, int val); 108int msp_write_dsp(struct i2c_client *client, int addr, int val);
diff --git a/drivers/media/video/msp3400-kthreads.c b/drivers/media/video/msp3400-kthreads.c
index 846a14a61fd1..a655e9c30146 100644
--- a/drivers/media/video/msp3400-kthreads.c
+++ b/drivers/media/video/msp3400-kthreads.c
@@ -159,7 +159,7 @@ const char *msp_standard_std_name(int std)
159 159
160static void msp_set_source(struct i2c_client *client, u16 src) 160static void msp_set_source(struct i2c_client *client, u16 src)
161{ 161{
162 struct msp_state *state = i2c_get_clientdata(client); 162 struct msp_state *state = to_state(i2c_get_clientdata(client));
163 163
164 if (msp_dolby) { 164 if (msp_dolby) {
165 msp_write_dsp(client, 0x0008, 0x0520); /* I2S1 */ 165 msp_write_dsp(client, 0x0008, 0x0520); /* I2S1 */
@@ -186,7 +186,7 @@ void msp3400c_set_carrier(struct i2c_client *client, int cdo1, int cdo2)
186 186
187void msp3400c_set_mode(struct i2c_client *client, int mode) 187void msp3400c_set_mode(struct i2c_client *client, int mode)
188{ 188{
189 struct msp_state *state = i2c_get_clientdata(client); 189 struct msp_state *state = to_state(i2c_get_clientdata(client));
190 struct msp3400c_init_data_dem *data = &msp3400c_init_data[mode]; 190 struct msp3400c_init_data_dem *data = &msp3400c_init_data[mode];
191 int tuner = (state->routing.input >> 3) & 1; 191 int tuner = (state->routing.input >> 3) & 1;
192 int i; 192 int i;
@@ -227,7 +227,7 @@ static void msp3400c_set_audmode(struct i2c_client *client)
227 static char *strmode[] = { 227 static char *strmode[] = {
228 "mono", "stereo", "lang2", "lang1", "lang1+lang2" 228 "mono", "stereo", "lang2", "lang1", "lang1+lang2"
229 }; 229 };
230 struct msp_state *state = i2c_get_clientdata(client); 230 struct msp_state *state = to_state(i2c_get_clientdata(client));
231 char *modestr = (state->audmode >= 0 && state->audmode < 5) ? 231 char *modestr = (state->audmode >= 0 && state->audmode < 5) ?
232 strmode[state->audmode] : "unknown"; 232 strmode[state->audmode] : "unknown";
233 int src = 0; /* channel source: FM/AM, nicam or SCART */ 233 int src = 0; /* channel source: FM/AM, nicam or SCART */
@@ -356,7 +356,7 @@ static void msp3400c_set_audmode(struct i2c_client *client)
356 356
357static void msp3400c_print_mode(struct i2c_client *client) 357static void msp3400c_print_mode(struct i2c_client *client)
358{ 358{
359 struct msp_state *state = i2c_get_clientdata(client); 359 struct msp_state *state = to_state(i2c_get_clientdata(client));
360 360
361 if (state->main == state->second) 361 if (state->main == state->second)
362 v4l_dbg(1, msp_debug, client, 362 v4l_dbg(1, msp_debug, client,
@@ -385,7 +385,7 @@ static void msp3400c_print_mode(struct i2c_client *client)
385 385
386static int msp3400c_detect_stereo(struct i2c_client *client) 386static int msp3400c_detect_stereo(struct i2c_client *client)
387{ 387{
388 struct msp_state *state = i2c_get_clientdata(client); 388 struct msp_state *state = to_state(i2c_get_clientdata(client));
389 int val; 389 int val;
390 int rxsubchans = state->rxsubchans; 390 int rxsubchans = state->rxsubchans;
391 int newnicam = state->nicam_on; 391 int newnicam = state->nicam_on;
@@ -463,7 +463,7 @@ static int msp3400c_detect_stereo(struct i2c_client *client)
463/* stereo/multilang monitoring */ 463/* stereo/multilang monitoring */
464static void watch_stereo(struct i2c_client *client) 464static void watch_stereo(struct i2c_client *client)
465{ 465{
466 struct msp_state *state = i2c_get_clientdata(client); 466 struct msp_state *state = to_state(i2c_get_clientdata(client));
467 467
468 if (msp_detect_stereo(client)) 468 if (msp_detect_stereo(client))
469 msp_set_audmode(client); 469 msp_set_audmode(client);
@@ -475,7 +475,7 @@ static void watch_stereo(struct i2c_client *client)
475int msp3400c_thread(void *data) 475int msp3400c_thread(void *data)
476{ 476{
477 struct i2c_client *client = data; 477 struct i2c_client *client = data;
478 struct msp_state *state = i2c_get_clientdata(client); 478 struct msp_state *state = to_state(i2c_get_clientdata(client));
479 struct msp3400c_carrier_detect *cd; 479 struct msp3400c_carrier_detect *cd;
480 int count, max1, max2, val1, val2, val, i; 480 int count, max1, max2, val1, val2, val, i;
481 481
@@ -659,7 +659,7 @@ no_second:
659int msp3410d_thread(void *data) 659int msp3410d_thread(void *data)
660{ 660{
661 struct i2c_client *client = data; 661 struct i2c_client *client = data;
662 struct msp_state *state = i2c_get_clientdata(client); 662 struct msp_state *state = to_state(i2c_get_clientdata(client));
663 int val, i, std, count; 663 int val, i, std, count;
664 664
665 v4l_dbg(1, msp_debug, client, "msp3410 daemon started\n"); 665 v4l_dbg(1, msp_debug, client, "msp3410 daemon started\n");
@@ -825,7 +825,7 @@ restart:
825 825
826static int msp34xxg_modus(struct i2c_client *client) 826static int msp34xxg_modus(struct i2c_client *client)
827{ 827{
828 struct msp_state *state = i2c_get_clientdata(client); 828 struct msp_state *state = to_state(i2c_get_clientdata(client));
829 829
830 if (state->radio) { 830 if (state->radio) {
831 v4l_dbg(1, msp_debug, client, "selected radio modus\n"); 831 v4l_dbg(1, msp_debug, client, "selected radio modus\n");
@@ -852,7 +852,7 @@ static int msp34xxg_modus(struct i2c_client *client)
852 852
853static void msp34xxg_set_source(struct i2c_client *client, u16 reg, int in) 853static void msp34xxg_set_source(struct i2c_client *client, u16 reg, int in)
854 { 854 {
855 struct msp_state *state = i2c_get_clientdata(client); 855 struct msp_state *state = to_state(i2c_get_clientdata(client));
856 int source, matrix; 856 int source, matrix;
857 857
858 switch (state->audmode) { 858 switch (state->audmode) {
@@ -895,7 +895,7 @@ static void msp34xxg_set_source(struct i2c_client *client, u16 reg, int in)
895 895
896static void msp34xxg_set_sources(struct i2c_client *client) 896static void msp34xxg_set_sources(struct i2c_client *client)
897{ 897{
898 struct msp_state *state = i2c_get_clientdata(client); 898 struct msp_state *state = to_state(i2c_get_clientdata(client));
899 u32 in = state->routing.input; 899 u32 in = state->routing.input;
900 900
901 msp34xxg_set_source(client, 0x0008, (in >> 4) & 0xf); 901 msp34xxg_set_source(client, 0x0008, (in >> 4) & 0xf);
@@ -911,7 +911,7 @@ static void msp34xxg_set_sources(struct i2c_client *client)
911/* (re-)initialize the msp34xxg */ 911/* (re-)initialize the msp34xxg */
912static void msp34xxg_reset(struct i2c_client *client) 912static void msp34xxg_reset(struct i2c_client *client)
913{ 913{
914 struct msp_state *state = i2c_get_clientdata(client); 914 struct msp_state *state = to_state(i2c_get_clientdata(client));
915 int tuner = (state->routing.input >> 3) & 1; 915 int tuner = (state->routing.input >> 3) & 1;
916 int modus; 916 int modus;
917 917
@@ -954,7 +954,7 @@ static void msp34xxg_reset(struct i2c_client *client)
954int msp34xxg_thread(void *data) 954int msp34xxg_thread(void *data)
955{ 955{
956 struct i2c_client *client = data; 956 struct i2c_client *client = data;
957 struct msp_state *state = i2c_get_clientdata(client); 957 struct msp_state *state = to_state(i2c_get_clientdata(client));
958 int val, i; 958 int val, i;
959 959
960 v4l_dbg(1, msp_debug, client, "msp34xxg daemon started\n"); 960 v4l_dbg(1, msp_debug, client, "msp34xxg daemon started\n");
@@ -1049,7 +1049,7 @@ unmute:
1049 1049
1050static int msp34xxg_detect_stereo(struct i2c_client *client) 1050static int msp34xxg_detect_stereo(struct i2c_client *client)
1051{ 1051{
1052 struct msp_state *state = i2c_get_clientdata(client); 1052 struct msp_state *state = to_state(i2c_get_clientdata(client));
1053 int status = msp_read_dem(client, 0x0200); 1053 int status = msp_read_dem(client, 0x0200);
1054 int is_bilingual = status & 0x100; 1054 int is_bilingual = status & 0x100;
1055 int is_stereo = status & 0x40; 1055 int is_stereo = status & 0x40;
@@ -1078,7 +1078,7 @@ static int msp34xxg_detect_stereo(struct i2c_client *client)
1078 1078
1079static void msp34xxg_set_audmode(struct i2c_client *client) 1079static void msp34xxg_set_audmode(struct i2c_client *client)
1080{ 1080{
1081 struct msp_state *state = i2c_get_clientdata(client); 1081 struct msp_state *state = to_state(i2c_get_clientdata(client));
1082 1082
1083 if (state->std == 0x20) { 1083 if (state->std == 0x20) {
1084 if ((state->rxsubchans & V4L2_TUNER_SUB_SAP) && 1084 if ((state->rxsubchans & V4L2_TUNER_SUB_SAP) &&
@@ -1095,7 +1095,7 @@ static void msp34xxg_set_audmode(struct i2c_client *client)
1095 1095
1096void msp_set_audmode(struct i2c_client *client) 1096void msp_set_audmode(struct i2c_client *client)
1097{ 1097{
1098 struct msp_state *state = i2c_get_clientdata(client); 1098 struct msp_state *state = to_state(i2c_get_clientdata(client));
1099 1099
1100 switch (state->opmode) { 1100 switch (state->opmode) {
1101 case OPMODE_MANUAL: 1101 case OPMODE_MANUAL:
@@ -1110,7 +1110,7 @@ void msp_set_audmode(struct i2c_client *client)
1110 1110
1111int msp_detect_stereo(struct i2c_client *client) 1111int msp_detect_stereo(struct i2c_client *client)
1112{ 1112{
1113 struct msp_state *state = i2c_get_clientdata(client); 1113 struct msp_state *state = to_state(i2c_get_clientdata(client));
1114 1114
1115 switch (state->opmode) { 1115 switch (state->opmode) {
1116 case OPMODE_MANUAL: 1116 case OPMODE_MANUAL:
diff --git a/drivers/media/video/mt9m001.c b/drivers/media/video/mt9m001.c
index 0c524376b67e..1a1a12453672 100644
--- a/drivers/media/video/mt9m001.c
+++ b/drivers/media/video/mt9m001.c
@@ -272,21 +272,20 @@ static int mt9m001_set_bus_param(struct soc_camera_device *icd,
272static unsigned long mt9m001_query_bus_param(struct soc_camera_device *icd) 272static unsigned long mt9m001_query_bus_param(struct soc_camera_device *icd)
273{ 273{
274 struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); 274 struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd);
275 unsigned int width_flag = SOCAM_DATAWIDTH_10; 275 struct soc_camera_link *icl = mt9m001->client->dev.platform_data;
276 /* MT9M001 has all capture_format parameters fixed */
277 unsigned long flags = SOCAM_DATAWIDTH_10 | SOCAM_PCLK_SAMPLE_RISING |
278 SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_HIGH |
279 SOCAM_MASTER;
276 280
277 if (bus_switch_possible(mt9m001)) 281 if (bus_switch_possible(mt9m001))
278 width_flag |= SOCAM_DATAWIDTH_8; 282 flags |= SOCAM_DATAWIDTH_8;
279 283
280 /* MT9M001 has all capture_format parameters fixed */ 284 return soc_camera_apply_sensor_flags(icl, flags);
281 return SOCAM_PCLK_SAMPLE_RISING |
282 SOCAM_HSYNC_ACTIVE_HIGH |
283 SOCAM_VSYNC_ACTIVE_HIGH |
284 SOCAM_MASTER |
285 width_flag;
286} 285}
287 286
288static int mt9m001_set_fmt_cap(struct soc_camera_device *icd, 287static int mt9m001_set_fmt(struct soc_camera_device *icd,
289 __u32 pixfmt, struct v4l2_rect *rect) 288 __u32 pixfmt, struct v4l2_rect *rect)
290{ 289{
291 struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); 290 struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd);
292 int ret; 291 int ret;
@@ -298,7 +297,7 @@ static int mt9m001_set_fmt_cap(struct soc_camera_device *icd,
298 ret = reg_write(icd, MT9M001_VERTICAL_BLANKING, vblank); 297 ret = reg_write(icd, MT9M001_VERTICAL_BLANKING, vblank);
299 298
300 /* The caller provides a supported format, as verified per 299 /* The caller provides a supported format, as verified per
301 * call to icd->try_fmt_cap() */ 300 * call to icd->try_fmt() */
302 if (!ret) 301 if (!ret)
303 ret = reg_write(icd, MT9M001_COLUMN_START, rect->left); 302 ret = reg_write(icd, MT9M001_COLUMN_START, rect->left);
304 if (!ret) 303 if (!ret)
@@ -325,18 +324,20 @@ static int mt9m001_set_fmt_cap(struct soc_camera_device *icd,
325 return ret; 324 return ret;
326} 325}
327 326
328static int mt9m001_try_fmt_cap(struct soc_camera_device *icd, 327static int mt9m001_try_fmt(struct soc_camera_device *icd,
329 struct v4l2_format *f) 328 struct v4l2_format *f)
330{ 329{
331 if (f->fmt.pix.height < 32 + icd->y_skip_top) 330 struct v4l2_pix_format *pix = &f->fmt.pix;
332 f->fmt.pix.height = 32 + icd->y_skip_top; 331
333 if (f->fmt.pix.height > 1024 + icd->y_skip_top) 332 if (pix->height < 32 + icd->y_skip_top)
334 f->fmt.pix.height = 1024 + icd->y_skip_top; 333 pix->height = 32 + icd->y_skip_top;
335 if (f->fmt.pix.width < 48) 334 if (pix->height > 1024 + icd->y_skip_top)
336 f->fmt.pix.width = 48; 335 pix->height = 1024 + icd->y_skip_top;
337 if (f->fmt.pix.width > 1280) 336 if (pix->width < 48)
338 f->fmt.pix.width = 1280; 337 pix->width = 48;
339 f->fmt.pix.width &= ~0x01; /* has to be even, unsure why was ~3 */ 338 if (pix->width > 1280)
339 pix->width = 1280;
340 pix->width &= ~0x01; /* has to be even, unsure why was ~3 */
340 341
341 return 0; 342 return 0;
342} 343}
@@ -447,8 +448,8 @@ static struct soc_camera_ops mt9m001_ops = {
447 .release = mt9m001_release, 448 .release = mt9m001_release,
448 .start_capture = mt9m001_start_capture, 449 .start_capture = mt9m001_start_capture,
449 .stop_capture = mt9m001_stop_capture, 450 .stop_capture = mt9m001_stop_capture,
450 .set_fmt_cap = mt9m001_set_fmt_cap, 451 .set_fmt = mt9m001_set_fmt,
451 .try_fmt_cap = mt9m001_try_fmt_cap, 452 .try_fmt = mt9m001_try_fmt,
452 .set_bus_param = mt9m001_set_bus_param, 453 .set_bus_param = mt9m001_set_bus_param,
453 .query_bus_param = mt9m001_query_bus_param, 454 .query_bus_param = mt9m001_query_bus_param,
454 .controls = mt9m001_controls, 455 .controls = mt9m001_controls,
@@ -578,6 +579,7 @@ static int mt9m001_set_control(struct soc_camera_device *icd, struct v4l2_contro
578static int mt9m001_video_probe(struct soc_camera_device *icd) 579static int mt9m001_video_probe(struct soc_camera_device *icd)
579{ 580{
580 struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); 581 struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd);
582 struct soc_camera_link *icl = mt9m001->client->dev.platform_data;
581 s32 data; 583 s32 data;
582 int ret; 584 int ret;
583 585
@@ -588,7 +590,7 @@ static int mt9m001_video_probe(struct soc_camera_device *icd)
588 return -ENODEV; 590 return -ENODEV;
589 591
590 /* Enable the chip */ 592 /* Enable the chip */
591 data = reg_write(&mt9m001->icd, MT9M001_CHIP_ENABLE, 1); 593 data = reg_write(icd, MT9M001_CHIP_ENABLE, 1);
592 dev_dbg(&icd->dev, "write: %d\n", data); 594 dev_dbg(&icd->dev, "write: %d\n", data);
593 595
594 /* Read out the chip version register */ 596 /* Read out the chip version register */
@@ -600,7 +602,7 @@ static int mt9m001_video_probe(struct soc_camera_device *icd)
600 case 0x8421: 602 case 0x8421:
601 mt9m001->model = V4L2_IDENT_MT9M001C12ST; 603 mt9m001->model = V4L2_IDENT_MT9M001C12ST;
602 icd->formats = mt9m001_colour_formats; 604 icd->formats = mt9m001_colour_formats;
603 if (mt9m001->client->dev.platform_data) 605 if (gpio_is_valid(icl->gpio))
604 icd->num_formats = ARRAY_SIZE(mt9m001_colour_formats); 606 icd->num_formats = ARRAY_SIZE(mt9m001_colour_formats);
605 else 607 else
606 icd->num_formats = 1; 608 icd->num_formats = 1;
@@ -608,7 +610,7 @@ static int mt9m001_video_probe(struct soc_camera_device *icd)
608 case 0x8431: 610 case 0x8431:
609 mt9m001->model = V4L2_IDENT_MT9M001C12STM; 611 mt9m001->model = V4L2_IDENT_MT9M001C12STM;
610 icd->formats = mt9m001_monochrome_formats; 612 icd->formats = mt9m001_monochrome_formats;
611 if (mt9m001->client->dev.platform_data) 613 if (gpio_is_valid(icl->gpio))
612 icd->num_formats = ARRAY_SIZE(mt9m001_monochrome_formats); 614 icd->num_formats = ARRAY_SIZE(mt9m001_monochrome_formats);
613 else 615 else
614 icd->num_formats = 1; 616 icd->num_formats = 1;
@@ -640,8 +642,8 @@ static void mt9m001_video_remove(struct soc_camera_device *icd)
640 struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); 642 struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd);
641 643
642 dev_dbg(&icd->dev, "Video %x removed: %p, %p\n", mt9m001->client->addr, 644 dev_dbg(&icd->dev, "Video %x removed: %p, %p\n", mt9m001->client->addr,
643 mt9m001->icd.dev.parent, mt9m001->icd.vdev); 645 icd->dev.parent, icd->vdev);
644 soc_camera_video_stop(&mt9m001->icd); 646 soc_camera_video_stop(icd);
645} 647}
646 648
647static int mt9m001_probe(struct i2c_client *client, 649static int mt9m001_probe(struct i2c_client *client,
diff --git a/drivers/media/video/mt9m111.c b/drivers/media/video/mt9m111.c
index da0b2d553fd0..c89ea41fe259 100644
--- a/drivers/media/video/mt9m111.c
+++ b/drivers/media/video/mt9m111.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Driver for MT9M111 CMOS Image Sensor from Micron 2 * Driver for MT9M111/MT9M112 CMOS Image Sensor from Micron
3 * 3 *
4 * Copyright (C) 2008, Robert Jarzmik <robert.jarzmik@free.fr> 4 * Copyright (C) 2008, Robert Jarzmik <robert.jarzmik@free.fr>
5 * 5 *
@@ -19,7 +19,7 @@
19#include <media/soc_camera.h> 19#include <media/soc_camera.h>
20 20
21/* 21/*
22 * mt9m111 i2c address is 0x5d or 0x48 (depending on SAddr pin) 22 * mt9m111 and mt9m112 i2c address is 0x5d or 0x48 (depending on SAddr pin)
23 * The platform has to define i2c_board_info and call i2c_register_board_info() 23 * The platform has to define i2c_board_info and call i2c_register_board_info()
24 */ 24 */
25 25
@@ -90,7 +90,7 @@
90#define MT9M111_OUTPUT_FORMAT_CTRL2_B 0x19b 90#define MT9M111_OUTPUT_FORMAT_CTRL2_B 0x19b
91 91
92#define MT9M111_OPMODE_AUTOEXPO_EN (1 << 14) 92#define MT9M111_OPMODE_AUTOEXPO_EN (1 << 14)
93 93#define MT9M111_OPMODE_AUTOWHITEBAL_EN (1 << 1)
94 94
95#define MT9M111_OUTFMT_PROCESSED_BAYER (1 << 14) 95#define MT9M111_OUTFMT_PROCESSED_BAYER (1 << 14)
96#define MT9M111_OUTFMT_BYPASS_IFP (1 << 10) 96#define MT9M111_OUTFMT_BYPASS_IFP (1 << 10)
@@ -128,9 +128,14 @@
128 .colorspace = _colorspace } 128 .colorspace = _colorspace }
129#define RGB_FMT(_name, _depth, _fourcc) \ 129#define RGB_FMT(_name, _depth, _fourcc) \
130 COL_FMT(_name, _depth, _fourcc, V4L2_COLORSPACE_SRGB) 130 COL_FMT(_name, _depth, _fourcc, V4L2_COLORSPACE_SRGB)
131#define JPG_FMT(_name, _depth, _fourcc) \
132 COL_FMT(_name, _depth, _fourcc, V4L2_COLORSPACE_JPEG)
131 133
132static const struct soc_camera_data_format mt9m111_colour_formats[] = { 134static const struct soc_camera_data_format mt9m111_colour_formats[] = {
133 COL_FMT("YCrYCb 8 bit", 8, V4L2_PIX_FMT_YUYV, V4L2_COLORSPACE_JPEG), 135 JPG_FMT("CbYCrY 16 bit", 16, V4L2_PIX_FMT_UYVY),
136 JPG_FMT("CrYCbY 16 bit", 16, V4L2_PIX_FMT_VYUY),
137 JPG_FMT("YCbYCr 16 bit", 16, V4L2_PIX_FMT_YUYV),
138 JPG_FMT("YCrYCb 16 bit", 16, V4L2_PIX_FMT_YVYU),
134 RGB_FMT("RGB 565", 16, V4L2_PIX_FMT_RGB565), 139 RGB_FMT("RGB 565", 16, V4L2_PIX_FMT_RGB565),
135 RGB_FMT("RGB 555", 16, V4L2_PIX_FMT_RGB555), 140 RGB_FMT("RGB 555", 16, V4L2_PIX_FMT_RGB555),
136 RGB_FMT("Bayer (sRGB) 10 bit", 10, V4L2_PIX_FMT_SBGGR16), 141 RGB_FMT("Bayer (sRGB) 10 bit", 10, V4L2_PIX_FMT_SBGGR16),
@@ -145,7 +150,7 @@ enum mt9m111_context {
145struct mt9m111 { 150struct mt9m111 {
146 struct i2c_client *client; 151 struct i2c_client *client;
147 struct soc_camera_device icd; 152 struct soc_camera_device icd;
148 int model; /* V4L2_IDENT_MT9M111* codes from v4l2-chip-ident.h */ 153 int model; /* V4L2_IDENT_MT9M11x* codes from v4l2-chip-ident.h */
149 enum mt9m111_context context; 154 enum mt9m111_context context;
150 unsigned int left, top, width, height; 155 unsigned int left, top, width, height;
151 u32 pixfmt; 156 u32 pixfmt;
@@ -158,6 +163,7 @@ struct mt9m111 {
158 unsigned int swap_rgb_red_blue:1; 163 unsigned int swap_rgb_red_blue:1;
159 unsigned int swap_yuv_y_chromas:1; 164 unsigned int swap_yuv_y_chromas:1;
160 unsigned int swap_yuv_cb_cr:1; 165 unsigned int swap_yuv_cb_cr:1;
166 unsigned int autowhitebalance:1;
161}; 167};
162 168
163static int reg_page_map_set(struct i2c_client *client, const u16 reg) 169static int reg_page_map_set(struct i2c_client *client, const u16 reg)
@@ -410,9 +416,13 @@ static int mt9m111_stop_capture(struct soc_camera_device *icd)
410 416
411static unsigned long mt9m111_query_bus_param(struct soc_camera_device *icd) 417static unsigned long mt9m111_query_bus_param(struct soc_camera_device *icd)
412{ 418{
413 return SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING | 419 struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
420 struct soc_camera_link *icl = mt9m111->client->dev.platform_data;
421 unsigned long flags = SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING |
414 SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_HIGH | 422 SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_HIGH |
415 SOCAM_DATAWIDTH_8; 423 SOCAM_DATAWIDTH_8;
424
425 return soc_camera_apply_sensor_flags(icl, flags);
416} 426}
417 427
418static int mt9m111_set_bus_param(struct soc_camera_device *icd, unsigned long f) 428static int mt9m111_set_bus_param(struct soc_camera_device *icd, unsigned long f)
@@ -438,7 +448,24 @@ static int mt9m111_set_pixfmt(struct soc_camera_device *icd, u32 pixfmt)
438 case V4L2_PIX_FMT_RGB565: 448 case V4L2_PIX_FMT_RGB565:
439 ret = mt9m111_setfmt_rgb565(icd); 449 ret = mt9m111_setfmt_rgb565(icd);
440 break; 450 break;
451 case V4L2_PIX_FMT_UYVY:
452 mt9m111->swap_yuv_y_chromas = 0;
453 mt9m111->swap_yuv_cb_cr = 0;
454 ret = mt9m111_setfmt_yuv(icd);
455 break;
456 case V4L2_PIX_FMT_VYUY:
457 mt9m111->swap_yuv_y_chromas = 0;
458 mt9m111->swap_yuv_cb_cr = 1;
459 ret = mt9m111_setfmt_yuv(icd);
460 break;
441 case V4L2_PIX_FMT_YUYV: 461 case V4L2_PIX_FMT_YUYV:
462 mt9m111->swap_yuv_y_chromas = 1;
463 mt9m111->swap_yuv_cb_cr = 0;
464 ret = mt9m111_setfmt_yuv(icd);
465 break;
466 case V4L2_PIX_FMT_YVYU:
467 mt9m111->swap_yuv_y_chromas = 1;
468 mt9m111->swap_yuv_cb_cr = 1;
442 ret = mt9m111_setfmt_yuv(icd); 469 ret = mt9m111_setfmt_yuv(icd);
443 break; 470 break;
444 default: 471 default:
@@ -452,8 +479,8 @@ static int mt9m111_set_pixfmt(struct soc_camera_device *icd, u32 pixfmt)
452 return ret; 479 return ret;
453} 480}
454 481
455static int mt9m111_set_fmt_cap(struct soc_camera_device *icd, 482static int mt9m111_set_fmt(struct soc_camera_device *icd,
456 __u32 pixfmt, struct v4l2_rect *rect) 483 __u32 pixfmt, struct v4l2_rect *rect)
457{ 484{
458 struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); 485 struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
459 int ret; 486 int ret;
@@ -473,13 +500,15 @@ static int mt9m111_set_fmt_cap(struct soc_camera_device *icd,
473 return ret; 500 return ret;
474} 501}
475 502
476static int mt9m111_try_fmt_cap(struct soc_camera_device *icd, 503static int mt9m111_try_fmt(struct soc_camera_device *icd,
477 struct v4l2_format *f) 504 struct v4l2_format *f)
478{ 505{
479 if (f->fmt.pix.height > MT9M111_MAX_HEIGHT) 506 struct v4l2_pix_format *pix = &f->fmt.pix;
480 f->fmt.pix.height = MT9M111_MAX_HEIGHT; 507
481 if (f->fmt.pix.width > MT9M111_MAX_WIDTH) 508 if (pix->height > MT9M111_MAX_HEIGHT)
482 f->fmt.pix.width = MT9M111_MAX_WIDTH; 509 pix->height = MT9M111_MAX_HEIGHT;
510 if (pix->width > MT9M111_MAX_WIDTH)
511 pix->width = MT9M111_MAX_WIDTH;
483 512
484 return 0; 513 return 0;
485} 514}
@@ -597,8 +626,8 @@ static struct soc_camera_ops mt9m111_ops = {
597 .release = mt9m111_release, 626 .release = mt9m111_release,
598 .start_capture = mt9m111_start_capture, 627 .start_capture = mt9m111_start_capture,
599 .stop_capture = mt9m111_stop_capture, 628 .stop_capture = mt9m111_stop_capture,
600 .set_fmt_cap = mt9m111_set_fmt_cap, 629 .set_fmt = mt9m111_set_fmt,
601 .try_fmt_cap = mt9m111_try_fmt_cap, 630 .try_fmt = mt9m111_try_fmt,
602 .query_bus_param = mt9m111_query_bus_param, 631 .query_bus_param = mt9m111_query_bus_param,
603 .set_bus_param = mt9m111_set_bus_param, 632 .set_bus_param = mt9m111_set_bus_param,
604 .controls = mt9m111_controls, 633 .controls = mt9m111_controls,
@@ -634,18 +663,15 @@ static int mt9m111_set_flip(struct soc_camera_device *icd, int flip, int mask)
634 663
635static int mt9m111_get_global_gain(struct soc_camera_device *icd) 664static int mt9m111_get_global_gain(struct soc_camera_device *icd)
636{ 665{
637 unsigned int data, gain; 666 int data;
638 667
639 data = reg_read(GLOBAL_GAIN); 668 data = reg_read(GLOBAL_GAIN);
640 if (data >= 0) 669 if (data >= 0)
641 gain = ((data & (1 << 10)) * 2) 670 return (data & 0x2f) * (1 << ((data >> 10) & 1)) *
642 | ((data & (1 << 9)) * 2) 671 (1 << ((data >> 9) & 1));
643 | (data & 0x2f); 672 return data;
644 else
645 gain = data;
646
647 return gain;
648} 673}
674
649static int mt9m111_set_global_gain(struct soc_camera_device *icd, int gain) 675static int mt9m111_set_global_gain(struct soc_camera_device *icd, int gain)
650{ 676{
651 u16 val; 677 u16 val;
@@ -679,6 +705,23 @@ static int mt9m111_set_autoexposure(struct soc_camera_device *icd, int on)
679 705
680 return ret; 706 return ret;
681} 707}
708
709static int mt9m111_set_autowhitebalance(struct soc_camera_device *icd, int on)
710{
711 struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
712 int ret;
713
714 if (on)
715 ret = reg_set(OPER_MODE_CTRL, MT9M111_OPMODE_AUTOWHITEBAL_EN);
716 else
717 ret = reg_clear(OPER_MODE_CTRL, MT9M111_OPMODE_AUTOWHITEBAL_EN);
718
719 if (!ret)
720 mt9m111->autowhitebalance = on;
721
722 return ret;
723}
724
682static int mt9m111_get_control(struct soc_camera_device *icd, 725static int mt9m111_get_control(struct soc_camera_device *icd,
683 struct v4l2_control *ctrl) 726 struct v4l2_control *ctrl)
684{ 727{
@@ -715,6 +758,9 @@ static int mt9m111_get_control(struct soc_camera_device *icd,
715 case V4L2_CID_EXPOSURE_AUTO: 758 case V4L2_CID_EXPOSURE_AUTO:
716 ctrl->value = mt9m111->autoexposure; 759 ctrl->value = mt9m111->autoexposure;
717 break; 760 break;
761 case V4L2_CID_AUTO_WHITE_BALANCE:
762 ctrl->value = mt9m111->autowhitebalance;
763 break;
718 } 764 }
719 return 0; 765 return 0;
720} 766}
@@ -748,6 +794,9 @@ static int mt9m111_set_control(struct soc_camera_device *icd,
748 case V4L2_CID_EXPOSURE_AUTO: 794 case V4L2_CID_EXPOSURE_AUTO:
749 ret = mt9m111_set_autoexposure(icd, ctrl->value); 795 ret = mt9m111_set_autoexposure(icd, ctrl->value);
750 break; 796 break;
797 case V4L2_CID_AUTO_WHITE_BALANCE:
798 ret = mt9m111_set_autowhitebalance(icd, ctrl->value);
799 break;
751 default: 800 default:
752 ret = -EINVAL; 801 ret = -EINVAL;
753 } 802 }
@@ -766,6 +815,7 @@ static int mt9m111_restore_state(struct soc_camera_device *icd)
766 mt9m111_set_flip(icd, mt9m111->vflip, MT9M111_RMB_MIRROR_ROWS); 815 mt9m111_set_flip(icd, mt9m111->vflip, MT9M111_RMB_MIRROR_ROWS);
767 mt9m111_set_global_gain(icd, icd->gain); 816 mt9m111_set_global_gain(icd, icd->gain);
768 mt9m111_set_autoexposure(icd, mt9m111->autoexposure); 817 mt9m111_set_autoexposure(icd, mt9m111->autoexposure);
818 mt9m111_set_autowhitebalance(icd, mt9m111->autowhitebalance);
769 return 0; 819 return 0;
770} 820}
771 821
@@ -798,7 +848,7 @@ static int mt9m111_init(struct soc_camera_device *icd)
798 if (!ret) 848 if (!ret)
799 ret = mt9m111_set_autoexposure(icd, mt9m111->autoexposure); 849 ret = mt9m111_set_autoexposure(icd, mt9m111->autoexposure);
800 if (ret) 850 if (ret)
801 dev_err(&icd->dev, "mt9m111 init failed: %d\n", ret); 851 dev_err(&icd->dev, "mt9m11x init failed: %d\n", ret);
802 return ret; 852 return ret;
803} 853}
804 854
@@ -808,7 +858,7 @@ static int mt9m111_release(struct soc_camera_device *icd)
808 858
809 ret = mt9m111_disable(icd); 859 ret = mt9m111_disable(icd);
810 if (ret < 0) 860 if (ret < 0)
811 dev_err(&icd->dev, "mt9m111 release failed: %d\n", ret); 861 dev_err(&icd->dev, "mt9m11x release failed: %d\n", ret);
812 862
813 return ret; 863 return ret;
814} 864}
@@ -841,25 +891,30 @@ static int mt9m111_video_probe(struct soc_camera_device *icd)
841 data = reg_read(CHIP_VERSION); 891 data = reg_read(CHIP_VERSION);
842 892
843 switch (data) { 893 switch (data) {
844 case 0x143a: 894 case 0x143a: /* MT9M111 */
845 mt9m111->model = V4L2_IDENT_MT9M111; 895 mt9m111->model = V4L2_IDENT_MT9M111;
846 icd->formats = mt9m111_colour_formats; 896 break;
847 icd->num_formats = ARRAY_SIZE(mt9m111_colour_formats); 897 case 0x148c: /* MT9M112 */
898 mt9m111->model = V4L2_IDENT_MT9M112;
848 break; 899 break;
849 default: 900 default:
850 ret = -ENODEV; 901 ret = -ENODEV;
851 dev_err(&icd->dev, 902 dev_err(&icd->dev,
852 "No MT9M111 chip detected, register read %x\n", data); 903 "No MT9M11x chip detected, register read %x\n", data);
853 goto ei2c; 904 goto ei2c;
854 } 905 }
855 906
856 dev_info(&icd->dev, "Detected a MT9M111 chip ID 0x143a\n"); 907 icd->formats = mt9m111_colour_formats;
908 icd->num_formats = ARRAY_SIZE(mt9m111_colour_formats);
909
910 dev_info(&icd->dev, "Detected a MT9M11x chip ID %x\n", data);
857 911
858 ret = soc_camera_video_start(icd); 912 ret = soc_camera_video_start(icd);
859 if (ret) 913 if (ret)
860 goto eisis; 914 goto eisis;
861 915
862 mt9m111->autoexposure = 1; 916 mt9m111->autoexposure = 1;
917 mt9m111->autowhitebalance = 1;
863 918
864 mt9m111->swap_rgb_even_odd = 1; 919 mt9m111->swap_rgb_even_odd = 1;
865 mt9m111->swap_rgb_red_blue = 1; 920 mt9m111->swap_rgb_red_blue = 1;
@@ -889,7 +944,7 @@ static int mt9m111_probe(struct i2c_client *client,
889 int ret; 944 int ret;
890 945
891 if (!icl) { 946 if (!icl) {
892 dev_err(&client->dev, "MT9M111 driver needs platform data\n"); 947 dev_err(&client->dev, "MT9M11x driver needs platform data\n");
893 return -EINVAL; 948 return -EINVAL;
894 } 949 }
895 950
@@ -968,6 +1023,6 @@ static void __exit mt9m111_mod_exit(void)
968module_init(mt9m111_mod_init); 1023module_init(mt9m111_mod_init);
969module_exit(mt9m111_mod_exit); 1024module_exit(mt9m111_mod_exit);
970 1025
971MODULE_DESCRIPTION("Micron MT9M111 Camera driver"); 1026MODULE_DESCRIPTION("Micron MT9M111/MT9M112 Camera driver");
972MODULE_AUTHOR("Robert Jarzmik"); 1027MODULE_AUTHOR("Robert Jarzmik");
973MODULE_LICENSE("GPL"); 1028MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/mt9t031.c b/drivers/media/video/mt9t031.c
new file mode 100644
index 000000000000..1a9d53966d06
--- /dev/null
+++ b/drivers/media/video/mt9t031.c
@@ -0,0 +1,736 @@
1/*
2 * Driver for MT9T031 CMOS Image Sensor from Micron
3 *
4 * Copyright (C) 2008, Guennadi Liakhovetski, DENX Software Engineering <lg@denx.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/videodev2.h>
12#include <linux/slab.h>
13#include <linux/i2c.h>
14#include <linux/log2.h>
15
16#include <media/v4l2-common.h>
17#include <media/v4l2-chip-ident.h>
18#include <media/soc_camera.h>
19
20/* mt9t031 i2c address 0x5d
21 * The platform has to define i2c_board_info
22 * and call i2c_register_board_info() */
23
24/* mt9t031 selected register addresses */
25#define MT9T031_CHIP_VERSION 0x00
26#define MT9T031_ROW_START 0x01
27#define MT9T031_COLUMN_START 0x02
28#define MT9T031_WINDOW_HEIGHT 0x03
29#define MT9T031_WINDOW_WIDTH 0x04
30#define MT9T031_HORIZONTAL_BLANKING 0x05
31#define MT9T031_VERTICAL_BLANKING 0x06
32#define MT9T031_OUTPUT_CONTROL 0x07
33#define MT9T031_SHUTTER_WIDTH_UPPER 0x08
34#define MT9T031_SHUTTER_WIDTH 0x09
35#define MT9T031_PIXEL_CLOCK_CONTROL 0x0a
36#define MT9T031_FRAME_RESTART 0x0b
37#define MT9T031_SHUTTER_DELAY 0x0c
38#define MT9T031_RESET 0x0d
39#define MT9T031_READ_MODE_1 0x1e
40#define MT9T031_READ_MODE_2 0x20
41#define MT9T031_READ_MODE_3 0x21
42#define MT9T031_ROW_ADDRESS_MODE 0x22
43#define MT9T031_COLUMN_ADDRESS_MODE 0x23
44#define MT9T031_GLOBAL_GAIN 0x35
45#define MT9T031_CHIP_ENABLE 0xF8
46
47#define MT9T031_MAX_HEIGHT 1536
48#define MT9T031_MAX_WIDTH 2048
49#define MT9T031_MIN_HEIGHT 2
50#define MT9T031_MIN_WIDTH 2
51#define MT9T031_HORIZONTAL_BLANK 142
52#define MT9T031_VERTICAL_BLANK 25
53#define MT9T031_COLUMN_SKIP 32
54#define MT9T031_ROW_SKIP 20
55
56#define MT9T031_BUS_PARAM (SOCAM_PCLK_SAMPLE_RISING | \
57 SOCAM_PCLK_SAMPLE_FALLING | SOCAM_HSYNC_ACTIVE_HIGH | \
58 SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_DATA_ACTIVE_HIGH | \
59 SOCAM_MASTER | SOCAM_DATAWIDTH_10)
60
61static const struct soc_camera_data_format mt9t031_colour_formats[] = {
62 {
63 .name = "Bayer (sRGB) 10 bit",
64 .depth = 10,
65 .fourcc = V4L2_PIX_FMT_SGRBG10,
66 .colorspace = V4L2_COLORSPACE_SRGB,
67 }
68};
69
70struct mt9t031 {
71 struct i2c_client *client;
72 struct soc_camera_device icd;
73 int model; /* V4L2_IDENT_MT9T031* codes from v4l2-chip-ident.h */
74 unsigned char autoexposure;
75 u16 xskip;
76 u16 yskip;
77};
78
79static int reg_read(struct soc_camera_device *icd, const u8 reg)
80{
81 struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd);
82 struct i2c_client *client = mt9t031->client;
83 s32 data = i2c_smbus_read_word_data(client, reg);
84 return data < 0 ? data : swab16(data);
85}
86
87static int reg_write(struct soc_camera_device *icd, const u8 reg,
88 const u16 data)
89{
90 struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd);
91 return i2c_smbus_write_word_data(mt9t031->client, reg, swab16(data));
92}
93
94static int reg_set(struct soc_camera_device *icd, const u8 reg,
95 const u16 data)
96{
97 int ret;
98
99 ret = reg_read(icd, reg);
100 if (ret < 0)
101 return ret;
102 return reg_write(icd, reg, ret | data);
103}
104
105static int reg_clear(struct soc_camera_device *icd, const u8 reg,
106 const u16 data)
107{
108 int ret;
109
110 ret = reg_read(icd, reg);
111 if (ret < 0)
112 return ret;
113 return reg_write(icd, reg, ret & ~data);
114}
115
116static int set_shutter(struct soc_camera_device *icd, const u32 data)
117{
118 int ret;
119
120 ret = reg_write(icd, MT9T031_SHUTTER_WIDTH_UPPER, data >> 16);
121
122 if (ret >= 0)
123 ret = reg_write(icd, MT9T031_SHUTTER_WIDTH, data & 0xffff);
124
125 return ret;
126}
127
128static int get_shutter(struct soc_camera_device *icd, u32 *data)
129{
130 int ret;
131
132 ret = reg_read(icd, MT9T031_SHUTTER_WIDTH_UPPER);
133 *data = ret << 16;
134
135 if (ret >= 0)
136 ret = reg_read(icd, MT9T031_SHUTTER_WIDTH);
137 *data |= ret & 0xffff;
138
139 return ret < 0 ? ret : 0;
140}
141
142static int mt9t031_init(struct soc_camera_device *icd)
143{
144 int ret;
145
146 /* Disable chip output, synchronous option update */
147 dev_dbg(icd->vdev->parent, "%s\n", __func__);
148
149 ret = reg_write(icd, MT9T031_RESET, 1);
150 if (ret >= 0)
151 ret = reg_write(icd, MT9T031_RESET, 0);
152 if (ret >= 0)
153 ret = reg_clear(icd, MT9T031_OUTPUT_CONTROL, 3);
154
155 return ret >= 0 ? 0 : -EIO;
156}
157
158static int mt9t031_release(struct soc_camera_device *icd)
159{
160 /* Disable the chip */
161 reg_clear(icd, MT9T031_OUTPUT_CONTROL, 3);
162 return 0;
163}
164
165static int mt9t031_start_capture(struct soc_camera_device *icd)
166{
167 /* Switch to master "normal" mode */
168 if (reg_set(icd, MT9T031_OUTPUT_CONTROL, 3) < 0)
169 return -EIO;
170 return 0;
171}
172
173static int mt9t031_stop_capture(struct soc_camera_device *icd)
174{
175 /* Stop sensor readout */
176 if (reg_clear(icd, MT9T031_OUTPUT_CONTROL, 3) < 0)
177 return -EIO;
178 return 0;
179}
180
181static int mt9t031_set_bus_param(struct soc_camera_device *icd,
182 unsigned long flags)
183{
184 /* The caller should have queried our parameters, check anyway */
185 if (flags & ~MT9T031_BUS_PARAM)
186 return -EINVAL;
187
188 if (flags & SOCAM_PCLK_SAMPLE_FALLING)
189 reg_set(icd, MT9T031_PIXEL_CLOCK_CONTROL, 0x8000);
190 else
191 reg_clear(icd, MT9T031_PIXEL_CLOCK_CONTROL, 0x8000);
192
193 return 0;
194}
195
196static unsigned long mt9t031_query_bus_param(struct soc_camera_device *icd)
197{
198 struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd);
199 struct soc_camera_link *icl = mt9t031->client->dev.platform_data;
200
201 return soc_camera_apply_sensor_flags(icl, MT9T031_BUS_PARAM);
202}
203
204static int mt9t031_set_fmt(struct soc_camera_device *icd,
205 __u32 pixfmt, struct v4l2_rect *rect)
206{
207 struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd);
208 int ret;
209 const u16 hblank = MT9T031_HORIZONTAL_BLANK,
210 vblank = MT9T031_VERTICAL_BLANK;
211 u16 xbin, xskip = mt9t031->xskip, ybin, yskip = mt9t031->yskip,
212 width = rect->width * xskip, height = rect->height * yskip;
213
214 if (pixfmt) {
215 /* S_FMT - use binning and skipping for scaling, recalculate */
216 /* Is this more optimal than just a division? */
217 for (xskip = 8; xskip > 1; xskip--)
218 if (rect->width * xskip <= icd->width_max)
219 break;
220
221 for (yskip = 8; yskip > 1; yskip--)
222 if (rect->height * yskip <= icd->height_max)
223 break;
224
225 width = rect->width * xskip;
226 height = rect->height * yskip;
227
228 dev_dbg(&icd->dev, "xskip %u, width %u, yskip %u, height %u\n",
229 xskip, width, yskip, height);
230 }
231
232 xbin = min(xskip, (u16)3);
233 ybin = min(yskip, (u16)3);
234
235 /* Make sure we don't exceed frame limits */
236 if (rect->left + width > icd->width_max)
237 rect->left = (icd->width_max - width) / 2;
238
239 if (rect->top + height > icd->height_max)
240 rect->top = (icd->height_max - height) / 2;
241
242 /* Could just do roundup(rect->left, [xy]bin); but this is cheaper */
243 switch (xbin) {
244 case 2:
245 rect->left = (rect->left + 1) & ~1;
246 break;
247 case 3:
248 rect->left = roundup(rect->left, 3);
249 }
250
251 switch (ybin) {
252 case 2:
253 rect->top = (rect->top + 1) & ~1;
254 break;
255 case 3:
256 rect->top = roundup(rect->top, 3);
257 }
258
259 /* Blanking and start values - default... */
260 ret = reg_write(icd, MT9T031_HORIZONTAL_BLANKING, hblank);
261 if (ret >= 0)
262 ret = reg_write(icd, MT9T031_VERTICAL_BLANKING, vblank);
263
264 if (pixfmt) {
265 /* Binning, skipping */
266 if (ret >= 0)
267 ret = reg_write(icd, MT9T031_COLUMN_ADDRESS_MODE,
268 ((xbin - 1) << 4) | (xskip - 1));
269 if (ret >= 0)
270 ret = reg_write(icd, MT9T031_ROW_ADDRESS_MODE,
271 ((ybin - 1) << 4) | (yskip - 1));
272 }
273 dev_dbg(&icd->dev, "new left %u, top %u\n", rect->left, rect->top);
274
275 /* The caller provides a supported format, as guaranteed by
276 * icd->try_fmt_cap(), soc_camera_s_crop() and soc_camera_cropcap() */
277 if (ret >= 0)
278 ret = reg_write(icd, MT9T031_COLUMN_START, rect->left);
279 if (ret >= 0)
280 ret = reg_write(icd, MT9T031_ROW_START, rect->top);
281 if (ret >= 0)
282 ret = reg_write(icd, MT9T031_WINDOW_WIDTH, width - 1);
283 if (ret >= 0)
284 ret = reg_write(icd, MT9T031_WINDOW_HEIGHT,
285 height + icd->y_skip_top - 1);
286 if (ret >= 0 && mt9t031->autoexposure) {
287 ret = set_shutter(icd, height + icd->y_skip_top + vblank);
288 if (ret >= 0) {
289 const u32 shutter_max = MT9T031_MAX_HEIGHT + vblank;
290 const struct v4l2_queryctrl *qctrl =
291 soc_camera_find_qctrl(icd->ops,
292 V4L2_CID_EXPOSURE);
293 icd->exposure = (shutter_max / 2 + (height +
294 icd->y_skip_top + vblank - 1) *
295 (qctrl->maximum - qctrl->minimum)) /
296 shutter_max + qctrl->minimum;
297 }
298 }
299
300 if (!ret && pixfmt) {
301 mt9t031->xskip = xskip;
302 mt9t031->yskip = yskip;
303 }
304
305 return ret < 0 ? ret : 0;
306}
307
308static int mt9t031_try_fmt(struct soc_camera_device *icd,
309 struct v4l2_format *f)
310{
311 struct v4l2_pix_format *pix = &f->fmt.pix;
312
313 if (pix->height < icd->height_min)
314 pix->height = icd->height_min;
315 if (pix->height > icd->height_max)
316 pix->height = icd->height_max;
317 if (pix->width < icd->width_min)
318 pix->width = icd->width_min;
319 if (pix->width > icd->width_max)
320 pix->width = icd->width_max;
321
322 pix->width &= ~0x01; /* has to be even */
323 pix->height &= ~0x01; /* has to be even */
324
325 return 0;
326}
327
328static int mt9t031_get_chip_id(struct soc_camera_device *icd,
329 struct v4l2_chip_ident *id)
330{
331 struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd);
332
333 if (id->match_type != V4L2_CHIP_MATCH_I2C_ADDR)
334 return -EINVAL;
335
336 if (id->match_chip != mt9t031->client->addr)
337 return -ENODEV;
338
339 id->ident = mt9t031->model;
340 id->revision = 0;
341
342 return 0;
343}
344
345#ifdef CONFIG_VIDEO_ADV_DEBUG
346static int mt9t031_get_register(struct soc_camera_device *icd,
347 struct v4l2_register *reg)
348{
349 struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd);
350
351 if (reg->match_type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff)
352 return -EINVAL;
353
354 if (reg->match_chip != mt9t031->client->addr)
355 return -ENODEV;
356
357 reg->val = reg_read(icd, reg->reg);
358
359 if (reg->val > 0xffff)
360 return -EIO;
361
362 return 0;
363}
364
365static int mt9t031_set_register(struct soc_camera_device *icd,
366 struct v4l2_register *reg)
367{
368 struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd);
369
370 if (reg->match_type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff)
371 return -EINVAL;
372
373 if (reg->match_chip != mt9t031->client->addr)
374 return -ENODEV;
375
376 if (reg_write(icd, reg->reg, reg->val) < 0)
377 return -EIO;
378
379 return 0;
380}
381#endif
382
383static const struct v4l2_queryctrl mt9t031_controls[] = {
384 {
385 .id = V4L2_CID_VFLIP,
386 .type = V4L2_CTRL_TYPE_BOOLEAN,
387 .name = "Flip Vertically",
388 .minimum = 0,
389 .maximum = 1,
390 .step = 1,
391 .default_value = 0,
392 }, {
393 .id = V4L2_CID_GAIN,
394 .type = V4L2_CTRL_TYPE_INTEGER,
395 .name = "Gain",
396 .minimum = 0,
397 .maximum = 127,
398 .step = 1,
399 .default_value = 64,
400 .flags = V4L2_CTRL_FLAG_SLIDER,
401 }, {
402 .id = V4L2_CID_EXPOSURE,
403 .type = V4L2_CTRL_TYPE_INTEGER,
404 .name = "Exposure",
405 .minimum = 1,
406 .maximum = 255,
407 .step = 1,
408 .default_value = 255,
409 .flags = V4L2_CTRL_FLAG_SLIDER,
410 }, {
411 .id = V4L2_CID_EXPOSURE_AUTO,
412 .type = V4L2_CTRL_TYPE_BOOLEAN,
413 .name = "Automatic Exposure",
414 .minimum = 0,
415 .maximum = 1,
416 .step = 1,
417 .default_value = 1,
418 }
419};
420
421static int mt9t031_video_probe(struct soc_camera_device *);
422static void mt9t031_video_remove(struct soc_camera_device *);
423static int mt9t031_get_control(struct soc_camera_device *, struct v4l2_control *);
424static int mt9t031_set_control(struct soc_camera_device *, struct v4l2_control *);
425
426static struct soc_camera_ops mt9t031_ops = {
427 .owner = THIS_MODULE,
428 .probe = mt9t031_video_probe,
429 .remove = mt9t031_video_remove,
430 .init = mt9t031_init,
431 .release = mt9t031_release,
432 .start_capture = mt9t031_start_capture,
433 .stop_capture = mt9t031_stop_capture,
434 .set_fmt = mt9t031_set_fmt,
435 .try_fmt = mt9t031_try_fmt,
436 .set_bus_param = mt9t031_set_bus_param,
437 .query_bus_param = mt9t031_query_bus_param,
438 .controls = mt9t031_controls,
439 .num_controls = ARRAY_SIZE(mt9t031_controls),
440 .get_control = mt9t031_get_control,
441 .set_control = mt9t031_set_control,
442 .get_chip_id = mt9t031_get_chip_id,
443#ifdef CONFIG_VIDEO_ADV_DEBUG
444 .get_register = mt9t031_get_register,
445 .set_register = mt9t031_set_register,
446#endif
447};
448
449static int mt9t031_get_control(struct soc_camera_device *icd, struct v4l2_control *ctrl)
450{
451 struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd);
452 int data;
453
454 switch (ctrl->id) {
455 case V4L2_CID_VFLIP:
456 data = reg_read(icd, MT9T031_READ_MODE_2);
457 if (data < 0)
458 return -EIO;
459 ctrl->value = !!(data & 0x8000);
460 break;
461 case V4L2_CID_HFLIP:
462 data = reg_read(icd, MT9T031_READ_MODE_2);
463 if (data < 0)
464 return -EIO;
465 ctrl->value = !!(data & 0x4000);
466 break;
467 case V4L2_CID_EXPOSURE_AUTO:
468 ctrl->value = mt9t031->autoexposure;
469 break;
470 }
471 return 0;
472}
473
474static int mt9t031_set_control(struct soc_camera_device *icd, struct v4l2_control *ctrl)
475{
476 struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd);
477 const struct v4l2_queryctrl *qctrl;
478 int data;
479
480 qctrl = soc_camera_find_qctrl(&mt9t031_ops, ctrl->id);
481
482 if (!qctrl)
483 return -EINVAL;
484
485 switch (ctrl->id) {
486 case V4L2_CID_VFLIP:
487 if (ctrl->value)
488 data = reg_set(icd, MT9T031_READ_MODE_2, 0x8000);
489 else
490 data = reg_clear(icd, MT9T031_READ_MODE_2, 0x8000);
491 if (data < 0)
492 return -EIO;
493 break;
494 case V4L2_CID_HFLIP:
495 if (ctrl->value)
496 data = reg_set(icd, MT9T031_READ_MODE_2, 0x4000);
497 else
498 data = reg_clear(icd, MT9T031_READ_MODE_2, 0x4000);
499 if (data < 0)
500 return -EIO;
501 break;
502 case V4L2_CID_GAIN:
503 if (ctrl->value > qctrl->maximum || ctrl->value < qctrl->minimum)
504 return -EINVAL;
505 /* See Datasheet Table 7, Gain settings. */
506 if (ctrl->value <= qctrl->default_value) {
507 /* Pack it into 0..1 step 0.125, register values 0..8 */
508 unsigned long range = qctrl->default_value - qctrl->minimum;
509 data = ((ctrl->value - qctrl->minimum) * 8 + range / 2) / range;
510
511 dev_dbg(&icd->dev, "Setting gain %d\n", data);
512 data = reg_write(icd, MT9T031_GLOBAL_GAIN, data);
513 if (data < 0)
514 return -EIO;
515 } else {
516 /* Pack it into 1.125..15 variable step, register values 9..67 */
517 /* We assume qctrl->maximum - qctrl->default_value - 1 > 0 */
518 unsigned long range = qctrl->maximum - qctrl->default_value - 1;
519 unsigned long gain = ((ctrl->value - qctrl->default_value - 1) *
520 111 + range / 2) / range + 9;
521
522 if (gain <= 32)
523 data = gain;
524 else if (gain <= 64)
525 data = ((gain - 32) * 16 + 16) / 32 + 80;
526 else
527 data = ((gain - 64) * 7 + 28) / 56 + 96;
528
529 dev_dbg(&icd->dev, "Setting gain from %d to %d\n",
530 reg_read(icd, MT9T031_GLOBAL_GAIN), data);
531 data = reg_write(icd, MT9T031_GLOBAL_GAIN, data);
532 if (data < 0)
533 return -EIO;
534 }
535
536 /* Success */
537 icd->gain = ctrl->value;
538 break;
539 case V4L2_CID_EXPOSURE:
540 /* mt9t031 has maximum == default */
541 if (ctrl->value > qctrl->maximum || ctrl->value < qctrl->minimum)
542 return -EINVAL;
543 else {
544 const unsigned long range = qctrl->maximum - qctrl->minimum;
545 const u32 shutter = ((ctrl->value - qctrl->minimum) * 1048 +
546 range / 2) / range + 1;
547 u32 old;
548
549 get_shutter(icd, &old);
550 dev_dbg(&icd->dev, "Setting shutter width from %u to %u\n",
551 old, shutter);
552 if (set_shutter(icd, shutter) < 0)
553 return -EIO;
554 icd->exposure = ctrl->value;
555 mt9t031->autoexposure = 0;
556 }
557 break;
558 case V4L2_CID_EXPOSURE_AUTO:
559 if (ctrl->value) {
560 const u16 vblank = MT9T031_VERTICAL_BLANK;
561 const u32 shutter_max = MT9T031_MAX_HEIGHT + vblank;
562 if (set_shutter(icd, icd->height +
563 icd->y_skip_top + vblank) < 0)
564 return -EIO;
565 qctrl = soc_camera_find_qctrl(icd->ops, V4L2_CID_EXPOSURE);
566 icd->exposure = (shutter_max / 2 + (icd->height +
567 icd->y_skip_top + vblank - 1) *
568 (qctrl->maximum - qctrl->minimum)) /
569 shutter_max + qctrl->minimum;
570 mt9t031->autoexposure = 1;
571 } else
572 mt9t031->autoexposure = 0;
573 break;
574 }
575 return 0;
576}
577
578/* Interface active, can use i2c. If it fails, it can indeed mean, that
579 * this wasn't our capture interface, so, we wait for the right one */
580static int mt9t031_video_probe(struct soc_camera_device *icd)
581{
582 struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd);
583 s32 data;
584 int ret;
585
586 /* We must have a parent by now. And it cannot be a wrong one.
587 * So this entire test is completely redundant. */
588 if (!icd->dev.parent ||
589 to_soc_camera_host(icd->dev.parent)->nr != icd->iface)
590 return -ENODEV;
591
592 /* Enable the chip */
593 data = reg_write(icd, MT9T031_CHIP_ENABLE, 1);
594 dev_dbg(&icd->dev, "write: %d\n", data);
595
596 /* Read out the chip version register */
597 data = reg_read(icd, MT9T031_CHIP_VERSION);
598
599 switch (data) {
600 case 0x1621:
601 mt9t031->model = V4L2_IDENT_MT9T031;
602 icd->formats = mt9t031_colour_formats;
603 icd->num_formats = ARRAY_SIZE(mt9t031_colour_formats);
604 break;
605 default:
606 ret = -ENODEV;
607 dev_err(&icd->dev,
608 "No MT9T031 chip detected, register read %x\n", data);
609 goto ei2c;
610 }
611
612 dev_info(&icd->dev, "Detected a MT9T031 chip ID %x\n", data);
613
614 /* Now that we know the model, we can start video */
615 ret = soc_camera_video_start(icd);
616 if (ret)
617 goto evstart;
618
619 return 0;
620
621evstart:
622ei2c:
623 return ret;
624}
625
626static void mt9t031_video_remove(struct soc_camera_device *icd)
627{
628 struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd);
629
630 dev_dbg(&icd->dev, "Video %x removed: %p, %p\n", mt9t031->client->addr,
631 icd->dev.parent, icd->vdev);
632 soc_camera_video_stop(icd);
633}
634
635static int mt9t031_probe(struct i2c_client *client,
636 const struct i2c_device_id *did)
637{
638 struct mt9t031 *mt9t031;
639 struct soc_camera_device *icd;
640 struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
641 struct soc_camera_link *icl = client->dev.platform_data;
642 int ret;
643
644 if (!icl) {
645 dev_err(&client->dev, "MT9T031 driver needs platform data\n");
646 return -EINVAL;
647 }
648
649 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA)) {
650 dev_warn(&adapter->dev,
651 "I2C-Adapter doesn't support I2C_FUNC_SMBUS_WORD\n");
652 return -EIO;
653 }
654
655 mt9t031 = kzalloc(sizeof(struct mt9t031), GFP_KERNEL);
656 if (!mt9t031)
657 return -ENOMEM;
658
659 mt9t031->client = client;
660 i2c_set_clientdata(client, mt9t031);
661
662 /* Second stage probe - when a capture adapter is there */
663 icd = &mt9t031->icd;
664 icd->ops = &mt9t031_ops;
665 icd->control = &client->dev;
666 icd->x_min = MT9T031_COLUMN_SKIP;
667 icd->y_min = MT9T031_ROW_SKIP;
668 icd->x_current = icd->x_min;
669 icd->y_current = icd->y_min;
670 icd->width_min = MT9T031_MIN_WIDTH;
671 icd->width_max = MT9T031_MAX_WIDTH;
672 icd->height_min = MT9T031_MIN_HEIGHT;
673 icd->height_max = MT9T031_MAX_HEIGHT;
674 icd->y_skip_top = 0;
675 icd->iface = icl->bus_id;
676 /* Simulated autoexposure. If enabled, we calculate shutter width
677 * ourselves in the driver based on vertical blanking and frame width */
678 mt9t031->autoexposure = 1;
679
680 mt9t031->xskip = 1;
681 mt9t031->yskip = 1;
682
683 ret = soc_camera_device_register(icd);
684 if (ret)
685 goto eisdr;
686
687 return 0;
688
689eisdr:
690 i2c_set_clientdata(client, NULL);
691 kfree(mt9t031);
692 return ret;
693}
694
695static int mt9t031_remove(struct i2c_client *client)
696{
697 struct mt9t031 *mt9t031 = i2c_get_clientdata(client);
698
699 soc_camera_device_unregister(&mt9t031->icd);
700 i2c_set_clientdata(client, NULL);
701 kfree(mt9t031);
702
703 return 0;
704}
705
706static const struct i2c_device_id mt9t031_id[] = {
707 { "mt9t031", 0 },
708 { }
709};
710MODULE_DEVICE_TABLE(i2c, mt9t031_id);
711
712static struct i2c_driver mt9t031_i2c_driver = {
713 .driver = {
714 .name = "mt9t031",
715 },
716 .probe = mt9t031_probe,
717 .remove = mt9t031_remove,
718 .id_table = mt9t031_id,
719};
720
721static int __init mt9t031_mod_init(void)
722{
723 return i2c_add_driver(&mt9t031_i2c_driver);
724}
725
726static void __exit mt9t031_mod_exit(void)
727{
728 i2c_del_driver(&mt9t031_i2c_driver);
729}
730
731module_init(mt9t031_mod_init);
732module_exit(mt9t031_mod_exit);
733
734MODULE_DESCRIPTION("Micron MT9T031 Camera driver");
735MODULE_AUTHOR("Guennadi Liakhovetski <lg@denx.de>");
736MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/mt9v022.c b/drivers/media/video/mt9v022.c
index 2584201059d8..14a5f9c21ffa 100644
--- a/drivers/media/video/mt9v022.c
+++ b/drivers/media/video/mt9v022.c
@@ -273,6 +273,7 @@ static int mt9v022_set_bus_param(struct soc_camera_device *icd,
273 unsigned long flags) 273 unsigned long flags)
274{ 274{
275 struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); 275 struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd);
276 struct soc_camera_link *icl = mt9v022->client->dev.platform_data;
276 unsigned int width_flag = flags & SOCAM_DATAWIDTH_MASK; 277 unsigned int width_flag = flags & SOCAM_DATAWIDTH_MASK;
277 int ret; 278 int ret;
278 u16 pixclk = 0; 279 u16 pixclk = 0;
@@ -296,6 +297,8 @@ static int mt9v022_set_bus_param(struct soc_camera_device *icd,
296 mt9v022->datawidth = width_flag == SOCAM_DATAWIDTH_8 ? 8 : 10; 297 mt9v022->datawidth = width_flag == SOCAM_DATAWIDTH_8 ? 8 : 10;
297 } 298 }
298 299
300 flags = soc_camera_apply_sensor_flags(icl, flags);
301
299 if (flags & SOCAM_PCLK_SAMPLE_RISING) 302 if (flags & SOCAM_PCLK_SAMPLE_RISING)
300 pixclk |= 0x10; 303 pixclk |= 0x10;
301 304
@@ -337,14 +340,14 @@ static unsigned long mt9v022_query_bus_param(struct soc_camera_device *icd)
337 width_flag; 340 width_flag;
338} 341}
339 342
340static int mt9v022_set_fmt_cap(struct soc_camera_device *icd, 343static int mt9v022_set_fmt(struct soc_camera_device *icd,
341 __u32 pixfmt, struct v4l2_rect *rect) 344 __u32 pixfmt, struct v4l2_rect *rect)
342{ 345{
343 struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); 346 struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd);
344 int ret; 347 int ret;
345 348
346 /* The caller provides a supported format, as verified per call to 349 /* The caller provides a supported format, as verified per call to
347 * icd->try_fmt_cap(), datawidth is from our supported format list */ 350 * icd->try_fmt(), datawidth is from our supported format list */
348 switch (pixfmt) { 351 switch (pixfmt) {
349 case V4L2_PIX_FMT_GREY: 352 case V4L2_PIX_FMT_GREY:
350 case V4L2_PIX_FMT_Y16: 353 case V4L2_PIX_FMT_Y16:
@@ -400,18 +403,20 @@ static int mt9v022_set_fmt_cap(struct soc_camera_device *icd,
400 return 0; 403 return 0;
401} 404}
402 405
403static int mt9v022_try_fmt_cap(struct soc_camera_device *icd, 406static int mt9v022_try_fmt(struct soc_camera_device *icd,
404 struct v4l2_format *f) 407 struct v4l2_format *f)
405{ 408{
406 if (f->fmt.pix.height < 32 + icd->y_skip_top) 409 struct v4l2_pix_format *pix = &f->fmt.pix;
407 f->fmt.pix.height = 32 + icd->y_skip_top; 410
408 if (f->fmt.pix.height > 480 + icd->y_skip_top) 411 if (pix->height < 32 + icd->y_skip_top)
409 f->fmt.pix.height = 480 + icd->y_skip_top; 412 pix->height = 32 + icd->y_skip_top;
410 if (f->fmt.pix.width < 48) 413 if (pix->height > 480 + icd->y_skip_top)
411 f->fmt.pix.width = 48; 414 pix->height = 480 + icd->y_skip_top;
412 if (f->fmt.pix.width > 752) 415 if (pix->width < 48)
413 f->fmt.pix.width = 752; 416 pix->width = 48;
414 f->fmt.pix.width &= ~0x03; /* ? */ 417 if (pix->width > 752)
418 pix->width = 752;
419 pix->width &= ~0x03; /* ? */
415 420
416 return 0; 421 return 0;
417} 422}
@@ -538,8 +543,8 @@ static struct soc_camera_ops mt9v022_ops = {
538 .release = mt9v022_release, 543 .release = mt9v022_release,
539 .start_capture = mt9v022_start_capture, 544 .start_capture = mt9v022_start_capture,
540 .stop_capture = mt9v022_stop_capture, 545 .stop_capture = mt9v022_stop_capture,
541 .set_fmt_cap = mt9v022_set_fmt_cap, 546 .set_fmt = mt9v022_set_fmt,
542 .try_fmt_cap = mt9v022_try_fmt_cap, 547 .try_fmt = mt9v022_try_fmt,
543 .set_bus_param = mt9v022_set_bus_param, 548 .set_bus_param = mt9v022_set_bus_param,
544 .query_bus_param = mt9v022_query_bus_param, 549 .query_bus_param = mt9v022_query_bus_param,
545 .controls = mt9v022_controls, 550 .controls = mt9v022_controls,
@@ -690,6 +695,7 @@ static int mt9v022_set_control(struct soc_camera_device *icd,
690static int mt9v022_video_probe(struct soc_camera_device *icd) 695static int mt9v022_video_probe(struct soc_camera_device *icd)
691{ 696{
692 struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); 697 struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd);
698 struct soc_camera_link *icl = mt9v022->client->dev.platform_data;
693 s32 data; 699 s32 data;
694 int ret; 700 int ret;
695 701
@@ -725,7 +731,7 @@ static int mt9v022_video_probe(struct soc_camera_device *icd)
725 ret = reg_write(icd, MT9V022_PIXEL_OPERATION_MODE, 4 | 0x11); 731 ret = reg_write(icd, MT9V022_PIXEL_OPERATION_MODE, 4 | 0x11);
726 mt9v022->model = V4L2_IDENT_MT9V022IX7ATC; 732 mt9v022->model = V4L2_IDENT_MT9V022IX7ATC;
727 icd->formats = mt9v022_colour_formats; 733 icd->formats = mt9v022_colour_formats;
728 if (mt9v022->client->dev.platform_data) 734 if (gpio_is_valid(icl->gpio))
729 icd->num_formats = ARRAY_SIZE(mt9v022_colour_formats); 735 icd->num_formats = ARRAY_SIZE(mt9v022_colour_formats);
730 else 736 else
731 icd->num_formats = 1; 737 icd->num_formats = 1;
@@ -733,7 +739,7 @@ static int mt9v022_video_probe(struct soc_camera_device *icd)
733 ret = reg_write(icd, MT9V022_PIXEL_OPERATION_MODE, 0x11); 739 ret = reg_write(icd, MT9V022_PIXEL_OPERATION_MODE, 0x11);
734 mt9v022->model = V4L2_IDENT_MT9V022IX7ATM; 740 mt9v022->model = V4L2_IDENT_MT9V022IX7ATM;
735 icd->formats = mt9v022_monochrome_formats; 741 icd->formats = mt9v022_monochrome_formats;
736 if (mt9v022->client->dev.platform_data) 742 if (gpio_is_valid(icl->gpio))
737 icd->num_formats = ARRAY_SIZE(mt9v022_monochrome_formats); 743 icd->num_formats = ARRAY_SIZE(mt9v022_monochrome_formats);
738 else 744 else
739 icd->num_formats = 1; 745 icd->num_formats = 1;
@@ -760,8 +766,8 @@ static void mt9v022_video_remove(struct soc_camera_device *icd)
760 struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); 766 struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd);
761 767
762 dev_dbg(&icd->dev, "Video %x removed: %p, %p\n", mt9v022->client->addr, 768 dev_dbg(&icd->dev, "Video %x removed: %p, %p\n", mt9v022->client->addr,
763 mt9v022->icd.dev.parent, mt9v022->icd.vdev); 769 icd->dev.parent, icd->vdev);
764 soc_camera_video_stop(&mt9v022->icd); 770 soc_camera_video_stop(icd);
765} 771}
766 772
767static int mt9v022_probe(struct i2c_client *client, 773static int mt9v022_probe(struct i2c_client *client,
diff --git a/drivers/media/video/omap24xxcam-dma.c b/drivers/media/video/omap24xxcam-dma.c
new file mode 100644
index 000000000000..1d54b86c936b
--- /dev/null
+++ b/drivers/media/video/omap24xxcam-dma.c
@@ -0,0 +1,601 @@
1/*
2 * drivers/media/video/omap24xxcam-dma.c
3 *
4 * Copyright (C) 2004 MontaVista Software, Inc.
5 * Copyright (C) 2004 Texas Instruments.
6 * Copyright (C) 2007 Nokia Corporation.
7 *
8 * Contact: Sakari Ailus <sakari.ailus@nokia.com>
9 *
10 * Based on code from Andy Lowe <source@mvista.com> and
11 * David Cohen <david.cohen@indt.org.br>.
12 *
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * version 2 as published by the Free Software Foundation.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
25 * 02110-1301 USA
26 */
27
28#include <linux/kernel.h>
29#include <linux/io.h>
30#include <linux/scatterlist.h>
31
32#include "omap24xxcam.h"
33
34/*
35 *
36 * DMA hardware.
37 *
38 */
39
40/* Ack all interrupt on CSR and IRQSTATUS_L0 */
41static void omap24xxcam_dmahw_ack_all(unsigned long base)
42{
43 u32 csr;
44 int i;
45
46 for (i = 0; i < NUM_CAMDMA_CHANNELS; ++i) {
47 csr = omap24xxcam_reg_in(base, CAMDMA_CSR(i));
48 /* ack interrupt in CSR */
49 omap24xxcam_reg_out(base, CAMDMA_CSR(i), csr);
50 }
51 omap24xxcam_reg_out(base, CAMDMA_IRQSTATUS_L0, 0xf);
52}
53
54/* Ack dmach on CSR and IRQSTATUS_L0 */
55static u32 omap24xxcam_dmahw_ack_ch(unsigned long base, int dmach)
56{
57 u32 csr;
58
59 csr = omap24xxcam_reg_in(base, CAMDMA_CSR(dmach));
60 /* ack interrupt in CSR */
61 omap24xxcam_reg_out(base, CAMDMA_CSR(dmach), csr);
62 /* ack interrupt in IRQSTATUS */
63 omap24xxcam_reg_out(base, CAMDMA_IRQSTATUS_L0, (1 << dmach));
64
65 return csr;
66}
67
68static int omap24xxcam_dmahw_running(unsigned long base, int dmach)
69{
70 return omap24xxcam_reg_in(base, CAMDMA_CCR(dmach)) & CAMDMA_CCR_ENABLE;
71}
72
73static void omap24xxcam_dmahw_transfer_setup(unsigned long base, int dmach,
74 dma_addr_t start, u32 len)
75{
76 omap24xxcam_reg_out(base, CAMDMA_CCR(dmach),
77 CAMDMA_CCR_SEL_SRC_DST_SYNC
78 | CAMDMA_CCR_BS
79 | CAMDMA_CCR_DST_AMODE_POST_INC
80 | CAMDMA_CCR_SRC_AMODE_POST_INC
81 | CAMDMA_CCR_FS
82 | CAMDMA_CCR_WR_ACTIVE
83 | CAMDMA_CCR_RD_ACTIVE
84 | CAMDMA_CCR_SYNCHRO_CAMERA);
85 omap24xxcam_reg_out(base, CAMDMA_CLNK_CTRL(dmach), 0);
86 omap24xxcam_reg_out(base, CAMDMA_CEN(dmach), len);
87 omap24xxcam_reg_out(base, CAMDMA_CFN(dmach), 1);
88 omap24xxcam_reg_out(base, CAMDMA_CSDP(dmach),
89 CAMDMA_CSDP_WRITE_MODE_POSTED
90 | CAMDMA_CSDP_DST_BURST_EN_32
91 | CAMDMA_CSDP_DST_PACKED
92 | CAMDMA_CSDP_SRC_BURST_EN_32
93 | CAMDMA_CSDP_SRC_PACKED
94 | CAMDMA_CSDP_DATA_TYPE_8BITS);
95 omap24xxcam_reg_out(base, CAMDMA_CSSA(dmach), 0);
96 omap24xxcam_reg_out(base, CAMDMA_CDSA(dmach), start);
97 omap24xxcam_reg_out(base, CAMDMA_CSEI(dmach), 0);
98 omap24xxcam_reg_out(base, CAMDMA_CSFI(dmach), DMA_THRESHOLD);
99 omap24xxcam_reg_out(base, CAMDMA_CDEI(dmach), 0);
100 omap24xxcam_reg_out(base, CAMDMA_CDFI(dmach), 0);
101 omap24xxcam_reg_out(base, CAMDMA_CSR(dmach),
102 CAMDMA_CSR_MISALIGNED_ERR
103 | CAMDMA_CSR_SECURE_ERR
104 | CAMDMA_CSR_TRANS_ERR
105 | CAMDMA_CSR_BLOCK
106 | CAMDMA_CSR_DROP);
107 omap24xxcam_reg_out(base, CAMDMA_CICR(dmach),
108 CAMDMA_CICR_MISALIGNED_ERR_IE
109 | CAMDMA_CICR_SECURE_ERR_IE
110 | CAMDMA_CICR_TRANS_ERR_IE
111 | CAMDMA_CICR_BLOCK_IE
112 | CAMDMA_CICR_DROP_IE);
113}
114
115static void omap24xxcam_dmahw_transfer_start(unsigned long base, int dmach)
116{
117 omap24xxcam_reg_out(base, CAMDMA_CCR(dmach),
118 CAMDMA_CCR_SEL_SRC_DST_SYNC
119 | CAMDMA_CCR_BS
120 | CAMDMA_CCR_DST_AMODE_POST_INC
121 | CAMDMA_CCR_SRC_AMODE_POST_INC
122 | CAMDMA_CCR_ENABLE
123 | CAMDMA_CCR_FS
124 | CAMDMA_CCR_SYNCHRO_CAMERA);
125}
126
127static void omap24xxcam_dmahw_transfer_chain(unsigned long base, int dmach,
128 int free_dmach)
129{
130 int prev_dmach, ch;
131
132 if (dmach == 0)
133 prev_dmach = NUM_CAMDMA_CHANNELS - 1;
134 else
135 prev_dmach = dmach - 1;
136 omap24xxcam_reg_out(base, CAMDMA_CLNK_CTRL(prev_dmach),
137 CAMDMA_CLNK_CTRL_ENABLE_LNK | dmach);
138 /* Did we chain the DMA transfer before the previous one
139 * finished?
140 */
141 ch = (dmach + free_dmach) % NUM_CAMDMA_CHANNELS;
142 while (!(omap24xxcam_reg_in(base, CAMDMA_CCR(ch))
143 & CAMDMA_CCR_ENABLE)) {
144 if (ch == dmach) {
145 /* The previous transfer has ended and this one
146 * hasn't started, so we must not have chained
147 * to the previous one in time. We'll have to
148 * start it now.
149 */
150 omap24xxcam_dmahw_transfer_start(base, dmach);
151 break;
152 } else
153 ch = (ch + 1) % NUM_CAMDMA_CHANNELS;
154 }
155}
156
157/* Abort all chained DMA transfers. After all transfers have been
158 * aborted and the DMA controller is idle, the completion routines for
159 * any aborted transfers will be called in sequence. The DMA
160 * controller may not be idle after this routine completes, because
161 * the completion routines might start new transfers.
162 */
163static void omap24xxcam_dmahw_abort_ch(unsigned long base, int dmach)
164{
165 /* mask all interrupts from this channel */
166 omap24xxcam_reg_out(base, CAMDMA_CICR(dmach), 0);
167 /* unlink this channel */
168 omap24xxcam_reg_merge(base, CAMDMA_CLNK_CTRL(dmach), 0,
169 CAMDMA_CLNK_CTRL_ENABLE_LNK);
170 /* disable this channel */
171 omap24xxcam_reg_merge(base, CAMDMA_CCR(dmach), 0, CAMDMA_CCR_ENABLE);
172}
173
174static void omap24xxcam_dmahw_init(unsigned long base)
175{
176 omap24xxcam_reg_out(base, CAMDMA_OCP_SYSCONFIG,
177 CAMDMA_OCP_SYSCONFIG_MIDLEMODE_FSTANDBY
178 | CAMDMA_OCP_SYSCONFIG_SIDLEMODE_FIDLE
179 | CAMDMA_OCP_SYSCONFIG_AUTOIDLE);
180
181 omap24xxcam_reg_merge(base, CAMDMA_GCR, 0x10,
182 CAMDMA_GCR_MAX_CHANNEL_FIFO_DEPTH);
183
184 omap24xxcam_reg_out(base, CAMDMA_IRQENABLE_L0, 0xf);
185}
186
187/*
188 *
189 * Individual DMA channel handling.
190 *
191 */
192
193/* Start a DMA transfer from the camera to memory.
194 * Returns zero if the transfer was successfully started, or non-zero if all
195 * DMA channels are already in use or starting is currently inhibited.
196 */
197static int omap24xxcam_dma_start(struct omap24xxcam_dma *dma, dma_addr_t start,
198 u32 len, dma_callback_t callback, void *arg)
199{
200 unsigned long flags;
201 int dmach;
202
203 spin_lock_irqsave(&dma->lock, flags);
204
205 if (!dma->free_dmach || atomic_read(&dma->dma_stop)) {
206 spin_unlock_irqrestore(&dma->lock, flags);
207 return -EBUSY;
208 }
209
210 dmach = dma->next_dmach;
211
212 dma->ch_state[dmach].callback = callback;
213 dma->ch_state[dmach].arg = arg;
214
215 omap24xxcam_dmahw_transfer_setup(dma->base, dmach, start, len);
216
217 /* We're ready to start the DMA transfer. */
218
219 if (dma->free_dmach < NUM_CAMDMA_CHANNELS) {
220 /* A transfer is already in progress, so try to chain to it. */
221 omap24xxcam_dmahw_transfer_chain(dma->base, dmach,
222 dma->free_dmach);
223 } else {
224 /* No transfer is in progress, so we'll just start this one
225 * now.
226 */
227 omap24xxcam_dmahw_transfer_start(dma->base, dmach);
228 }
229
230 dma->next_dmach = (dma->next_dmach + 1) % NUM_CAMDMA_CHANNELS;
231 dma->free_dmach--;
232
233 spin_unlock_irqrestore(&dma->lock, flags);
234
235 return 0;
236}
237
238/* Abort all chained DMA transfers. After all transfers have been
239 * aborted and the DMA controller is idle, the completion routines for
240 * any aborted transfers will be called in sequence. The DMA
241 * controller may not be idle after this routine completes, because
242 * the completion routines might start new transfers.
243 */
244static void omap24xxcam_dma_abort(struct omap24xxcam_dma *dma, u32 csr)
245{
246 unsigned long flags;
247 int dmach, i, free_dmach;
248 dma_callback_t callback;
249 void *arg;
250
251 spin_lock_irqsave(&dma->lock, flags);
252
253 /* stop any DMA transfers in progress */
254 dmach = (dma->next_dmach + dma->free_dmach) % NUM_CAMDMA_CHANNELS;
255 for (i = 0; i < NUM_CAMDMA_CHANNELS; i++) {
256 omap24xxcam_dmahw_abort_ch(dma->base, dmach);
257 dmach = (dmach + 1) % NUM_CAMDMA_CHANNELS;
258 }
259
260 /* We have to be careful here because the callback routine
261 * might start a new DMA transfer, and we only want to abort
262 * transfers that were started before this routine was called.
263 */
264 free_dmach = dma->free_dmach;
265 while ((dma->free_dmach < NUM_CAMDMA_CHANNELS) &&
266 (free_dmach < NUM_CAMDMA_CHANNELS)) {
267 dmach = (dma->next_dmach + dma->free_dmach)
268 % NUM_CAMDMA_CHANNELS;
269 callback = dma->ch_state[dmach].callback;
270 arg = dma->ch_state[dmach].arg;
271 dma->free_dmach++;
272 free_dmach++;
273 if (callback) {
274 /* leave interrupts disabled during callback */
275 spin_unlock(&dma->lock);
276 (*callback) (dma, csr, arg);
277 spin_lock(&dma->lock);
278 }
279 }
280
281 spin_unlock_irqrestore(&dma->lock, flags);
282}
283
284/* Abort all chained DMA transfers. After all transfers have been
285 * aborted and the DMA controller is idle, the completion routines for
286 * any aborted transfers will be called in sequence. If the completion
287 * routines attempt to start a new DMA transfer it will fail, so the
288 * DMA controller will be idle after this routine completes.
289 */
290static void omap24xxcam_dma_stop(struct omap24xxcam_dma *dma, u32 csr)
291{
292 atomic_inc(&dma->dma_stop);
293 omap24xxcam_dma_abort(dma, csr);
294 atomic_dec(&dma->dma_stop);
295}
296
297/* Camera DMA interrupt service routine. */
298void omap24xxcam_dma_isr(struct omap24xxcam_dma *dma)
299{
300 int dmach;
301 dma_callback_t callback;
302 void *arg;
303 u32 csr;
304 const u32 csr_error = CAMDMA_CSR_MISALIGNED_ERR
305 | CAMDMA_CSR_SUPERVISOR_ERR | CAMDMA_CSR_SECURE_ERR
306 | CAMDMA_CSR_TRANS_ERR | CAMDMA_CSR_DROP;
307
308 spin_lock(&dma->lock);
309
310 if (dma->free_dmach == NUM_CAMDMA_CHANNELS) {
311 /* A camera DMA interrupt occurred while all channels
312 * are idle, so we'll acknowledge the interrupt in the
313 * IRQSTATUS register and exit.
314 */
315 omap24xxcam_dmahw_ack_all(dma->base);
316 spin_unlock(&dma->lock);
317 return;
318 }
319
320 while (dma->free_dmach < NUM_CAMDMA_CHANNELS) {
321 dmach = (dma->next_dmach + dma->free_dmach)
322 % NUM_CAMDMA_CHANNELS;
323 if (omap24xxcam_dmahw_running(dma->base, dmach)) {
324 /* This buffer hasn't finished yet, so we're done. */
325 break;
326 }
327 csr = omap24xxcam_dmahw_ack_ch(dma->base, dmach);
328 if (csr & csr_error) {
329 /* A DMA error occurred, so stop all DMA
330 * transfers in progress.
331 */
332 spin_unlock(&dma->lock);
333 omap24xxcam_dma_stop(dma, csr);
334 return;
335 } else {
336 callback = dma->ch_state[dmach].callback;
337 arg = dma->ch_state[dmach].arg;
338 dma->free_dmach++;
339 if (callback) {
340 spin_unlock(&dma->lock);
341 (*callback) (dma, csr, arg);
342 spin_lock(&dma->lock);
343 }
344 }
345 }
346
347 spin_unlock(&dma->lock);
348
349 omap24xxcam_sgdma_process(
350 container_of(dma, struct omap24xxcam_sgdma, dma));
351}
352
353void omap24xxcam_dma_hwinit(struct omap24xxcam_dma *dma)
354{
355 unsigned long flags;
356
357 spin_lock_irqsave(&dma->lock, flags);
358
359 omap24xxcam_dmahw_init(dma->base);
360
361 spin_unlock_irqrestore(&dma->lock, flags);
362}
363
364static void omap24xxcam_dma_init(struct omap24xxcam_dma *dma,
365 unsigned long base)
366{
367 int ch;
368
369 /* group all channels on DMA IRQ0 and unmask irq */
370 spin_lock_init(&dma->lock);
371 dma->base = base;
372 dma->free_dmach = NUM_CAMDMA_CHANNELS;
373 dma->next_dmach = 0;
374 for (ch = 0; ch < NUM_CAMDMA_CHANNELS; ch++) {
375 dma->ch_state[ch].callback = NULL;
376 dma->ch_state[ch].arg = NULL;
377 }
378}
379
380/*
381 *
382 * Scatter-gather DMA.
383 *
384 * High-level DMA construct for transferring whole picture frames to
385 * memory that is discontinuous.
386 *
387 */
388
389/* DMA completion routine for the scatter-gather DMA fragments. */
390static void omap24xxcam_sgdma_callback(struct omap24xxcam_dma *dma, u32 csr,
391 void *arg)
392{
393 struct omap24xxcam_sgdma *sgdma =
394 container_of(dma, struct omap24xxcam_sgdma, dma);
395 int sgslot = (int)arg;
396 struct sgdma_state *sg_state;
397 const u32 csr_error = CAMDMA_CSR_MISALIGNED_ERR
398 | CAMDMA_CSR_SUPERVISOR_ERR | CAMDMA_CSR_SECURE_ERR
399 | CAMDMA_CSR_TRANS_ERR | CAMDMA_CSR_DROP;
400
401 spin_lock(&sgdma->lock);
402
403 /* We got an interrupt, we can remove the timer */
404 del_timer(&sgdma->reset_timer);
405
406 sg_state = sgdma->sg_state + sgslot;
407 if (!sg_state->queued_sglist) {
408 spin_unlock(&sgdma->lock);
409 printk(KERN_ERR "%s: sgdma completed when none queued!\n",
410 __func__);
411 return;
412 }
413
414 sg_state->csr |= csr;
415 if (!--sg_state->queued_sglist) {
416 /* Queue for this sglist is empty, so check to see if we're
417 * done.
418 */
419 if ((sg_state->next_sglist == sg_state->sglen)
420 || (sg_state->csr & csr_error)) {
421 sgdma_callback_t callback = sg_state->callback;
422 void *arg = sg_state->arg;
423 u32 sg_csr = sg_state->csr;
424 /* All done with this sglist */
425 sgdma->free_sgdma++;
426 if (callback) {
427 spin_unlock(&sgdma->lock);
428 (*callback) (sgdma, sg_csr, arg);
429 return;
430 }
431 }
432 }
433
434 spin_unlock(&sgdma->lock);
435}
436
437/* Start queued scatter-gather DMA transfers. */
438void omap24xxcam_sgdma_process(struct omap24xxcam_sgdma *sgdma)
439{
440 unsigned long flags;
441 int queued_sgdma, sgslot;
442 struct sgdma_state *sg_state;
443 const u32 csr_error = CAMDMA_CSR_MISALIGNED_ERR
444 | CAMDMA_CSR_SUPERVISOR_ERR | CAMDMA_CSR_SECURE_ERR
445 | CAMDMA_CSR_TRANS_ERR | CAMDMA_CSR_DROP;
446
447 spin_lock_irqsave(&sgdma->lock, flags);
448
449 queued_sgdma = NUM_SG_DMA - sgdma->free_sgdma;
450 sgslot = (sgdma->next_sgdma + sgdma->free_sgdma) % NUM_SG_DMA;
451 while (queued_sgdma > 0) {
452 sg_state = sgdma->sg_state + sgslot;
453 while ((sg_state->next_sglist < sg_state->sglen) &&
454 !(sg_state->csr & csr_error)) {
455 const struct scatterlist *sglist;
456 unsigned int len;
457
458 sglist = sg_state->sglist + sg_state->next_sglist;
459 /* try to start the next DMA transfer */
460 if (sg_state->next_sglist + 1 == sg_state->sglen) {
461 /*
462 * On the last sg, we handle the case where
463 * cam->img.pix.sizeimage % PAGE_ALIGN != 0
464 */
465 len = sg_state->len - sg_state->bytes_read;
466 } else {
467 len = sg_dma_len(sglist);
468 }
469
470 if (omap24xxcam_dma_start(&sgdma->dma,
471 sg_dma_address(sglist),
472 len,
473 omap24xxcam_sgdma_callback,
474 (void *)sgslot)) {
475 /* DMA start failed */
476 spin_unlock_irqrestore(&sgdma->lock, flags);
477 return;
478 } else {
479 unsigned long expires;
480 /* DMA start was successful */
481 sg_state->next_sglist++;
482 sg_state->bytes_read += len;
483 sg_state->queued_sglist++;
484
485 /* We start the reset timer */
486 expires = jiffies + HZ;
487 mod_timer(&sgdma->reset_timer, expires);
488 }
489 }
490 queued_sgdma--;
491 sgslot = (sgslot + 1) % NUM_SG_DMA;
492 }
493
494 spin_unlock_irqrestore(&sgdma->lock, flags);
495}
496
497/*
498 * Queue a scatter-gather DMA transfer from the camera to memory.
499 * Returns zero if the transfer was successfully queued, or non-zero
500 * if all of the scatter-gather slots are already in use.
501 */
502int omap24xxcam_sgdma_queue(struct omap24xxcam_sgdma *sgdma,
503 const struct scatterlist *sglist, int sglen,
504 int len, sgdma_callback_t callback, void *arg)
505{
506 unsigned long flags;
507 struct sgdma_state *sg_state;
508
509 if ((sglen < 0) || ((sglen > 0) & !sglist))
510 return -EINVAL;
511
512 spin_lock_irqsave(&sgdma->lock, flags);
513
514 if (!sgdma->free_sgdma) {
515 spin_unlock_irqrestore(&sgdma->lock, flags);
516 return -EBUSY;
517 }
518
519 sg_state = sgdma->sg_state + sgdma->next_sgdma;
520
521 sg_state->sglist = sglist;
522 sg_state->sglen = sglen;
523 sg_state->next_sglist = 0;
524 sg_state->bytes_read = 0;
525 sg_state->len = len;
526 sg_state->queued_sglist = 0;
527 sg_state->csr = 0;
528 sg_state->callback = callback;
529 sg_state->arg = arg;
530
531 sgdma->next_sgdma = (sgdma->next_sgdma + 1) % NUM_SG_DMA;
532 sgdma->free_sgdma--;
533
534 spin_unlock_irqrestore(&sgdma->lock, flags);
535
536 omap24xxcam_sgdma_process(sgdma);
537
538 return 0;
539}
540
541/* Sync scatter-gather DMA by aborting any DMA transfers currently in progress.
542 * Any queued scatter-gather DMA transactions that have not yet been started
543 * will remain queued. The DMA controller will be idle after this routine
544 * completes. When the scatter-gather queue is restarted, the next
545 * scatter-gather DMA transfer will begin at the start of a new transaction.
546 */
547void omap24xxcam_sgdma_sync(struct omap24xxcam_sgdma *sgdma)
548{
549 unsigned long flags;
550 int sgslot;
551 struct sgdma_state *sg_state;
552 u32 csr = CAMDMA_CSR_TRANS_ERR;
553
554 /* stop any DMA transfers in progress */
555 omap24xxcam_dma_stop(&sgdma->dma, csr);
556
557 spin_lock_irqsave(&sgdma->lock, flags);
558
559 if (sgdma->free_sgdma < NUM_SG_DMA) {
560 sgslot = (sgdma->next_sgdma + sgdma->free_sgdma) % NUM_SG_DMA;
561 sg_state = sgdma->sg_state + sgslot;
562 if (sg_state->next_sglist != 0) {
563 /* This DMA transfer was in progress, so abort it. */
564 sgdma_callback_t callback = sg_state->callback;
565 void *arg = sg_state->arg;
566 sgdma->free_sgdma++;
567 if (callback) {
568 /* leave interrupts masked */
569 spin_unlock(&sgdma->lock);
570 (*callback) (sgdma, csr, arg);
571 spin_lock(&sgdma->lock);
572 }
573 }
574 }
575
576 spin_unlock_irqrestore(&sgdma->lock, flags);
577}
578
579void omap24xxcam_sgdma_init(struct omap24xxcam_sgdma *sgdma,
580 unsigned long base,
581 void (*reset_callback)(unsigned long data),
582 unsigned long reset_callback_data)
583{
584 int sg;
585
586 spin_lock_init(&sgdma->lock);
587 sgdma->free_sgdma = NUM_SG_DMA;
588 sgdma->next_sgdma = 0;
589 for (sg = 0; sg < NUM_SG_DMA; sg++) {
590 sgdma->sg_state[sg].sglen = 0;
591 sgdma->sg_state[sg].next_sglist = 0;
592 sgdma->sg_state[sg].bytes_read = 0;
593 sgdma->sg_state[sg].queued_sglist = 0;
594 sgdma->sg_state[sg].csr = 0;
595 sgdma->sg_state[sg].callback = NULL;
596 sgdma->sg_state[sg].arg = NULL;
597 }
598
599 omap24xxcam_dma_init(&sgdma->dma, base);
600 setup_timer(&sgdma->reset_timer, reset_callback, reset_callback_data);
601}
diff --git a/drivers/media/video/omap24xxcam.c b/drivers/media/video/omap24xxcam.c
new file mode 100644
index 000000000000..85c3c7c92af1
--- /dev/null
+++ b/drivers/media/video/omap24xxcam.c
@@ -0,0 +1,1908 @@
1/*
2 * drivers/media/video/omap24xxcam.c
3 *
4 * OMAP 2 camera block driver.
5 *
6 * Copyright (C) 2004 MontaVista Software, Inc.
7 * Copyright (C) 2004 Texas Instruments.
8 * Copyright (C) 2007-2008 Nokia Corporation.
9 *
10 * Contact: Sakari Ailus <sakari.ailus@nokia.com>
11 *
12 * Based on code from Andy Lowe <source@mvista.com>
13 *
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * version 2 as published by the Free Software Foundation.
17 *
18 * This program is distributed in the hope that it will be useful, but
19 * WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 * General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
26 * 02110-1301 USA
27 */
28
29#include <linux/delay.h>
30#include <linux/kernel.h>
31#include <linux/interrupt.h>
32#include <linux/videodev2.h>
33#include <linux/pci.h> /* needed for videobufs */
34#include <linux/version.h>
35#include <linux/platform_device.h>
36#include <linux/clk.h>
37#include <linux/io.h>
38
39#include <media/v4l2-common.h>
40#include <media/v4l2-ioctl.h>
41
42#include "omap24xxcam.h"
43
44#define OMAP24XXCAM_VERSION KERNEL_VERSION(0, 0, 0)
45
46#define RESET_TIMEOUT_NS 10000
47
48static void omap24xxcam_reset(struct omap24xxcam_device *cam);
49static int omap24xxcam_sensor_if_enable(struct omap24xxcam_device *cam);
50static void omap24xxcam_device_unregister(struct v4l2_int_device *s);
51static int omap24xxcam_remove(struct platform_device *pdev);
52
53/* module parameters */
54static int video_nr = -1; /* video device minor (-1 ==> auto assign) */
55/*
56 * Maximum amount of memory to use for capture buffers.
57 * Default is 4800KB, enough to double-buffer SXGA.
58 */
59static int capture_mem = 1280 * 960 * 2 * 2;
60
61static struct v4l2_int_device omap24xxcam;
62
63/*
64 *
65 * Clocks.
66 *
67 */
68
69static void omap24xxcam_clock_put(struct omap24xxcam_device *cam)
70{
71 if (cam->ick != NULL && !IS_ERR(cam->ick))
72 clk_put(cam->ick);
73 if (cam->fck != NULL && !IS_ERR(cam->fck))
74 clk_put(cam->fck);
75
76 cam->ick = cam->fck = NULL;
77}
78
79static int omap24xxcam_clock_get(struct omap24xxcam_device *cam)
80{
81 int rval = 0;
82
83 cam->fck = clk_get(cam->dev, "cam_fck");
84 if (IS_ERR(cam->fck)) {
85 dev_err(cam->dev, "can't get cam_fck");
86 rval = PTR_ERR(cam->fck);
87 omap24xxcam_clock_put(cam);
88 return rval;
89 }
90
91 cam->ick = clk_get(cam->dev, "cam_ick");
92 if (IS_ERR(cam->ick)) {
93 dev_err(cam->dev, "can't get cam_ick");
94 rval = PTR_ERR(cam->ick);
95 omap24xxcam_clock_put(cam);
96 }
97
98 return rval;
99}
100
101static void omap24xxcam_clock_on(struct omap24xxcam_device *cam)
102{
103 clk_enable(cam->fck);
104 clk_enable(cam->ick);
105}
106
107static void omap24xxcam_clock_off(struct omap24xxcam_device *cam)
108{
109 clk_disable(cam->fck);
110 clk_disable(cam->ick);
111}
112
113/*
114 *
115 * Camera core
116 *
117 */
118
119/*
120 * Set xclk.
121 *
122 * To disable xclk, use value zero.
123 */
124static void omap24xxcam_core_xclk_set(const struct omap24xxcam_device *cam,
125 u32 xclk)
126{
127 if (xclk) {
128 u32 divisor = CAM_MCLK / xclk;
129
130 if (divisor == 1)
131 omap24xxcam_reg_out(cam->mmio_base + CC_REG_OFFSET,
132 CC_CTRL_XCLK,
133 CC_CTRL_XCLK_DIV_BYPASS);
134 else
135 omap24xxcam_reg_out(cam->mmio_base + CC_REG_OFFSET,
136 CC_CTRL_XCLK, divisor);
137 } else
138 omap24xxcam_reg_out(cam->mmio_base + CC_REG_OFFSET,
139 CC_CTRL_XCLK, CC_CTRL_XCLK_DIV_STABLE_LOW);
140}
141
142static void omap24xxcam_core_hwinit(const struct omap24xxcam_device *cam)
143{
144 /*
145 * Setting the camera core AUTOIDLE bit causes problems with frame
146 * synchronization, so we will clear the AUTOIDLE bit instead.
147 */
148 omap24xxcam_reg_out(cam->mmio_base + CC_REG_OFFSET, CC_SYSCONFIG,
149 CC_SYSCONFIG_AUTOIDLE);
150
151 /* program the camera interface DMA packet size */
152 omap24xxcam_reg_out(cam->mmio_base + CC_REG_OFFSET, CC_CTRL_DMA,
153 CC_CTRL_DMA_EN | (DMA_THRESHOLD / 4 - 1));
154
155 /* enable camera core error interrupts */
156 omap24xxcam_reg_out(cam->mmio_base + CC_REG_OFFSET, CC_IRQENABLE,
157 CC_IRQENABLE_FW_ERR_IRQ
158 | CC_IRQENABLE_FSC_ERR_IRQ
159 | CC_IRQENABLE_SSC_ERR_IRQ
160 | CC_IRQENABLE_FIFO_OF_IRQ);
161}
162
163/*
164 * Enable the camera core.
165 *
166 * Data transfer to the camera DMA starts from next starting frame.
167 */
168static void omap24xxcam_core_enable(const struct omap24xxcam_device *cam)
169{
170
171 omap24xxcam_reg_out(cam->mmio_base + CC_REG_OFFSET, CC_CTRL,
172 cam->cc_ctrl);
173}
174
175/*
176 * Disable camera core.
177 *
178 * The data transfer will be stopped immediately (CC_CTRL_CC_RST). The
179 * core internal state machines will be reset. Use
180 * CC_CTRL_CC_FRAME_TRIG instead if you want to transfer the current
181 * frame completely.
182 */
183static void omap24xxcam_core_disable(const struct omap24xxcam_device *cam)
184{
185 omap24xxcam_reg_out(cam->mmio_base + CC_REG_OFFSET, CC_CTRL,
186 CC_CTRL_CC_RST);
187}
188
189/* Interrupt service routine for camera core interrupts. */
190static void omap24xxcam_core_isr(struct omap24xxcam_device *cam)
191{
192 u32 cc_irqstatus;
193 const u32 cc_irqstatus_err =
194 CC_IRQSTATUS_FW_ERR_IRQ
195 | CC_IRQSTATUS_FSC_ERR_IRQ
196 | CC_IRQSTATUS_SSC_ERR_IRQ
197 | CC_IRQSTATUS_FIFO_UF_IRQ
198 | CC_IRQSTATUS_FIFO_OF_IRQ;
199
200 cc_irqstatus = omap24xxcam_reg_in(cam->mmio_base + CC_REG_OFFSET,
201 CC_IRQSTATUS);
202 omap24xxcam_reg_out(cam->mmio_base + CC_REG_OFFSET, CC_IRQSTATUS,
203 cc_irqstatus);
204
205 if (cc_irqstatus & cc_irqstatus_err
206 && !atomic_read(&cam->in_reset)) {
207 dev_dbg(cam->dev, "resetting camera, cc_irqstatus 0x%x\n",
208 cc_irqstatus);
209 omap24xxcam_reset(cam);
210 }
211}
212
213/*
214 *
215 * videobuf_buffer handling.
216 *
217 * Memory for mmapped videobuf_buffers is not allocated
218 * conventionally, but by several kmalloc allocations and then
219 * creating the scatterlist on our own. User-space buffers are handled
220 * normally.
221 *
222 */
223
224/*
225 * Free the memory-mapped buffer memory allocated for a
226 * videobuf_buffer and the associated scatterlist.
227 */
228static void omap24xxcam_vbq_free_mmap_buffer(struct videobuf_buffer *vb)
229{
230 struct videobuf_dmabuf *dma = videobuf_to_dma(vb);
231 size_t alloc_size;
232 struct page *page;
233 int i;
234
235 if (dma->sglist == NULL)
236 return;
237
238 i = dma->sglen;
239 while (i) {
240 i--;
241 alloc_size = sg_dma_len(&dma->sglist[i]);
242 page = sg_page(&dma->sglist[i]);
243 do {
244 ClearPageReserved(page++);
245 } while (alloc_size -= PAGE_SIZE);
246 __free_pages(sg_page(&dma->sglist[i]),
247 get_order(sg_dma_len(&dma->sglist[i])));
248 }
249
250 kfree(dma->sglist);
251 dma->sglist = NULL;
252}
253
254/* Release all memory related to the videobuf_queue. */
255static void omap24xxcam_vbq_free_mmap_buffers(struct videobuf_queue *vbq)
256{
257 int i;
258
259 mutex_lock(&vbq->vb_lock);
260
261 for (i = 0; i < VIDEO_MAX_FRAME; i++) {
262 if (NULL == vbq->bufs[i])
263 continue;
264 if (V4L2_MEMORY_MMAP != vbq->bufs[i]->memory)
265 continue;
266 vbq->ops->buf_release(vbq, vbq->bufs[i]);
267 omap24xxcam_vbq_free_mmap_buffer(vbq->bufs[i]);
268 kfree(vbq->bufs[i]);
269 vbq->bufs[i] = NULL;
270 }
271
272 mutex_unlock(&vbq->vb_lock);
273
274 videobuf_mmap_free(vbq);
275}
276
277/*
278 * Allocate physically as contiguous as possible buffer for video
279 * frame and allocate and build DMA scatter-gather list for it.
280 */
281static int omap24xxcam_vbq_alloc_mmap_buffer(struct videobuf_buffer *vb)
282{
283 unsigned int order;
284 size_t alloc_size, size = vb->bsize; /* vb->bsize is page aligned */
285 struct page *page;
286 int max_pages, err = 0, i = 0;
287 struct videobuf_dmabuf *dma = videobuf_to_dma(vb);
288
289 /*
290 * allocate maximum size scatter-gather list. Note this is
291 * overhead. We may not use as many entries as we allocate
292 */
293 max_pages = vb->bsize >> PAGE_SHIFT;
294 dma->sglist = kcalloc(max_pages, sizeof(*dma->sglist), GFP_KERNEL);
295 if (dma->sglist == NULL) {
296 err = -ENOMEM;
297 goto out;
298 }
299
300 while (size) {
301 order = get_order(size);
302 /*
303 * do not over-allocate even if we would get larger
304 * contiguous chunk that way
305 */
306 if ((PAGE_SIZE << order) > size)
307 order--;
308
309 /* try to allocate as many contiguous pages as possible */
310 page = alloc_pages(GFP_KERNEL | GFP_DMA, order);
311 /* if allocation fails, try to allocate smaller amount */
312 while (page == NULL) {
313 order--;
314 page = alloc_pages(GFP_KERNEL | GFP_DMA, order);
315 if (page == NULL && !order) {
316 err = -ENOMEM;
317 goto out;
318 }
319 }
320 size -= (PAGE_SIZE << order);
321
322 /* append allocated chunk of pages into scatter-gather list */
323 sg_set_page(&dma->sglist[i], page, PAGE_SIZE << order, 0);
324 dma->sglen++;
325 i++;
326
327 alloc_size = (PAGE_SIZE << order);
328
329 /* clear pages before giving them to user space */
330 memset(page_address(page), 0, alloc_size);
331
332 /* mark allocated pages reserved */
333 do {
334 SetPageReserved(page++);
335 } while (alloc_size -= PAGE_SIZE);
336 }
337 /*
338 * REVISIT: not fully correct to assign nr_pages == sglen but
339 * video-buf is passing nr_pages for e.g. unmap_sg calls
340 */
341 dma->nr_pages = dma->sglen;
342 dma->direction = PCI_DMA_FROMDEVICE;
343
344 return 0;
345
346out:
347 omap24xxcam_vbq_free_mmap_buffer(vb);
348 return err;
349}
350
351static int omap24xxcam_vbq_alloc_mmap_buffers(struct videobuf_queue *vbq,
352 unsigned int count)
353{
354 int i, err = 0;
355 struct omap24xxcam_fh *fh =
356 container_of(vbq, struct omap24xxcam_fh, vbq);
357
358 mutex_lock(&vbq->vb_lock);
359
360 for (i = 0; i < count; i++) {
361 err = omap24xxcam_vbq_alloc_mmap_buffer(vbq->bufs[i]);
362 if (err)
363 goto out;
364 dev_dbg(fh->cam->dev, "sglen is %d for buffer %d\n",
365 videobuf_to_dma(vbq->bufs[i])->sglen, i);
366 }
367
368 mutex_unlock(&vbq->vb_lock);
369
370 return 0;
371out:
372 while (i) {
373 i--;
374 omap24xxcam_vbq_free_mmap_buffer(vbq->bufs[i]);
375 }
376
377 mutex_unlock(&vbq->vb_lock);
378
379 return err;
380}
381
382/*
383 * This routine is called from interrupt context when a scatter-gather DMA
384 * transfer of a videobuf_buffer completes.
385 */
386static void omap24xxcam_vbq_complete(struct omap24xxcam_sgdma *sgdma,
387 u32 csr, void *arg)
388{
389 struct omap24xxcam_device *cam =
390 container_of(sgdma, struct omap24xxcam_device, sgdma);
391 struct omap24xxcam_fh *fh = cam->streaming->private_data;
392 struct videobuf_buffer *vb = (struct videobuf_buffer *)arg;
393 const u32 csr_error = CAMDMA_CSR_MISALIGNED_ERR
394 | CAMDMA_CSR_SUPERVISOR_ERR | CAMDMA_CSR_SECURE_ERR
395 | CAMDMA_CSR_TRANS_ERR | CAMDMA_CSR_DROP;
396 unsigned long flags;
397
398 spin_lock_irqsave(&cam->core_enable_disable_lock, flags);
399 if (--cam->sgdma_in_queue == 0)
400 omap24xxcam_core_disable(cam);
401 spin_unlock_irqrestore(&cam->core_enable_disable_lock, flags);
402
403 do_gettimeofday(&vb->ts);
404 vb->field_count = atomic_add_return(2, &fh->field_count);
405 if (csr & csr_error) {
406 vb->state = VIDEOBUF_ERROR;
407 if (!atomic_read(&fh->cam->in_reset)) {
408 dev_dbg(cam->dev, "resetting camera, csr 0x%x\n", csr);
409 omap24xxcam_reset(cam);
410 }
411 } else
412 vb->state = VIDEOBUF_DONE;
413 wake_up(&vb->done);
414}
415
416static void omap24xxcam_vbq_release(struct videobuf_queue *vbq,
417 struct videobuf_buffer *vb)
418{
419 struct videobuf_dmabuf *dma = videobuf_to_dma(vb);
420
421 /* wait for buffer, especially to get out of the sgdma queue */
422 videobuf_waiton(vb, 0, 0);
423 if (vb->memory == V4L2_MEMORY_MMAP) {
424 dma_unmap_sg(vbq->dev, dma->sglist, dma->sglen,
425 dma->direction);
426 dma->direction = DMA_NONE;
427 } else {
428 videobuf_dma_unmap(vbq, videobuf_to_dma(vb));
429 videobuf_dma_free(videobuf_to_dma(vb));
430 }
431
432 vb->state = VIDEOBUF_NEEDS_INIT;
433}
434
435/*
436 * Limit the number of available kernel image capture buffers based on the
437 * number requested, the currently selected image size, and the maximum
438 * amount of memory permitted for kernel capture buffers.
439 */
440static int omap24xxcam_vbq_setup(struct videobuf_queue *vbq, unsigned int *cnt,
441 unsigned int *size)
442{
443 struct omap24xxcam_fh *fh = vbq->priv_data;
444
445 if (*cnt <= 0)
446 *cnt = VIDEO_MAX_FRAME; /* supply a default number of buffers */
447
448 if (*cnt > VIDEO_MAX_FRAME)
449 *cnt = VIDEO_MAX_FRAME;
450
451 *size = fh->pix.sizeimage;
452
453 /* accessing fh->cam->capture_mem is ok, it's constant */
454 while (*size * *cnt > fh->cam->capture_mem)
455 (*cnt)--;
456
457 return 0;
458}
459
460static int omap24xxcam_dma_iolock(struct videobuf_queue *vbq,
461 struct videobuf_dmabuf *dma)
462{
463 int err = 0;
464
465 dma->direction = PCI_DMA_FROMDEVICE;
466 if (!dma_map_sg(vbq->dev, dma->sglist, dma->sglen, dma->direction)) {
467 kfree(dma->sglist);
468 dma->sglist = NULL;
469 dma->sglen = 0;
470 err = -EIO;
471 }
472
473 return err;
474}
475
476static int omap24xxcam_vbq_prepare(struct videobuf_queue *vbq,
477 struct videobuf_buffer *vb,
478 enum v4l2_field field)
479{
480 struct omap24xxcam_fh *fh = vbq->priv_data;
481 int err = 0;
482
483 /*
484 * Accessing pix here is okay since it's constant while
485 * streaming is on (and we only get called then).
486 */
487 if (vb->baddr) {
488 /* This is a userspace buffer. */
489 if (fh->pix.sizeimage > vb->bsize) {
490 /* The buffer isn't big enough. */
491 err = -EINVAL;
492 } else
493 vb->size = fh->pix.sizeimage;
494 } else {
495 if (vb->state != VIDEOBUF_NEEDS_INIT) {
496 /*
497 * We have a kernel bounce buffer that has
498 * already been allocated.
499 */
500 if (fh->pix.sizeimage > vb->size) {
501 /*
502 * The image size has been changed to
503 * a larger size since this buffer was
504 * allocated, so we need to free and
505 * reallocate it.
506 */
507 omap24xxcam_vbq_release(vbq, vb);
508 vb->size = fh->pix.sizeimage;
509 }
510 } else {
511 /* We need to allocate a new kernel bounce buffer. */
512 vb->size = fh->pix.sizeimage;
513 }
514 }
515
516 if (err)
517 return err;
518
519 vb->width = fh->pix.width;
520 vb->height = fh->pix.height;
521 vb->field = field;
522
523 if (vb->state == VIDEOBUF_NEEDS_INIT) {
524 if (vb->memory == V4L2_MEMORY_MMAP)
525 /*
526 * we have built the scatter-gather list by ourself so
527 * do the scatter-gather mapping as well
528 */
529 err = omap24xxcam_dma_iolock(vbq, videobuf_to_dma(vb));
530 else
531 err = videobuf_iolock(vbq, vb, NULL);
532 }
533
534 if (!err)
535 vb->state = VIDEOBUF_PREPARED;
536 else
537 omap24xxcam_vbq_release(vbq, vb);
538
539 return err;
540}
541
542static void omap24xxcam_vbq_queue(struct videobuf_queue *vbq,
543 struct videobuf_buffer *vb)
544{
545 struct omap24xxcam_fh *fh = vbq->priv_data;
546 struct omap24xxcam_device *cam = fh->cam;
547 enum videobuf_state state = vb->state;
548 unsigned long flags;
549 int err;
550
551 /*
552 * FIXME: We're marking the buffer active since we have no
553 * pretty way of marking it active exactly when the
554 * scatter-gather transfer starts.
555 */
556 vb->state = VIDEOBUF_ACTIVE;
557
558 err = omap24xxcam_sgdma_queue(&fh->cam->sgdma,
559 videobuf_to_dma(vb)->sglist,
560 videobuf_to_dma(vb)->sglen, vb->size,
561 omap24xxcam_vbq_complete, vb);
562
563 if (!err) {
564 spin_lock_irqsave(&cam->core_enable_disable_lock, flags);
565 if (++cam->sgdma_in_queue == 1
566 && !atomic_read(&cam->in_reset))
567 omap24xxcam_core_enable(cam);
568 spin_unlock_irqrestore(&cam->core_enable_disable_lock, flags);
569 } else {
570 /*
571 * Oops. We're not supposed to get any errors here.
572 * The only way we could get an error is if we ran out
573 * of scatter-gather DMA slots, but we are supposed to
574 * have at least as many scatter-gather DMA slots as
575 * video buffers so that can't happen.
576 */
577 dev_err(cam->dev, "failed to queue a video buffer for dma!\n");
578 dev_err(cam->dev, "likely a bug in the driver!\n");
579 vb->state = state;
580 }
581}
582
583static struct videobuf_queue_ops omap24xxcam_vbq_ops = {
584 .buf_setup = omap24xxcam_vbq_setup,
585 .buf_prepare = omap24xxcam_vbq_prepare,
586 .buf_queue = omap24xxcam_vbq_queue,
587 .buf_release = omap24xxcam_vbq_release,
588};
589
590/*
591 *
592 * OMAP main camera system
593 *
594 */
595
596/*
597 * Reset camera block to power-on state.
598 */
599static void omap24xxcam_poweron_reset(struct omap24xxcam_device *cam)
600{
601 int max_loop = RESET_TIMEOUT_NS;
602
603 /* Reset whole camera subsystem */
604 omap24xxcam_reg_out(cam->mmio_base,
605 CAM_SYSCONFIG,
606 CAM_SYSCONFIG_SOFTRESET);
607
608 /* Wait till it's finished */
609 while (!(omap24xxcam_reg_in(cam->mmio_base, CAM_SYSSTATUS)
610 & CAM_SYSSTATUS_RESETDONE)
611 && --max_loop) {
612 ndelay(1);
613 }
614
615 if (!(omap24xxcam_reg_in(cam->mmio_base, CAM_SYSSTATUS)
616 & CAM_SYSSTATUS_RESETDONE))
617 dev_err(cam->dev, "camera soft reset timeout\n");
618}
619
620/*
621 * (Re)initialise the camera block.
622 */
623static void omap24xxcam_hwinit(struct omap24xxcam_device *cam)
624{
625 omap24xxcam_poweron_reset(cam);
626
627 /* set the camera subsystem autoidle bit */
628 omap24xxcam_reg_out(cam->mmio_base, CAM_SYSCONFIG,
629 CAM_SYSCONFIG_AUTOIDLE);
630
631 /* set the camera MMU autoidle bit */
632 omap24xxcam_reg_out(cam->mmio_base,
633 CAMMMU_REG_OFFSET + CAMMMU_SYSCONFIG,
634 CAMMMU_SYSCONFIG_AUTOIDLE);
635
636 omap24xxcam_core_hwinit(cam);
637
638 omap24xxcam_dma_hwinit(&cam->sgdma.dma);
639}
640
641/*
642 * Callback for dma transfer stalling.
643 */
644static void omap24xxcam_stalled_dma_reset(unsigned long data)
645{
646 struct omap24xxcam_device *cam = (struct omap24xxcam_device *)data;
647
648 if (!atomic_read(&cam->in_reset)) {
649 dev_dbg(cam->dev, "dma stalled, resetting camera\n");
650 omap24xxcam_reset(cam);
651 }
652}
653
654/*
655 * Stop capture. Mark we're doing a reset, stop DMA transfers and
656 * core. (No new scatter-gather transfers will be queued whilst
657 * in_reset is non-zero.)
658 *
659 * If omap24xxcam_capture_stop is called from several places at
660 * once, only the first call will have an effect. Similarly, the last
661 * call omap24xxcam_streaming_cont will have effect.
662 *
663 * Serialisation is ensured by using cam->core_enable_disable_lock.
664 */
665static void omap24xxcam_capture_stop(struct omap24xxcam_device *cam)
666{
667 unsigned long flags;
668
669 spin_lock_irqsave(&cam->core_enable_disable_lock, flags);
670
671 if (atomic_inc_return(&cam->in_reset) != 1) {
672 spin_unlock_irqrestore(&cam->core_enable_disable_lock, flags);
673 return;
674 }
675
676 omap24xxcam_core_disable(cam);
677
678 spin_unlock_irqrestore(&cam->core_enable_disable_lock, flags);
679
680 omap24xxcam_sgdma_sync(&cam->sgdma);
681}
682
683/*
684 * Reset and continue streaming.
685 *
686 * Note: Resetting the camera FIFO via the CC_RST bit in the CC_CTRL
687 * register is supposed to be sufficient to recover from a camera
688 * interface error, but it doesn't seem to be enough. If we only do
689 * that then subsequent image captures are out of sync by either one
690 * or two times DMA_THRESHOLD bytes. Resetting and re-initializing the
691 * entire camera subsystem prevents the problem with frame
692 * synchronization.
693 */
694static void omap24xxcam_capture_cont(struct omap24xxcam_device *cam)
695{
696 unsigned long flags;
697
698 spin_lock_irqsave(&cam->core_enable_disable_lock, flags);
699
700 if (atomic_read(&cam->in_reset) != 1)
701 goto out;
702
703 omap24xxcam_hwinit(cam);
704
705 omap24xxcam_sensor_if_enable(cam);
706
707 omap24xxcam_sgdma_process(&cam->sgdma);
708
709 if (cam->sgdma_in_queue)
710 omap24xxcam_core_enable(cam);
711
712out:
713 atomic_dec(&cam->in_reset);
714 spin_unlock_irqrestore(&cam->core_enable_disable_lock, flags);
715}
716
717static ssize_t
718omap24xxcam_streaming_show(struct device *dev, struct device_attribute *attr,
719 char *buf)
720{
721 struct omap24xxcam_device *cam = dev_get_drvdata(dev);
722
723 return sprintf(buf, "%s\n", cam->streaming ? "active" : "inactive");
724}
725static DEVICE_ATTR(streaming, S_IRUGO, omap24xxcam_streaming_show, NULL);
726
727/*
728 * Stop capture and restart it. I.e. reset the camera during use.
729 */
730static void omap24xxcam_reset(struct omap24xxcam_device *cam)
731{
732 omap24xxcam_capture_stop(cam);
733 omap24xxcam_capture_cont(cam);
734}
735
736/*
737 * The main interrupt handler.
738 */
739static irqreturn_t omap24xxcam_isr(int irq, void *arg)
740{
741 struct omap24xxcam_device *cam = (struct omap24xxcam_device *)arg;
742 u32 irqstatus;
743 unsigned int irqhandled = 0;
744
745 irqstatus = omap24xxcam_reg_in(cam->mmio_base, CAM_IRQSTATUS);
746
747 if (irqstatus &
748 (CAM_IRQSTATUS_DMA_IRQ2 | CAM_IRQSTATUS_DMA_IRQ1
749 | CAM_IRQSTATUS_DMA_IRQ0)) {
750 omap24xxcam_dma_isr(&cam->sgdma.dma);
751 irqhandled = 1;
752 }
753 if (irqstatus & CAM_IRQSTATUS_CC_IRQ) {
754 omap24xxcam_core_isr(cam);
755 irqhandled = 1;
756 }
757 if (irqstatus & CAM_IRQSTATUS_MMU_IRQ)
758 dev_err(cam->dev, "unhandled camera MMU interrupt!\n");
759
760 return IRQ_RETVAL(irqhandled);
761}
762
763/*
764 *
765 * Sensor handling.
766 *
767 */
768
769/*
770 * Enable the external sensor interface. Try to negotiate interface
771 * parameters with the sensor and start using the new ones. The calls
772 * to sensor_if_enable and sensor_if_disable need not to be balanced.
773 */
774static int omap24xxcam_sensor_if_enable(struct omap24xxcam_device *cam)
775{
776 int rval;
777 struct v4l2_ifparm p;
778
779 rval = vidioc_int_g_ifparm(cam->sdev, &p);
780 if (rval) {
781 dev_err(cam->dev, "vidioc_int_g_ifparm failed with %d\n", rval);
782 return rval;
783 }
784
785 cam->if_type = p.if_type;
786
787 cam->cc_ctrl = CC_CTRL_CC_EN;
788
789 switch (p.if_type) {
790 case V4L2_IF_TYPE_BT656:
791 if (p.u.bt656.frame_start_on_rising_vs)
792 cam->cc_ctrl |= CC_CTRL_NOBT_SYNCHRO;
793 if (p.u.bt656.bt_sync_correct)
794 cam->cc_ctrl |= CC_CTRL_BT_CORRECT;
795 if (p.u.bt656.swap)
796 cam->cc_ctrl |= CC_CTRL_PAR_ORDERCAM;
797 if (p.u.bt656.latch_clk_inv)
798 cam->cc_ctrl |= CC_CTRL_PAR_CLK_POL;
799 if (p.u.bt656.nobt_hs_inv)
800 cam->cc_ctrl |= CC_CTRL_NOBT_HS_POL;
801 if (p.u.bt656.nobt_vs_inv)
802 cam->cc_ctrl |= CC_CTRL_NOBT_VS_POL;
803
804 switch (p.u.bt656.mode) {
805 case V4L2_IF_TYPE_BT656_MODE_NOBT_8BIT:
806 cam->cc_ctrl |= CC_CTRL_PAR_MODE_NOBT8;
807 break;
808 case V4L2_IF_TYPE_BT656_MODE_NOBT_10BIT:
809 cam->cc_ctrl |= CC_CTRL_PAR_MODE_NOBT10;
810 break;
811 case V4L2_IF_TYPE_BT656_MODE_NOBT_12BIT:
812 cam->cc_ctrl |= CC_CTRL_PAR_MODE_NOBT12;
813 break;
814 case V4L2_IF_TYPE_BT656_MODE_BT_8BIT:
815 cam->cc_ctrl |= CC_CTRL_PAR_MODE_BT8;
816 break;
817 case V4L2_IF_TYPE_BT656_MODE_BT_10BIT:
818 cam->cc_ctrl |= CC_CTRL_PAR_MODE_BT10;
819 break;
820 default:
821 dev_err(cam->dev,
822 "bt656 interface mode %d not supported\n",
823 p.u.bt656.mode);
824 return -EINVAL;
825 }
826 /*
827 * The clock rate that the sensor wants has changed.
828 * We have to adjust the xclk from OMAP 2 side to
829 * match the sensor's wish as closely as possible.
830 */
831 if (p.u.bt656.clock_curr != cam->if_u.bt656.xclk) {
832 u32 xclk = p.u.bt656.clock_curr;
833 u32 divisor;
834
835 if (xclk == 0)
836 return -EINVAL;
837
838 if (xclk > CAM_MCLK)
839 xclk = CAM_MCLK;
840
841 divisor = CAM_MCLK / xclk;
842 if (divisor * xclk < CAM_MCLK)
843 divisor++;
844 if (CAM_MCLK / divisor < p.u.bt656.clock_min
845 && divisor > 1)
846 divisor--;
847 if (divisor > 30)
848 divisor = 30;
849
850 xclk = CAM_MCLK / divisor;
851
852 if (xclk < p.u.bt656.clock_min
853 || xclk > p.u.bt656.clock_max)
854 return -EINVAL;
855
856 cam->if_u.bt656.xclk = xclk;
857 }
858 omap24xxcam_core_xclk_set(cam, cam->if_u.bt656.xclk);
859 break;
860 default:
861 /* FIXME: how about other interfaces? */
862 dev_err(cam->dev, "interface type %d not supported\n",
863 p.if_type);
864 return -EINVAL;
865 }
866
867 return 0;
868}
869
870static void omap24xxcam_sensor_if_disable(const struct omap24xxcam_device *cam)
871{
872 switch (cam->if_type) {
873 case V4L2_IF_TYPE_BT656:
874 omap24xxcam_core_xclk_set(cam, 0);
875 break;
876 }
877}
878
879/*
880 * Initialise the sensor hardware.
881 */
882static int omap24xxcam_sensor_init(struct omap24xxcam_device *cam)
883{
884 int err = 0;
885 struct v4l2_int_device *sdev = cam->sdev;
886
887 omap24xxcam_clock_on(cam);
888 err = omap24xxcam_sensor_if_enable(cam);
889 if (err) {
890 dev_err(cam->dev, "sensor interface could not be enabled at "
891 "initialisation, %d\n", err);
892 cam->sdev = NULL;
893 goto out;
894 }
895
896 /* power up sensor during sensor initialization */
897 vidioc_int_s_power(sdev, 1);
898
899 err = vidioc_int_dev_init(sdev);
900 if (err) {
901 dev_err(cam->dev, "cannot initialize sensor, error %d\n", err);
902 /* Sensor init failed --- it's nonexistent to us! */
903 cam->sdev = NULL;
904 goto out;
905 }
906
907 dev_info(cam->dev, "sensor is %s\n", sdev->name);
908
909out:
910 omap24xxcam_sensor_if_disable(cam);
911 omap24xxcam_clock_off(cam);
912
913 vidioc_int_s_power(sdev, 0);
914
915 return err;
916}
917
918static void omap24xxcam_sensor_exit(struct omap24xxcam_device *cam)
919{
920 if (cam->sdev)
921 vidioc_int_dev_exit(cam->sdev);
922}
923
924static void omap24xxcam_sensor_disable(struct omap24xxcam_device *cam)
925{
926 omap24xxcam_sensor_if_disable(cam);
927 omap24xxcam_clock_off(cam);
928 vidioc_int_s_power(cam->sdev, 0);
929}
930
931/*
932 * Power-up and configure camera sensor. It's ready for capturing now.
933 */
934static int omap24xxcam_sensor_enable(struct omap24xxcam_device *cam)
935{
936 int rval;
937
938 omap24xxcam_clock_on(cam);
939
940 omap24xxcam_sensor_if_enable(cam);
941
942 rval = vidioc_int_s_power(cam->sdev, 1);
943 if (rval)
944 goto out;
945
946 rval = vidioc_int_init(cam->sdev);
947 if (rval)
948 goto out;
949
950 return 0;
951
952out:
953 omap24xxcam_sensor_disable(cam);
954
955 return rval;
956}
957
958static void omap24xxcam_sensor_reset_work(struct work_struct *work)
959{
960 struct omap24xxcam_device *cam =
961 container_of(work, struct omap24xxcam_device,
962 sensor_reset_work);
963
964 if (atomic_read(&cam->reset_disable))
965 return;
966
967 omap24xxcam_capture_stop(cam);
968
969 if (vidioc_int_reset(cam->sdev) == 0) {
970 vidioc_int_init(cam->sdev);
971 } else {
972 /* Can't reset it by vidioc_int_reset. */
973 omap24xxcam_sensor_disable(cam);
974 omap24xxcam_sensor_enable(cam);
975 }
976
977 omap24xxcam_capture_cont(cam);
978}
979
980/*
981 *
982 * IOCTL interface.
983 *
984 */
985
986static int vidioc_querycap(struct file *file, void *fh,
987 struct v4l2_capability *cap)
988{
989 struct omap24xxcam_fh *ofh = fh;
990 struct omap24xxcam_device *cam = ofh->cam;
991
992 strlcpy(cap->driver, CAM_NAME, sizeof(cap->driver));
993 strlcpy(cap->card, cam->vfd->name, sizeof(cap->card));
994 cap->version = OMAP24XXCAM_VERSION;
995 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
996
997 return 0;
998}
999
1000static int vidioc_enum_fmt_vid_cap(struct file *file, void *fh,
1001 struct v4l2_fmtdesc *f)
1002{
1003 struct omap24xxcam_fh *ofh = fh;
1004 struct omap24xxcam_device *cam = ofh->cam;
1005 int rval;
1006
1007 rval = vidioc_int_enum_fmt_cap(cam->sdev, f);
1008
1009 return rval;
1010}
1011
1012static int vidioc_g_fmt_vid_cap(struct file *file, void *fh,
1013 struct v4l2_format *f)
1014{
1015 struct omap24xxcam_fh *ofh = fh;
1016 struct omap24xxcam_device *cam = ofh->cam;
1017 int rval;
1018
1019 mutex_lock(&cam->mutex);
1020 rval = vidioc_int_g_fmt_cap(cam->sdev, f);
1021 mutex_unlock(&cam->mutex);
1022
1023 return rval;
1024}
1025
1026static int vidioc_s_fmt_vid_cap(struct file *file, void *fh,
1027 struct v4l2_format *f)
1028{
1029 struct omap24xxcam_fh *ofh = fh;
1030 struct omap24xxcam_device *cam = ofh->cam;
1031 int rval;
1032
1033 mutex_lock(&cam->mutex);
1034 if (cam->streaming) {
1035 rval = -EBUSY;
1036 goto out;
1037 }
1038
1039 rval = vidioc_int_s_fmt_cap(cam->sdev, f);
1040
1041out:
1042 mutex_unlock(&cam->mutex);
1043
1044 if (!rval) {
1045 mutex_lock(&ofh->vbq.vb_lock);
1046 ofh->pix = f->fmt.pix;
1047 mutex_unlock(&ofh->vbq.vb_lock);
1048 }
1049
1050 memset(f, 0, sizeof(*f));
1051 vidioc_g_fmt_vid_cap(file, fh, f);
1052
1053 return rval;
1054}
1055
1056static int vidioc_try_fmt_vid_cap(struct file *file, void *fh,
1057 struct v4l2_format *f)
1058{
1059 struct omap24xxcam_fh *ofh = fh;
1060 struct omap24xxcam_device *cam = ofh->cam;
1061 int rval;
1062
1063 mutex_lock(&cam->mutex);
1064 rval = vidioc_int_try_fmt_cap(cam->sdev, f);
1065 mutex_unlock(&cam->mutex);
1066
1067 return rval;
1068}
1069
1070static int vidioc_reqbufs(struct file *file, void *fh,
1071 struct v4l2_requestbuffers *b)
1072{
1073 struct omap24xxcam_fh *ofh = fh;
1074 struct omap24xxcam_device *cam = ofh->cam;
1075 int rval;
1076
1077 mutex_lock(&cam->mutex);
1078 if (cam->streaming) {
1079 mutex_unlock(&cam->mutex);
1080 return -EBUSY;
1081 }
1082
1083 omap24xxcam_vbq_free_mmap_buffers(&ofh->vbq);
1084 mutex_unlock(&cam->mutex);
1085
1086 rval = videobuf_reqbufs(&ofh->vbq, b);
1087
1088 /*
1089 * Either videobuf_reqbufs failed or the buffers are not
1090 * memory-mapped (which would need special attention).
1091 */
1092 if (rval < 0 || b->memory != V4L2_MEMORY_MMAP)
1093 goto out;
1094
1095 rval = omap24xxcam_vbq_alloc_mmap_buffers(&ofh->vbq, rval);
1096 if (rval)
1097 omap24xxcam_vbq_free_mmap_buffers(&ofh->vbq);
1098
1099out:
1100 return rval;
1101}
1102
1103static int vidioc_querybuf(struct file *file, void *fh,
1104 struct v4l2_buffer *b)
1105{
1106 struct omap24xxcam_fh *ofh = fh;
1107
1108 return videobuf_querybuf(&ofh->vbq, b);
1109}
1110
1111static int vidioc_qbuf(struct file *file, void *fh, struct v4l2_buffer *b)
1112{
1113 struct omap24xxcam_fh *ofh = fh;
1114
1115 return videobuf_qbuf(&ofh->vbq, b);
1116}
1117
1118static int vidioc_dqbuf(struct file *file, void *fh, struct v4l2_buffer *b)
1119{
1120 struct omap24xxcam_fh *ofh = fh;
1121 struct omap24xxcam_device *cam = ofh->cam;
1122 struct videobuf_buffer *vb;
1123 int rval;
1124
1125videobuf_dqbuf_again:
1126 rval = videobuf_dqbuf(&ofh->vbq, b, file->f_flags & O_NONBLOCK);
1127 if (rval)
1128 goto out;
1129
1130 vb = ofh->vbq.bufs[b->index];
1131
1132 mutex_lock(&cam->mutex);
1133 /* _needs_reset returns -EIO if reset is required. */
1134 rval = vidioc_int_g_needs_reset(cam->sdev, (void *)vb->baddr);
1135 mutex_unlock(&cam->mutex);
1136 if (rval == -EIO)
1137 schedule_work(&cam->sensor_reset_work);
1138 else
1139 rval = 0;
1140
1141out:
1142 /*
1143 * This is a hack. We don't want to show -EIO to the user
1144 * space. Requeue the buffer and try again if we're not doing
1145 * this in non-blocking mode.
1146 */
1147 if (rval == -EIO) {
1148 videobuf_qbuf(&ofh->vbq, b);
1149 if (!(file->f_flags & O_NONBLOCK))
1150 goto videobuf_dqbuf_again;
1151 /*
1152 * We don't have a videobuf_buffer now --- maybe next
1153 * time...
1154 */
1155 rval = -EAGAIN;
1156 }
1157
1158 return rval;
1159}
1160
1161static int vidioc_streamon(struct file *file, void *fh, enum v4l2_buf_type i)
1162{
1163 struct omap24xxcam_fh *ofh = fh;
1164 struct omap24xxcam_device *cam = ofh->cam;
1165 int rval;
1166
1167 mutex_lock(&cam->mutex);
1168 if (cam->streaming) {
1169 rval = -EBUSY;
1170 goto out;
1171 }
1172
1173 rval = omap24xxcam_sensor_if_enable(cam);
1174 if (rval) {
1175 dev_dbg(cam->dev, "vidioc_int_g_ifparm failed\n");
1176 goto out;
1177 }
1178
1179 rval = videobuf_streamon(&ofh->vbq);
1180 if (!rval) {
1181 cam->streaming = file;
1182 sysfs_notify(&cam->dev->kobj, NULL, "streaming");
1183 }
1184
1185out:
1186 mutex_unlock(&cam->mutex);
1187
1188 return rval;
1189}
1190
1191static int vidioc_streamoff(struct file *file, void *fh, enum v4l2_buf_type i)
1192{
1193 struct omap24xxcam_fh *ofh = fh;
1194 struct omap24xxcam_device *cam = ofh->cam;
1195 struct videobuf_queue *q = &ofh->vbq;
1196 int rval;
1197
1198 atomic_inc(&cam->reset_disable);
1199
1200 flush_scheduled_work();
1201
1202 rval = videobuf_streamoff(q);
1203 if (!rval) {
1204 mutex_lock(&cam->mutex);
1205 cam->streaming = NULL;
1206 mutex_unlock(&cam->mutex);
1207 sysfs_notify(&cam->dev->kobj, NULL, "streaming");
1208 }
1209
1210 atomic_dec(&cam->reset_disable);
1211
1212 return rval;
1213}
1214
1215static int vidioc_enum_input(struct file *file, void *fh,
1216 struct v4l2_input *inp)
1217{
1218 if (inp->index > 0)
1219 return -EINVAL;
1220
1221 strlcpy(inp->name, "camera", sizeof(inp->name));
1222 inp->type = V4L2_INPUT_TYPE_CAMERA;
1223
1224 return 0;
1225}
1226
1227static int vidioc_g_input(struct file *file, void *fh, unsigned int *i)
1228{
1229 *i = 0;
1230
1231 return 0;
1232}
1233
1234static int vidioc_s_input(struct file *file, void *fh, unsigned int i)
1235{
1236 if (i > 0)
1237 return -EINVAL;
1238
1239 return 0;
1240}
1241
1242static int vidioc_queryctrl(struct file *file, void *fh,
1243 struct v4l2_queryctrl *a)
1244{
1245 struct omap24xxcam_fh *ofh = fh;
1246 struct omap24xxcam_device *cam = ofh->cam;
1247 int rval;
1248
1249 rval = vidioc_int_queryctrl(cam->sdev, a);
1250
1251 return rval;
1252}
1253
1254static int vidioc_g_ctrl(struct file *file, void *fh,
1255 struct v4l2_control *a)
1256{
1257 struct omap24xxcam_fh *ofh = fh;
1258 struct omap24xxcam_device *cam = ofh->cam;
1259 int rval;
1260
1261 mutex_lock(&cam->mutex);
1262 rval = vidioc_int_g_ctrl(cam->sdev, a);
1263 mutex_unlock(&cam->mutex);
1264
1265 return rval;
1266}
1267
1268static int vidioc_s_ctrl(struct file *file, void *fh,
1269 struct v4l2_control *a)
1270{
1271 struct omap24xxcam_fh *ofh = fh;
1272 struct omap24xxcam_device *cam = ofh->cam;
1273 int rval;
1274
1275 mutex_lock(&cam->mutex);
1276 rval = vidioc_int_s_ctrl(cam->sdev, a);
1277 mutex_unlock(&cam->mutex);
1278
1279 return rval;
1280}
1281
1282static int vidioc_g_parm(struct file *file, void *fh,
1283 struct v4l2_streamparm *a) {
1284 struct omap24xxcam_fh *ofh = fh;
1285 struct omap24xxcam_device *cam = ofh->cam;
1286 int rval;
1287
1288 if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1289 return -EINVAL;
1290
1291 mutex_lock(&cam->mutex);
1292 rval = vidioc_int_g_parm(cam->sdev, a);
1293 mutex_unlock(&cam->mutex);
1294
1295 return rval;
1296}
1297
1298static int vidioc_s_parm(struct file *file, void *fh,
1299 struct v4l2_streamparm *a)
1300{
1301 struct omap24xxcam_fh *ofh = fh;
1302 struct omap24xxcam_device *cam = ofh->cam;
1303 struct v4l2_streamparm old_streamparm;
1304 int rval;
1305
1306 if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1307 return -EINVAL;
1308
1309 mutex_lock(&cam->mutex);
1310 if (cam->streaming) {
1311 rval = -EBUSY;
1312 goto out;
1313 }
1314
1315 old_streamparm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1316 rval = vidioc_int_g_parm(cam->sdev, &old_streamparm);
1317 if (rval)
1318 goto out;
1319
1320 rval = vidioc_int_s_parm(cam->sdev, a);
1321 if (rval)
1322 goto out;
1323
1324 rval = omap24xxcam_sensor_if_enable(cam);
1325 /*
1326 * Revert to old streaming parameters if enabling sensor
1327 * interface with the new ones failed.
1328 */
1329 if (rval)
1330 vidioc_int_s_parm(cam->sdev, &old_streamparm);
1331
1332out:
1333 mutex_unlock(&cam->mutex);
1334
1335 return rval;
1336}
1337
1338/*
1339 *
1340 * File operations.
1341 *
1342 */
1343
1344static unsigned int omap24xxcam_poll(struct file *file,
1345 struct poll_table_struct *wait)
1346{
1347 struct omap24xxcam_fh *fh = file->private_data;
1348 struct omap24xxcam_device *cam = fh->cam;
1349 struct videobuf_buffer *vb;
1350
1351 mutex_lock(&cam->mutex);
1352 if (cam->streaming != file) {
1353 mutex_unlock(&cam->mutex);
1354 return POLLERR;
1355 }
1356 mutex_unlock(&cam->mutex);
1357
1358 mutex_lock(&fh->vbq.vb_lock);
1359 if (list_empty(&fh->vbq.stream)) {
1360 mutex_unlock(&fh->vbq.vb_lock);
1361 return POLLERR;
1362 }
1363 vb = list_entry(fh->vbq.stream.next, struct videobuf_buffer, stream);
1364 mutex_unlock(&fh->vbq.vb_lock);
1365
1366 poll_wait(file, &vb->done, wait);
1367
1368 if (vb->state == VIDEOBUF_DONE || vb->state == VIDEOBUF_ERROR)
1369 return POLLIN | POLLRDNORM;
1370
1371 return 0;
1372}
1373
1374static int omap24xxcam_mmap_buffers(struct file *file,
1375 struct vm_area_struct *vma)
1376{
1377 struct omap24xxcam_fh *fh = file->private_data;
1378 struct omap24xxcam_device *cam = fh->cam;
1379 struct videobuf_queue *vbq = &fh->vbq;
1380 unsigned int first, last, size, i, j;
1381 int err = 0;
1382
1383 mutex_lock(&cam->mutex);
1384 if (cam->streaming) {
1385 mutex_unlock(&cam->mutex);
1386 return -EBUSY;
1387 }
1388 mutex_unlock(&cam->mutex);
1389 mutex_lock(&vbq->vb_lock);
1390
1391 /* look for first buffer to map */
1392 for (first = 0; first < VIDEO_MAX_FRAME; first++) {
1393 if (NULL == vbq->bufs[first])
1394 continue;
1395 if (V4L2_MEMORY_MMAP != vbq->bufs[first]->memory)
1396 continue;
1397 if (vbq->bufs[first]->boff == (vma->vm_pgoff << PAGE_SHIFT))
1398 break;
1399 }
1400
1401 /* look for last buffer to map */
1402 for (size = 0, last = first; last < VIDEO_MAX_FRAME; last++) {
1403 if (NULL == vbq->bufs[last])
1404 continue;
1405 if (V4L2_MEMORY_MMAP != vbq->bufs[last]->memory)
1406 continue;
1407 size += vbq->bufs[last]->bsize;
1408 if (size == (vma->vm_end - vma->vm_start))
1409 break;
1410 }
1411
1412 size = 0;
1413 for (i = first; i <= last; i++) {
1414 struct videobuf_dmabuf *dma = videobuf_to_dma(vbq->bufs[i]);
1415
1416 for (j = 0; j < dma->sglen; j++) {
1417 err = remap_pfn_range(
1418 vma, vma->vm_start + size,
1419 page_to_pfn(sg_page(&dma->sglist[j])),
1420 sg_dma_len(&dma->sglist[j]), vma->vm_page_prot);
1421 if (err)
1422 goto out;
1423 size += sg_dma_len(&dma->sglist[j]);
1424 }
1425 }
1426
1427out:
1428 mutex_unlock(&vbq->vb_lock);
1429
1430 return err;
1431}
1432
1433static int omap24xxcam_mmap(struct file *file, struct vm_area_struct *vma)
1434{
1435 struct omap24xxcam_fh *fh = file->private_data;
1436 int rval;
1437
1438 /* let the video-buf mapper check arguments and set-up structures */
1439 rval = videobuf_mmap_mapper(&fh->vbq, vma);
1440 if (rval)
1441 return rval;
1442
1443 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
1444
1445 /* do mapping to our allocated buffers */
1446 rval = omap24xxcam_mmap_buffers(file, vma);
1447 /*
1448 * In case of error, free vma->vm_private_data allocated by
1449 * videobuf_mmap_mapper.
1450 */
1451 if (rval)
1452 kfree(vma->vm_private_data);
1453
1454 return rval;
1455}
1456
1457static int omap24xxcam_open(struct inode *inode, struct file *file)
1458{
1459 int minor = iminor(inode);
1460 struct omap24xxcam_device *cam = omap24xxcam.priv;
1461 struct omap24xxcam_fh *fh;
1462 struct v4l2_format format;
1463
1464 if (!cam || !cam->vfd || (cam->vfd->minor != minor))
1465 return -ENODEV;
1466
1467 fh = kzalloc(sizeof(*fh), GFP_KERNEL);
1468 if (fh == NULL)
1469 return -ENOMEM;
1470
1471 mutex_lock(&cam->mutex);
1472 if (cam->sdev == NULL || !try_module_get(cam->sdev->module)) {
1473 mutex_unlock(&cam->mutex);
1474 goto out_try_module_get;
1475 }
1476
1477 if (atomic_inc_return(&cam->users) == 1) {
1478 omap24xxcam_hwinit(cam);
1479 if (omap24xxcam_sensor_enable(cam)) {
1480 mutex_unlock(&cam->mutex);
1481 goto out_omap24xxcam_sensor_enable;
1482 }
1483 }
1484 mutex_unlock(&cam->mutex);
1485
1486 fh->cam = cam;
1487 mutex_lock(&cam->mutex);
1488 vidioc_int_g_fmt_cap(cam->sdev, &format);
1489 mutex_unlock(&cam->mutex);
1490 /* FIXME: how about fh->pix when there are more users? */
1491 fh->pix = format.fmt.pix;
1492
1493 file->private_data = fh;
1494
1495 spin_lock_init(&fh->vbq_lock);
1496
1497 videobuf_queue_sg_init(&fh->vbq, &omap24xxcam_vbq_ops, NULL,
1498 &fh->vbq_lock, V4L2_BUF_TYPE_VIDEO_CAPTURE,
1499 V4L2_FIELD_NONE,
1500 sizeof(struct videobuf_buffer), fh);
1501
1502 return 0;
1503
1504out_omap24xxcam_sensor_enable:
1505 omap24xxcam_poweron_reset(cam);
1506 module_put(cam->sdev->module);
1507
1508out_try_module_get:
1509 kfree(fh);
1510
1511 return -ENODEV;
1512}
1513
1514static int omap24xxcam_release(struct inode *inode, struct file *file)
1515{
1516 struct omap24xxcam_fh *fh = file->private_data;
1517 struct omap24xxcam_device *cam = fh->cam;
1518
1519 atomic_inc(&cam->reset_disable);
1520
1521 flush_scheduled_work();
1522
1523 /* stop streaming capture */
1524 videobuf_streamoff(&fh->vbq);
1525
1526 mutex_lock(&cam->mutex);
1527 if (cam->streaming == file) {
1528 cam->streaming = NULL;
1529 mutex_unlock(&cam->mutex);
1530 sysfs_notify(&cam->dev->kobj, NULL, "streaming");
1531 } else {
1532 mutex_unlock(&cam->mutex);
1533 }
1534
1535 atomic_dec(&cam->reset_disable);
1536
1537 omap24xxcam_vbq_free_mmap_buffers(&fh->vbq);
1538
1539 /*
1540 * Make sure the reset work we might have scheduled is not
1541 * pending! It may be run *only* if we have users. (And it may
1542 * not be scheduled anymore since streaming is already
1543 * disabled.)
1544 */
1545 flush_scheduled_work();
1546
1547 mutex_lock(&cam->mutex);
1548 if (atomic_dec_return(&cam->users) == 0) {
1549 omap24xxcam_sensor_disable(cam);
1550 omap24xxcam_poweron_reset(cam);
1551 }
1552 mutex_unlock(&cam->mutex);
1553
1554 file->private_data = NULL;
1555
1556 module_put(cam->sdev->module);
1557 kfree(fh);
1558
1559 return 0;
1560}
1561
1562static struct file_operations omap24xxcam_fops = {
1563 .llseek = no_llseek,
1564 .ioctl = video_ioctl2,
1565 .poll = omap24xxcam_poll,
1566 .mmap = omap24xxcam_mmap,
1567 .open = omap24xxcam_open,
1568 .release = omap24xxcam_release,
1569};
1570
1571/*
1572 *
1573 * Power management.
1574 *
1575 */
1576
1577#ifdef CONFIG_PM
1578static int omap24xxcam_suspend(struct platform_device *pdev, pm_message_t state)
1579{
1580 struct omap24xxcam_device *cam = platform_get_drvdata(pdev);
1581
1582 if (atomic_read(&cam->users) == 0)
1583 return 0;
1584
1585 if (!atomic_read(&cam->reset_disable))
1586 omap24xxcam_capture_stop(cam);
1587
1588 omap24xxcam_sensor_disable(cam);
1589 omap24xxcam_poweron_reset(cam);
1590
1591 return 0;
1592}
1593
1594static int omap24xxcam_resume(struct platform_device *pdev)
1595{
1596 struct omap24xxcam_device *cam = platform_get_drvdata(pdev);
1597
1598 if (atomic_read(&cam->users) == 0)
1599 return 0;
1600
1601 omap24xxcam_hwinit(cam);
1602 omap24xxcam_sensor_enable(cam);
1603
1604 if (!atomic_read(&cam->reset_disable))
1605 omap24xxcam_capture_cont(cam);
1606
1607 return 0;
1608}
1609#endif /* CONFIG_PM */
1610
1611static const struct v4l2_ioctl_ops omap24xxcam_ioctl_fops = {
1612 .vidioc_querycap = vidioc_querycap,
1613 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
1614 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
1615 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
1616 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
1617 .vidioc_reqbufs = vidioc_reqbufs,
1618 .vidioc_querybuf = vidioc_querybuf,
1619 .vidioc_qbuf = vidioc_qbuf,
1620 .vidioc_dqbuf = vidioc_dqbuf,
1621 .vidioc_streamon = vidioc_streamon,
1622 .vidioc_streamoff = vidioc_streamoff,
1623 .vidioc_enum_input = vidioc_enum_input,
1624 .vidioc_g_input = vidioc_g_input,
1625 .vidioc_s_input = vidioc_s_input,
1626 .vidioc_queryctrl = vidioc_queryctrl,
1627 .vidioc_g_ctrl = vidioc_g_ctrl,
1628 .vidioc_s_ctrl = vidioc_s_ctrl,
1629 .vidioc_g_parm = vidioc_g_parm,
1630 .vidioc_s_parm = vidioc_s_parm,
1631};
1632
1633/*
1634 *
1635 * Camera device (i.e. /dev/video).
1636 *
1637 */
1638
1639static int omap24xxcam_device_register(struct v4l2_int_device *s)
1640{
1641 struct omap24xxcam_device *cam = s->u.slave->master->priv;
1642 struct video_device *vfd;
1643 int rval;
1644
1645 /* We already have a slave. */
1646 if (cam->sdev)
1647 return -EBUSY;
1648
1649 cam->sdev = s;
1650
1651 if (device_create_file(cam->dev, &dev_attr_streaming) != 0) {
1652 dev_err(cam->dev, "could not register sysfs entry\n");
1653 rval = -EBUSY;
1654 goto err;
1655 }
1656
1657 /* initialize the video_device struct */
1658 vfd = cam->vfd = video_device_alloc();
1659 if (!vfd) {
1660 dev_err(cam->dev, "could not allocate video device struct\n");
1661 rval = -ENOMEM;
1662 goto err;
1663 }
1664 vfd->release = video_device_release;
1665
1666 vfd->parent = cam->dev;
1667
1668 strlcpy(vfd->name, CAM_NAME, sizeof(vfd->name));
1669 vfd->vfl_type = VID_TYPE_CAPTURE | VID_TYPE_CHROMAKEY;
1670 vfd->fops = &omap24xxcam_fops;
1671 vfd->minor = -1;
1672 vfd->ioctl_ops = &omap24xxcam_ioctl_fops;
1673
1674 omap24xxcam_hwinit(cam);
1675
1676 rval = omap24xxcam_sensor_init(cam);
1677 if (rval)
1678 goto err;
1679
1680 if (video_register_device(vfd, VFL_TYPE_GRABBER, video_nr) < 0) {
1681 dev_err(cam->dev, "could not register V4L device\n");
1682 vfd->minor = -1;
1683 rval = -EBUSY;
1684 goto err;
1685 }
1686
1687 omap24xxcam_poweron_reset(cam);
1688
1689 dev_info(cam->dev, "registered device video%d\n", vfd->minor);
1690
1691 return 0;
1692
1693err:
1694 omap24xxcam_device_unregister(s);
1695
1696 return rval;
1697}
1698
1699static void omap24xxcam_device_unregister(struct v4l2_int_device *s)
1700{
1701 struct omap24xxcam_device *cam = s->u.slave->master->priv;
1702
1703 omap24xxcam_sensor_exit(cam);
1704
1705 if (cam->vfd) {
1706 if (cam->vfd->minor == -1) {
1707 /*
1708 * The device was never registered, so release the
1709 * video_device struct directly.
1710 */
1711 video_device_release(cam->vfd);
1712 } else {
1713 /*
1714 * The unregister function will release the
1715 * video_device struct as well as
1716 * unregistering it.
1717 */
1718 video_unregister_device(cam->vfd);
1719 }
1720 cam->vfd = NULL;
1721 }
1722
1723 device_remove_file(cam->dev, &dev_attr_streaming);
1724
1725 cam->sdev = NULL;
1726}
1727
1728static struct v4l2_int_master omap24xxcam_master = {
1729 .attach = omap24xxcam_device_register,
1730 .detach = omap24xxcam_device_unregister,
1731};
1732
1733static struct v4l2_int_device omap24xxcam = {
1734 .module = THIS_MODULE,
1735 .name = CAM_NAME,
1736 .type = v4l2_int_type_master,
1737 .u = {
1738 .master = &omap24xxcam_master
1739 },
1740};
1741
1742/*
1743 *
1744 * Driver initialisation and deinitialisation.
1745 *
1746 */
1747
1748static int __init omap24xxcam_probe(struct platform_device *pdev)
1749{
1750 struct omap24xxcam_device *cam;
1751 struct resource *mem;
1752 int irq;
1753
1754 cam = kzalloc(sizeof(*cam), GFP_KERNEL);
1755 if (!cam) {
1756 dev_err(&pdev->dev, "could not allocate memory\n");
1757 goto err;
1758 }
1759
1760 platform_set_drvdata(pdev, cam);
1761
1762 cam->dev = &pdev->dev;
1763
1764 /*
1765 * Impose a lower limit on the amount of memory allocated for
1766 * capture. We require at least enough memory to double-buffer
1767 * QVGA (300KB).
1768 */
1769 if (capture_mem < 320 * 240 * 2 * 2)
1770 capture_mem = 320 * 240 * 2 * 2;
1771 cam->capture_mem = capture_mem;
1772
1773 /* request the mem region for the camera registers */
1774 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1775 if (!mem) {
1776 dev_err(cam->dev, "no mem resource?\n");
1777 goto err;
1778 }
1779 if (!request_mem_region(mem->start, (mem->end - mem->start) + 1,
1780 pdev->name)) {
1781 dev_err(cam->dev,
1782 "cannot reserve camera register I/O region\n");
1783 goto err;
1784 }
1785 cam->mmio_base_phys = mem->start;
1786 cam->mmio_size = (mem->end - mem->start) + 1;
1787
1788 /* map the region */
1789 cam->mmio_base = (unsigned long)
1790 ioremap_nocache(cam->mmio_base_phys, cam->mmio_size);
1791 if (!cam->mmio_base) {
1792 dev_err(cam->dev, "cannot map camera register I/O region\n");
1793 goto err;
1794 }
1795
1796 irq = platform_get_irq(pdev, 0);
1797 if (irq <= 0) {
1798 dev_err(cam->dev, "no irq for camera?\n");
1799 goto err;
1800 }
1801
1802 /* install the interrupt service routine */
1803 if (request_irq(irq, omap24xxcam_isr, 0, CAM_NAME, cam)) {
1804 dev_err(cam->dev,
1805 "could not install interrupt service routine\n");
1806 goto err;
1807 }
1808 cam->irq = irq;
1809
1810 if (omap24xxcam_clock_get(cam))
1811 goto err;
1812
1813 INIT_WORK(&cam->sensor_reset_work, omap24xxcam_sensor_reset_work);
1814
1815 mutex_init(&cam->mutex);
1816 spin_lock_init(&cam->core_enable_disable_lock);
1817
1818 omap24xxcam_sgdma_init(&cam->sgdma,
1819 cam->mmio_base + CAMDMA_REG_OFFSET,
1820 omap24xxcam_stalled_dma_reset,
1821 (unsigned long)cam);
1822
1823 omap24xxcam.priv = cam;
1824
1825 if (v4l2_int_device_register(&omap24xxcam))
1826 goto err;
1827
1828 return 0;
1829
1830err:
1831 omap24xxcam_remove(pdev);
1832 return -ENODEV;
1833}
1834
1835static int omap24xxcam_remove(struct platform_device *pdev)
1836{
1837 struct omap24xxcam_device *cam = platform_get_drvdata(pdev);
1838
1839 if (!cam)
1840 return 0;
1841
1842 if (omap24xxcam.priv != NULL)
1843 v4l2_int_device_unregister(&omap24xxcam);
1844 omap24xxcam.priv = NULL;
1845
1846 omap24xxcam_clock_put(cam);
1847
1848 if (cam->irq) {
1849 free_irq(cam->irq, cam);
1850 cam->irq = 0;
1851 }
1852
1853 if (cam->mmio_base) {
1854 iounmap((void *)cam->mmio_base);
1855 cam->mmio_base = 0;
1856 }
1857
1858 if (cam->mmio_base_phys) {
1859 release_mem_region(cam->mmio_base_phys, cam->mmio_size);
1860 cam->mmio_base_phys = 0;
1861 }
1862
1863 kfree(cam);
1864
1865 return 0;
1866}
1867
1868static struct platform_driver omap24xxcam_driver = {
1869 .probe = omap24xxcam_probe,
1870 .remove = omap24xxcam_remove,
1871#ifdef CONFIG_PM
1872 .suspend = omap24xxcam_suspend,
1873 .resume = omap24xxcam_resume,
1874#endif
1875 .driver = {
1876 .name = CAM_NAME,
1877 .owner = THIS_MODULE,
1878 },
1879};
1880
1881/*
1882 *
1883 * Module initialisation and deinitialisation
1884 *
1885 */
1886
1887static int __init omap24xxcam_init(void)
1888{
1889 return platform_driver_register(&omap24xxcam_driver);
1890}
1891
1892static void __exit omap24xxcam_cleanup(void)
1893{
1894 platform_driver_unregister(&omap24xxcam_driver);
1895}
1896
1897MODULE_AUTHOR("Sakari Ailus <sakari.ailus@nokia.com>");
1898MODULE_DESCRIPTION("OMAP24xx Video for Linux camera driver");
1899MODULE_LICENSE("GPL");
1900module_param(video_nr, int, 0);
1901MODULE_PARM_DESC(video_nr,
1902 "Minor number for video device (-1 ==> auto assign)");
1903module_param(capture_mem, int, 0);
1904MODULE_PARM_DESC(capture_mem, "Maximum amount of memory for capture "
1905 "buffers (default 4800kiB)");
1906
1907module_init(omap24xxcam_init);
1908module_exit(omap24xxcam_cleanup);
diff --git a/drivers/media/video/omap24xxcam.h b/drivers/media/video/omap24xxcam.h
new file mode 100644
index 000000000000..2ce67f5a48d5
--- /dev/null
+++ b/drivers/media/video/omap24xxcam.h
@@ -0,0 +1,593 @@
1/*
2 * drivers/media/video/omap24xxcam.h
3 *
4 * Copyright (C) 2004 MontaVista Software, Inc.
5 * Copyright (C) 2004 Texas Instruments.
6 * Copyright (C) 2007 Nokia Corporation.
7 *
8 * Contact: Sakari Ailus <sakari.ailus@nokia.com>
9 *
10 * Based on code from Andy Lowe <source@mvista.com>.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * version 2 as published by the Free Software Foundation.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * 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., 51 Franklin St, Fifth Floor, Boston, MA
24 * 02110-1301 USA
25 */
26
27#ifndef OMAP24XXCAM_H
28#define OMAP24XXCAM_H
29
30#include <media/videobuf-dma-sg.h>
31#include <media/v4l2-int-device.h>
32
33/*
34 *
35 * General driver related definitions.
36 *
37 */
38
39#define CAM_NAME "omap24xxcam"
40
41#define CAM_MCLK 96000000
42
43/* number of bytes transferred per DMA request */
44#define DMA_THRESHOLD 32
45
46/*
47 * NUM_CAMDMA_CHANNELS is the number of logical channels provided by
48 * the camera DMA controller.
49 */
50#define NUM_CAMDMA_CHANNELS 4
51
52/*
53 * NUM_SG_DMA is the number of scatter-gather DMA transfers that can
54 * be queued. (We don't have any overlay sglists now.)
55 */
56#define NUM_SG_DMA (VIDEO_MAX_FRAME)
57
58/*
59 *
60 * Register definitions.
61 *
62 */
63
64/* subsystem register block offsets */
65#define CC_REG_OFFSET 0x00000400
66#define CAMDMA_REG_OFFSET 0x00000800
67#define CAMMMU_REG_OFFSET 0x00000C00
68
69/* define camera subsystem register offsets */
70#define CAM_REVISION 0x000
71#define CAM_SYSCONFIG 0x010
72#define CAM_SYSSTATUS 0x014
73#define CAM_IRQSTATUS 0x018
74#define CAM_GPO 0x040
75#define CAM_GPI 0x050
76
77/* define camera core register offsets */
78#define CC_REVISION 0x000
79#define CC_SYSCONFIG 0x010
80#define CC_SYSSTATUS 0x014
81#define CC_IRQSTATUS 0x018
82#define CC_IRQENABLE 0x01C
83#define CC_CTRL 0x040
84#define CC_CTRL_DMA 0x044
85#define CC_CTRL_XCLK 0x048
86#define CC_FIFODATA 0x04C
87#define CC_TEST 0x050
88#define CC_GENPAR 0x054
89#define CC_CCPFSCR 0x058
90#define CC_CCPFECR 0x05C
91#define CC_CCPLSCR 0x060
92#define CC_CCPLECR 0x064
93#define CC_CCPDFR 0x068
94
95/* define camera dma register offsets */
96#define CAMDMA_REVISION 0x000
97#define CAMDMA_IRQSTATUS_L0 0x008
98#define CAMDMA_IRQSTATUS_L1 0x00C
99#define CAMDMA_IRQSTATUS_L2 0x010
100#define CAMDMA_IRQSTATUS_L3 0x014
101#define CAMDMA_IRQENABLE_L0 0x018
102#define CAMDMA_IRQENABLE_L1 0x01C
103#define CAMDMA_IRQENABLE_L2 0x020
104#define CAMDMA_IRQENABLE_L3 0x024
105#define CAMDMA_SYSSTATUS 0x028
106#define CAMDMA_OCP_SYSCONFIG 0x02C
107#define CAMDMA_CAPS_0 0x064
108#define CAMDMA_CAPS_2 0x06C
109#define CAMDMA_CAPS_3 0x070
110#define CAMDMA_CAPS_4 0x074
111#define CAMDMA_GCR 0x078
112#define CAMDMA_CCR(n) (0x080 + (n)*0x60)
113#define CAMDMA_CLNK_CTRL(n) (0x084 + (n)*0x60)
114#define CAMDMA_CICR(n) (0x088 + (n)*0x60)
115#define CAMDMA_CSR(n) (0x08C + (n)*0x60)
116#define CAMDMA_CSDP(n) (0x090 + (n)*0x60)
117#define CAMDMA_CEN(n) (0x094 + (n)*0x60)
118#define CAMDMA_CFN(n) (0x098 + (n)*0x60)
119#define CAMDMA_CSSA(n) (0x09C + (n)*0x60)
120#define CAMDMA_CDSA(n) (0x0A0 + (n)*0x60)
121#define CAMDMA_CSEI(n) (0x0A4 + (n)*0x60)
122#define CAMDMA_CSFI(n) (0x0A8 + (n)*0x60)
123#define CAMDMA_CDEI(n) (0x0AC + (n)*0x60)
124#define CAMDMA_CDFI(n) (0x0B0 + (n)*0x60)
125#define CAMDMA_CSAC(n) (0x0B4 + (n)*0x60)
126#define CAMDMA_CDAC(n) (0x0B8 + (n)*0x60)
127#define CAMDMA_CCEN(n) (0x0BC + (n)*0x60)
128#define CAMDMA_CCFN(n) (0x0C0 + (n)*0x60)
129#define CAMDMA_COLOR(n) (0x0C4 + (n)*0x60)
130
131/* define camera mmu register offsets */
132#define CAMMMU_REVISION 0x000
133#define CAMMMU_SYSCONFIG 0x010
134#define CAMMMU_SYSSTATUS 0x014
135#define CAMMMU_IRQSTATUS 0x018
136#define CAMMMU_IRQENABLE 0x01C
137#define CAMMMU_WALKING_ST 0x040
138#define CAMMMU_CNTL 0x044
139#define CAMMMU_FAULT_AD 0x048
140#define CAMMMU_TTB 0x04C
141#define CAMMMU_LOCK 0x050
142#define CAMMMU_LD_TLB 0x054
143#define CAMMMU_CAM 0x058
144#define CAMMMU_RAM 0x05C
145#define CAMMMU_GFLUSH 0x060
146#define CAMMMU_FLUSH_ENTRY 0x064
147#define CAMMMU_READ_CAM 0x068
148#define CAMMMU_READ_RAM 0x06C
149#define CAMMMU_EMU_FAULT_AD 0x070
150
151/* Define bit fields within selected registers */
152#define CAM_REVISION_MAJOR (15 << 4)
153#define CAM_REVISION_MAJOR_SHIFT 4
154#define CAM_REVISION_MINOR (15 << 0)
155#define CAM_REVISION_MINOR_SHIFT 0
156
157#define CAM_SYSCONFIG_SOFTRESET (1 << 1)
158#define CAM_SYSCONFIG_AUTOIDLE (1 << 0)
159
160#define CAM_SYSSTATUS_RESETDONE (1 << 0)
161
162#define CAM_IRQSTATUS_CC_IRQ (1 << 4)
163#define CAM_IRQSTATUS_MMU_IRQ (1 << 3)
164#define CAM_IRQSTATUS_DMA_IRQ2 (1 << 2)
165#define CAM_IRQSTATUS_DMA_IRQ1 (1 << 1)
166#define CAM_IRQSTATUS_DMA_IRQ0 (1 << 0)
167
168#define CAM_GPO_CAM_S_P_EN (1 << 1)
169#define CAM_GPO_CAM_CCP_MODE (1 << 0)
170
171#define CAM_GPI_CC_DMA_REQ1 (1 << 24)
172#define CAP_GPI_CC_DMA_REQ0 (1 << 23)
173#define CAP_GPI_CAM_MSTANDBY (1 << 21)
174#define CAP_GPI_CAM_WAIT (1 << 20)
175#define CAP_GPI_CAM_S_DATA (1 << 17)
176#define CAP_GPI_CAM_S_CLK (1 << 16)
177#define CAP_GPI_CAM_P_DATA (0xFFF << 3)
178#define CAP_GPI_CAM_P_DATA_SHIFT 3
179#define CAP_GPI_CAM_P_VS (1 << 2)
180#define CAP_GPI_CAM_P_HS (1 << 1)
181#define CAP_GPI_CAM_P_CLK (1 << 0)
182
183#define CC_REVISION_MAJOR (15 << 4)
184#define CC_REVISION_MAJOR_SHIFT 4
185#define CC_REVISION_MINOR (15 << 0)
186#define CC_REVISION_MINOR_SHIFT 0
187
188#define CC_SYSCONFIG_SIDLEMODE (3 << 3)
189#define CC_SYSCONFIG_SIDLEMODE_FIDLE (0 << 3)
190#define CC_SYSCONFIG_SIDLEMODE_NIDLE (1 << 3)
191#define CC_SYSCONFIG_SOFTRESET (1 << 1)
192#define CC_SYSCONFIG_AUTOIDLE (1 << 0)
193
194#define CC_SYSSTATUS_RESETDONE (1 << 0)
195
196#define CC_IRQSTATUS_FS_IRQ (1 << 19)
197#define CC_IRQSTATUS_LE_IRQ (1 << 18)
198#define CC_IRQSTATUS_LS_IRQ (1 << 17)
199#define CC_IRQSTATUS_FE_IRQ (1 << 16)
200#define CC_IRQSTATUS_FW_ERR_IRQ (1 << 10)
201#define CC_IRQSTATUS_FSC_ERR_IRQ (1 << 9)
202#define CC_IRQSTATUS_SSC_ERR_IRQ (1 << 8)
203#define CC_IRQSTATUS_FIFO_NOEMPTY_IRQ (1 << 4)
204#define CC_IRQSTATUS_FIFO_FULL_IRQ (1 << 3)
205#define CC_IRQSTATUS_FIFO_THR_IRQ (1 << 2)
206#define CC_IRQSTATUS_FIFO_OF_IRQ (1 << 1)
207#define CC_IRQSTATUS_FIFO_UF_IRQ (1 << 0)
208
209#define CC_IRQENABLE_FS_IRQ (1 << 19)
210#define CC_IRQENABLE_LE_IRQ (1 << 18)
211#define CC_IRQENABLE_LS_IRQ (1 << 17)
212#define CC_IRQENABLE_FE_IRQ (1 << 16)
213#define CC_IRQENABLE_FW_ERR_IRQ (1 << 10)
214#define CC_IRQENABLE_FSC_ERR_IRQ (1 << 9)
215#define CC_IRQENABLE_SSC_ERR_IRQ (1 << 8)
216#define CC_IRQENABLE_FIFO_NOEMPTY_IRQ (1 << 4)
217#define CC_IRQENABLE_FIFO_FULL_IRQ (1 << 3)
218#define CC_IRQENABLE_FIFO_THR_IRQ (1 << 2)
219#define CC_IRQENABLE_FIFO_OF_IRQ (1 << 1)
220#define CC_IRQENABLE_FIFO_UF_IRQ (1 << 0)
221
222#define CC_CTRL_CC_ONE_SHOT (1 << 20)
223#define CC_CTRL_CC_IF_SYNCHRO (1 << 19)
224#define CC_CTRL_CC_RST (1 << 18)
225#define CC_CTRL_CC_FRAME_TRIG (1 << 17)
226#define CC_CTRL_CC_EN (1 << 16)
227#define CC_CTRL_NOBT_SYNCHRO (1 << 13)
228#define CC_CTRL_BT_CORRECT (1 << 12)
229#define CC_CTRL_PAR_ORDERCAM (1 << 11)
230#define CC_CTRL_PAR_CLK_POL (1 << 10)
231#define CC_CTRL_NOBT_HS_POL (1 << 9)
232#define CC_CTRL_NOBT_VS_POL (1 << 8)
233#define CC_CTRL_PAR_MODE (7 << 1)
234#define CC_CTRL_PAR_MODE_SHIFT 1
235#define CC_CTRL_PAR_MODE_NOBT8 (0 << 1)
236#define CC_CTRL_PAR_MODE_NOBT10 (1 << 1)
237#define CC_CTRL_PAR_MODE_NOBT12 (2 << 1)
238#define CC_CTRL_PAR_MODE_BT8 (4 << 1)
239#define CC_CTRL_PAR_MODE_BT10 (5 << 1)
240#define CC_CTRL_PAR_MODE_FIFOTEST (7 << 1)
241#define CC_CTRL_CCP_MODE (1 << 0)
242
243#define CC_CTRL_DMA_EN (1 << 8)
244#define CC_CTRL_DMA_FIFO_THRESHOLD (0x7F << 0)
245#define CC_CTRL_DMA_FIFO_THRESHOLD_SHIFT 0
246
247#define CC_CTRL_XCLK_DIV (0x1F << 0)
248#define CC_CTRL_XCLK_DIV_SHIFT 0
249#define CC_CTRL_XCLK_DIV_STABLE_LOW (0 << 0)
250#define CC_CTRL_XCLK_DIV_STABLE_HIGH (1 << 0)
251#define CC_CTRL_XCLK_DIV_BYPASS (31 << 0)
252
253#define CC_TEST_FIFO_RD_POINTER (0xFF << 24)
254#define CC_TEST_FIFO_RD_POINTER_SHIFT 24
255#define CC_TEST_FIFO_WR_POINTER (0xFF << 16)
256#define CC_TEST_FIFO_WR_POINTER_SHIFT 16
257#define CC_TEST_FIFO_LEVEL (0xFF << 8)
258#define CC_TEST_FIFO_LEVEL_SHIFT 8
259#define CC_TEST_FIFO_LEVEL_PEAK (0xFF << 0)
260#define CC_TEST_FIFO_LEVEL_PEAK_SHIFT 0
261
262#define CC_GENPAR_FIFO_DEPTH (7 << 0)
263#define CC_GENPAR_FIFO_DEPTH_SHIFT 0
264
265#define CC_CCPDFR_ALPHA (0xFF << 8)
266#define CC_CCPDFR_ALPHA_SHIFT 8
267#define CC_CCPDFR_DATAFORMAT (15 << 0)
268#define CC_CCPDFR_DATAFORMAT_SHIFT 0
269#define CC_CCPDFR_DATAFORMAT_YUV422BE (0 << 0)
270#define CC_CCPDFR_DATAFORMAT_YUV422 (1 << 0)
271#define CC_CCPDFR_DATAFORMAT_YUV420 (2 << 0)
272#define CC_CCPDFR_DATAFORMAT_RGB444 (4 << 0)
273#define CC_CCPDFR_DATAFORMAT_RGB565 (5 << 0)
274#define CC_CCPDFR_DATAFORMAT_RGB888NDE (6 << 0)
275#define CC_CCPDFR_DATAFORMAT_RGB888 (7 << 0)
276#define CC_CCPDFR_DATAFORMAT_RAW8NDE (8 << 0)
277#define CC_CCPDFR_DATAFORMAT_RAW8 (9 << 0)
278#define CC_CCPDFR_DATAFORMAT_RAW10NDE (10 << 0)
279#define CC_CCPDFR_DATAFORMAT_RAW10 (11 << 0)
280#define CC_CCPDFR_DATAFORMAT_RAW12NDE (12 << 0)
281#define CC_CCPDFR_DATAFORMAT_RAW12 (13 << 0)
282#define CC_CCPDFR_DATAFORMAT_JPEG8 (15 << 0)
283
284#define CAMDMA_REVISION_MAJOR (15 << 4)
285#define CAMDMA_REVISION_MAJOR_SHIFT 4
286#define CAMDMA_REVISION_MINOR (15 << 0)
287#define CAMDMA_REVISION_MINOR_SHIFT 0
288
289#define CAMDMA_OCP_SYSCONFIG_MIDLEMODE (3 << 12)
290#define CAMDMA_OCP_SYSCONFIG_MIDLEMODE_FSTANDBY (0 << 12)
291#define CAMDMA_OCP_SYSCONFIG_MIDLEMODE_NSTANDBY (1 << 12)
292#define CAMDMA_OCP_SYSCONFIG_MIDLEMODE_SSTANDBY (2 << 12)
293#define CAMDMA_OCP_SYSCONFIG_FUNC_CLOCK (1 << 9)
294#define CAMDMA_OCP_SYSCONFIG_OCP_CLOCK (1 << 8)
295#define CAMDMA_OCP_SYSCONFIG_EMUFREE (1 << 5)
296#define CAMDMA_OCP_SYSCONFIG_SIDLEMODE (3 << 3)
297#define CAMDMA_OCP_SYSCONFIG_SIDLEMODE_FIDLE (0 << 3)
298#define CAMDMA_OCP_SYSCONFIG_SIDLEMODE_NIDLE (1 << 3)
299#define CAMDMA_OCP_SYSCONFIG_SIDLEMODE_SIDLE (2 << 3)
300#define CAMDMA_OCP_SYSCONFIG_SOFTRESET (1 << 1)
301#define CAMDMA_OCP_SYSCONFIG_AUTOIDLE (1 << 0)
302
303#define CAMDMA_SYSSTATUS_RESETDONE (1 << 0)
304
305#define CAMDMA_GCR_ARBITRATION_RATE (0xFF << 16)
306#define CAMDMA_GCR_ARBITRATION_RATE_SHIFT 16
307#define CAMDMA_GCR_MAX_CHANNEL_FIFO_DEPTH (0xFF << 0)
308#define CAMDMA_GCR_MAX_CHANNEL_FIFO_DEPTH_SHIFT 0
309
310#define CAMDMA_CCR_SEL_SRC_DST_SYNC (1 << 24)
311#define CAMDMA_CCR_PREFETCH (1 << 23)
312#define CAMDMA_CCR_SUPERVISOR (1 << 22)
313#define CAMDMA_CCR_SECURE (1 << 21)
314#define CAMDMA_CCR_BS (1 << 18)
315#define CAMDMA_CCR_TRANSPARENT_COPY_ENABLE (1 << 17)
316#define CAMDMA_CCR_CONSTANT_FILL_ENABLE (1 << 16)
317#define CAMDMA_CCR_DST_AMODE (3 << 14)
318#define CAMDMA_CCR_DST_AMODE_CONST_ADDR (0 << 14)
319#define CAMDMA_CCR_DST_AMODE_POST_INC (1 << 14)
320#define CAMDMA_CCR_DST_AMODE_SGL_IDX (2 << 14)
321#define CAMDMA_CCR_DST_AMODE_DBL_IDX (3 << 14)
322#define CAMDMA_CCR_SRC_AMODE (3 << 12)
323#define CAMDMA_CCR_SRC_AMODE_CONST_ADDR (0 << 12)
324#define CAMDMA_CCR_SRC_AMODE_POST_INC (1 << 12)
325#define CAMDMA_CCR_SRC_AMODE_SGL_IDX (2 << 12)
326#define CAMDMA_CCR_SRC_AMODE_DBL_IDX (3 << 12)
327#define CAMDMA_CCR_WR_ACTIVE (1 << 10)
328#define CAMDMA_CCR_RD_ACTIVE (1 << 9)
329#define CAMDMA_CCR_SUSPEND_SENSITIVE (1 << 8)
330#define CAMDMA_CCR_ENABLE (1 << 7)
331#define CAMDMA_CCR_PRIO (1 << 6)
332#define CAMDMA_CCR_FS (1 << 5)
333#define CAMDMA_CCR_SYNCHRO ((3 << 19) | (31 << 0))
334#define CAMDMA_CCR_SYNCHRO_CAMERA 0x01
335
336#define CAMDMA_CLNK_CTRL_ENABLE_LNK (1 << 15)
337#define CAMDMA_CLNK_CTRL_NEXTLCH_ID (0x1F << 0)
338#define CAMDMA_CLNK_CTRL_NEXTLCH_ID_SHIFT 0
339
340#define CAMDMA_CICR_MISALIGNED_ERR_IE (1 << 11)
341#define CAMDMA_CICR_SUPERVISOR_ERR_IE (1 << 10)
342#define CAMDMA_CICR_SECURE_ERR_IE (1 << 9)
343#define CAMDMA_CICR_TRANS_ERR_IE (1 << 8)
344#define CAMDMA_CICR_PACKET_IE (1 << 7)
345#define CAMDMA_CICR_BLOCK_IE (1 << 5)
346#define CAMDMA_CICR_LAST_IE (1 << 4)
347#define CAMDMA_CICR_FRAME_IE (1 << 3)
348#define CAMDMA_CICR_HALF_IE (1 << 2)
349#define CAMDMA_CICR_DROP_IE (1 << 1)
350
351#define CAMDMA_CSR_MISALIGNED_ERR (1 << 11)
352#define CAMDMA_CSR_SUPERVISOR_ERR (1 << 10)
353#define CAMDMA_CSR_SECURE_ERR (1 << 9)
354#define CAMDMA_CSR_TRANS_ERR (1 << 8)
355#define CAMDMA_CSR_PACKET (1 << 7)
356#define CAMDMA_CSR_SYNC (1 << 6)
357#define CAMDMA_CSR_BLOCK (1 << 5)
358#define CAMDMA_CSR_LAST (1 << 4)
359#define CAMDMA_CSR_FRAME (1 << 3)
360#define CAMDMA_CSR_HALF (1 << 2)
361#define CAMDMA_CSR_DROP (1 << 1)
362
363#define CAMDMA_CSDP_SRC_ENDIANNESS (1 << 21)
364#define CAMDMA_CSDP_SRC_ENDIANNESS_LOCK (1 << 20)
365#define CAMDMA_CSDP_DST_ENDIANNESS (1 << 19)
366#define CAMDMA_CSDP_DST_ENDIANNESS_LOCK (1 << 18)
367#define CAMDMA_CSDP_WRITE_MODE (3 << 16)
368#define CAMDMA_CSDP_WRITE_MODE_WRNP (0 << 16)
369#define CAMDMA_CSDP_WRITE_MODE_POSTED (1 << 16)
370#define CAMDMA_CSDP_WRITE_MODE_POSTED_LAST_WRNP (2 << 16)
371#define CAMDMA_CSDP_DST_BURST_EN (3 << 14)
372#define CAMDMA_CSDP_DST_BURST_EN_1 (0 << 14)
373#define CAMDMA_CSDP_DST_BURST_EN_16 (1 << 14)
374#define CAMDMA_CSDP_DST_BURST_EN_32 (2 << 14)
375#define CAMDMA_CSDP_DST_BURST_EN_64 (3 << 14)
376#define CAMDMA_CSDP_DST_PACKED (1 << 13)
377#define CAMDMA_CSDP_WR_ADD_TRSLT (15 << 9)
378#define CAMDMA_CSDP_WR_ADD_TRSLT_ENABLE_MREQADD (3 << 9)
379#define CAMDMA_CSDP_SRC_BURST_EN (3 << 7)
380#define CAMDMA_CSDP_SRC_BURST_EN_1 (0 << 7)
381#define CAMDMA_CSDP_SRC_BURST_EN_16 (1 << 7)
382#define CAMDMA_CSDP_SRC_BURST_EN_32 (2 << 7)
383#define CAMDMA_CSDP_SRC_BURST_EN_64 (3 << 7)
384#define CAMDMA_CSDP_SRC_PACKED (1 << 6)
385#define CAMDMA_CSDP_RD_ADD_TRSLT (15 << 2)
386#define CAMDMA_CSDP_RD_ADD_TRSLT_ENABLE_MREQADD (3 << 2)
387#define CAMDMA_CSDP_DATA_TYPE (3 << 0)
388#define CAMDMA_CSDP_DATA_TYPE_8BITS (0 << 0)
389#define CAMDMA_CSDP_DATA_TYPE_16BITS (1 << 0)
390#define CAMDMA_CSDP_DATA_TYPE_32BITS (2 << 0)
391
392#define CAMMMU_SYSCONFIG_AUTOIDLE (1 << 0)
393
394/*
395 *
396 * Declarations.
397 *
398 */
399
400/* forward declarations */
401struct omap24xxcam_sgdma;
402struct omap24xxcam_dma;
403
404typedef void (*sgdma_callback_t)(struct omap24xxcam_sgdma *cam,
405 u32 status, void *arg);
406typedef void (*dma_callback_t)(struct omap24xxcam_dma *cam,
407 u32 status, void *arg);
408
409struct channel_state {
410 dma_callback_t callback;
411 void *arg;
412};
413
414/* sgdma state for each of the possible videobuf_buffers + 2 overlays */
415struct sgdma_state {
416 const struct scatterlist *sglist;
417 int sglen; /* number of sglist entries */
418 int next_sglist; /* index of next sglist entry to process */
419 unsigned int bytes_read; /* number of bytes read */
420 unsigned int len; /* total length of sglist (excluding
421 * bytes due to page alignment) */
422 int queued_sglist; /* number of sglist entries queued for DMA */
423 u32 csr; /* DMA return code */
424 sgdma_callback_t callback;
425 void *arg;
426};
427
428/* physical DMA channel management */
429struct omap24xxcam_dma {
430 spinlock_t lock; /* Lock for the whole structure. */
431
432 unsigned long base; /* base address for dma controller */
433
434 /* While dma_stop!=0, an attempt to start a new DMA transfer will
435 * fail.
436 */
437 atomic_t dma_stop;
438 int free_dmach; /* number of dma channels free */
439 int next_dmach; /* index of next dma channel to use */
440 struct channel_state ch_state[NUM_CAMDMA_CHANNELS];
441};
442
443/* scatter-gather DMA (scatterlist stuff) management */
444struct omap24xxcam_sgdma {
445 struct omap24xxcam_dma dma;
446
447 spinlock_t lock; /* Lock for the fields below. */
448 int free_sgdma; /* number of free sg dma slots */
449 int next_sgdma; /* index of next sg dma slot to use */
450 struct sgdma_state sg_state[NUM_SG_DMA];
451
452 /* Reset timer data */
453 struct timer_list reset_timer;
454};
455
456/* per-device data structure */
457struct omap24xxcam_device {
458 /*** mutex ***/
459 /*
460 * mutex serialises access to this structure. Also camera
461 * opening and releasing is synchronised by this.
462 */
463 struct mutex mutex;
464
465 /*** general driver state information ***/
466 atomic_t users;
467 /*
468 * Lock to serialise core enabling and disabling and access to
469 * sgdma_in_queue.
470 */
471 spinlock_t core_enable_disable_lock;
472 /*
473 * Number or sgdma requests in scatter-gather queue, protected
474 * by the lock above.
475 */
476 int sgdma_in_queue;
477 /*
478 * Sensor interface parameters: interface type, CC_CTRL
479 * register value and interface specific data.
480 */
481 int if_type;
482 union {
483 struct parallel {
484 u32 xclk;
485 } bt656;
486 } if_u;
487 u32 cc_ctrl;
488
489 /*** subsystem structures ***/
490 struct omap24xxcam_sgdma sgdma;
491
492 /*** hardware resources ***/
493 unsigned int irq;
494 unsigned long mmio_base;
495 unsigned long mmio_base_phys;
496 unsigned long mmio_size;
497
498 /*** interfaces and device ***/
499 struct v4l2_int_device *sdev;
500 struct device *dev;
501 struct video_device *vfd;
502
503 /*** camera and sensor reset related stuff ***/
504 struct work_struct sensor_reset_work;
505 /*
506 * We're in the middle of a reset. Don't enable core if this
507 * is non-zero! This exists to help decisionmaking in a case
508 * where videobuf_qbuf is called while we are in the middle of
509 * a reset.
510 */
511 atomic_t in_reset;
512 /*
513 * Non-zero if we don't want any resets for now. Used to
514 * prevent reset work to run when we're about to stop
515 * streaming.
516 */
517 atomic_t reset_disable;
518
519 /*** video device parameters ***/
520 int capture_mem;
521
522 /*** camera module clocks ***/
523 struct clk *fck;
524 struct clk *ick;
525
526 /*** capture data ***/
527 /* file handle, if streaming is on */
528 struct file *streaming;
529};
530
531/* Per-file handle data. */
532struct omap24xxcam_fh {
533 spinlock_t vbq_lock; /* spinlock for the videobuf queue */
534 struct videobuf_queue vbq;
535 struct v4l2_pix_format pix; /* serialise pix by vbq->lock */
536 atomic_t field_count; /* field counter for videobuf_buffer */
537 /* accessing cam here doesn't need serialisation: it's constant */
538 struct omap24xxcam_device *cam;
539};
540
541/*
542 *
543 * Register I/O functions.
544 *
545 */
546
547static inline u32 omap24xxcam_reg_in(unsigned long base, u32 offset)
548{
549 return readl(base + offset);
550}
551
552static inline u32 omap24xxcam_reg_out(unsigned long base, u32 offset,
553 u32 val)
554{
555 writel(val, base + offset);
556 return val;
557}
558
559static inline u32 omap24xxcam_reg_merge(unsigned long base, u32 offset,
560 u32 val, u32 mask)
561{
562 u32 addr = base + offset;
563 u32 new_val = (readl(addr) & ~mask) | (val & mask);
564
565 writel(new_val, addr);
566 return new_val;
567}
568
569/*
570 *
571 * Function prototypes.
572 *
573 */
574
575/* dma prototypes */
576
577void omap24xxcam_dma_hwinit(struct omap24xxcam_dma *dma);
578void omap24xxcam_dma_isr(struct omap24xxcam_dma *dma);
579
580/* sgdma prototypes */
581
582void omap24xxcam_sgdma_process(struct omap24xxcam_sgdma *sgdma);
583int omap24xxcam_sgdma_queue(struct omap24xxcam_sgdma *sgdma,
584 const struct scatterlist *sglist, int sglen,
585 int len, sgdma_callback_t callback, void *arg);
586void omap24xxcam_sgdma_sync(struct omap24xxcam_sgdma *sgdma);
587void omap24xxcam_sgdma_init(struct omap24xxcam_sgdma *sgdma,
588 unsigned long base,
589 void (*reset_callback)(unsigned long data),
590 unsigned long reset_callback_data);
591void omap24xxcam_sgdma_exit(struct omap24xxcam_sgdma *sgdma);
592
593#endif
diff --git a/drivers/media/video/ov511.c b/drivers/media/video/ov511.c
index 210f1240b331..6ee9b69cc4a9 100644
--- a/drivers/media/video/ov511.c
+++ b/drivers/media/video/ov511.c
@@ -4011,8 +4011,7 @@ ov51x_v4l1_close(struct inode *inode, struct file *file)
4011 4011
4012/* Do not call this function directly! */ 4012/* Do not call this function directly! */
4013static int 4013static int
4014ov51x_v4l1_ioctl_internal(struct inode *inode, struct file *file, 4014ov51x_v4l1_ioctl_internal(struct file *file, unsigned int cmd, void *arg)
4015 unsigned int cmd, void *arg)
4016{ 4015{
4017 struct video_device *vdev = file->private_data; 4016 struct video_device *vdev = file->private_data;
4018 struct usb_ov511 *ov = video_get_drvdata(vdev); 4017 struct usb_ov511 *ov = video_get_drvdata(vdev);
@@ -4461,7 +4460,7 @@ ov51x_v4l1_ioctl(struct inode *inode, struct file *file,
4461 if (mutex_lock_interruptible(&ov->lock)) 4460 if (mutex_lock_interruptible(&ov->lock))
4462 return -EINTR; 4461 return -EINTR;
4463 4462
4464 rc = video_usercopy(inode, file, cmd, arg, ov51x_v4l1_ioctl_internal); 4463 rc = video_usercopy(file, cmd, arg, ov51x_v4l1_ioctl_internal);
4465 4464
4466 mutex_unlock(&ov->lock); 4465 mutex_unlock(&ov->lock);
4467 return rc; 4466 return rc;
diff --git a/drivers/media/video/ov772x.c b/drivers/media/video/ov772x.c
new file mode 100644
index 000000000000..54b736fcc07a
--- /dev/null
+++ b/drivers/media/video/ov772x.c
@@ -0,0 +1,1012 @@
1/*
2 * ov772x Camera Driver
3 *
4 * Copyright (C) 2008 Renesas Solutions Corp.
5 * Kuninori Morimoto <morimoto.kuninori@renesas.com>
6 *
7 * Based on ov7670 and soc_camera_platform driver,
8 *
9 * Copyright 2006-7 Jonathan Corbet <corbet@lwn.net>
10 * Copyright (C) 2008 Magnus Damm
11 * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de>
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License version 2 as
15 * published by the Free Software Foundation.
16 */
17
18#include <linux/init.h>
19#include <linux/module.h>
20#include <linux/i2c.h>
21#include <linux/slab.h>
22#include <linux/delay.h>
23#include <linux/videodev2.h>
24#include <media/v4l2-chip-ident.h>
25#include <media/v4l2-common.h>
26#include <media/soc_camera.h>
27#include <media/ov772x.h>
28
29/*
30 * register offset
31 */
32#define GAIN 0x00 /* AGC - Gain control gain setting */
33#define BLUE 0x01 /* AWB - Blue channel gain setting */
34#define RED 0x02 /* AWB - Red channel gain setting */
35#define GREEN 0x03 /* AWB - Green channel gain setting */
36#define COM1 0x04 /* Common control 1 */
37#define BAVG 0x05 /* U/B Average Level */
38#define GAVG 0x06 /* Y/Gb Average Level */
39#define RAVG 0x07 /* V/R Average Level */
40#define AECH 0x08 /* Exposure Value - AEC MSBs */
41#define COM2 0x09 /* Common control 2 */
42#define PID 0x0A /* Product ID Number MSB */
43#define VER 0x0B /* Product ID Number LSB */
44#define COM3 0x0C /* Common control 3 */
45#define COM4 0x0D /* Common control 4 */
46#define COM5 0x0E /* Common control 5 */
47#define COM6 0x0F /* Common control 6 */
48#define AEC 0x10 /* Exposure Value */
49#define CLKRC 0x11 /* Internal clock */
50#define COM7 0x12 /* Common control 7 */
51#define COM8 0x13 /* Common control 8 */
52#define COM9 0x14 /* Common control 9 */
53#define COM10 0x15 /* Common control 10 */
54#define REG16 0x16 /* Register 16 */
55#define HSTART 0x17 /* Horizontal sensor size */
56#define HSIZE 0x18 /* Horizontal frame (HREF column) end high 8-bit */
57#define VSTART 0x19 /* Vertical frame (row) start high 8-bit */
58#define VSIZE 0x1A /* Vertical sensor size */
59#define PSHFT 0x1B /* Data format - pixel delay select */
60#define MIDH 0x1C /* Manufacturer ID byte - high */
61#define MIDL 0x1D /* Manufacturer ID byte - low */
62#define LAEC 0x1F /* Fine AEC value */
63#define COM11 0x20 /* Common control 11 */
64#define BDBASE 0x22 /* Banding filter Minimum AEC value */
65#define DBSTEP 0x23 /* Banding filter Maximum Setp */
66#define AEW 0x24 /* AGC/AEC - Stable operating region (upper limit) */
67#define AEB 0x25 /* AGC/AEC - Stable operating region (lower limit) */
68#define VPT 0x26 /* AGC/AEC Fast mode operating region */
69#define REG28 0x28 /* Register 28 */
70#define HOUTSIZE 0x29 /* Horizontal data output size MSBs */
71#define EXHCH 0x2A /* Dummy pixel insert MSB */
72#define EXHCL 0x2B /* Dummy pixel insert LSB */
73#define VOUTSIZE 0x2C /* Vertical data output size MSBs */
74#define ADVFL 0x2D /* LSB of insert dummy lines in Vertical direction */
75#define ADVFH 0x2E /* MSG of insert dummy lines in Vertical direction */
76#define YAVE 0x2F /* Y/G Channel Average value */
77#define LUMHTH 0x30 /* Histogram AEC/AGC Luminance high level threshold */
78#define LUMLTH 0x31 /* Histogram AEC/AGC Luminance low level threshold */
79#define HREF 0x32 /* Image start and size control */
80#define DM_LNL 0x33 /* Dummy line low 8 bits */
81#define DM_LNH 0x34 /* Dummy line high 8 bits */
82#define ADOFF_B 0x35 /* AD offset compensation value for B channel */
83#define ADOFF_R 0x36 /* AD offset compensation value for R channel */
84#define ADOFF_GB 0x37 /* AD offset compensation value for Gb channel */
85#define ADOFF_GR 0x38 /* AD offset compensation value for Gr channel */
86#define OFF_B 0x39 /* Analog process B channel offset value */
87#define OFF_R 0x3A /* Analog process R channel offset value */
88#define OFF_GB 0x3B /* Analog process Gb channel offset value */
89#define OFF_GR 0x3C /* Analog process Gr channel offset value */
90#define COM12 0x3D /* Common control 12 */
91#define COM13 0x3E /* Common control 13 */
92#define COM14 0x3F /* Common control 14 */
93#define COM15 0x40 /* Common control 15*/
94#define COM16 0x41 /* Common control 16 */
95#define TGT_B 0x42 /* BLC blue channel target value */
96#define TGT_R 0x43 /* BLC red channel target value */
97#define TGT_GB 0x44 /* BLC Gb channel target value */
98#define TGT_GR 0x45 /* BLC Gr channel target value */
99/* for ov7720 */
100#define LCC0 0x46 /* Lens correction control 0 */
101#define LCC1 0x47 /* Lens correction option 1 - X coordinate */
102#define LCC2 0x48 /* Lens correction option 2 - Y coordinate */
103#define LCC3 0x49 /* Lens correction option 3 */
104#define LCC4 0x4A /* Lens correction option 4 - radius of the circular */
105#define LCC5 0x4B /* Lens correction option 5 */
106#define LCC6 0x4C /* Lens correction option 6 */
107/* for ov7725 */
108#define LC_CTR 0x46 /* Lens correction control */
109#define LC_XC 0x47 /* X coordinate of lens correction center relative */
110#define LC_YC 0x48 /* Y coordinate of lens correction center relative */
111#define LC_COEF 0x49 /* Lens correction coefficient */
112#define LC_RADI 0x4A /* Lens correction radius */
113#define LC_COEFB 0x4B /* Lens B channel compensation coefficient */
114#define LC_COEFR 0x4C /* Lens R channel compensation coefficient */
115
116#define FIXGAIN 0x4D /* Analog fix gain amplifer */
117#define AREF0 0x4E /* Sensor reference control */
118#define AREF1 0x4F /* Sensor reference current control */
119#define AREF2 0x50 /* Analog reference control */
120#define AREF3 0x51 /* ADC reference control */
121#define AREF4 0x52 /* ADC reference control */
122#define AREF5 0x53 /* ADC reference control */
123#define AREF6 0x54 /* Analog reference control */
124#define AREF7 0x55 /* Analog reference control */
125#define UFIX 0x60 /* U channel fixed value output */
126#define VFIX 0x61 /* V channel fixed value output */
127#define AWBB_BLK 0x62 /* AWB option for advanced AWB */
128#define AWB_CTRL0 0x63 /* AWB control byte 0 */
129#define DSP_CTRL1 0x64 /* DSP control byte 1 */
130#define DSP_CTRL2 0x65 /* DSP control byte 2 */
131#define DSP_CTRL3 0x66 /* DSP control byte 3 */
132#define DSP_CTRL4 0x67 /* DSP control byte 4 */
133#define AWB_BIAS 0x68 /* AWB BLC level clip */
134#define AWB_CTRL1 0x69 /* AWB control 1 */
135#define AWB_CTRL2 0x6A /* AWB control 2 */
136#define AWB_CTRL3 0x6B /* AWB control 3 */
137#define AWB_CTRL4 0x6C /* AWB control 4 */
138#define AWB_CTRL5 0x6D /* AWB control 5 */
139#define AWB_CTRL6 0x6E /* AWB control 6 */
140#define AWB_CTRL7 0x6F /* AWB control 7 */
141#define AWB_CTRL8 0x70 /* AWB control 8 */
142#define AWB_CTRL9 0x71 /* AWB control 9 */
143#define AWB_CTRL10 0x72 /* AWB control 10 */
144#define AWB_CTRL11 0x73 /* AWB control 11 */
145#define AWB_CTRL12 0x74 /* AWB control 12 */
146#define AWB_CTRL13 0x75 /* AWB control 13 */
147#define AWB_CTRL14 0x76 /* AWB control 14 */
148#define AWB_CTRL15 0x77 /* AWB control 15 */
149#define AWB_CTRL16 0x78 /* AWB control 16 */
150#define AWB_CTRL17 0x79 /* AWB control 17 */
151#define AWB_CTRL18 0x7A /* AWB control 18 */
152#define AWB_CTRL19 0x7B /* AWB control 19 */
153#define AWB_CTRL20 0x7C /* AWB control 20 */
154#define AWB_CTRL21 0x7D /* AWB control 21 */
155#define GAM1 0x7E /* Gamma Curve 1st segment input end point */
156#define GAM2 0x7F /* Gamma Curve 2nd segment input end point */
157#define GAM3 0x80 /* Gamma Curve 3rd segment input end point */
158#define GAM4 0x81 /* Gamma Curve 4th segment input end point */
159#define GAM5 0x82 /* Gamma Curve 5th segment input end point */
160#define GAM6 0x83 /* Gamma Curve 6th segment input end point */
161#define GAM7 0x84 /* Gamma Curve 7th segment input end point */
162#define GAM8 0x85 /* Gamma Curve 8th segment input end point */
163#define GAM9 0x86 /* Gamma Curve 9th segment input end point */
164#define GAM10 0x87 /* Gamma Curve 10th segment input end point */
165#define GAM11 0x88 /* Gamma Curve 11th segment input end point */
166#define GAM12 0x89 /* Gamma Curve 12th segment input end point */
167#define GAM13 0x8A /* Gamma Curve 13th segment input end point */
168#define GAM14 0x8B /* Gamma Curve 14th segment input end point */
169#define GAM15 0x8C /* Gamma Curve 15th segment input end point */
170#define SLOP 0x8D /* Gamma curve highest segment slope */
171#define DNSTH 0x8E /* De-noise threshold */
172#define EDGE0 0x8F /* Edge enhancement control 0 */
173#define EDGE1 0x90 /* Edge enhancement control 1 */
174#define DNSOFF 0x91 /* Auto De-noise threshold control */
175#define EDGE2 0x92 /* Edge enhancement strength low point control */
176#define EDGE3 0x93 /* Edge enhancement strength high point control */
177#define MTX1 0x94 /* Matrix coefficient 1 */
178#define MTX2 0x95 /* Matrix coefficient 2 */
179#define MTX3 0x96 /* Matrix coefficient 3 */
180#define MTX4 0x97 /* Matrix coefficient 4 */
181#define MTX5 0x98 /* Matrix coefficient 5 */
182#define MTX6 0x99 /* Matrix coefficient 6 */
183#define MTX_CTRL 0x9A /* Matrix control */
184#define BRIGHT 0x9B /* Brightness control */
185#define CNTRST 0x9C /* Contrast contrast */
186#define CNTRST_CTRL 0x9D /* Contrast contrast center */
187#define UVAD_J0 0x9E /* Auto UV adjust contrast 0 */
188#define UVAD_J1 0x9F /* Auto UV adjust contrast 1 */
189#define SCAL0 0xA0 /* Scaling control 0 */
190#define SCAL1 0xA1 /* Scaling control 1 */
191#define SCAL2 0xA2 /* Scaling control 2 */
192#define FIFODLYM 0xA3 /* FIFO manual mode delay control */
193#define FIFODLYA 0xA4 /* FIFO auto mode delay control */
194#define SDE 0xA6 /* Special digital effect control */
195#define USAT 0xA7 /* U component saturation control */
196#define VSAT 0xA8 /* V component saturation control */
197/* for ov7720 */
198#define HUE0 0xA9 /* Hue control 0 */
199#define HUE1 0xAA /* Hue control 1 */
200/* for ov7725 */
201#define HUECOS 0xA9 /* Cosine value */
202#define HUESIN 0xAA /* Sine value */
203
204#define SIGN 0xAB /* Sign bit for Hue and contrast */
205#define DSPAUTO 0xAC /* DSP auto function ON/OFF control */
206
207/*
208 * register detail
209 */
210
211/* COM2 */
212#define SOFT_SLEEP_MODE 0x10 /* Soft sleep mode */
213 /* Output drive capability */
214#define OCAP_1x 0x00 /* 1x */
215#define OCAP_2x 0x01 /* 2x */
216#define OCAP_3x 0x02 /* 3x */
217#define OCAP_4x 0x03 /* 4x */
218
219/* COM3 */
220#define SWAP_MASK 0x38
221
222#define VFIMG_ON_OFF 0x80 /* Vertical flip image ON/OFF selection */
223#define HMIMG_ON_OFF 0x40 /* Horizontal mirror image ON/OFF selection */
224#define SWAP_RGB 0x20 /* Swap B/R output sequence in RGB mode */
225#define SWAP_YUV 0x10 /* Swap Y/UV output sequence in YUV mode */
226#define SWAP_ML 0x08 /* Swap output MSB/LSB */
227 /* Tri-state option for output clock */
228#define NOTRI_CLOCK 0x04 /* 0: Tri-state at this period */
229 /* 1: No tri-state at this period */
230 /* Tri-state option for output data */
231#define NOTRI_DATA 0x02 /* 0: Tri-state at this period */
232 /* 1: No tri-state at this period */
233#define SCOLOR_TEST 0x01 /* Sensor color bar test pattern */
234
235/* COM4 */
236 /* PLL frequency control */
237#define PLL_BYPASS 0x00 /* 00: Bypass PLL */
238#define PLL_4x 0x40 /* 01: PLL 4x */
239#define PLL_6x 0x80 /* 10: PLL 6x */
240#define PLL_8x 0xc0 /* 11: PLL 8x */
241 /* AEC evaluate window */
242#define AEC_FULL 0x00 /* 00: Full window */
243#define AEC_1p2 0x10 /* 01: 1/2 window */
244#define AEC_1p4 0x20 /* 10: 1/4 window */
245#define AEC_2p3 0x30 /* 11: Low 2/3 window */
246
247/* COM5 */
248#define AFR_ON_OFF 0x80 /* Auto frame rate control ON/OFF selection */
249#define AFR_SPPED 0x40 /* Auto frame rate control speed slection */
250 /* Auto frame rate max rate control */
251#define AFR_NO_RATE 0x00 /* No reduction of frame rate */
252#define AFR_1p2 0x10 /* Max reduction to 1/2 frame rate */
253#define AFR_1p4 0x20 /* Max reduction to 1/4 frame rate */
254#define AFR_1p8 0x30 /* Max reduction to 1/8 frame rate */
255 /* Auto frame rate active point control */
256#define AF_2x 0x00 /* Add frame when AGC reaches 2x gain */
257#define AF_4x 0x04 /* Add frame when AGC reaches 4x gain */
258#define AF_8x 0x08 /* Add frame when AGC reaches 8x gain */
259#define AF_16x 0x0c /* Add frame when AGC reaches 16x gain */
260 /* AEC max step control */
261#define AEC_NO_LIMIT 0x01 /* 0 : AEC incease step has limit */
262 /* 1 : No limit to AEC increase step */
263
264/* COM7 */
265 /* SCCB Register Reset */
266#define SCCB_RESET 0x80 /* 0 : No change */
267 /* 1 : Resets all registers to default */
268 /* Resolution selection */
269#define SLCT_MASK 0x40 /* Mask of VGA or QVGA */
270#define SLCT_VGA 0x00 /* 0 : VGA */
271#define SLCT_QVGA 0x40 /* 1 : QVGA */
272#define ITU656_ON_OFF 0x20 /* ITU656 protocol ON/OFF selection */
273 /* RGB output format control */
274#define FMT_GBR422 0x00 /* 00 : GBR 4:2:2 */
275#define FMT_RGB565 0x04 /* 01 : RGB 565 */
276#define FMT_RGB555 0x08 /* 10 : RGB 555 */
277#define FMT_RGB444 0x0c /* 11 : RGB 444 */
278 /* Output format control */
279#define OFMT_YUV 0x00 /* 00 : YUV */
280#define OFMT_P_BRAW 0x01 /* 01 : Processed Bayer RAW */
281#define OFMT_RGB 0x02 /* 10 : RGB */
282#define OFMT_BRAW 0x03 /* 11 : Bayer RAW */
283
284/* COM8 */
285#define FAST_ALGO 0x80 /* Enable fast AGC/AEC algorithm */
286 /* AEC Setp size limit */
287#define UNLMT_STEP 0x40 /* 0 : Step size is limited */
288 /* 1 : Unlimited step size */
289#define BNDF_ON_OFF 0x20 /* Banding filter ON/OFF */
290#define AEC_BND 0x10 /* Enable AEC below banding value */
291#define AEC_ON_OFF 0x08 /* Fine AEC ON/OFF control */
292#define AGC_ON 0x04 /* AGC Enable */
293#define AWB_ON 0x02 /* AWB Enable */
294#define AEC_ON 0x01 /* AEC Enable */
295
296/* COM9 */
297#define BASE_AECAGC 0x80 /* Histogram or average based AEC/AGC */
298 /* Automatic gain ceiling - maximum AGC value */
299#define GAIN_2x 0x00 /* 000 : 2x */
300#define GAIN_4x 0x10 /* 001 : 4x */
301#define GAIN_8x 0x20 /* 010 : 8x */
302#define GAIN_16x 0x30 /* 011 : 16x */
303#define GAIN_32x 0x40 /* 100 : 32x */
304#define GAIN_64x 0x50 /* 101 : 64x */
305#define GAIN_128x 0x60 /* 110 : 128x */
306#define DROP_VSYNC 0x04 /* Drop VSYNC output of corrupt frame */
307#define DROP_HREF 0x02 /* Drop HREF output of corrupt frame */
308
309/* COM11 */
310#define SGLF_ON_OFF 0x02 /* Single frame ON/OFF selection */
311#define SGLF_TRIG 0x01 /* Single frame transfer trigger */
312
313/* EXHCH */
314#define VSIZE_LSB 0x04 /* Vertical data output size LSB */
315
316/* DSP_CTRL1 */
317#define FIFO_ON 0x80 /* FIFO enable/disable selection */
318#define UV_ON_OFF 0x40 /* UV adjust function ON/OFF selection */
319#define YUV444_2_422 0x20 /* YUV444 to 422 UV channel option selection */
320#define CLR_MTRX_ON_OFF 0x10 /* Color matrix ON/OFF selection */
321#define INTPLT_ON_OFF 0x08 /* Interpolation ON/OFF selection */
322#define GMM_ON_OFF 0x04 /* Gamma function ON/OFF selection */
323#define AUTO_BLK_ON_OFF 0x02 /* Black defect auto correction ON/OFF */
324#define AUTO_WHT_ON_OFF 0x01 /* White define auto correction ON/OFF */
325
326/* DSP_CTRL3 */
327#define UV_MASK 0x80 /* UV output sequence option */
328#define UV_ON 0x80 /* ON */
329#define UV_OFF 0x00 /* OFF */
330#define CBAR_MASK 0x20 /* DSP Color bar mask */
331#define CBAR_ON 0x20 /* ON */
332#define CBAR_OFF 0x00 /* OFF */
333
334/* HSTART */
335#define HST_VGA 0x23
336#define HST_QVGA 0x3F
337
338/* HSIZE */
339#define HSZ_VGA 0xA0
340#define HSZ_QVGA 0x50
341
342/* VSTART */
343#define VST_VGA 0x07
344#define VST_QVGA 0x03
345
346/* VSIZE */
347#define VSZ_VGA 0xF0
348#define VSZ_QVGA 0x78
349
350/* HOUTSIZE */
351#define HOSZ_VGA 0xA0
352#define HOSZ_QVGA 0x50
353
354/* VOUTSIZE */
355#define VOSZ_VGA 0xF0
356#define VOSZ_QVGA 0x78
357
358/*
359 * bit configure (32 bit)
360 * this is used in struct ov772x_color_format :: option
361 */
362#define OP_UV 0x00000001
363#define OP_SWAP_RGB 0x00000002
364
365/*
366 * ID
367 */
368#define OV7720 0x7720
369#define OV7725 0x7721
370#define VERSION(pid, ver) ((pid<<8)|(ver&0xFF))
371
372/*
373 * struct
374 */
375struct regval_list {
376 unsigned char reg_num;
377 unsigned char value;
378};
379
380struct ov772x_color_format {
381 char *name;
382 __u32 fourcc;
383 const struct regval_list *regs;
384 unsigned int option;
385};
386
387struct ov772x_win_size {
388 char *name;
389 __u32 width;
390 __u32 height;
391 unsigned char com7_bit;
392 const struct regval_list *regs;
393};
394
395struct ov772x_priv {
396 struct ov772x_camera_info *info;
397 struct i2c_client *client;
398 struct soc_camera_device icd;
399 const struct ov772x_color_format *fmt;
400 const struct ov772x_win_size *win;
401 int model;
402};
403
404#define ENDMARKER { 0xff, 0xff }
405
406/*
407 * register setting for color format
408 */
409static const struct regval_list ov772x_RGB555_regs[] = {
410 { COM3, 0x00 },
411 { COM7, FMT_RGB555 | OFMT_RGB },
412 ENDMARKER,
413};
414
415static const struct regval_list ov772x_RGB565_regs[] = {
416 { COM3, 0x00 },
417 { COM7, FMT_RGB565 | OFMT_RGB },
418 ENDMARKER,
419};
420
421static const struct regval_list ov772x_YYUV_regs[] = {
422 { COM3, SWAP_YUV },
423 { COM7, OFMT_YUV },
424 ENDMARKER,
425};
426
427static const struct regval_list ov772x_UVYY_regs[] = {
428 { COM3, 0x00 },
429 { COM7, OFMT_YUV },
430 ENDMARKER,
431};
432
433
434/*
435 * register setting for window size
436 */
437static const struct regval_list ov772x_qvga_regs[] = {
438 { HSTART, HST_QVGA },
439 { HSIZE, HSZ_QVGA },
440 { VSTART, VST_QVGA },
441 { VSIZE, VSZ_QVGA },
442 { HOUTSIZE, HOSZ_QVGA },
443 { VOUTSIZE, VOSZ_QVGA },
444 ENDMARKER,
445};
446
447static const struct regval_list ov772x_vga_regs[] = {
448 { HSTART, HST_VGA },
449 { HSIZE, HSZ_VGA },
450 { VSTART, VST_VGA },
451 { VSIZE, VSZ_VGA },
452 { HOUTSIZE, HOSZ_VGA },
453 { VOUTSIZE, VOSZ_VGA },
454 ENDMARKER,
455};
456
457/*
458 * supported format list
459 */
460
461#define SETFOURCC(type) .name = (#type), .fourcc = (V4L2_PIX_FMT_ ## type)
462static const struct soc_camera_data_format ov772x_fmt_lists[] = {
463 {
464 SETFOURCC(YUYV),
465 .depth = 16,
466 .colorspace = V4L2_COLORSPACE_JPEG,
467 },
468 {
469 SETFOURCC(YVYU),
470 .depth = 16,
471 .colorspace = V4L2_COLORSPACE_JPEG,
472 },
473 {
474 SETFOURCC(UYVY),
475 .depth = 16,
476 .colorspace = V4L2_COLORSPACE_JPEG,
477 },
478 {
479 SETFOURCC(RGB555),
480 .depth = 16,
481 .colorspace = V4L2_COLORSPACE_SRGB,
482 },
483 {
484 SETFOURCC(RGB555X),
485 .depth = 16,
486 .colorspace = V4L2_COLORSPACE_SRGB,
487 },
488 {
489 SETFOURCC(RGB565),
490 .depth = 16,
491 .colorspace = V4L2_COLORSPACE_SRGB,
492 },
493 {
494 SETFOURCC(RGB565X),
495 .depth = 16,
496 .colorspace = V4L2_COLORSPACE_SRGB,
497 },
498};
499
500/*
501 * color format list
502 */
503#define T_YUYV 0
504static const struct ov772x_color_format ov772x_cfmts[] = {
505 [T_YUYV] = {
506 SETFOURCC(YUYV),
507 .regs = ov772x_YYUV_regs,
508 },
509 {
510 SETFOURCC(YVYU),
511 .regs = ov772x_YYUV_regs,
512 .option = OP_UV,
513 },
514 {
515 SETFOURCC(UYVY),
516 .regs = ov772x_UVYY_regs,
517 },
518 {
519 SETFOURCC(RGB555),
520 .regs = ov772x_RGB555_regs,
521 .option = OP_SWAP_RGB,
522 },
523 {
524 SETFOURCC(RGB555X),
525 .regs = ov772x_RGB555_regs,
526 },
527 {
528 SETFOURCC(RGB565),
529 .regs = ov772x_RGB565_regs,
530 .option = OP_SWAP_RGB,
531 },
532 {
533 SETFOURCC(RGB565X),
534 .regs = ov772x_RGB565_regs,
535 },
536};
537
538
539/*
540 * window size list
541 */
542#define VGA_WIDTH 640
543#define VGA_HEIGHT 480
544#define QVGA_WIDTH 320
545#define QVGA_HEIGHT 240
546#define MAX_WIDTH VGA_WIDTH
547#define MAX_HEIGHT VGA_HEIGHT
548
549static const struct ov772x_win_size ov772x_win_vga = {
550 .name = "VGA",
551 .width = VGA_WIDTH,
552 .height = VGA_HEIGHT,
553 .com7_bit = SLCT_VGA,
554 .regs = ov772x_vga_regs,
555};
556
557static const struct ov772x_win_size ov772x_win_qvga = {
558 .name = "QVGA",
559 .width = QVGA_WIDTH,
560 .height = QVGA_HEIGHT,
561 .com7_bit = SLCT_QVGA,
562 .regs = ov772x_qvga_regs,
563};
564
565
566/*
567 * general function
568 */
569
570static int ov772x_write_array(struct i2c_client *client,
571 const struct regval_list *vals)
572{
573 while (vals->reg_num != 0xff) {
574 int ret = i2c_smbus_write_byte_data(client,
575 vals->reg_num,
576 vals->value);
577 if (ret < 0)
578 return ret;
579 vals++;
580 }
581 return 0;
582}
583
584static int ov772x_mask_set(struct i2c_client *client,
585 u8 command,
586 u8 mask,
587 u8 set)
588{
589 s32 val = i2c_smbus_read_byte_data(client, command);
590 val &= ~mask;
591 val |= set;
592
593 return i2c_smbus_write_byte_data(client, command, val);
594}
595
596static int ov772x_reset(struct i2c_client *client)
597{
598 int ret = i2c_smbus_write_byte_data(client, COM7, SCCB_RESET);
599 msleep(1);
600 return ret;
601}
602
603/*
604 * soc_camera_ops function
605 */
606
607static int ov772x_init(struct soc_camera_device *icd)
608{
609 struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd);
610 int ret = 0;
611
612 if (priv->info->link.power) {
613 ret = priv->info->link.power(&priv->client->dev, 1);
614 if (ret < 0)
615 return ret;
616 }
617
618 if (priv->info->link.reset)
619 ret = priv->info->link.reset(&priv->client->dev);
620
621 return ret;
622}
623
624static int ov772x_release(struct soc_camera_device *icd)
625{
626 struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd);
627 int ret = 0;
628
629 if (priv->info->link.power)
630 ret = priv->info->link.power(&priv->client->dev, 0);
631
632 return ret;
633}
634
635static int ov772x_start_capture(struct soc_camera_device *icd)
636{
637 struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd);
638 int ret;
639
640 if (!priv->win)
641 priv->win = &ov772x_win_vga;
642 if (!priv->fmt)
643 priv->fmt = &ov772x_cfmts[T_YUYV];
644
645 /*
646 * reset hardware
647 */
648 ov772x_reset(priv->client);
649
650 /*
651 * set color format
652 */
653 ret = ov772x_write_array(priv->client, priv->fmt->regs);
654 if (ret < 0)
655 goto start_end;
656
657 /*
658 * set size format
659 */
660 ret = ov772x_write_array(priv->client, priv->win->regs);
661 if (ret < 0)
662 goto start_end;
663
664 /*
665 * set COM7 bit ( QVGA or VGA )
666 */
667 ret = ov772x_mask_set(priv->client,
668 COM7, SLCT_MASK, priv->win->com7_bit);
669 if (ret < 0)
670 goto start_end;
671
672 /*
673 * set UV setting
674 */
675 if (priv->fmt->option & OP_UV) {
676 ret = ov772x_mask_set(priv->client,
677 DSP_CTRL3, UV_MASK, UV_ON);
678 if (ret < 0)
679 goto start_end;
680 }
681
682 /*
683 * set SWAP setting
684 */
685 if (priv->fmt->option & OP_SWAP_RGB) {
686 ret = ov772x_mask_set(priv->client,
687 COM3, SWAP_MASK, SWAP_RGB);
688 if (ret < 0)
689 goto start_end;
690 }
691
692 dev_dbg(&icd->dev,
693 "format %s, win %s\n", priv->fmt->name, priv->win->name);
694
695start_end:
696 priv->fmt = NULL;
697 priv->win = NULL;
698
699 return ret;
700}
701
702static int ov772x_stop_capture(struct soc_camera_device *icd)
703{
704 struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd);
705 ov772x_reset(priv->client);
706 return 0;
707}
708
709static int ov772x_set_bus_param(struct soc_camera_device *icd,
710 unsigned long flags)
711{
712 return 0;
713}
714
715static unsigned long ov772x_query_bus_param(struct soc_camera_device *icd)
716{
717 struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd);
718 struct soc_camera_link *icl = priv->client->dev.platform_data;
719 unsigned long flags = SOCAM_PCLK_SAMPLE_RISING | SOCAM_MASTER |
720 SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_HSYNC_ACTIVE_HIGH |
721 priv->info->buswidth;
722
723 return soc_camera_apply_sensor_flags(icl, flags);
724}
725
726static int ov772x_get_chip_id(struct soc_camera_device *icd,
727 struct v4l2_chip_ident *id)
728{
729 struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd);
730
731 id->ident = priv->model;
732 id->revision = 0;
733
734 return 0;
735}
736
737#ifdef CONFIG_VIDEO_ADV_DEBUG
738static int ov772x_get_register(struct soc_camera_device *icd,
739 struct v4l2_register *reg)
740{
741 struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd);
742 int ret;
743
744 if (reg->reg > 0xff)
745 return -EINVAL;
746
747 ret = i2c_smbus_read_byte_data(priv->client, reg->reg);
748 if (ret < 0)
749 return ret;
750
751 reg->val = (__u64)ret;
752
753 return 0;
754}
755
756static int ov772x_set_register(struct soc_camera_device *icd,
757 struct v4l2_register *reg)
758{
759 struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd);
760
761 if (reg->reg > 0xff ||
762 reg->val > 0xff)
763 return -EINVAL;
764
765 return i2c_smbus_write_byte_data(priv->client, reg->reg, reg->val);
766}
767#endif
768
769static const struct ov772x_win_size*
770ov772x_select_win(u32 width, u32 height)
771{
772 __u32 diff;
773 const struct ov772x_win_size *win;
774
775 /* default is QVGA */
776 diff = abs(width - ov772x_win_qvga.width) +
777 abs(height - ov772x_win_qvga.height);
778 win = &ov772x_win_qvga;
779
780 /* VGA */
781 if (diff >
782 abs(width - ov772x_win_vga.width) +
783 abs(height - ov772x_win_vga.height))
784 win = &ov772x_win_vga;
785
786 return win;
787}
788
789
790static int ov772x_set_fmt(struct soc_camera_device *icd,
791 __u32 pixfmt,
792 struct v4l2_rect *rect)
793{
794 struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd);
795 int ret = -EINVAL;
796 int i;
797
798 /*
799 * select format
800 */
801 priv->fmt = NULL;
802 for (i = 0; i < ARRAY_SIZE(ov772x_cfmts); i++) {
803 if (pixfmt == ov772x_cfmts[i].fourcc) {
804 priv->fmt = ov772x_cfmts + i;
805 ret = 0;
806 break;
807 }
808 }
809
810 /*
811 * select win
812 */
813 priv->win = ov772x_select_win(rect->width, rect->height);
814
815 return ret;
816}
817
818static int ov772x_try_fmt(struct soc_camera_device *icd,
819 struct v4l2_format *f)
820{
821 struct v4l2_pix_format *pix = &f->fmt.pix;
822 const struct ov772x_win_size *win;
823
824 /*
825 * select suitable win
826 */
827 win = ov772x_select_win(pix->width, pix->height);
828
829 pix->width = win->width;
830 pix->height = win->height;
831 pix->field = V4L2_FIELD_NONE;
832
833 return 0;
834}
835
836static int ov772x_video_probe(struct soc_camera_device *icd)
837{
838 struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd);
839 u8 pid, ver;
840 const char *devname;
841
842 /*
843 * We must have a parent by now. And it cannot be a wrong one.
844 * So this entire test is completely redundant.
845 */
846 if (!icd->dev.parent ||
847 to_soc_camera_host(icd->dev.parent)->nr != icd->iface)
848 return -ENODEV;
849
850 /*
851 * ov772x only use 8 or 10 bit bus width
852 */
853 if (SOCAM_DATAWIDTH_10 != priv->info->buswidth &&
854 SOCAM_DATAWIDTH_8 != priv->info->buswidth) {
855 dev_err(&icd->dev, "bus width error\n");
856 return -ENODEV;
857 }
858
859 icd->formats = ov772x_fmt_lists;
860 icd->num_formats = ARRAY_SIZE(ov772x_fmt_lists);
861
862 /*
863 * check and show product ID and manufacturer ID
864 */
865 pid = i2c_smbus_read_byte_data(priv->client, PID);
866 ver = i2c_smbus_read_byte_data(priv->client, VER);
867
868 switch (VERSION(pid, ver)) {
869 case OV7720:
870 devname = "ov7720";
871 priv->model = V4L2_IDENT_OV7720;
872 break;
873 case OV7725:
874 devname = "ov7725";
875 priv->model = V4L2_IDENT_OV7725;
876 break;
877 default:
878 dev_err(&icd->dev,
879 "Product ID error %x:%x\n", pid, ver);
880 return -ENODEV;
881 }
882
883 dev_info(&icd->dev,
884 "%s Product ID %0x:%0x Manufacturer ID %x:%x\n",
885 devname,
886 pid,
887 ver,
888 i2c_smbus_read_byte_data(priv->client, MIDH),
889 i2c_smbus_read_byte_data(priv->client, MIDL));
890
891
892 return soc_camera_video_start(icd);
893}
894
895static void ov772x_video_remove(struct soc_camera_device *icd)
896{
897 soc_camera_video_stop(icd);
898}
899
900static struct soc_camera_ops ov772x_ops = {
901 .owner = THIS_MODULE,
902 .probe = ov772x_video_probe,
903 .remove = ov772x_video_remove,
904 .init = ov772x_init,
905 .release = ov772x_release,
906 .start_capture = ov772x_start_capture,
907 .stop_capture = ov772x_stop_capture,
908 .set_fmt = ov772x_set_fmt,
909 .try_fmt = ov772x_try_fmt,
910 .set_bus_param = ov772x_set_bus_param,
911 .query_bus_param = ov772x_query_bus_param,
912 .get_chip_id = ov772x_get_chip_id,
913#ifdef CONFIG_VIDEO_ADV_DEBUG
914 .get_register = ov772x_get_register,
915 .set_register = ov772x_set_register,
916#endif
917};
918
919/*
920 * i2c_driver function
921 */
922
923static int ov772x_probe(struct i2c_client *client,
924 const struct i2c_device_id *did)
925{
926 struct ov772x_priv *priv;
927 struct ov772x_camera_info *info;
928 struct soc_camera_device *icd;
929 struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
930 int ret;
931
932 info = client->dev.platform_data;
933 if (!info)
934 return -EINVAL;
935
936 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
937 dev_err(&adapter->dev,
938 "I2C-Adapter doesn't support "
939 "I2C_FUNC_SMBUS_BYTE_DATA\n");
940 return -EIO;
941 }
942
943 priv = kzalloc(sizeof(*priv), GFP_KERNEL);
944 if (!priv)
945 return -ENOMEM;
946
947 priv->info = info;
948 priv->client = client;
949 i2c_set_clientdata(client, priv);
950
951 icd = &priv->icd;
952 icd->ops = &ov772x_ops;
953 icd->control = &client->dev;
954 icd->width_max = MAX_WIDTH;
955 icd->height_max = MAX_HEIGHT;
956 icd->iface = priv->info->link.bus_id;
957
958 ret = soc_camera_device_register(icd);
959
960 if (ret) {
961 i2c_set_clientdata(client, NULL);
962 kfree(priv);
963 }
964
965 return ret;
966}
967
968static int ov772x_remove(struct i2c_client *client)
969{
970 struct ov772x_priv *priv = i2c_get_clientdata(client);
971
972 soc_camera_device_unregister(&priv->icd);
973 i2c_set_clientdata(client, NULL);
974 kfree(priv);
975 return 0;
976}
977
978static const struct i2c_device_id ov772x_id[] = {
979 { "ov772x", 0 },
980 { }
981};
982MODULE_DEVICE_TABLE(i2c, ov772x_id);
983
984static struct i2c_driver ov772x_i2c_driver = {
985 .driver = {
986 .name = "ov772x",
987 },
988 .probe = ov772x_probe,
989 .remove = ov772x_remove,
990 .id_table = ov772x_id,
991};
992
993/*
994 * module function
995 */
996
997static int __init ov772x_module_init(void)
998{
999 return i2c_add_driver(&ov772x_i2c_driver);
1000}
1001
1002static void __exit ov772x_module_exit(void)
1003{
1004 i2c_del_driver(&ov772x_i2c_driver);
1005}
1006
1007module_init(ov772x_module_init);
1008module_exit(ov772x_module_exit);
1009
1010MODULE_DESCRIPTION("SoC Camera driver for ov772x");
1011MODULE_AUTHOR("Kuninori Morimoto");
1012MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/pms.c b/drivers/media/video/pms.c
index 994807818aa2..45730fac1570 100644
--- a/drivers/media/video/pms.c
+++ b/drivers/media/video/pms.c
@@ -10,8 +10,8 @@
10 * 14478 Potsdam, Germany 10 * 14478 Potsdam, Germany
11 * 11 *
12 * Most of this code is directly derived from his userspace driver. 12 * Most of this code is directly derived from his userspace driver.
13 * His driver works so send any reports to alan@redhat.com unless the 13 * His driver works so send any reports to alan@lxorguk.ukuu.org.uk
14 * 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 * 08/07/2003 Daniele Bellucci <bellucda@tiscali.it>
@@ -680,8 +680,7 @@ static int pms_capture(struct pms_device *dev, char __user *buf, int rgb555, int
680 * Video4linux interfacing 680 * Video4linux interfacing
681 */ 681 */
682 682
683static int pms_do_ioctl(struct inode *inode, struct file *file, 683static int pms_do_ioctl(struct file *file, unsigned int cmd, void *arg)
684 unsigned int cmd, void *arg)
685{ 684{
686 struct video_device *dev = video_devdata(file); 685 struct video_device *dev = video_devdata(file);
687 struct pms_device *pd=(struct pms_device *)dev; 686 struct pms_device *pd=(struct pms_device *)dev;
@@ -866,7 +865,7 @@ static int pms_do_ioctl(struct inode *inode, struct file *file,
866static int pms_ioctl(struct inode *inode, struct file *file, 865static int pms_ioctl(struct inode *inode, struct file *file,
867 unsigned int cmd, unsigned long arg) 866 unsigned int cmd, unsigned long arg)
868{ 867{
869 return video_usercopy(inode, file, cmd, arg, pms_do_ioctl); 868 return video_usercopy(file, cmd, arg, pms_do_ioctl);
870} 869}
871 870
872static ssize_t pms_read(struct file *file, char __user *buf, 871static ssize_t pms_read(struct file *file, char __user *buf,
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
index 5b81ba469641..4358079f1966 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
@@ -2395,7 +2395,7 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf,
2395 2395
2396 scnprintf(hdw->bus_info,sizeof(hdw->bus_info), 2396 scnprintf(hdw->bus_info,sizeof(hdw->bus_info),
2397 "usb %s address %d", 2397 "usb %s address %d",
2398 hdw->usb_dev->dev.bus_id, 2398 dev_name(&hdw->usb_dev->dev),
2399 hdw->usb_dev->devnum); 2399 hdw->usb_dev->devnum);
2400 2400
2401 ifnum = hdw->usb_intf->cur_altsetting->desc.bInterfaceNumber; 2401 ifnum = hdw->usb_intf->cur_altsetting->desc.bInterfaceNumber;
diff --git a/drivers/media/video/pvrusb2/pvrusb2-sysfs.c b/drivers/media/video/pvrusb2/pvrusb2-sysfs.c
index 733680f21317..e641cd971453 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-sysfs.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-sysfs.c
@@ -628,10 +628,10 @@ static void class_dev_create(struct pvr2_sysfs *sfp,
628 628
629 class_dev->class = &class_ptr->class; 629 class_dev->class = &class_ptr->class;
630 if (pvr2_hdw_get_sn(sfp->channel.hdw)) { 630 if (pvr2_hdw_get_sn(sfp->channel.hdw)) {
631 snprintf(class_dev->bus_id, BUS_ID_SIZE, "sn-%lu", 631 dev_set_name(class_dev, "sn-%lu",
632 pvr2_hdw_get_sn(sfp->channel.hdw)); 632 pvr2_hdw_get_sn(sfp->channel.hdw));
633 } else if (pvr2_hdw_get_unit_number(sfp->channel.hdw) >= 0) { 633 } else if (pvr2_hdw_get_unit_number(sfp->channel.hdw) >= 0) {
634 snprintf(class_dev->bus_id, BUS_ID_SIZE, "unit-%c", 634 dev_set_name(class_dev, "unit-%c",
635 pvr2_hdw_get_unit_number(sfp->channel.hdw) + 'a'); 635 pvr2_hdw_get_unit_number(sfp->channel.hdw) + 'a');
636 } else { 636 } else {
637 kfree(class_dev); 637 kfree(class_dev);
diff --git a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
index 97ed95957992..52af1c435965 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
@@ -168,8 +168,7 @@ static const char *get_v4l_name(int v4l_type)
168 * This is part of Video 4 Linux API. The procedure handles ioctl() calls. 168 * This is part of Video 4 Linux API. The procedure handles ioctl() calls.
169 * 169 *
170 */ 170 */
171static int __pvr2_v4l2_do_ioctl(struct file *file, 171static int pvr2_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
172 unsigned int cmd, void *arg)
173{ 172{
174 struct pvr2_v4l2_fh *fh = file->private_data; 173 struct pvr2_v4l2_fh *fh = file->private_data;
175 struct pvr2_v4l2 *vp = fh->vhead; 174 struct pvr2_v4l2 *vp = fh->vhead;
@@ -864,7 +863,7 @@ static int __pvr2_v4l2_do_ioctl(struct file *file,
864 863
865 default : 864 default :
866 ret = v4l_compat_translate_ioctl(file, cmd, 865 ret = v4l_compat_translate_ioctl(file, cmd,
867 arg, __pvr2_v4l2_do_ioctl); 866 arg, pvr2_v4l2_do_ioctl);
868 } 867 }
869 868
870 pvr2_hdw_commit_ctl(hdw); 869 pvr2_hdw_commit_ctl(hdw);
@@ -890,12 +889,6 @@ static int __pvr2_v4l2_do_ioctl(struct file *file,
890 return ret; 889 return ret;
891} 890}
892 891
893static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file,
894 unsigned int cmd, void *arg)
895{
896 return __pvr2_v4l2_do_ioctl(file, cmd, arg);
897}
898
899static void pvr2_v4l2_dev_destroy(struct pvr2_v4l2_dev *dip) 892static void pvr2_v4l2_dev_destroy(struct pvr2_v4l2_dev *dip)
900{ 893{
901 int num = dip->devbase.num; 894 int num = dip->devbase.num;
@@ -963,7 +956,7 @@ static int pvr2_v4l2_ioctl(struct inode *inode, struct file *file,
963#define IVTV_IOC_G_CODEC 0xFFEE7703 956#define IVTV_IOC_G_CODEC 0xFFEE7703
964#define IVTV_IOC_S_CODEC 0xFFEE7704 957#define IVTV_IOC_S_CODEC 0xFFEE7704
965 if (cmd == IVTV_IOC_G_CODEC || cmd == IVTV_IOC_S_CODEC) return 0; 958 if (cmd == IVTV_IOC_G_CODEC || cmd == IVTV_IOC_S_CODEC) return 0;
966 return video_usercopy(inode, file, cmd, arg, pvr2_v4l2_do_ioctl); 959 return video_usercopy(file, cmd, arg, pvr2_v4l2_do_ioctl);
967} 960}
968 961
969 962
diff --git a/drivers/media/video/pwc/pwc-if.c b/drivers/media/video/pwc/pwc-if.c
index f3897a3fdb75..1ce9da167b7e 100644
--- a/drivers/media/video/pwc/pwc-if.c
+++ b/drivers/media/video/pwc/pwc-if.c
@@ -1412,7 +1412,7 @@ static int pwc_video_ioctl(struct inode *inode, struct file *file,
1412 1412
1413 mutex_lock(&pdev->modlock); 1413 mutex_lock(&pdev->modlock);
1414 if (!pdev->unplugged) 1414 if (!pdev->unplugged)
1415 r = video_usercopy(inode, file, cmd, arg, pwc_video_do_ioctl); 1415 r = video_usercopy(file, cmd, arg, pwc_video_do_ioctl);
1416 mutex_unlock(&pdev->modlock); 1416 mutex_unlock(&pdev->modlock);
1417out: 1417out:
1418 return r; 1418 return r;
diff --git a/drivers/media/video/pwc/pwc-v4l.c b/drivers/media/video/pwc/pwc-v4l.c
index 76a1376c9751..d7c147328e35 100644
--- a/drivers/media/video/pwc/pwc-v4l.c
+++ b/drivers/media/video/pwc/pwc-v4l.c
@@ -337,8 +337,7 @@ static int pwc_vidioc_set_fmt(struct pwc_device *pdev, struct v4l2_format *f)
337 337
338} 338}
339 339
340int pwc_video_do_ioctl(struct inode *inode, struct file *file, 340int pwc_video_do_ioctl(struct file *file, unsigned int cmd, void *arg)
341 unsigned int cmd, void *arg)
342{ 341{
343 struct video_device *vdev = video_devdata(file); 342 struct video_device *vdev = video_devdata(file);
344 struct pwc_device *pdev; 343 struct pwc_device *pdev;
diff --git a/drivers/media/video/pwc/pwc.h b/drivers/media/video/pwc/pwc.h
index 74178754b39b..c046a2535668 100644
--- a/drivers/media/video/pwc/pwc.h
+++ b/drivers/media/video/pwc/pwc.h
@@ -340,8 +340,7 @@ extern int pwc_camera_power(struct pwc_device *pdev, int power);
340extern int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg); 340extern int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg);
341 341
342/** Functions in pwc-v4l.c */ 342/** Functions in pwc-v4l.c */
343extern int pwc_video_do_ioctl(struct inode *inode, struct file *file, 343extern int pwc_video_do_ioctl(struct file *file, unsigned int cmd, void *arg);
344 unsigned int cmd, void *arg);
345 344
346/** pwc-uncompress.c */ 345/** pwc-uncompress.c */
347/* Expand frame to image, possibly including decompression. Uses read_frame and fill_image */ 346/* Expand frame to image, possibly including decompression. Uses read_frame and fill_image */
diff --git a/drivers/media/video/pxa_camera.c b/drivers/media/video/pxa_camera.c
index 70a77625107d..9d33de22cc48 100644
--- a/drivers/media/video/pxa_camera.c
+++ b/drivers/media/video/pxa_camera.c
@@ -25,7 +25,6 @@
25#include <linux/version.h> 25#include <linux/version.h>
26#include <linux/device.h> 26#include <linux/device.h>
27#include <linux/platform_device.h> 27#include <linux/platform_device.h>
28#include <linux/mutex.h>
29#include <linux/clk.h> 28#include <linux/clk.h>
30 29
31#include <media/v4l2-common.h> 30#include <media/v4l2-common.h>
@@ -44,6 +43,101 @@
44#define PXA_CAM_VERSION_CODE KERNEL_VERSION(0, 0, 5) 43#define PXA_CAM_VERSION_CODE KERNEL_VERSION(0, 0, 5)
45#define PXA_CAM_DRV_NAME "pxa27x-camera" 44#define PXA_CAM_DRV_NAME "pxa27x-camera"
46 45
46/* Camera Interface */
47#define CICR0 0x0000
48#define CICR1 0x0004
49#define CICR2 0x0008
50#define CICR3 0x000C
51#define CICR4 0x0010
52#define CISR 0x0014
53#define CIFR 0x0018
54#define CITOR 0x001C
55#define CIBR0 0x0028
56#define CIBR1 0x0030
57#define CIBR2 0x0038
58
59#define CICR0_DMAEN (1 << 31) /* DMA request enable */
60#define CICR0_PAR_EN (1 << 30) /* Parity enable */
61#define CICR0_SL_CAP_EN (1 << 29) /* Capture enable for slave mode */
62#define CICR0_ENB (1 << 28) /* Camera interface enable */
63#define CICR0_DIS (1 << 27) /* Camera interface disable */
64#define CICR0_SIM (0x7 << 24) /* Sensor interface mode mask */
65#define CICR0_TOM (1 << 9) /* Time-out mask */
66#define CICR0_RDAVM (1 << 8) /* Receive-data-available mask */
67#define CICR0_FEM (1 << 7) /* FIFO-empty mask */
68#define CICR0_EOLM (1 << 6) /* End-of-line mask */
69#define CICR0_PERRM (1 << 5) /* Parity-error mask */
70#define CICR0_QDM (1 << 4) /* Quick-disable mask */
71#define CICR0_CDM (1 << 3) /* Disable-done mask */
72#define CICR0_SOFM (1 << 2) /* Start-of-frame mask */
73#define CICR0_EOFM (1 << 1) /* End-of-frame mask */
74#define CICR0_FOM (1 << 0) /* FIFO-overrun mask */
75
76#define CICR1_TBIT (1 << 31) /* Transparency bit */
77#define CICR1_RGBT_CONV (0x3 << 29) /* RGBT conversion mask */
78#define CICR1_PPL (0x7ff << 15) /* Pixels per line mask */
79#define CICR1_RGB_CONV (0x7 << 12) /* RGB conversion mask */
80#define CICR1_RGB_F (1 << 11) /* RGB format */
81#define CICR1_YCBCR_F (1 << 10) /* YCbCr format */
82#define CICR1_RGB_BPP (0x7 << 7) /* RGB bis per pixel mask */
83#define CICR1_RAW_BPP (0x3 << 5) /* Raw bis per pixel mask */
84#define CICR1_COLOR_SP (0x3 << 3) /* Color space mask */
85#define CICR1_DW (0x7 << 0) /* Data width mask */
86
87#define CICR2_BLW (0xff << 24) /* Beginning-of-line pixel clock
88 wait count mask */
89#define CICR2_ELW (0xff << 16) /* End-of-line pixel clock
90 wait count mask */
91#define CICR2_HSW (0x3f << 10) /* Horizontal sync pulse width mask */
92#define CICR2_BFPW (0x3f << 3) /* Beginning-of-frame pixel clock
93 wait count mask */
94#define CICR2_FSW (0x7 << 0) /* Frame stabilization
95 wait count mask */
96
97#define CICR3_BFW (0xff << 24) /* Beginning-of-frame line clock
98 wait count mask */
99#define CICR3_EFW (0xff << 16) /* End-of-frame line clock
100 wait count mask */
101#define CICR3_VSW (0x3f << 10) /* Vertical sync pulse width mask */
102#define CICR3_BFPW (0x3f << 3) /* Beginning-of-frame pixel clock
103 wait count mask */
104#define CICR3_LPF (0x7ff << 0) /* Lines per frame mask */
105
106#define CICR4_MCLK_DLY (0x3 << 24) /* MCLK Data Capture Delay mask */
107#define CICR4_PCLK_EN (1 << 23) /* Pixel clock enable */
108#define CICR4_PCP (1 << 22) /* Pixel clock polarity */
109#define CICR4_HSP (1 << 21) /* Horizontal sync polarity */
110#define CICR4_VSP (1 << 20) /* Vertical sync polarity */
111#define CICR4_MCLK_EN (1 << 19) /* MCLK enable */
112#define CICR4_FR_RATE (0x7 << 8) /* Frame rate mask */
113#define CICR4_DIV (0xff << 0) /* Clock divisor mask */
114
115#define CISR_FTO (1 << 15) /* FIFO time-out */
116#define CISR_RDAV_2 (1 << 14) /* Channel 2 receive data available */
117#define CISR_RDAV_1 (1 << 13) /* Channel 1 receive data available */
118#define CISR_RDAV_0 (1 << 12) /* Channel 0 receive data available */
119#define CISR_FEMPTY_2 (1 << 11) /* Channel 2 FIFO empty */
120#define CISR_FEMPTY_1 (1 << 10) /* Channel 1 FIFO empty */
121#define CISR_FEMPTY_0 (1 << 9) /* Channel 0 FIFO empty */
122#define CISR_EOL (1 << 8) /* End of line */
123#define CISR_PAR_ERR (1 << 7) /* Parity error */
124#define CISR_CQD (1 << 6) /* Camera interface quick disable */
125#define CISR_CDD (1 << 5) /* Camera interface disable done */
126#define CISR_SOF (1 << 4) /* Start of frame */
127#define CISR_EOF (1 << 3) /* End of frame */
128#define CISR_IFO_2 (1 << 2) /* FIFO overrun for Channel 2 */
129#define CISR_IFO_1 (1 << 1) /* FIFO overrun for Channel 1 */
130#define CISR_IFO_0 (1 << 0) /* FIFO overrun for Channel 0 */
131
132#define CIFR_FLVL2 (0x7f << 23) /* FIFO 2 level mask */
133#define CIFR_FLVL1 (0x7f << 16) /* FIFO 1 level mask */
134#define CIFR_FLVL0 (0xff << 8) /* FIFO 0 level mask */
135#define CIFR_THL_0 (0x3 << 4) /* Threshold Level for Channel 0 FIFO */
136#define CIFR_RESET_F (1 << 3) /* Reset input FIFOs */
137#define CIFR_FEN2 (1 << 2) /* FIFO enable for channel 2 */
138#define CIFR_FEN1 (1 << 1) /* FIFO enable for channel 1 */
139#define CIFR_FEN0 (1 << 0) /* FIFO enable for channel 0 */
140
47#define CICR0_SIM_MP (0 << 24) 141#define CICR0_SIM_MP (0 << 24)
48#define CICR0_SIM_SP (1 << 24) 142#define CICR0_SIM_SP (1 << 24)
49#define CICR0_SIM_MS (2 << 24) 143#define CICR0_SIM_MS (2 << 24)
@@ -71,8 +165,6 @@
71 CICR0_PERRM | CICR0_QDM | CICR0_CDM | CICR0_SOFM | \ 165 CICR0_PERRM | CICR0_QDM | CICR0_CDM | CICR0_SOFM | \
72 CICR0_EOFM | CICR0_FOM) 166 CICR0_EOFM | CICR0_FOM)
73 167
74static DEFINE_MUTEX(camera_lock);
75
76/* 168/*
77 * Structures 169 * Structures
78 */ 170 */
@@ -122,7 +214,9 @@ struct pxa_camera_dev {
122 struct pxacamera_platform_data *pdata; 214 struct pxacamera_platform_data *pdata;
123 struct resource *res; 215 struct resource *res;
124 unsigned long platform_flags; 216 unsigned long platform_flags;
125 unsigned long platform_mclk_10khz; 217 unsigned long ciclk;
218 unsigned long mclk;
219 u32 mclk_divisor;
126 220
127 struct list_head capture; 221 struct list_head capture;
128 222
@@ -145,8 +239,7 @@ static int pxa_videobuf_setup(struct videobuf_queue *vq, unsigned int *count,
145 unsigned int *size) 239 unsigned int *size)
146{ 240{
147 struct soc_camera_device *icd = vq->priv_data; 241 struct soc_camera_device *icd = vq->priv_data;
148 struct soc_camera_host *ici = 242 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
149 to_soc_camera_host(icd->dev.parent);
150 struct pxa_camera_dev *pcdev = ici->priv; 243 struct pxa_camera_dev *pcdev = ici->priv;
151 244
152 dev_dbg(&icd->dev, "count=%d, size=%d\n", *count, *size); 245 dev_dbg(&icd->dev, "count=%d, size=%d\n", *count, *size);
@@ -172,8 +265,7 @@ static int pxa_videobuf_setup(struct videobuf_queue *vq, unsigned int *count,
172static void free_buffer(struct videobuf_queue *vq, struct pxa_buffer *buf) 265static void free_buffer(struct videobuf_queue *vq, struct pxa_buffer *buf)
173{ 266{
174 struct soc_camera_device *icd = vq->priv_data; 267 struct soc_camera_device *icd = vq->priv_data;
175 struct soc_camera_host *ici = 268 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
176 to_soc_camera_host(icd->dev.parent);
177 struct pxa_camera_dev *pcdev = ici->priv; 269 struct pxa_camera_dev *pcdev = ici->priv;
178 struct videobuf_dmabuf *dma = videobuf_to_dma(&buf->vb); 270 struct videobuf_dmabuf *dma = videobuf_to_dma(&buf->vb);
179 int i; 271 int i;
@@ -249,8 +341,7 @@ static int pxa_videobuf_prepare(struct videobuf_queue *vq,
249 struct videobuf_buffer *vb, enum v4l2_field field) 341 struct videobuf_buffer *vb, enum v4l2_field field)
250{ 342{
251 struct soc_camera_device *icd = vq->priv_data; 343 struct soc_camera_device *icd = vq->priv_data;
252 struct soc_camera_host *ici = 344 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
253 to_soc_camera_host(icd->dev.parent);
254 struct pxa_camera_dev *pcdev = ici->priv; 345 struct pxa_camera_dev *pcdev = ici->priv;
255 struct pxa_buffer *buf = container_of(vb, struct pxa_buffer, vb); 346 struct pxa_buffer *buf = container_of(vb, struct pxa_buffer, vb);
256 int ret; 347 int ret;
@@ -369,8 +460,7 @@ static void pxa_videobuf_queue(struct videobuf_queue *vq,
369 struct videobuf_buffer *vb) 460 struct videobuf_buffer *vb)
370{ 461{
371 struct soc_camera_device *icd = vq->priv_data; 462 struct soc_camera_device *icd = vq->priv_data;
372 struct soc_camera_host *ici = 463 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
373 to_soc_camera_host(icd->dev.parent);
374 struct pxa_camera_dev *pcdev = ici->priv; 464 struct pxa_camera_dev *pcdev = ici->priv;
375 struct pxa_buffer *buf = container_of(vb, struct pxa_buffer, vb); 465 struct pxa_buffer *buf = container_of(vb, struct pxa_buffer, vb);
376 struct pxa_buffer *active; 466 struct pxa_buffer *active;
@@ -387,7 +477,10 @@ static void pxa_videobuf_queue(struct videobuf_queue *vq,
387 active = pcdev->active; 477 active = pcdev->active;
388 478
389 if (!active) { 479 if (!active) {
390 CIFR |= CIFR_RESET_F; 480 unsigned long cifr, cicr0;
481
482 cifr = __raw_readl(pcdev->base + CIFR) | CIFR_RESET_F;
483 __raw_writel(cifr, pcdev->base + CIFR);
391 484
392 for (i = 0; i < pcdev->channels; i++) { 485 for (i = 0; i < pcdev->channels; i++) {
393 DDADR(pcdev->dma_chans[i]) = buf->dmas[i].sg_dma; 486 DDADR(pcdev->dma_chans[i]) = buf->dmas[i].sg_dma;
@@ -396,7 +489,9 @@ static void pxa_videobuf_queue(struct videobuf_queue *vq,
396 } 489 }
397 490
398 pcdev->active = buf; 491 pcdev->active = buf;
399 CICR0 |= CICR0_ENB; 492
493 cicr0 = __raw_readl(pcdev->base + CICR0) | CICR0_ENB;
494 __raw_writel(cicr0, pcdev->base + CICR0);
400 } else { 495 } else {
401 struct pxa_cam_dma *buf_dma; 496 struct pxa_cam_dma *buf_dma;
402 struct pxa_cam_dma *act_dma; 497 struct pxa_cam_dma *act_dma;
@@ -480,6 +575,8 @@ static void pxa_camera_wakeup(struct pxa_camera_dev *pcdev,
480 struct videobuf_buffer *vb, 575 struct videobuf_buffer *vb,
481 struct pxa_buffer *buf) 576 struct pxa_buffer *buf)
482{ 577{
578 unsigned long cicr0;
579
483 /* _init is used to debug races, see comment in pxa_camera_reqbufs() */ 580 /* _init is used to debug races, see comment in pxa_camera_reqbufs() */
484 list_del_init(&vb->queue); 581 list_del_init(&vb->queue);
485 vb->state = VIDEOBUF_DONE; 582 vb->state = VIDEOBUF_DONE;
@@ -492,7 +589,9 @@ static void pxa_camera_wakeup(struct pxa_camera_dev *pcdev,
492 DCSR(pcdev->dma_chans[0]) = 0; 589 DCSR(pcdev->dma_chans[0]) = 0;
493 DCSR(pcdev->dma_chans[1]) = 0; 590 DCSR(pcdev->dma_chans[1]) = 0;
494 DCSR(pcdev->dma_chans[2]) = 0; 591 DCSR(pcdev->dma_chans[2]) = 0;
495 CICR0 &= ~CICR0_ENB; 592
593 cicr0 = __raw_readl(pcdev->base + CICR0) & ~CICR0_ENB;
594 __raw_writel(cicr0, pcdev->base + CICR0);
496 return; 595 return;
497 } 596 }
498 597
@@ -507,6 +606,7 @@ static void pxa_camera_dma_irq(int channel, struct pxa_camera_dev *pcdev,
507 unsigned long flags; 606 unsigned long flags;
508 u32 status, camera_status, overrun; 607 u32 status, camera_status, overrun;
509 struct videobuf_buffer *vb; 608 struct videobuf_buffer *vb;
609 unsigned long cifr, cicr0;
510 610
511 spin_lock_irqsave(&pcdev->lock, flags); 611 spin_lock_irqsave(&pcdev->lock, flags);
512 612
@@ -529,22 +629,26 @@ static void pxa_camera_dma_irq(int channel, struct pxa_camera_dev *pcdev,
529 goto out; 629 goto out;
530 } 630 }
531 631
532 camera_status = CISR; 632 camera_status = __raw_readl(pcdev->base + CISR);
533 overrun = CISR_IFO_0; 633 overrun = CISR_IFO_0;
534 if (pcdev->channels == 3) 634 if (pcdev->channels == 3)
535 overrun |= CISR_IFO_1 | CISR_IFO_2; 635 overrun |= CISR_IFO_1 | CISR_IFO_2;
536 if (camera_status & overrun) { 636 if (camera_status & overrun) {
537 dev_dbg(pcdev->dev, "FIFO overrun! CISR: %x\n", camera_status); 637 dev_dbg(pcdev->dev, "FIFO overrun! CISR: %x\n", camera_status);
538 /* Stop the Capture Interface */ 638 /* Stop the Capture Interface */
539 CICR0 &= ~CICR0_ENB; 639 cicr0 = __raw_readl(pcdev->base + CICR0) & ~CICR0_ENB;
640 __raw_writel(cicr0, pcdev->base + CICR0);
641
540 /* Stop DMA */ 642 /* Stop DMA */
541 DCSR(channel) = 0; 643 DCSR(channel) = 0;
542 /* Reset the FIFOs */ 644 /* Reset the FIFOs */
543 CIFR |= CIFR_RESET_F; 645 cifr = __raw_readl(pcdev->base + CIFR) | CIFR_RESET_F;
646 __raw_writel(cifr, pcdev->base + CIFR);
544 /* Enable End-Of-Frame Interrupt */ 647 /* Enable End-Of-Frame Interrupt */
545 CICR0 &= ~CICR0_EOFM; 648 cicr0 &= ~CICR0_EOFM;
649 __raw_writel(cicr0, pcdev->base + CICR0);
546 /* Restart the Capture Interface */ 650 /* Restart the Capture Interface */
547 CICR0 |= CICR0_ENB; 651 __raw_writel(cicr0 | CICR0_ENB, pcdev->base + CICR0);
548 goto out; 652 goto out;
549 } 653 }
550 654
@@ -600,24 +704,43 @@ static void pxa_camera_init_videobuf(struct videobuf_queue *q,
600 sizeof(struct pxa_buffer), icd); 704 sizeof(struct pxa_buffer), icd);
601} 705}
602 706
603static int mclk_get_divisor(struct pxa_camera_dev *pcdev) 707static u32 mclk_get_divisor(struct pxa_camera_dev *pcdev)
604{ 708{
605 unsigned int mclk_10khz = pcdev->platform_mclk_10khz; 709 unsigned long mclk = pcdev->mclk;
606 unsigned long div; 710 u32 div;
607 unsigned long lcdclk; 711 unsigned long lcdclk;
608 712
609 lcdclk = clk_get_rate(pcdev->clk) / 10000; 713 lcdclk = clk_get_rate(pcdev->clk);
714 pcdev->ciclk = lcdclk;
715
716 /* mclk <= ciclk / 4 (27.4.2) */
717 if (mclk > lcdclk / 4) {
718 mclk = lcdclk / 4;
719 dev_warn(pcdev->dev, "Limiting master clock to %lu\n", mclk);
720 }
721
722 /* We verify mclk != 0, so if anyone breaks it, here comes their Oops */
723 div = (lcdclk + 2 * mclk - 1) / (2 * mclk) - 1;
610 724
611 /* We verify platform_mclk_10khz != 0, so if anyone breaks it, here 725 /* If we're not supplying MCLK, leave it at 0 */
612 * they get a nice Oops */ 726 if (pcdev->platform_flags & PXA_CAMERA_MCLK_EN)
613 div = (lcdclk + 2 * mclk_10khz - 1) / (2 * mclk_10khz) - 1; 727 pcdev->mclk = lcdclk / (2 * (div + 1));
614 728
615 dev_dbg(pcdev->dev, "LCD clock %lukHz, target freq %dkHz, " 729 dev_dbg(pcdev->dev, "LCD clock %luHz, target freq %luHz, "
616 "divisor %lu\n", lcdclk * 10, mclk_10khz * 10, div); 730 "divisor %u\n", lcdclk, mclk, div);
617 731
618 return div; 732 return div;
619} 733}
620 734
735static void recalculate_fifo_timeout(struct pxa_camera_dev *pcdev,
736 unsigned long pclk)
737{
738 /* We want a timeout > 1 pixel time, not ">=" */
739 u32 ciclk_per_pixel = pcdev->ciclk / pclk + 1;
740
741 __raw_writel(ciclk_per_pixel, pcdev->base + CITOR);
742}
743
621static void pxa_camera_activate(struct pxa_camera_dev *pcdev) 744static void pxa_camera_activate(struct pxa_camera_dev *pcdev)
622{ 745{
623 struct pxacamera_platform_data *pdata = pcdev->pdata; 746 struct pxacamera_platform_data *pdata = pcdev->pdata;
@@ -631,7 +754,8 @@ static void pxa_camera_activate(struct pxa_camera_dev *pcdev)
631 pdata->init(pcdev->dev); 754 pdata->init(pcdev->dev);
632 } 755 }
633 756
634 CICR0 = 0x3FF; /* disable all interrupts */ 757 /* disable all interrupts */
758 __raw_writel(0x3ff, pcdev->base + CICR0);
635 759
636 if (pcdev->platform_flags & PXA_CAMERA_PCLK_EN) 760 if (pcdev->platform_flags & PXA_CAMERA_PCLK_EN)
637 cicr4 |= CICR4_PCLK_EN; 761 cicr4 |= CICR4_PCLK_EN;
@@ -644,7 +768,14 @@ static void pxa_camera_activate(struct pxa_camera_dev *pcdev)
644 if (pcdev->platform_flags & PXA_CAMERA_VSP) 768 if (pcdev->platform_flags & PXA_CAMERA_VSP)
645 cicr4 |= CICR4_VSP; 769 cicr4 |= CICR4_VSP;
646 770
647 CICR4 = mclk_get_divisor(pcdev) | cicr4; 771 __raw_writel(pcdev->mclk_divisor | cicr4, pcdev->base + CICR4);
772
773 if (pcdev->platform_flags & PXA_CAMERA_MCLK_EN)
774 /* Initialise the timeout under the assumption pclk = mclk */
775 recalculate_fifo_timeout(pcdev, pcdev->mclk);
776 else
777 /* "Safe default" - 13MHz */
778 recalculate_fifo_timeout(pcdev, 13000000);
648 779
649 clk_enable(pcdev->clk); 780 clk_enable(pcdev->clk);
650} 781}
@@ -657,14 +788,15 @@ static void pxa_camera_deactivate(struct pxa_camera_dev *pcdev)
657static irqreturn_t pxa_camera_irq(int irq, void *data) 788static irqreturn_t pxa_camera_irq(int irq, void *data)
658{ 789{
659 struct pxa_camera_dev *pcdev = data; 790 struct pxa_camera_dev *pcdev = data;
660 unsigned int status = CISR; 791 unsigned long status, cicr0;
661 792
662 dev_dbg(pcdev->dev, "Camera interrupt status 0x%x\n", status); 793 status = __raw_readl(pcdev->base + CISR);
794 dev_dbg(pcdev->dev, "Camera interrupt status 0x%lx\n", status);
663 795
664 if (!status) 796 if (!status)
665 return IRQ_NONE; 797 return IRQ_NONE;
666 798
667 CISR = status; 799 __raw_writel(status, pcdev->base + CISR);
668 800
669 if (status & CISR_EOF) { 801 if (status & CISR_EOF) {
670 int i; 802 int i;
@@ -673,22 +805,24 @@ static irqreturn_t pxa_camera_irq(int irq, void *data)
673 pcdev->active->dmas[i].sg_dma; 805 pcdev->active->dmas[i].sg_dma;
674 DCSR(pcdev->dma_chans[i]) = DCSR_RUN; 806 DCSR(pcdev->dma_chans[i]) = DCSR_RUN;
675 } 807 }
676 CICR0 |= CICR0_EOFM; 808 cicr0 = __raw_readl(pcdev->base + CICR0) | CICR0_EOFM;
809 __raw_writel(cicr0, pcdev->base + CICR0);
677 } 810 }
678 811
679 return IRQ_HANDLED; 812 return IRQ_HANDLED;
680} 813}
681 814
682/* The following two functions absolutely depend on the fact, that 815/*
683 * there can be only one camera on PXA quick capture interface */ 816 * The following two functions absolutely depend on the fact, that
817 * there can be only one camera on PXA quick capture interface
818 * Called with .video_lock held
819 */
684static int pxa_camera_add_device(struct soc_camera_device *icd) 820static int pxa_camera_add_device(struct soc_camera_device *icd)
685{ 821{
686 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 822 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
687 struct pxa_camera_dev *pcdev = ici->priv; 823 struct pxa_camera_dev *pcdev = ici->priv;
688 int ret; 824 int ret;
689 825
690 mutex_lock(&camera_lock);
691
692 if (pcdev->icd) { 826 if (pcdev->icd) {
693 ret = -EBUSY; 827 ret = -EBUSY;
694 goto ebusy; 828 goto ebusy;
@@ -704,11 +838,10 @@ static int pxa_camera_add_device(struct soc_camera_device *icd)
704 pcdev->icd = icd; 838 pcdev->icd = icd;
705 839
706ebusy: 840ebusy:
707 mutex_unlock(&camera_lock);
708
709 return ret; 841 return ret;
710} 842}
711 843
844/* Called with .video_lock held */
712static void pxa_camera_remove_device(struct soc_camera_device *icd) 845static void pxa_camera_remove_device(struct soc_camera_device *icd)
713{ 846{
714 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 847 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
@@ -720,7 +853,7 @@ static void pxa_camera_remove_device(struct soc_camera_device *icd)
720 icd->devnum); 853 icd->devnum);
721 854
722 /* disable capture, disable interrupts */ 855 /* disable capture, disable interrupts */
723 CICR0 = 0x3ff; 856 __raw_writel(0x3ff, pcdev->base + CICR0);
724 857
725 /* Stop DMA engine */ 858 /* Stop DMA engine */
726 DCSR(pcdev->dma_chans[0]) = 0; 859 DCSR(pcdev->dma_chans[0]) = 0;
@@ -767,6 +900,9 @@ static int test_platform_param(struct pxa_camera_dev *pcdev,
767 if (!(pcdev->platform_flags & PXA_CAMERA_DATAWIDTH_8)) 900 if (!(pcdev->platform_flags & PXA_CAMERA_DATAWIDTH_8))
768 return -EINVAL; 901 return -EINVAL;
769 *flags |= SOCAM_DATAWIDTH_8; 902 *flags |= SOCAM_DATAWIDTH_8;
903 break;
904 default:
905 return -EINVAL;
770 } 906 }
771 907
772 return 0; 908 return 0;
@@ -774,11 +910,10 @@ static int test_platform_param(struct pxa_camera_dev *pcdev,
774 910
775static int pxa_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt) 911static int pxa_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
776{ 912{
777 struct soc_camera_host *ici = 913 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
778 to_soc_camera_host(icd->dev.parent);
779 struct pxa_camera_dev *pcdev = ici->priv; 914 struct pxa_camera_dev *pcdev = ici->priv;
780 unsigned long dw, bpp, bus_flags, camera_flags, common_flags; 915 unsigned long dw, bpp, bus_flags, camera_flags, common_flags;
781 u32 cicr0, cicr1, cicr4 = 0; 916 u32 cicr0, cicr1, cicr2, cicr3, cicr4 = 0;
782 int ret = test_platform_param(pcdev, icd->buswidth, &bus_flags); 917 int ret = test_platform_param(pcdev, icd->buswidth, &bus_flags);
783 918
784 if (ret < 0) 919 if (ret < 0)
@@ -825,12 +960,10 @@ static int pxa_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
825 * We fix bit-per-pixel equal to data-width... */ 960 * We fix bit-per-pixel equal to data-width... */
826 switch (common_flags & SOCAM_DATAWIDTH_MASK) { 961 switch (common_flags & SOCAM_DATAWIDTH_MASK) {
827 case SOCAM_DATAWIDTH_10: 962 case SOCAM_DATAWIDTH_10:
828 icd->buswidth = 10;
829 dw = 4; 963 dw = 4;
830 bpp = 0x40; 964 bpp = 0x40;
831 break; 965 break;
832 case SOCAM_DATAWIDTH_9: 966 case SOCAM_DATAWIDTH_9:
833 icd->buswidth = 9;
834 dw = 3; 967 dw = 3;
835 bpp = 0x20; 968 bpp = 0x20;
836 break; 969 break;
@@ -838,7 +971,6 @@ static int pxa_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
838 /* Actually it can only be 8 now, 971 /* Actually it can only be 8 now,
839 * default is just to silence compiler warnings */ 972 * default is just to silence compiler warnings */
840 case SOCAM_DATAWIDTH_8: 973 case SOCAM_DATAWIDTH_8:
841 icd->buswidth = 8;
842 dw = 2; 974 dw = 2;
843 bpp = 0; 975 bpp = 0;
844 } 976 }
@@ -854,9 +986,9 @@ static int pxa_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
854 if (common_flags & SOCAM_VSYNC_ACTIVE_LOW) 986 if (common_flags & SOCAM_VSYNC_ACTIVE_LOW)
855 cicr4 |= CICR4_VSP; 987 cicr4 |= CICR4_VSP;
856 988
857 cicr0 = CICR0; 989 cicr0 = __raw_readl(pcdev->base + CICR0);
858 if (cicr0 & CICR0_ENB) 990 if (cicr0 & CICR0_ENB)
859 CICR0 = cicr0 & ~CICR0_ENB; 991 __raw_writel(cicr0 & ~CICR0_ENB, pcdev->base + CICR0);
860 992
861 cicr1 = CICR1_PPL_VAL(icd->width - 1) | bpp | dw; 993 cicr1 = CICR1_PPL_VAL(icd->width - 1) | bpp | dw;
862 994
@@ -864,7 +996,17 @@ static int pxa_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
864 case V4L2_PIX_FMT_YUV422P: 996 case V4L2_PIX_FMT_YUV422P:
865 pcdev->channels = 3; 997 pcdev->channels = 3;
866 cicr1 |= CICR1_YCBCR_F; 998 cicr1 |= CICR1_YCBCR_F;
999 /*
1000 * Normally, pxa bus wants as input UYVY format. We allow all
1001 * reorderings of the YUV422 format, as no processing is done,
1002 * and the YUV stream is just passed through without any
1003 * transformation. Note that UYVY is the only format that
1004 * should be used if pxa framebuffer Overlay2 is used.
1005 */
1006 case V4L2_PIX_FMT_UYVY:
1007 case V4L2_PIX_FMT_VYUY:
867 case V4L2_PIX_FMT_YUYV: 1008 case V4L2_PIX_FMT_YUYV:
1009 case V4L2_PIX_FMT_YVYU:
868 cicr1 |= CICR1_COLOR_SP_VAL(2); 1010 cicr1 |= CICR1_COLOR_SP_VAL(2);
869 break; 1011 break;
870 case V4L2_PIX_FMT_RGB555: 1012 case V4L2_PIX_FMT_RGB555:
@@ -876,27 +1018,32 @@ static int pxa_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
876 break; 1018 break;
877 } 1019 }
878 1020
879 CICR1 = cicr1; 1021 cicr2 = 0;
880 CICR2 = 0; 1022 cicr3 = CICR3_LPF_VAL(icd->height - 1) |
881 CICR3 = CICR3_LPF_VAL(icd->height - 1) |
882 CICR3_BFW_VAL(min((unsigned short)255, icd->y_skip_top)); 1023 CICR3_BFW_VAL(min((unsigned short)255, icd->y_skip_top));
883 CICR4 = mclk_get_divisor(pcdev) | cicr4; 1024 cicr4 |= pcdev->mclk_divisor;
1025
1026 __raw_writel(cicr1, pcdev->base + CICR1);
1027 __raw_writel(cicr2, pcdev->base + CICR2);
1028 __raw_writel(cicr3, pcdev->base + CICR3);
1029 __raw_writel(cicr4, pcdev->base + CICR4);
884 1030
885 /* CIF interrupts are not used, only DMA */ 1031 /* CIF interrupts are not used, only DMA */
886 CICR0 = (pcdev->platform_flags & PXA_CAMERA_MASTER ? 1032 cicr0 = (cicr0 & CICR0_ENB) | (pcdev->platform_flags & PXA_CAMERA_MASTER ?
887 CICR0_SIM_MP : (CICR0_SL_CAP_EN | CICR0_SIM_SP)) | 1033 CICR0_SIM_MP : (CICR0_SL_CAP_EN | CICR0_SIM_SP));
888 CICR0_DMAEN | CICR0_IRQ_MASK | (cicr0 & CICR0_ENB); 1034 cicr0 |= CICR0_DMAEN | CICR0_IRQ_MASK;
1035 __raw_writel(cicr0, pcdev->base + CICR0);
889 1036
890 return 0; 1037 return 0;
891} 1038}
892 1039
893static int pxa_camera_try_bus_param(struct soc_camera_device *icd, __u32 pixfmt) 1040static int pxa_camera_try_bus_param(struct soc_camera_device *icd,
1041 unsigned char buswidth)
894{ 1042{
895 struct soc_camera_host *ici = 1043 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
896 to_soc_camera_host(icd->dev.parent);
897 struct pxa_camera_dev *pcdev = ici->priv; 1044 struct pxa_camera_dev *pcdev = ici->priv;
898 unsigned long bus_flags, camera_flags; 1045 unsigned long bus_flags, camera_flags;
899 int ret = test_platform_param(pcdev, icd->buswidth, &bus_flags); 1046 int ret = test_platform_param(pcdev, buswidth, &bus_flags);
900 1047
901 if (ret < 0) 1048 if (ret < 0)
902 return ret; 1049 return ret;
@@ -906,28 +1053,210 @@ static int pxa_camera_try_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
906 return soc_camera_bus_param_compatible(camera_flags, bus_flags) ? 0 : -EINVAL; 1053 return soc_camera_bus_param_compatible(camera_flags, bus_flags) ? 0 : -EINVAL;
907} 1054}
908 1055
909static int pxa_camera_set_fmt_cap(struct soc_camera_device *icd, 1056static const struct soc_camera_data_format pxa_camera_formats[] = {
910 __u32 pixfmt, struct v4l2_rect *rect) 1057 {
1058 .name = "Planar YUV422 16 bit",
1059 .depth = 16,
1060 .fourcc = V4L2_PIX_FMT_YUV422P,
1061 .colorspace = V4L2_COLORSPACE_JPEG,
1062 },
1063};
1064
1065static bool buswidth_supported(struct soc_camera_device *icd, int depth)
1066{
1067 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
1068 struct pxa_camera_dev *pcdev = ici->priv;
1069
1070 switch (depth) {
1071 case 8:
1072 return !!(pcdev->platform_flags & PXA_CAMERA_DATAWIDTH_8);
1073 case 9:
1074 return !!(pcdev->platform_flags & PXA_CAMERA_DATAWIDTH_9);
1075 case 10:
1076 return !!(pcdev->platform_flags & PXA_CAMERA_DATAWIDTH_10);
1077 }
1078 return false;
1079}
1080
1081static int required_buswidth(const struct soc_camera_data_format *fmt)
911{ 1082{
912 return icd->ops->set_fmt_cap(icd, pixfmt, rect); 1083 switch (fmt->fourcc) {
1084 case V4L2_PIX_FMT_UYVY:
1085 case V4L2_PIX_FMT_VYUY:
1086 case V4L2_PIX_FMT_YUYV:
1087 case V4L2_PIX_FMT_YVYU:
1088 case V4L2_PIX_FMT_RGB565:
1089 case V4L2_PIX_FMT_RGB555:
1090 return 8;
1091 default:
1092 return fmt->depth;
1093 }
913} 1094}
914 1095
915static int pxa_camera_try_fmt_cap(struct soc_camera_device *icd, 1096static int pxa_camera_get_formats(struct soc_camera_device *icd, int idx,
916 struct v4l2_format *f) 1097 struct soc_camera_format_xlate *xlate)
917{ 1098{
918 /* limit to pxa hardware capabilities */ 1099 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
919 if (f->fmt.pix.height < 32) 1100 int formats = 0, buswidth, ret;
920 f->fmt.pix.height = 32; 1101
921 if (f->fmt.pix.height > 2048) 1102 buswidth = required_buswidth(icd->formats + idx);
922 f->fmt.pix.height = 2048; 1103
923 if (f->fmt.pix.width < 48) 1104 if (!buswidth_supported(icd, buswidth))
924 f->fmt.pix.width = 48; 1105 return 0;
925 if (f->fmt.pix.width > 2048) 1106
926 f->fmt.pix.width = 2048; 1107 ret = pxa_camera_try_bus_param(icd, buswidth);
927 f->fmt.pix.width &= ~0x01; 1108 if (ret < 0)
1109 return 0;
1110
1111 switch (icd->formats[idx].fourcc) {
1112 case V4L2_PIX_FMT_UYVY:
1113 formats++;
1114 if (xlate) {
1115 xlate->host_fmt = &pxa_camera_formats[0];
1116 xlate->cam_fmt = icd->formats + idx;
1117 xlate->buswidth = buswidth;
1118 xlate++;
1119 dev_dbg(&ici->dev, "Providing format %s using %s\n",
1120 pxa_camera_formats[0].name,
1121 icd->formats[idx].name);
1122 }
1123 case V4L2_PIX_FMT_VYUY:
1124 case V4L2_PIX_FMT_YUYV:
1125 case V4L2_PIX_FMT_YVYU:
1126 case V4L2_PIX_FMT_RGB565:
1127 case V4L2_PIX_FMT_RGB555:
1128 formats++;
1129 if (xlate) {
1130 xlate->host_fmt = icd->formats + idx;
1131 xlate->cam_fmt = icd->formats + idx;
1132 xlate->buswidth = buswidth;
1133 xlate++;
1134 dev_dbg(&ici->dev, "Providing format %s packed\n",
1135 icd->formats[idx].name);
1136 }
1137 break;
1138 default:
1139 /* Generic pass-through */
1140 formats++;
1141 if (xlate) {
1142 xlate->host_fmt = icd->formats + idx;
1143 xlate->cam_fmt = icd->formats + idx;
1144 xlate->buswidth = icd->formats[idx].depth;
1145 xlate++;
1146 dev_dbg(&ici->dev,
1147 "Providing format %s in pass-through mode\n",
1148 icd->formats[idx].name);
1149 }
1150 }
1151
1152 return formats;
1153}
1154
1155static int pxa_camera_set_fmt(struct soc_camera_device *icd,
1156 __u32 pixfmt, struct v4l2_rect *rect)
1157{
1158 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
1159 struct pxa_camera_dev *pcdev = ici->priv;
1160 const struct soc_camera_data_format *host_fmt, *cam_fmt = NULL;
1161 const struct soc_camera_format_xlate *xlate;
1162 struct soc_camera_sense sense = {
1163 .master_clock = pcdev->mclk,
1164 .pixel_clock_max = pcdev->ciclk / 4,
1165 };
1166 int ret, buswidth;
1167
1168 xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
1169 if (!xlate) {
1170 dev_warn(&ici->dev, "Format %x not found\n", pixfmt);
1171 return -EINVAL;
1172 }
1173
1174 buswidth = xlate->buswidth;
1175 host_fmt = xlate->host_fmt;
1176 cam_fmt = xlate->cam_fmt;
1177
1178 /* If PCLK is used to latch data from the sensor, check sense */
1179 if (pcdev->platform_flags & PXA_CAMERA_PCLK_EN)
1180 icd->sense = &sense;
1181
1182 switch (pixfmt) {
1183 case 0: /* Only geometry change */
1184 ret = icd->ops->set_fmt(icd, pixfmt, rect);
1185 break;
1186 default:
1187 ret = icd->ops->set_fmt(icd, cam_fmt->fourcc, rect);
1188 }
1189
1190 icd->sense = NULL;
1191
1192 if (ret < 0) {
1193 dev_warn(&ici->dev, "Failed to configure for format %x\n",
1194 pixfmt);
1195 } else if (sense.flags & SOCAM_SENSE_PCLK_CHANGED) {
1196 if (sense.pixel_clock > sense.pixel_clock_max) {
1197 dev_err(&ici->dev,
1198 "pixel clock %lu set by the camera too high!",
1199 sense.pixel_clock);
1200 return -EIO;
1201 }
1202 recalculate_fifo_timeout(pcdev, sense.pixel_clock);
1203 }
928 1204
1205 if (pixfmt && !ret) {
1206 icd->buswidth = buswidth;
1207 icd->current_fmt = host_fmt;
1208 }
1209
1210 return ret;
1211}
1212
1213static int pxa_camera_try_fmt(struct soc_camera_device *icd,
1214 struct v4l2_format *f)
1215{
1216 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
1217 const struct soc_camera_format_xlate *xlate;
1218 struct v4l2_pix_format *pix = &f->fmt.pix;
1219 __u32 pixfmt = pix->pixelformat;
1220 enum v4l2_field field;
1221 int ret;
1222
1223 xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
1224 if (!xlate) {
1225 dev_warn(&ici->dev, "Format %x not found\n", pixfmt);
1226 return -EINVAL;
1227 }
1228
1229 /* limit to pxa hardware capabilities */
1230 if (pix->height < 32)
1231 pix->height = 32;
1232 if (pix->height > 2048)
1233 pix->height = 2048;
1234 if (pix->width < 48)
1235 pix->width = 48;
1236 if (pix->width > 2048)
1237 pix->width = 2048;
1238 pix->width &= ~0x01;
1239
1240 pix->bytesperline = pix->width *
1241 DIV_ROUND_UP(xlate->host_fmt->depth, 8);
1242 pix->sizeimage = pix->height * pix->bytesperline;
1243
1244 /* camera has to see its format, but the user the original one */
1245 pix->pixelformat = xlate->cam_fmt->fourcc;
929 /* limit to sensor capabilities */ 1246 /* limit to sensor capabilities */
930 return icd->ops->try_fmt_cap(icd, f); 1247 ret = icd->ops->try_fmt(icd, f);
1248 pix->pixelformat = xlate->host_fmt->fourcc;
1249
1250 field = pix->field;
1251
1252 if (field == V4L2_FIELD_ANY) {
1253 pix->field = V4L2_FIELD_NONE;
1254 } else if (field != V4L2_FIELD_NONE) {
1255 dev_err(&icd->dev, "Field type %d unsupported.\n", field);
1256 return -EINVAL;
1257 }
1258
1259 return ret;
931} 1260}
932 1261
933static int pxa_camera_reqbufs(struct soc_camera_file *icf, 1262static int pxa_camera_reqbufs(struct soc_camera_file *icf,
@@ -979,16 +1308,15 @@ static int pxa_camera_querycap(struct soc_camera_host *ici,
979 1308
980static int pxa_camera_suspend(struct soc_camera_device *icd, pm_message_t state) 1309static int pxa_camera_suspend(struct soc_camera_device *icd, pm_message_t state)
981{ 1310{
982 struct soc_camera_host *ici = 1311 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
983 to_soc_camera_host(icd->dev.parent);
984 struct pxa_camera_dev *pcdev = ici->priv; 1312 struct pxa_camera_dev *pcdev = ici->priv;
985 int i = 0, ret = 0; 1313 int i = 0, ret = 0;
986 1314
987 pcdev->save_cicr[i++] = CICR0; 1315 pcdev->save_cicr[i++] = __raw_readl(pcdev->base + CICR0);
988 pcdev->save_cicr[i++] = CICR1; 1316 pcdev->save_cicr[i++] = __raw_readl(pcdev->base + CICR1);
989 pcdev->save_cicr[i++] = CICR2; 1317 pcdev->save_cicr[i++] = __raw_readl(pcdev->base + CICR2);
990 pcdev->save_cicr[i++] = CICR3; 1318 pcdev->save_cicr[i++] = __raw_readl(pcdev->base + CICR3);
991 pcdev->save_cicr[i++] = CICR4; 1319 pcdev->save_cicr[i++] = __raw_readl(pcdev->base + CICR4);
992 1320
993 if ((pcdev->icd) && (pcdev->icd->ops->suspend)) 1321 if ((pcdev->icd) && (pcdev->icd->ops->suspend))
994 ret = pcdev->icd->ops->suspend(pcdev->icd, state); 1322 ret = pcdev->icd->ops->suspend(pcdev->icd, state);
@@ -998,8 +1326,7 @@ static int pxa_camera_suspend(struct soc_camera_device *icd, pm_message_t state)
998 1326
999static int pxa_camera_resume(struct soc_camera_device *icd) 1327static int pxa_camera_resume(struct soc_camera_device *icd)
1000{ 1328{
1001 struct soc_camera_host *ici = 1329 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
1002 to_soc_camera_host(icd->dev.parent);
1003 struct pxa_camera_dev *pcdev = ici->priv; 1330 struct pxa_camera_dev *pcdev = ici->priv;
1004 int i = 0, ret = 0; 1331 int i = 0, ret = 0;
1005 1332
@@ -1007,23 +1334,27 @@ static int pxa_camera_resume(struct soc_camera_device *icd)
1007 DRCMR(69) = pcdev->dma_chans[1] | DRCMR_MAPVLD; 1334 DRCMR(69) = pcdev->dma_chans[1] | DRCMR_MAPVLD;
1008 DRCMR(70) = pcdev->dma_chans[2] | DRCMR_MAPVLD; 1335 DRCMR(70) = pcdev->dma_chans[2] | DRCMR_MAPVLD;
1009 1336
1010 CICR0 = pcdev->save_cicr[i++] & ~CICR0_ENB; 1337 __raw_writel(pcdev->save_cicr[i++] & ~CICR0_ENB, pcdev->base + CICR0);
1011 CICR1 = pcdev->save_cicr[i++]; 1338 __raw_writel(pcdev->save_cicr[i++], pcdev->base + CICR1);
1012 CICR2 = pcdev->save_cicr[i++]; 1339 __raw_writel(pcdev->save_cicr[i++], pcdev->base + CICR2);
1013 CICR3 = pcdev->save_cicr[i++]; 1340 __raw_writel(pcdev->save_cicr[i++], pcdev->base + CICR3);
1014 CICR4 = pcdev->save_cicr[i++]; 1341 __raw_writel(pcdev->save_cicr[i++], pcdev->base + CICR4);
1015 1342
1016 if ((pcdev->icd) && (pcdev->icd->ops->resume)) 1343 if ((pcdev->icd) && (pcdev->icd->ops->resume))
1017 ret = pcdev->icd->ops->resume(pcdev->icd); 1344 ret = pcdev->icd->ops->resume(pcdev->icd);
1018 1345
1019 /* Restart frame capture if active buffer exists */ 1346 /* Restart frame capture if active buffer exists */
1020 if (!ret && pcdev->active) { 1347 if (!ret && pcdev->active) {
1348 unsigned long cifr, cicr0;
1349
1021 /* Reset the FIFOs */ 1350 /* Reset the FIFOs */
1022 CIFR |= CIFR_RESET_F; 1351 cifr = __raw_readl(pcdev->base + CIFR) | CIFR_RESET_F;
1023 /* Enable End-Of-Frame Interrupt */ 1352 __raw_writel(cifr, pcdev->base + CIFR);
1024 CICR0 &= ~CICR0_EOFM; 1353
1025 /* Restart the Capture Interface */ 1354 cicr0 = __raw_readl(pcdev->base + CICR0);
1026 CICR0 |= CICR0_ENB; 1355 cicr0 &= ~CICR0_EOFM; /* Enable End-Of-Frame Interrupt */
1356 cicr0 |= CICR0_ENB; /* Restart the Capture Interface */
1357 __raw_writel(cicr0, pcdev->base + CICR0);
1027 } 1358 }
1028 1359
1029 return ret; 1360 return ret;
@@ -1035,13 +1366,13 @@ static struct soc_camera_host_ops pxa_soc_camera_host_ops = {
1035 .remove = pxa_camera_remove_device, 1366 .remove = pxa_camera_remove_device,
1036 .suspend = pxa_camera_suspend, 1367 .suspend = pxa_camera_suspend,
1037 .resume = pxa_camera_resume, 1368 .resume = pxa_camera_resume,
1038 .set_fmt_cap = pxa_camera_set_fmt_cap, 1369 .get_formats = pxa_camera_get_formats,
1039 .try_fmt_cap = pxa_camera_try_fmt_cap, 1370 .set_fmt = pxa_camera_set_fmt,
1371 .try_fmt = pxa_camera_try_fmt,
1040 .init_videobuf = pxa_camera_init_videobuf, 1372 .init_videobuf = pxa_camera_init_videobuf,
1041 .reqbufs = pxa_camera_reqbufs, 1373 .reqbufs = pxa_camera_reqbufs,
1042 .poll = pxa_camera_poll, 1374 .poll = pxa_camera_poll,
1043 .querycap = pxa_camera_querycap, 1375 .querycap = pxa_camera_querycap,
1044 .try_bus_param = pxa_camera_try_bus_param,
1045 .set_bus_param = pxa_camera_set_bus_param, 1376 .set_bus_param = pxa_camera_set_bus_param,
1046}; 1377};
1047 1378
@@ -1092,14 +1423,17 @@ static int pxa_camera_probe(struct platform_device *pdev)
1092 "data widths, using default 10 bit\n"); 1423 "data widths, using default 10 bit\n");
1093 pcdev->platform_flags |= PXA_CAMERA_DATAWIDTH_10; 1424 pcdev->platform_flags |= PXA_CAMERA_DATAWIDTH_10;
1094 } 1425 }
1095 pcdev->platform_mclk_10khz = pcdev->pdata->mclk_10khz; 1426 pcdev->mclk = pcdev->pdata->mclk_10khz * 10000;
1096 if (!pcdev->platform_mclk_10khz) { 1427 if (!pcdev->mclk) {
1097 dev_warn(&pdev->dev, 1428 dev_warn(&pdev->dev,
1098 "mclk_10khz == 0! Please, fix your platform data. " 1429 "mclk == 0! Please, fix your platform data. "
1099 "Using default 20MHz\n"); 1430 "Using default 20MHz\n");
1100 pcdev->platform_mclk_10khz = 2000; 1431 pcdev->mclk = 20000000;
1101 } 1432 }
1102 1433
1434 pcdev->dev = &pdev->dev;
1435 pcdev->mclk_divisor = mclk_get_divisor(pcdev);
1436
1103 INIT_LIST_HEAD(&pcdev->capture); 1437 INIT_LIST_HEAD(&pcdev->capture);
1104 spin_lock_init(&pcdev->lock); 1438 spin_lock_init(&pcdev->lock);
1105 1439
@@ -1119,7 +1453,6 @@ static int pxa_camera_probe(struct platform_device *pdev)
1119 } 1453 }
1120 pcdev->irq = irq; 1454 pcdev->irq = irq;
1121 pcdev->base = base; 1455 pcdev->base = base;
1122 pcdev->dev = &pdev->dev;
1123 1456
1124 /* request dma */ 1457 /* request dma */
1125 err = pxa_request_dma("CI_Y", DMA_PRIO_HIGH, 1458 err = pxa_request_dma("CI_Y", DMA_PRIO_HIGH,
diff --git a/drivers/media/video/saa5246a.c b/drivers/media/video/saa5246a.c
index 4a21b8a6a709..f159441e9375 100644
--- a/drivers/media/video/saa5246a.c
+++ b/drivers/media/video/saa5246a.c
@@ -15,7 +15,7 @@
15 * <richard.guenther@student.uni-tuebingen.de> 15 * <richard.guenther@student.uni-tuebingen.de>
16 * 16 *
17 * with changes by 17 * with changes by
18 * Alan Cox <Alan.Cox@linux.org> 18 * Alan Cox <alan@lxorguk.ukuu.org.uk>
19 * 19 *
20 * and 20 * and
21 * 21 *
@@ -804,8 +804,7 @@ static inline int saa5246a_stop_dau(struct saa5246a_device *t,
804 * 804 *
805 * Returns 0 if successful 805 * Returns 0 if successful
806 */ 806 */
807static int do_saa5246a_ioctl(struct inode *inode, struct file *file, 807static int do_saa5246a_ioctl(struct file *file, unsigned int cmd, void *arg)
808 unsigned int cmd, void *arg)
809{ 808{
810 struct saa5246a_device *t = video_drvdata(file); 809 struct saa5246a_device *t = video_drvdata(file);
811 810
@@ -953,7 +952,7 @@ static int saa5246a_ioctl(struct inode *inode, struct file *file,
953 952
954 cmd = vtx_fix_command(cmd); 953 cmd = vtx_fix_command(cmd);
955 mutex_lock(&t->lock); 954 mutex_lock(&t->lock);
956 err = video_usercopy(inode, file, cmd, arg, do_saa5246a_ioctl); 955 err = video_usercopy(file, cmd, arg, do_saa5246a_ioctl);
957 mutex_unlock(&t->lock); 956 mutex_unlock(&t->lock);
958 return err; 957 return err;
959} 958}
diff --git a/drivers/media/video/saa5249.c b/drivers/media/video/saa5249.c
index 3bb959c25d9d..6ef3affb97f1 100644
--- a/drivers/media/video/saa5249.c
+++ b/drivers/media/video/saa5249.c
@@ -8,7 +8,7 @@
8 * you can add arbitary multiple teletext devices to Linux video4linux 8 * you can add arbitary multiple teletext devices to Linux video4linux
9 * now (well 32 anyway). 9 * now (well 32 anyway).
10 * 10 *
11 * Alan Cox <Alan.Cox@linux.org> 11 * Alan Cox <alan@lxorguk.ukuu.org.uk>
12 * 12 *
13 * The original driver was heavily modified to match the i2c interface 13 * The original driver was heavily modified to match the i2c interface
14 * It was truncated to use the WinTV boards, too. 14 * It was truncated to use the WinTV boards, too.
@@ -190,8 +190,7 @@ static int i2c_getdata(struct saa5249_device *t, int count, u8 *buf)
190 * Standard character-device-driver functions 190 * Standard character-device-driver functions
191 */ 191 */
192 192
193static int do_saa5249_ioctl(struct inode *inode, struct file *file, 193static int do_saa5249_ioctl(struct file *file, unsigned int cmd, void *arg)
194 unsigned int cmd, void *arg)
195{ 194{
196 static int virtual_mode = false; 195 static int virtual_mode = false;
197 struct saa5249_device *t = video_drvdata(file); 196 struct saa5249_device *t = video_drvdata(file);
@@ -488,7 +487,7 @@ static int saa5249_ioctl(struct inode *inode, struct file *file,
488 487
489 cmd = vtx_fix_command(cmd); 488 cmd = vtx_fix_command(cmd);
490 mutex_lock(&t->lock); 489 mutex_lock(&t->lock);
491 err = video_usercopy(inode,file,cmd,arg,do_saa5249_ioctl); 490 err = video_usercopy(file, cmd, arg, do_saa5249_ioctl);
492 mutex_unlock(&t->lock); 491 mutex_unlock(&t->lock);
493 return err; 492 return err;
494} 493}
diff --git a/drivers/media/video/saa7115.c b/drivers/media/video/saa7115.c
index c8e9cb3db30a..22708ecdf1bb 100644
--- a/drivers/media/video/saa7115.c
+++ b/drivers/media/video/saa7115.c
@@ -44,7 +44,7 @@
44#include <linux/slab.h> 44#include <linux/slab.h>
45#include <linux/i2c.h> 45#include <linux/i2c.h>
46#include <linux/videodev2.h> 46#include <linux/videodev2.h>
47#include <media/v4l2-common.h> 47#include <media/v4l2-device.h>
48#include <media/v4l2-chip-ident.h> 48#include <media/v4l2-chip-ident.h>
49#include <media/v4l2-i2c-drv-legacy.h> 49#include <media/v4l2-i2c-drv-legacy.h>
50#include <media/saa7115.h> 50#include <media/saa7115.h>
@@ -70,6 +70,7 @@ static unsigned short normal_i2c[] = {
70I2C_CLIENT_INSMOD; 70I2C_CLIENT_INSMOD;
71 71
72struct saa711x_state { 72struct saa711x_state {
73 struct v4l2_subdev sd;
73 v4l2_std_id std; 74 v4l2_std_id std;
74 int input; 75 int input;
75 int output; 76 int output;
@@ -89,10 +90,17 @@ struct saa711x_state {
89 u8 apll; 90 u8 apll;
90}; 91};
91 92
93static inline struct saa711x_state *to_state(struct v4l2_subdev *sd)
94{
95 return container_of(sd, struct saa711x_state, sd);
96}
97
92/* ----------------------------------------------------------------------- */ 98/* ----------------------------------------------------------------------- */
93 99
94static inline int saa711x_write(struct i2c_client *client, u8 reg, u8 value) 100static inline int saa711x_write(struct v4l2_subdev *sd, u8 reg, u8 value)
95{ 101{
102 struct i2c_client *client = v4l2_get_subdevdata(sd);
103
96 return i2c_smbus_write_byte_data(client, reg, value); 104 return i2c_smbus_write_byte_data(client, reg, value);
97} 105}
98 106
@@ -128,9 +136,9 @@ static int saa711x_has_reg(const int id, const u8 reg)
128 return 1; 136 return 1;
129} 137}
130 138
131static int saa711x_writeregs(struct i2c_client *client, const unsigned char *regs) 139static int saa711x_writeregs(struct v4l2_subdev *sd, const unsigned char *regs)
132{ 140{
133 struct saa711x_state *state = i2c_get_clientdata(client); 141 struct saa711x_state *state = to_state(sd);
134 unsigned char reg, data; 142 unsigned char reg, data;
135 143
136 while (*regs != 0x00) { 144 while (*regs != 0x00) {
@@ -139,18 +147,20 @@ static int saa711x_writeregs(struct i2c_client *client, const unsigned char *reg
139 147
140 /* According with datasheets, reserved regs should be 148 /* According with datasheets, reserved regs should be
141 filled with 0 - seems better not to touch on they */ 149 filled with 0 - seems better not to touch on they */
142 if (saa711x_has_reg(state->ident,reg)) { 150 if (saa711x_has_reg(state->ident, reg)) {
143 if (saa711x_write(client, reg, data) < 0) 151 if (saa711x_write(sd, reg, data) < 0)
144 return -1; 152 return -1;
145 } else { 153 } else {
146 v4l_dbg(1, debug, client, "tried to access reserved reg 0x%02x\n", reg); 154 v4l2_dbg(1, debug, sd, "tried to access reserved reg 0x%02x\n", reg);
147 } 155 }
148 } 156 }
149 return 0; 157 return 0;
150} 158}
151 159
152static inline int saa711x_read(struct i2c_client *client, u8 reg) 160static inline int saa711x_read(struct v4l2_subdev *sd, u8 reg)
153{ 161{
162 struct i2c_client *client = v4l2_get_subdevdata(sd);
163
154 return i2c_smbus_read_byte_data(client, reg); 164 return i2c_smbus_read_byte_data(client, reg);
155} 165}
156 166
@@ -601,7 +611,7 @@ static int saa711x_odd_parity(u8 c)
601 return c & 1; 611 return c & 1;
602} 612}
603 613
604static int saa711x_decode_vps(u8 * dst, u8 * p) 614static int saa711x_decode_vps(u8 *dst, u8 *p)
605{ 615{
606 static const u8 biphase_tbl[] = { 616 static const u8 biphase_tbl[] = {
607 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4, 617 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
@@ -648,7 +658,7 @@ static int saa711x_decode_vps(u8 * dst, u8 * p)
648 return err & 0xf0; 658 return err & 0xf0;
649} 659}
650 660
651static int saa711x_decode_wss(u8 * p) 661static int saa711x_decode_wss(u8 *p)
652{ 662{
653 static const int wss_bits[8] = { 663 static const int wss_bits[8] = {
654 0, 0, 0, 1, 0, 1, 1, 1 664 0, 0, 0, 1, 0, 1, 1, 1
@@ -675,9 +685,9 @@ static int saa711x_decode_wss(u8 * p)
675 return wss; 685 return wss;
676} 686}
677 687
678static int saa711x_set_audio_clock_freq(struct i2c_client *client, u32 freq) 688static int saa711x_s_clock_freq(struct v4l2_subdev *sd, u32 freq)
679{ 689{
680 struct saa711x_state *state = i2c_get_clientdata(client); 690 struct saa711x_state *state = to_state(sd);
681 u32 acpf; 691 u32 acpf;
682 u32 acni; 692 u32 acni;
683 u32 hz; 693 u32 hz;
@@ -685,10 +695,10 @@ static int saa711x_set_audio_clock_freq(struct i2c_client *client, u32 freq)
685 u8 acc = 0; /* reg 0x3a, audio clock control */ 695 u8 acc = 0; /* reg 0x3a, audio clock control */
686 696
687 /* Checks for chips that don't have audio clock (saa7111, saa7113) */ 697 /* Checks for chips that don't have audio clock (saa7111, saa7113) */
688 if (!saa711x_has_reg(state->ident,R_30_AUD_MAST_CLK_CYCLES_PER_FIELD)) 698 if (!saa711x_has_reg(state->ident, R_30_AUD_MAST_CLK_CYCLES_PER_FIELD))
689 return 0; 699 return 0;
690 700
691 v4l_dbg(1, debug, client, "set audio clock freq: %d\n", freq); 701 v4l2_dbg(1, debug, sd, "set audio clock freq: %d\n", freq);
692 702
693 /* sanity check */ 703 /* sanity check */
694 if (freq < 32000 || freq > 48000) 704 if (freq < 32000 || freq > 48000)
@@ -715,66 +725,66 @@ static int saa711x_set_audio_clock_freq(struct i2c_client *client, u32 freq)
715 if (state->apll) 725 if (state->apll)
716 acc |= 0x08; 726 acc |= 0x08;
717 727
718 saa711x_write(client, R_38_CLK_RATIO_AMXCLK_TO_ASCLK, 0x03); 728 saa711x_write(sd, R_38_CLK_RATIO_AMXCLK_TO_ASCLK, 0x03);
719 saa711x_write(client, R_39_CLK_RATIO_ASCLK_TO_ALRCLK, 0x10); 729 saa711x_write(sd, R_39_CLK_RATIO_ASCLK_TO_ALRCLK, 0x10);
720 saa711x_write(client, R_3A_AUD_CLK_GEN_BASIC_SETUP, acc); 730 saa711x_write(sd, R_3A_AUD_CLK_GEN_BASIC_SETUP, acc);
721 731
722 saa711x_write(client, R_30_AUD_MAST_CLK_CYCLES_PER_FIELD, acpf & 0xff); 732 saa711x_write(sd, R_30_AUD_MAST_CLK_CYCLES_PER_FIELD, acpf & 0xff);
723 saa711x_write(client, R_30_AUD_MAST_CLK_CYCLES_PER_FIELD+1, 733 saa711x_write(sd, R_30_AUD_MAST_CLK_CYCLES_PER_FIELD+1,
724 (acpf >> 8) & 0xff); 734 (acpf >> 8) & 0xff);
725 saa711x_write(client, R_30_AUD_MAST_CLK_CYCLES_PER_FIELD+2, 735 saa711x_write(sd, R_30_AUD_MAST_CLK_CYCLES_PER_FIELD+2,
726 (acpf >> 16) & 0x03); 736 (acpf >> 16) & 0x03);
727 737
728 saa711x_write(client, R_34_AUD_MAST_CLK_NOMINAL_INC, acni & 0xff); 738 saa711x_write(sd, R_34_AUD_MAST_CLK_NOMINAL_INC, acni & 0xff);
729 saa711x_write(client, R_34_AUD_MAST_CLK_NOMINAL_INC+1, (acni >> 8) & 0xff); 739 saa711x_write(sd, R_34_AUD_MAST_CLK_NOMINAL_INC+1, (acni >> 8) & 0xff);
730 saa711x_write(client, R_34_AUD_MAST_CLK_NOMINAL_INC+2, (acni >> 16) & 0x3f); 740 saa711x_write(sd, R_34_AUD_MAST_CLK_NOMINAL_INC+2, (acni >> 16) & 0x3f);
731 state->audclk_freq = freq; 741 state->audclk_freq = freq;
732 return 0; 742 return 0;
733} 743}
734 744
735static int saa711x_set_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl) 745static int saa711x_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
736{ 746{
737 struct saa711x_state *state = i2c_get_clientdata(client); 747 struct saa711x_state *state = to_state(sd);
738 748
739 switch (ctrl->id) { 749 switch (ctrl->id) {
740 case V4L2_CID_BRIGHTNESS: 750 case V4L2_CID_BRIGHTNESS:
741 if (ctrl->value < 0 || ctrl->value > 255) { 751 if (ctrl->value < 0 || ctrl->value > 255) {
742 v4l_err(client, "invalid brightness setting %d\n", ctrl->value); 752 v4l2_err(sd, "invalid brightness setting %d\n", ctrl->value);
743 return -ERANGE; 753 return -ERANGE;
744 } 754 }
745 755
746 state->bright = ctrl->value; 756 state->bright = ctrl->value;
747 saa711x_write(client, R_0A_LUMA_BRIGHT_CNTL, state->bright); 757 saa711x_write(sd, R_0A_LUMA_BRIGHT_CNTL, state->bright);
748 break; 758 break;
749 759
750 case V4L2_CID_CONTRAST: 760 case V4L2_CID_CONTRAST:
751 if (ctrl->value < 0 || ctrl->value > 127) { 761 if (ctrl->value < 0 || ctrl->value > 127) {
752 v4l_err(client, "invalid contrast setting %d\n", ctrl->value); 762 v4l2_err(sd, "invalid contrast setting %d\n", ctrl->value);
753 return -ERANGE; 763 return -ERANGE;
754 } 764 }
755 765
756 state->contrast = ctrl->value; 766 state->contrast = ctrl->value;
757 saa711x_write(client, R_0B_LUMA_CONTRAST_CNTL, state->contrast); 767 saa711x_write(sd, R_0B_LUMA_CONTRAST_CNTL, state->contrast);
758 break; 768 break;
759 769
760 case V4L2_CID_SATURATION: 770 case V4L2_CID_SATURATION:
761 if (ctrl->value < 0 || ctrl->value > 127) { 771 if (ctrl->value < 0 || ctrl->value > 127) {
762 v4l_err(client, "invalid saturation setting %d\n", ctrl->value); 772 v4l2_err(sd, "invalid saturation setting %d\n", ctrl->value);
763 return -ERANGE; 773 return -ERANGE;
764 } 774 }
765 775
766 state->sat = ctrl->value; 776 state->sat = ctrl->value;
767 saa711x_write(client, R_0C_CHROMA_SAT_CNTL, state->sat); 777 saa711x_write(sd, R_0C_CHROMA_SAT_CNTL, state->sat);
768 break; 778 break;
769 779
770 case V4L2_CID_HUE: 780 case V4L2_CID_HUE:
771 if (ctrl->value < -127 || ctrl->value > 127) { 781 if (ctrl->value < -127 || ctrl->value > 127) {
772 v4l_err(client, "invalid hue setting %d\n", ctrl->value); 782 v4l2_err(sd, "invalid hue setting %d\n", ctrl->value);
773 return -ERANGE; 783 return -ERANGE;
774 } 784 }
775 785
776 state->hue = ctrl->value; 786 state->hue = ctrl->value;
777 saa711x_write(client, R_0D_CHROMA_HUE_CNTL, state->hue); 787 saa711x_write(sd, R_0D_CHROMA_HUE_CNTL, state->hue);
778 break; 788 break;
779 789
780 default: 790 default:
@@ -784,9 +794,9 @@ static int saa711x_set_v4lctrl(struct i2c_client *client, struct v4l2_control *c
784 return 0; 794 return 0;
785} 795}
786 796
787static int saa711x_get_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl) 797static int saa711x_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
788{ 798{
789 struct saa711x_state *state = i2c_get_clientdata(client); 799 struct saa711x_state *state = to_state(sd);
790 800
791 switch (ctrl->id) { 801 switch (ctrl->id) {
792 case V4L2_CID_BRIGHTNESS: 802 case V4L2_CID_BRIGHTNESS:
@@ -808,16 +818,16 @@ static int saa711x_get_v4lctrl(struct i2c_client *client, struct v4l2_control *c
808 return 0; 818 return 0;
809} 819}
810 820
811static int saa711x_set_size(struct i2c_client *client, int width, int height) 821static int saa711x_set_size(struct v4l2_subdev *sd, int width, int height)
812{ 822{
813 struct saa711x_state *state = i2c_get_clientdata(client); 823 struct saa711x_state *state = to_state(sd);
814 int HPSC, HFSC; 824 int HPSC, HFSC;
815 int VSCY; 825 int VSCY;
816 int res; 826 int res;
817 int is_50hz = state->std & V4L2_STD_625_50; 827 int is_50hz = state->std & V4L2_STD_625_50;
818 int Vsrc = is_50hz ? 576 : 480; 828 int Vsrc = is_50hz ? 576 : 480;
819 829
820 v4l_dbg(1, debug, client, "decoder set size to %ix%i\n",width,height); 830 v4l2_dbg(1, debug, sd, "decoder set size to %ix%i\n", width, height);
821 831
822 /* FIXME need better bounds checking here */ 832 /* FIXME need better bounds checking here */
823 if ((width < 1) || (width > 1440)) 833 if ((width < 1) || (width > 1440))
@@ -825,7 +835,7 @@ static int saa711x_set_size(struct i2c_client *client, int width, int height)
825 if ((height < 1) || (height > Vsrc)) 835 if ((height < 1) || (height > Vsrc))
826 return -EINVAL; 836 return -EINVAL;
827 837
828 if (!saa711x_has_reg(state->ident,R_D0_B_HORIZ_PRESCALING)) { 838 if (!saa711x_has_reg(state->ident, R_D0_B_HORIZ_PRESCALING)) {
829 /* Decoder only supports 720 columns and 480 or 576 lines */ 839 /* Decoder only supports 720 columns and 480 or 576 lines */
830 if (width != 720) 840 if (width != 720)
831 return -EINVAL; 841 return -EINVAL;
@@ -843,22 +853,22 @@ static int saa711x_set_size(struct i2c_client *client, int width, int height)
843 /* Set output width/height */ 853 /* Set output width/height */
844 /* width */ 854 /* width */
845 855
846 saa711x_write(client, R_CC_B_HORIZ_OUTPUT_WINDOW_LENGTH, 856 saa711x_write(sd, R_CC_B_HORIZ_OUTPUT_WINDOW_LENGTH,
847 (u8) (width & 0xff)); 857 (u8) (width & 0xff));
848 saa711x_write(client, R_CD_B_HORIZ_OUTPUT_WINDOW_LENGTH_MSB, 858 saa711x_write(sd, R_CD_B_HORIZ_OUTPUT_WINDOW_LENGTH_MSB,
849 (u8) ((width >> 8) & 0xff)); 859 (u8) ((width >> 8) & 0xff));
850 860
851 /* Vertical Scaling uses height/2 */ 861 /* Vertical Scaling uses height/2 */
852 res=height/2; 862 res = height / 2;
853 863
854 /* On 60Hz, it is using a higher Vertical Output Size */ 864 /* On 60Hz, it is using a higher Vertical Output Size */
855 if (!is_50hz) 865 if (!is_50hz)
856 res += (VRES_60HZ - 480) >> 1; 866 res += (VRES_60HZ - 480) >> 1;
857 867
858 /* height */ 868 /* height */
859 saa711x_write(client, R_CE_B_VERT_OUTPUT_WINDOW_LENGTH, 869 saa711x_write(sd, R_CE_B_VERT_OUTPUT_WINDOW_LENGTH,
860 (u8) (res & 0xff)); 870 (u8) (res & 0xff));
861 saa711x_write(client, R_CF_B_VERT_OUTPUT_WINDOW_LENGTH_MSB, 871 saa711x_write(sd, R_CF_B_VERT_OUTPUT_WINDOW_LENGTH_MSB,
862 (u8) ((res >> 8) & 0xff)); 872 (u8) ((res >> 8) & 0xff));
863 873
864 /* Scaling settings */ 874 /* Scaling settings */
@@ -869,54 +879,54 @@ static int saa711x_set_size(struct i2c_client *client, int width, int height)
869 HFSC = (int)((1024 * 720) / (HPSC * width)); 879 HFSC = (int)((1024 * 720) / (HPSC * width));
870 /* FIXME hardcodes to "Task B" 880 /* FIXME hardcodes to "Task B"
871 * write H prescaler integer */ 881 * write H prescaler integer */
872 saa711x_write(client, R_D0_B_HORIZ_PRESCALING, 882 saa711x_write(sd, R_D0_B_HORIZ_PRESCALING,
873 (u8) (HPSC & 0x3f)); 883 (u8) (HPSC & 0x3f));
874 884
875 v4l_dbg(1, debug, client, "Hpsc: 0x%05x, Hfsc: 0x%05x\n", HPSC, HFSC); 885 v4l2_dbg(1, debug, sd, "Hpsc: 0x%05x, Hfsc: 0x%05x\n", HPSC, HFSC);
876 /* write H fine-scaling (luminance) */ 886 /* write H fine-scaling (luminance) */
877 saa711x_write(client, R_D8_B_HORIZ_LUMA_SCALING_INC, 887 saa711x_write(sd, R_D8_B_HORIZ_LUMA_SCALING_INC,
878 (u8) (HFSC & 0xff)); 888 (u8) (HFSC & 0xff));
879 saa711x_write(client, R_D9_B_HORIZ_LUMA_SCALING_INC_MSB, 889 saa711x_write(sd, R_D9_B_HORIZ_LUMA_SCALING_INC_MSB,
880 (u8) ((HFSC >> 8) & 0xff)); 890 (u8) ((HFSC >> 8) & 0xff));
881 /* write H fine-scaling (chrominance) 891 /* write H fine-scaling (chrominance)
882 * must be lum/2, so i'll just bitshift :) */ 892 * must be lum/2, so i'll just bitshift :) */
883 saa711x_write(client, R_DC_B_HORIZ_CHROMA_SCALING, 893 saa711x_write(sd, R_DC_B_HORIZ_CHROMA_SCALING,
884 (u8) ((HFSC >> 1) & 0xff)); 894 (u8) ((HFSC >> 1) & 0xff));
885 saa711x_write(client, R_DD_B_HORIZ_CHROMA_SCALING_MSB, 895 saa711x_write(sd, R_DD_B_HORIZ_CHROMA_SCALING_MSB,
886 (u8) ((HFSC >> 9) & 0xff)); 896 (u8) ((HFSC >> 9) & 0xff));
887 897
888 VSCY = (int)((1024 * Vsrc) / height); 898 VSCY = (int)((1024 * Vsrc) / height);
889 v4l_dbg(1, debug, client, "Vsrc: %d, Vscy: 0x%05x\n", Vsrc, VSCY); 899 v4l2_dbg(1, debug, sd, "Vsrc: %d, Vscy: 0x%05x\n", Vsrc, VSCY);
890 900
891 /* Correct Contrast and Luminance */ 901 /* Correct Contrast and Luminance */
892 saa711x_write(client, R_D5_B_LUMA_CONTRAST_CNTL, 902 saa711x_write(sd, R_D5_B_LUMA_CONTRAST_CNTL,
893 (u8) (64 * 1024 / VSCY)); 903 (u8) (64 * 1024 / VSCY));
894 saa711x_write(client, R_D6_B_CHROMA_SATURATION_CNTL, 904 saa711x_write(sd, R_D6_B_CHROMA_SATURATION_CNTL,
895 (u8) (64 * 1024 / VSCY)); 905 (u8) (64 * 1024 / VSCY));
896 906
897 /* write V fine-scaling (luminance) */ 907 /* write V fine-scaling (luminance) */
898 saa711x_write(client, R_E0_B_VERT_LUMA_SCALING_INC, 908 saa711x_write(sd, R_E0_B_VERT_LUMA_SCALING_INC,
899 (u8) (VSCY & 0xff)); 909 (u8) (VSCY & 0xff));
900 saa711x_write(client, R_E1_B_VERT_LUMA_SCALING_INC_MSB, 910 saa711x_write(sd, R_E1_B_VERT_LUMA_SCALING_INC_MSB,
901 (u8) ((VSCY >> 8) & 0xff)); 911 (u8) ((VSCY >> 8) & 0xff));
902 /* write V fine-scaling (chrominance) */ 912 /* write V fine-scaling (chrominance) */
903 saa711x_write(client, R_E2_B_VERT_CHROMA_SCALING_INC, 913 saa711x_write(sd, R_E2_B_VERT_CHROMA_SCALING_INC,
904 (u8) (VSCY & 0xff)); 914 (u8) (VSCY & 0xff));
905 saa711x_write(client, R_E3_B_VERT_CHROMA_SCALING_INC_MSB, 915 saa711x_write(sd, R_E3_B_VERT_CHROMA_SCALING_INC_MSB,
906 (u8) ((VSCY >> 8) & 0xff)); 916 (u8) ((VSCY >> 8) & 0xff));
907 917
908 saa711x_writeregs(client, saa7115_cfg_reset_scaler); 918 saa711x_writeregs(sd, saa7115_cfg_reset_scaler);
909 919
910 /* Activates task "B" */ 920 /* Activates task "B" */
911 saa711x_write(client, R_80_GLOBAL_CNTL_1, 921 saa711x_write(sd, R_80_GLOBAL_CNTL_1,
912 saa711x_read(client,R_80_GLOBAL_CNTL_1) | 0x20); 922 saa711x_read(sd, R_80_GLOBAL_CNTL_1) | 0x20);
913 923
914 return 0; 924 return 0;
915} 925}
916 926
917static void saa711x_set_v4lstd(struct i2c_client *client, v4l2_std_id std) 927static void saa711x_set_v4lstd(struct v4l2_subdev *sd, v4l2_std_id std)
918{ 928{
919 struct saa711x_state *state = i2c_get_clientdata(client); 929 struct saa711x_state *state = to_state(sd);
920 930
921 /* Prevent unnecessary standard changes. During a standard 931 /* Prevent unnecessary standard changes. During a standard
922 change the I-Port is temporarily disabled. Any devices 932 change the I-Port is temporarily disabled. Any devices
@@ -932,13 +942,13 @@ static void saa711x_set_v4lstd(struct i2c_client *client, v4l2_std_id std)
932 942
933 // This works for NTSC-M, SECAM-L and the 50Hz PAL variants. 943 // This works for NTSC-M, SECAM-L and the 50Hz PAL variants.
934 if (std & V4L2_STD_525_60) { 944 if (std & V4L2_STD_525_60) {
935 v4l_dbg(1, debug, client, "decoder set standard 60 Hz\n"); 945 v4l2_dbg(1, debug, sd, "decoder set standard 60 Hz\n");
936 saa711x_writeregs(client, saa7115_cfg_60hz_video); 946 saa711x_writeregs(sd, saa7115_cfg_60hz_video);
937 saa711x_set_size(client, 720, 480); 947 saa711x_set_size(sd, 720, 480);
938 } else { 948 } else {
939 v4l_dbg(1, debug, client, "decoder set standard 50 Hz\n"); 949 v4l2_dbg(1, debug, sd, "decoder set standard 50 Hz\n");
940 saa711x_writeregs(client, saa7115_cfg_50hz_video); 950 saa711x_writeregs(sd, saa7115_cfg_50hz_video);
941 saa711x_set_size(client, 720, 576); 951 saa711x_set_size(sd, 720, 576);
942 } 952 }
943 953
944 /* Register 0E - Bits D6-D4 on NO-AUTO mode 954 /* Register 0E - Bits D6-D4 on NO-AUTO mode
@@ -952,7 +962,7 @@ static void saa711x_set_v4lstd(struct i2c_client *client, v4l2_std_id std)
952 */ 962 */
953 if (state->ident == V4L2_IDENT_SAA7111 || 963 if (state->ident == V4L2_IDENT_SAA7111 ||
954 state->ident == V4L2_IDENT_SAA7113) { 964 state->ident == V4L2_IDENT_SAA7113) {
955 u8 reg = saa711x_read(client, R_0E_CHROMA_CNTL_1) & 0x8f; 965 u8 reg = saa711x_read(sd, R_0E_CHROMA_CNTL_1) & 0x8f;
956 966
957 if (std == V4L2_STD_PAL_M) { 967 if (std == V4L2_STD_PAL_M) {
958 reg |= 0x30; 968 reg |= 0x30;
@@ -965,87 +975,31 @@ static void saa711x_set_v4lstd(struct i2c_client *client, v4l2_std_id std)
965 } else if (std & V4L2_STD_SECAM) { 975 } else if (std & V4L2_STD_SECAM) {
966 reg |= 0x50; 976 reg |= 0x50;
967 } 977 }
968 saa711x_write(client, R_0E_CHROMA_CNTL_1, reg); 978 saa711x_write(sd, R_0E_CHROMA_CNTL_1, reg);
969 } else { 979 } else {
970 /* restart task B if needed */ 980 /* restart task B if needed */
971 int taskb = saa711x_read(client, R_80_GLOBAL_CNTL_1) & 0x10; 981 int taskb = saa711x_read(sd, R_80_GLOBAL_CNTL_1) & 0x10;
972 982
973 if (taskb && state->ident == V4L2_IDENT_SAA7114) { 983 if (taskb && state->ident == V4L2_IDENT_SAA7114) {
974 saa711x_writeregs(client, saa7115_cfg_vbi_on); 984 saa711x_writeregs(sd, saa7115_cfg_vbi_on);
975 } 985 }
976 986
977 /* switch audio mode too! */ 987 /* switch audio mode too! */
978 saa711x_set_audio_clock_freq(client, state->audclk_freq); 988 saa711x_s_clock_freq(sd, state->audclk_freq);
979 }
980}
981
982static v4l2_std_id saa711x_get_v4lstd(struct i2c_client *client)
983{
984 struct saa711x_state *state = i2c_get_clientdata(client);
985
986 return state->std;
987}
988
989static void saa711x_log_status(struct i2c_client *client)
990{
991 struct saa711x_state *state = i2c_get_clientdata(client);
992 int reg1e, reg1f;
993 int signalOk;
994 int vcr;
995
996 v4l_info(client, "Audio frequency: %d Hz\n", state->audclk_freq);
997 if (state->ident != V4L2_IDENT_SAA7115) {
998 /* status for the saa7114 */
999 reg1f = saa711x_read(client, R_1F_STATUS_BYTE_2_VD_DEC);
1000 signalOk = (reg1f & 0xc1) == 0x81;
1001 v4l_info(client, "Video signal: %s\n", signalOk ? "ok" : "bad");
1002 v4l_info(client, "Frequency: %s\n", (reg1f & 0x20) ? "60 Hz" : "50 Hz");
1003 return;
1004 }
1005
1006 /* status for the saa7115 */
1007 reg1e = saa711x_read(client, R_1E_STATUS_BYTE_1_VD_DEC);
1008 reg1f = saa711x_read(client, R_1F_STATUS_BYTE_2_VD_DEC);
1009
1010 signalOk = (reg1f & 0xc1) == 0x81 && (reg1e & 0xc0) == 0x80;
1011 vcr = !(reg1f & 0x10);
1012
1013 if (state->input >= 6) {
1014 v4l_info(client, "Input: S-Video %d\n", state->input - 6);
1015 } else {
1016 v4l_info(client, "Input: Composite %d\n", state->input);
1017 } 989 }
1018 v4l_info(client, "Video signal: %s\n", signalOk ? (vcr ? "VCR" : "broadcast/DVD") : "bad");
1019 v4l_info(client, "Frequency: %s\n", (reg1f & 0x20) ? "60 Hz" : "50 Hz");
1020
1021 switch (reg1e & 0x03) {
1022 case 1:
1023 v4l_info(client, "Detected format: NTSC\n");
1024 break;
1025 case 2:
1026 v4l_info(client, "Detected format: PAL\n");
1027 break;
1028 case 3:
1029 v4l_info(client, "Detected format: SECAM\n");
1030 break;
1031 default:
1032 v4l_info(client, "Detected format: BW/No color\n");
1033 break;
1034 }
1035 v4l_info(client, "Width, Height: %d, %d\n", state->width, state->height);
1036} 990}
1037 991
1038/* setup the sliced VBI lcr registers according to the sliced VBI format */ 992/* setup the sliced VBI lcr registers according to the sliced VBI format */
1039static void saa711x_set_lcr(struct i2c_client *client, struct v4l2_sliced_vbi_format *fmt) 993static void saa711x_set_lcr(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_format *fmt)
1040{ 994{
1041 struct saa711x_state *state = i2c_get_clientdata(client); 995 struct saa711x_state *state = to_state(sd);
1042 int is_50hz = (state->std & V4L2_STD_625_50); 996 int is_50hz = (state->std & V4L2_STD_625_50);
1043 u8 lcr[24]; 997 u8 lcr[24];
1044 int i, x; 998 int i, x;
1045 999
1046#if 1 1000#if 1
1047 /* saa7113/7114/7118 VBI support are experimental */ 1001 /* saa7113/7114/7118 VBI support are experimental */
1048 if (!saa711x_has_reg(state->ident,R_41_LCR_BASE)) 1002 if (!saa711x_has_reg(state->ident, R_41_LCR_BASE))
1049 return; 1003 return;
1050 1004
1051#else 1005#else
@@ -1109,16 +1063,16 @@ static void saa711x_set_lcr(struct i2c_client *client, struct v4l2_sliced_vbi_fo
1109 1063
1110 /* write the lcr registers */ 1064 /* write the lcr registers */
1111 for (i = 2; i <= 23; i++) { 1065 for (i = 2; i <= 23; i++) {
1112 saa711x_write(client, i - 2 + R_41_LCR_BASE, lcr[i]); 1066 saa711x_write(sd, i - 2 + R_41_LCR_BASE, lcr[i]);
1113 } 1067 }
1114 1068
1115 /* enable/disable raw VBI capturing */ 1069 /* enable/disable raw VBI capturing */
1116 saa711x_writeregs(client, fmt == NULL ? 1070 saa711x_writeregs(sd, fmt == NULL ?
1117 saa7115_cfg_vbi_on : 1071 saa7115_cfg_vbi_on :
1118 saa7115_cfg_vbi_off); 1072 saa7115_cfg_vbi_off);
1119} 1073}
1120 1074
1121static int saa711x_get_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt) 1075static int saa711x_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
1122{ 1076{
1123 static u16 lcr2vbi[] = { 1077 static u16 lcr2vbi[] = {
1124 0, V4L2_SLICED_TELETEXT_B, 0, /* 1 */ 1078 0, V4L2_SLICED_TELETEXT_B, 0, /* 1 */
@@ -1134,10 +1088,10 @@ static int saa711x_get_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt
1134 return -EINVAL; 1088 return -EINVAL;
1135 memset(sliced, 0, sizeof(*sliced)); 1089 memset(sliced, 0, sizeof(*sliced));
1136 /* done if using raw VBI */ 1090 /* done if using raw VBI */
1137 if (saa711x_read(client, R_80_GLOBAL_CNTL_1) & 0x10) 1091 if (saa711x_read(sd, R_80_GLOBAL_CNTL_1) & 0x10)
1138 return 0; 1092 return 0;
1139 for (i = 2; i <= 23; i++) { 1093 for (i = 2; i <= 23; i++) {
1140 u8 v = saa711x_read(client, i - 2 + R_41_LCR_BASE); 1094 u8 v = saa711x_read(sd, i - 2 + R_41_LCR_BASE);
1141 1095
1142 sliced->service_lines[0][i] = lcr2vbi[v >> 4]; 1096 sliced->service_lines[0][i] = lcr2vbi[v >> 4];
1143 sliced->service_lines[1][i] = lcr2vbi[v & 0xf]; 1097 sliced->service_lines[1][i] = lcr2vbi[v & 0xf];
@@ -1147,20 +1101,20 @@ static int saa711x_get_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt
1147 return 0; 1101 return 0;
1148} 1102}
1149 1103
1150static int saa711x_set_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt) 1104static int saa711x_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
1151{ 1105{
1152 if (fmt->type == V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) { 1106 if (fmt->type == V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) {
1153 saa711x_set_lcr(client, &fmt->fmt.sliced); 1107 saa711x_set_lcr(sd, &fmt->fmt.sliced);
1154 return 0; 1108 return 0;
1155 } 1109 }
1156 if (fmt->type == V4L2_BUF_TYPE_VBI_CAPTURE) { 1110 if (fmt->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
1157 saa711x_set_lcr(client, NULL); 1111 saa711x_set_lcr(sd, NULL);
1158 return 0; 1112 return 0;
1159 } 1113 }
1160 if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 1114 if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1161 return -EINVAL; 1115 return -EINVAL;
1162 1116
1163 return saa711x_set_size(client,fmt->fmt.pix.width,fmt->fmt.pix.height); 1117 return saa711x_set_size(sd, fmt->fmt.pix.width, fmt->fmt.pix.height);
1164} 1118}
1165 1119
1166/* Decode the sliced VBI data stream as created by the saa7115. 1120/* Decode the sliced VBI data stream as created by the saa7115.
@@ -1169,13 +1123,12 @@ static int saa711x_set_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt
1169 The current implementation uses SAV/EAV codes and not the ancillary data 1123 The current implementation uses SAV/EAV codes and not the ancillary data
1170 headers. The vbi->p pointer points to the R_5E_SDID byte right after the SAV 1124 headers. The vbi->p pointer points to the R_5E_SDID byte right after the SAV
1171 code. */ 1125 code. */
1172static void saa711x_decode_vbi_line(struct i2c_client *client, 1126static int saa711x_decode_vbi_line(struct v4l2_subdev *sd, struct v4l2_decode_vbi_line *vbi)
1173 struct v4l2_decode_vbi_line *vbi)
1174{ 1127{
1128 struct saa711x_state *state = to_state(sd);
1175 static const char vbi_no_data_pattern[] = { 1129 static const char vbi_no_data_pattern[] = {
1176 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0 1130 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0
1177 }; 1131 };
1178 struct saa711x_state *state = i2c_get_clientdata(client);
1179 u8 *p = vbi->p; 1132 u8 *p = vbi->p;
1180 u32 wss; 1133 u32 wss;
1181 int id1, id2; /* the ID1 and ID2 bytes from the internal header */ 1134 int id1, id2; /* the ID1 and ID2 bytes from the internal header */
@@ -1202,7 +1155,7 @@ static void saa711x_decode_vbi_line(struct i2c_client *client,
1202 /* If the VBI slicer does not detect any signal it will fill up 1155 /* If the VBI slicer does not detect any signal it will fill up
1203 the payload buffer with 0xa0 bytes. */ 1156 the payload buffer with 0xa0 bytes. */
1204 if (!memcmp(p, vbi_no_data_pattern, sizeof(vbi_no_data_pattern))) 1157 if (!memcmp(p, vbi_no_data_pattern, sizeof(vbi_no_data_pattern)))
1205 return; 1158 return 0;
1206 1159
1207 /* decode payloads */ 1160 /* decode payloads */
1208 switch (id2) { 1161 switch (id2) {
@@ -1211,275 +1164,352 @@ static void saa711x_decode_vbi_line(struct i2c_client *client,
1211 break; 1164 break;
1212 case 4: 1165 case 4:
1213 if (!saa711x_odd_parity(p[0]) || !saa711x_odd_parity(p[1])) 1166 if (!saa711x_odd_parity(p[0]) || !saa711x_odd_parity(p[1]))
1214 return; 1167 return 0;
1215 vbi->type = V4L2_SLICED_CAPTION_525; 1168 vbi->type = V4L2_SLICED_CAPTION_525;
1216 break; 1169 break;
1217 case 5: 1170 case 5:
1218 wss = saa711x_decode_wss(p); 1171 wss = saa711x_decode_wss(p);
1219 if (wss == -1) 1172 if (wss == -1)
1220 return; 1173 return 0;
1221 p[0] = wss & 0xff; 1174 p[0] = wss & 0xff;
1222 p[1] = wss >> 8; 1175 p[1] = wss >> 8;
1223 vbi->type = V4L2_SLICED_WSS_625; 1176 vbi->type = V4L2_SLICED_WSS_625;
1224 break; 1177 break;
1225 case 7: 1178 case 7:
1226 if (saa711x_decode_vps(p, p) != 0) 1179 if (saa711x_decode_vps(p, p) != 0)
1227 return; 1180 return 0;
1228 vbi->type = V4L2_SLICED_VPS; 1181 vbi->type = V4L2_SLICED_VPS;
1229 break; 1182 break;
1230 default: 1183 default:
1231 return; 1184 break;
1232 } 1185 }
1186 return 0;
1233} 1187}
1234 1188
1235/* ============ SAA7115 AUDIO settings (end) ============= */ 1189/* ============ SAA7115 AUDIO settings (end) ============= */
1236 1190
1237static int saa7115_command(struct i2c_client *client, unsigned int cmd, void *arg) 1191static int saa711x_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
1238{ 1192{
1239 struct saa711x_state *state = i2c_get_clientdata(client); 1193 struct saa711x_state *state = to_state(sd);
1194 int status;
1240 1195
1241 /* ioctls to allow direct access to the saa7115 registers for testing */ 1196 if (state->radio)
1242 switch (cmd) { 1197 return 0;
1243 case VIDIOC_S_FMT: 1198 status = saa711x_read(sd, R_1F_STATUS_BYTE_2_VD_DEC);
1244 return saa711x_set_v4lfmt(client, (struct v4l2_format *)arg);
1245 1199
1246 case VIDIOC_G_FMT: 1200 v4l2_dbg(1, debug, sd, "status: 0x%02x\n", status);
1247 return saa711x_get_v4lfmt(client, (struct v4l2_format *)arg); 1201 vt->signal = ((status & (1 << 6)) == 0) ? 0xffff : 0x0;
1202 return 0;
1203}
1248 1204
1249 case VIDIOC_INT_AUDIO_CLOCK_FREQ: 1205static int saa711x_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
1250 return saa711x_set_audio_clock_freq(client, *(u32 *)arg); 1206{
1207 switch (qc->id) {
1208 case V4L2_CID_BRIGHTNESS:
1209 case V4L2_CID_CONTRAST:
1210 case V4L2_CID_SATURATION:
1211 case V4L2_CID_HUE:
1212 return v4l2_ctrl_query_fill_std(qc);
1213 default:
1214 return -EINVAL;
1215 }
1216}
1251 1217
1252 case VIDIOC_G_TUNER: 1218static int saa711x_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
1253 { 1219{
1254 struct v4l2_tuner *vt = arg; 1220 struct saa711x_state *state = to_state(sd);
1255 int status;
1256 1221
1257 if (state->radio) 1222 state->radio = 0;
1258 break; 1223 saa711x_set_v4lstd(sd, std);
1259 status = saa711x_read(client, R_1F_STATUS_BYTE_2_VD_DEC); 1224 return 0;
1225}
1260 1226
1261 v4l_dbg(1, debug, client, "status: 0x%02x\n", status); 1227static int saa711x_s_radio(struct v4l2_subdev *sd)
1262 vt->signal = ((status & (1 << 6)) == 0) ? 0xffff : 0x0; 1228{
1263 break; 1229 struct saa711x_state *state = to_state(sd);
1264 }
1265 1230
1266 case VIDIOC_LOG_STATUS: 1231 state->radio = 1;
1267 saa711x_log_status(client); 1232 return 0;
1268 break; 1233}
1269 1234
1270 case VIDIOC_G_CTRL: 1235static int saa711x_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
1271 return saa711x_get_v4lctrl(client, (struct v4l2_control *)arg); 1236{
1237 struct saa711x_state *state = to_state(sd);
1238 u32 input = route->input;
1239 u8 mask = (state->ident == V4L2_IDENT_SAA7111) ? 0xf8 : 0xf0;
1240
1241 v4l2_dbg(1, debug, sd, "decoder set input %d output %d\n", route->input, route->output);
1242 /* saa7111/3 does not have these inputs */
1243 if ((state->ident == V4L2_IDENT_SAA7113 ||
1244 state->ident == V4L2_IDENT_SAA7111) &&
1245 (route->input == SAA7115_COMPOSITE4 ||
1246 route->input == SAA7115_COMPOSITE5)) {
1247 return -EINVAL;
1248 }
1249 if (route->input > SAA7115_SVIDEO3)
1250 return -EINVAL;
1251 if (route->output > SAA7115_IPORT_ON)
1252 return -EINVAL;
1253 if (state->input == route->input && state->output == route->output)
1254 return 0;
1255 v4l2_dbg(1, debug, sd, "now setting %s input %s output\n",
1256 (route->input >= SAA7115_SVIDEO0) ? "S-Video" : "Composite",
1257 (route->output == SAA7115_IPORT_ON) ? "iport on" : "iport off");
1258 state->input = route->input;
1259
1260 /* saa7111 has slightly different input numbering */
1261 if (state->ident == V4L2_IDENT_SAA7111) {
1262 if (input >= SAA7115_COMPOSITE4)
1263 input -= 2;
1264 /* saa7111 specific */
1265 saa711x_write(sd, R_10_CHROMA_CNTL_2,
1266 (saa711x_read(sd, R_10_CHROMA_CNTL_2) & 0x3f) |
1267 ((route->output & 0xc0) ^ 0x40));
1268 saa711x_write(sd, R_13_RT_X_PORT_OUT_CNTL,
1269 (saa711x_read(sd, R_13_RT_X_PORT_OUT_CNTL) & 0xf0) |
1270 ((route->output & 2) ? 0x0a : 0));
1271 }
1272 1272
1273 case VIDIOC_S_CTRL: 1273 /* select mode */
1274 return saa711x_set_v4lctrl(client, (struct v4l2_control *)arg); 1274 saa711x_write(sd, R_02_INPUT_CNTL_1,
1275 (saa711x_read(sd, R_02_INPUT_CNTL_1) & mask) |
1276 input);
1275 1277
1276 case VIDIOC_QUERYCTRL: 1278 /* bypass chrominance trap for S-Video modes */
1277 { 1279 saa711x_write(sd, R_09_LUMA_CNTL,
1278 struct v4l2_queryctrl *qc = arg; 1280 (saa711x_read(sd, R_09_LUMA_CNTL) & 0x7f) |
1281 (state->input >= SAA7115_SVIDEO0 ? 0x80 : 0x0));
1279 1282
1280 switch (qc->id) { 1283 state->output = route->output;
1281 case V4L2_CID_BRIGHTNESS: 1284 if (state->ident == V4L2_IDENT_SAA7114 ||
1282 case V4L2_CID_CONTRAST: 1285 state->ident == V4L2_IDENT_SAA7115) {
1283 case V4L2_CID_SATURATION: 1286 saa711x_write(sd, R_83_X_PORT_I_O_ENA_AND_OUT_CLK,
1284 case V4L2_CID_HUE: 1287 (saa711x_read(sd, R_83_X_PORT_I_O_ENA_AND_OUT_CLK) & 0xfe) |
1285 return v4l2_ctrl_query_fill_std(qc); 1288 (state->output & 0x01));
1286 default:
1287 return -EINVAL;
1288 }
1289 } 1289 }
1290 return 0;
1291}
1290 1292
1291 case VIDIOC_G_STD: 1293static int saa711x_s_gpio(struct v4l2_subdev *sd, u32 val)
1292 *(v4l2_std_id *)arg = saa711x_get_v4lstd(client); 1294{
1293 break; 1295 struct saa711x_state *state = to_state(sd);
1294 1296
1295 case VIDIOC_S_STD: 1297 if (state->ident != V4L2_IDENT_SAA7111)
1296 state->radio = 0; 1298 return -EINVAL;
1297 saa711x_set_v4lstd(client, *(v4l2_std_id *)arg); 1299 saa711x_write(sd, 0x11, (saa711x_read(sd, 0x11) & 0x7f) |
1298 break; 1300 (val ? 0x80 : 0));
1301 return 0;
1302}
1299 1303
1300 case AUDC_SET_RADIO: 1304static int saa711x_s_stream(struct v4l2_subdev *sd, int enable)
1301 state->radio = 1; 1305{
1302 break; 1306 struct saa711x_state *state = to_state(sd);
1303 1307
1304 case VIDIOC_INT_G_VIDEO_ROUTING: 1308 v4l2_dbg(1, debug, sd, "%s output\n",
1305 { 1309 enable ? "enable" : "disable");
1306 struct v4l2_routing *route = arg;
1307 1310
1308 route->input = state->input; 1311 if (state->enable != enable) {
1309 route->output = state->output; 1312 state->enable = enable;
1310 break; 1313 saa711x_write(sd, R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED,
1314 state->enable);
1311 } 1315 }
1316 return 0;
1317}
1312 1318
1313 case VIDIOC_INT_S_VIDEO_ROUTING: 1319static int saa711x_s_crystal_freq(struct v4l2_subdev *sd, struct v4l2_crystal_freq *freq)
1314 { 1320{
1315 struct v4l2_routing *route = arg; 1321 struct saa711x_state *state = to_state(sd);
1316 u32 input = route->input;
1317 u8 mask = (state->ident == V4L2_IDENT_SAA7111) ? 0xf8 : 0xf0;
1318
1319 v4l_dbg(1, debug, client, "decoder set input %d output %d\n", route->input, route->output);
1320 /* saa7111/3 does not have these inputs */
1321 if ((state->ident == V4L2_IDENT_SAA7113 ||
1322 state->ident == V4L2_IDENT_SAA7111) &&
1323 (route->input == SAA7115_COMPOSITE4 ||
1324 route->input == SAA7115_COMPOSITE5)) {
1325 return -EINVAL;
1326 }
1327 if (route->input > SAA7115_SVIDEO3)
1328 return -EINVAL;
1329 if (route->output > SAA7115_IPORT_ON)
1330 return -EINVAL;
1331 if (state->input == route->input && state->output == route->output)
1332 break;
1333 v4l_dbg(1, debug, client, "now setting %s input %s output\n",
1334 (route->input >= SAA7115_SVIDEO0) ? "S-Video" : "Composite", (route->output == SAA7115_IPORT_ON) ? "iport on" : "iport off");
1335 state->input = route->input;
1336
1337 /* saa7111 has slightly different input numbering */
1338 if (state->ident == V4L2_IDENT_SAA7111) {
1339 if (input >= SAA7115_COMPOSITE4)
1340 input -= 2;
1341 /* saa7111 specific */
1342 saa711x_write(client, R_10_CHROMA_CNTL_2,
1343 (saa711x_read(client, R_10_CHROMA_CNTL_2) & 0x3f) |
1344 ((route->output & 0xc0) ^ 0x40));
1345 saa711x_write(client, R_13_RT_X_PORT_OUT_CNTL,
1346 (saa711x_read(client, R_13_RT_X_PORT_OUT_CNTL) & 0xf0) |
1347 ((route->output & 2) ? 0x0a : 0));
1348 }
1349 1322
1350 /* select mode */ 1323 if (freq->freq != SAA7115_FREQ_32_11_MHZ &&
1351 saa711x_write(client, R_02_INPUT_CNTL_1, 1324 freq->freq != SAA7115_FREQ_24_576_MHZ)
1352 (saa711x_read(client, R_02_INPUT_CNTL_1) & mask) | 1325 return -EINVAL;
1353 input); 1326 state->crystal_freq = freq->freq;
1327 state->cgcdiv = (freq->flags & SAA7115_FREQ_FL_CGCDIV) ? 3 : 4;
1328 state->ucgc = (freq->flags & SAA7115_FREQ_FL_UCGC) ? 1 : 0;
1329 state->apll = (freq->flags & SAA7115_FREQ_FL_APLL) ? 1 : 0;
1330 saa711x_s_clock_freq(sd, state->audclk_freq);
1331 return 0;
1332}
1354 1333
1355 /* bypass chrominance trap for S-Video modes */ 1334static int saa711x_reset(struct v4l2_subdev *sd, u32 val)
1356 saa711x_write(client, R_09_LUMA_CNTL, 1335{
1357 (saa711x_read(client, R_09_LUMA_CNTL) & 0x7f) | 1336 v4l2_dbg(1, debug, sd, "decoder RESET\n");
1358 (state->input >= SAA7115_SVIDEO0 ? 0x80 : 0x0)); 1337 saa711x_writeregs(sd, saa7115_cfg_reset_scaler);
1338 return 0;
1339}
1359 1340
1360 state->output = route->output; 1341static int saa711x_g_vbi_data(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_data *data)
1361 if (state->ident == V4L2_IDENT_SAA7114 || 1342{
1362 state->ident == V4L2_IDENT_SAA7115) { 1343 /* Note: the internal field ID is inverted for NTSC,
1363 saa711x_write(client, R_83_X_PORT_I_O_ENA_AND_OUT_CLK, 1344 so data->field 0 maps to the saa7115 even field,
1364 (saa711x_read(client, R_83_X_PORT_I_O_ENA_AND_OUT_CLK) & 0xfe) | 1345 whereas for PAL it maps to the saa7115 odd field. */
1365 (state->output & 0x01)); 1346 switch (data->id) {
1347 case V4L2_SLICED_WSS_625:
1348 if (saa711x_read(sd, 0x6b) & 0xc0)
1349 return -EIO;
1350 data->data[0] = saa711x_read(sd, 0x6c);
1351 data->data[1] = saa711x_read(sd, 0x6d);
1352 return 0;
1353 case V4L2_SLICED_CAPTION_525:
1354 if (data->field == 0) {
1355 /* CC */
1356 if (saa711x_read(sd, 0x66) & 0x30)
1357 return -EIO;
1358 data->data[0] = saa711x_read(sd, 0x69);
1359 data->data[1] = saa711x_read(sd, 0x6a);
1360 return 0;
1366 } 1361 }
1367 break; 1362 /* XDS */
1363 if (saa711x_read(sd, 0x66) & 0xc0)
1364 return -EIO;
1365 data->data[0] = saa711x_read(sd, 0x67);
1366 data->data[1] = saa711x_read(sd, 0x68);
1367 return 0;
1368 default:
1369 return -EINVAL;
1368 } 1370 }
1371}
1369 1372
1370 case VIDIOC_STREAMON: 1373#ifdef CONFIG_VIDEO_ADV_DEBUG
1371 case VIDIOC_STREAMOFF: 1374static int saa711x_g_register(struct v4l2_subdev *sd, struct v4l2_register *reg)
1372 v4l_dbg(1, debug, client, "%s output\n", 1375{
1373 (cmd == VIDIOC_STREAMON) ? "enable" : "disable"); 1376 struct i2c_client *client = v4l2_get_subdevdata(sd);
1374
1375 if (state->enable != (cmd == VIDIOC_STREAMON)) {
1376 state->enable = (cmd == VIDIOC_STREAMON);
1377 saa711x_write(client,
1378 R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED,
1379 state->enable);
1380 }
1381 break;
1382 1377
1383 case VIDIOC_INT_S_CRYSTAL_FREQ: 1378 if (!v4l2_chip_match_i2c_client(client,
1384 { 1379 reg->match_type, reg->match_chip))
1385 struct v4l2_crystal_freq *freq = arg; 1380 return -EINVAL;
1381 if (!capable(CAP_SYS_ADMIN))
1382 return -EPERM;
1383 reg->val = saa711x_read(sd, reg->reg & 0xff);
1384 return 0;
1385}
1386 1386
1387 if (freq->freq != SAA7115_FREQ_32_11_MHZ && 1387static int saa711x_s_register(struct v4l2_subdev *sd, struct v4l2_register *reg)
1388 freq->freq != SAA7115_FREQ_24_576_MHZ) 1388{
1389 return -EINVAL; 1389 struct i2c_client *client = v4l2_get_subdevdata(sd);
1390 state->crystal_freq = freq->freq;
1391 state->cgcdiv = (freq->flags & SAA7115_FREQ_FL_CGCDIV) ? 3 : 4;
1392 state->ucgc = (freq->flags & SAA7115_FREQ_FL_UCGC) ? 1 : 0;
1393 state->apll = (freq->flags & SAA7115_FREQ_FL_APLL) ? 1 : 0;
1394 saa711x_set_audio_clock_freq(client, state->audclk_freq);
1395 break;
1396 }
1397 1390
1398 case VIDIOC_INT_DECODE_VBI_LINE: 1391 if (!v4l2_chip_match_i2c_client(client,
1399 saa711x_decode_vbi_line(client, arg); 1392 reg->match_type, reg->match_chip))
1400 break; 1393 return -EINVAL;
1394 if (!capable(CAP_SYS_ADMIN))
1395 return -EPERM;
1396 saa711x_write(sd, reg->reg & 0xff, reg->val & 0xff);
1397 return 0;
1398}
1399#endif
1401 1400
1402 case VIDIOC_INT_RESET: 1401static int saa711x_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_chip_ident *chip)
1403 v4l_dbg(1, debug, client, "decoder RESET\n"); 1402{
1404 saa711x_writeregs(client, saa7115_cfg_reset_scaler); 1403 struct saa711x_state *state = to_state(sd);
1405 break; 1404 struct i2c_client *client = v4l2_get_subdevdata(sd);
1406 1405
1407 case VIDIOC_INT_S_GPIO: 1406 return v4l2_chip_ident_i2c_client(client, chip, state->ident, 0);
1408 if (state->ident != V4L2_IDENT_SAA7111) 1407}
1409 return -EINVAL;
1410 saa711x_write(client, 0x11, (saa711x_read(client, 0x11) & 0x7f) |
1411 (*(u32 *)arg ? 0x80 : 0));
1412 break;
1413 1408
1414 case VIDIOC_INT_G_VBI_DATA: 1409static int saa711x_log_status(struct v4l2_subdev *sd)
1415 { 1410{
1416 struct v4l2_sliced_vbi_data *data = arg; 1411 struct saa711x_state *state = to_state(sd);
1412 int reg1e, reg1f;
1413 int signalOk;
1414 int vcr;
1417 1415
1418 /* Note: the internal field ID is inverted for NTSC, 1416 v4l2_info(sd, "Audio frequency: %d Hz\n", state->audclk_freq);
1419 so data->field 0 maps to the saa7115 even field, 1417 if (state->ident != V4L2_IDENT_SAA7115) {
1420 whereas for PAL it maps to the saa7115 odd field. */ 1418 /* status for the saa7114 */
1421 switch (data->id) { 1419 reg1f = saa711x_read(sd, R_1F_STATUS_BYTE_2_VD_DEC);
1422 case V4L2_SLICED_WSS_625: 1420 signalOk = (reg1f & 0xc1) == 0x81;
1423 if (saa711x_read(client, 0x6b) & 0xc0) 1421 v4l2_info(sd, "Video signal: %s\n", signalOk ? "ok" : "bad");
1424 return -EIO; 1422 v4l2_info(sd, "Frequency: %s\n", (reg1f & 0x20) ? "60 Hz" : "50 Hz");
1425 data->data[0] = saa711x_read(client, 0x6c); 1423 return 0;
1426 data->data[1] = saa711x_read(client, 0x6d);
1427 return 0;
1428 case V4L2_SLICED_CAPTION_525:
1429 if (data->field == 0) {
1430 /* CC */
1431 if (saa711x_read(client, 0x66) & 0x30)
1432 return -EIO;
1433 data->data[0] = saa711x_read(client, 0x69);
1434 data->data[1] = saa711x_read(client, 0x6a);
1435 return 0;
1436 }
1437 /* XDS */
1438 if (saa711x_read(client, 0x66) & 0xc0)
1439 return -EIO;
1440 data->data[0] = saa711x_read(client, 0x67);
1441 data->data[1] = saa711x_read(client, 0x68);
1442 return 0;
1443 default:
1444 return -EINVAL;
1445 }
1446 break;
1447 } 1424 }
1448 1425
1449#ifdef CONFIG_VIDEO_ADV_DEBUG 1426 /* status for the saa7115 */
1450 case VIDIOC_DBG_G_REGISTER: 1427 reg1e = saa711x_read(sd, R_1E_STATUS_BYTE_1_VD_DEC);
1451 case VIDIOC_DBG_S_REGISTER: 1428 reg1f = saa711x_read(sd, R_1F_STATUS_BYTE_2_VD_DEC);
1452 {
1453 struct v4l2_register *reg = arg;
1454 1429
1455 if (!v4l2_chip_match_i2c_client(client, reg->match_type, reg->match_chip)) 1430 signalOk = (reg1f & 0xc1) == 0x81 && (reg1e & 0xc0) == 0x80;
1456 return -EINVAL; 1431 vcr = !(reg1f & 0x10);
1457 if (!capable(CAP_SYS_ADMIN))
1458 return -EPERM;
1459 if (cmd == VIDIOC_DBG_G_REGISTER)
1460 reg->val = saa711x_read(client, reg->reg & 0xff);
1461 else
1462 saa711x_write(client, reg->reg & 0xff, reg->val & 0xff);
1463 break;
1464 }
1465#endif
1466 1432
1467 case VIDIOC_G_CHIP_IDENT: 1433 if (state->input >= 6)
1468 return v4l2_chip_ident_i2c_client(client, arg, state->ident, 0); 1434 v4l2_info(sd, "Input: S-Video %d\n", state->input - 6);
1435 else
1436 v4l2_info(sd, "Input: Composite %d\n", state->input);
1437 v4l2_info(sd, "Video signal: %s\n", signalOk ? (vcr ? "VCR" : "broadcast/DVD") : "bad");
1438 v4l2_info(sd, "Frequency: %s\n", (reg1f & 0x20) ? "60 Hz" : "50 Hz");
1469 1439
1440 switch (reg1e & 0x03) {
1441 case 1:
1442 v4l2_info(sd, "Detected format: NTSC\n");
1443 break;
1444 case 2:
1445 v4l2_info(sd, "Detected format: PAL\n");
1446 break;
1447 case 3:
1448 v4l2_info(sd, "Detected format: SECAM\n");
1449 break;
1470 default: 1450 default:
1471 return -EINVAL; 1451 v4l2_info(sd, "Detected format: BW/No color\n");
1452 break;
1472 } 1453 }
1473 1454 v4l2_info(sd, "Width, Height: %d, %d\n", state->width, state->height);
1474 return 0; 1455 return 0;
1475} 1456}
1476 1457
1458static int saa711x_command(struct i2c_client *client, unsigned cmd, void *arg)
1459{
1460 return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
1461}
1462
1463/* ----------------------------------------------------------------------- */
1464
1465static const struct v4l2_subdev_core_ops saa711x_core_ops = {
1466 .log_status = saa711x_log_status,
1467 .g_chip_ident = saa711x_g_chip_ident,
1468 .g_ctrl = saa711x_g_ctrl,
1469 .s_ctrl = saa711x_s_ctrl,
1470 .queryctrl = saa711x_queryctrl,
1471 .reset = saa711x_reset,
1472 .s_gpio = saa711x_s_gpio,
1473#ifdef CONFIG_VIDEO_ADV_DEBUG
1474 .g_register = saa711x_g_register,
1475 .s_register = saa711x_s_register,
1476#endif
1477};
1478
1479static const struct v4l2_subdev_tuner_ops saa711x_tuner_ops = {
1480 .s_std = saa711x_s_std,
1481 .s_radio = saa711x_s_radio,
1482 .g_tuner = saa711x_g_tuner,
1483};
1484
1485static const struct v4l2_subdev_audio_ops saa711x_audio_ops = {
1486 .s_clock_freq = saa711x_s_clock_freq,
1487};
1488
1489static const struct v4l2_subdev_video_ops saa711x_video_ops = {
1490 .s_routing = saa711x_s_routing,
1491 .s_crystal_freq = saa711x_s_crystal_freq,
1492 .g_fmt = saa711x_g_fmt,
1493 .s_fmt = saa711x_s_fmt,
1494 .g_vbi_data = saa711x_g_vbi_data,
1495 .decode_vbi_line = saa711x_decode_vbi_line,
1496 .s_stream = saa711x_s_stream,
1497};
1498
1499static const struct v4l2_subdev_ops saa711x_ops = {
1500 .core = &saa711x_core_ops,
1501 .tuner = &saa711x_tuner_ops,
1502 .audio = &saa711x_audio_ops,
1503 .video = &saa711x_video_ops,
1504};
1505
1477/* ----------------------------------------------------------------------- */ 1506/* ----------------------------------------------------------------------- */
1478 1507
1479static int saa7115_probe(struct i2c_client *client, 1508static int saa711x_probe(struct i2c_client *client,
1480 const struct i2c_device_id *id) 1509 const struct i2c_device_id *id)
1481{ 1510{
1482 struct saa711x_state *state; 1511 struct saa711x_state *state;
1512 struct v4l2_subdev *sd;
1483 int i; 1513 int i;
1484 char name[17]; 1514 char name[17];
1485 char chip_id; 1515 char chip_id;
@@ -1490,8 +1520,8 @@ static int saa7115_probe(struct i2c_client *client,
1490 return -EIO; 1520 return -EIO;
1491 1521
1492 for (i = 0; i < 0x0f; i++) { 1522 for (i = 0; i < 0x0f; i++) {
1493 saa711x_write(client, 0, i); 1523 i2c_smbus_write_byte_data(client, 0, i);
1494 name[i] = (saa711x_read(client, 0) & 0x0f) + '0'; 1524 name[i] = (i2c_smbus_read_byte_data(client, 0) & 0x0f) + '0';
1495 if (name[i] > '9') 1525 if (name[i] > '9')
1496 name[i] += 'a' - '9' - 1; 1526 name[i] += 'a' - '9' - 1;
1497 } 1527 }
@@ -1518,7 +1548,8 @@ static int saa7115_probe(struct i2c_client *client,
1518 state = kzalloc(sizeof(struct saa711x_state), GFP_KERNEL); 1548 state = kzalloc(sizeof(struct saa711x_state), GFP_KERNEL);
1519 if (state == NULL) 1549 if (state == NULL)
1520 return -ENOMEM; 1550 return -ENOMEM;
1521 i2c_set_clientdata(client, state); 1551 sd = &state->sd;
1552 v4l2_i2c_subdev_init(sd, client, &saa711x_ops);
1522 state->input = -1; 1553 state->input = -1;
1523 state->output = SAA7115_IPORT_ON; 1554 state->output = SAA7115_IPORT_ON;
1524 state->enable = 1; 1555 state->enable = 1;
@@ -1545,41 +1576,45 @@ static int saa7115_probe(struct i2c_client *client,
1545 break; 1576 break;
1546 default: 1577 default:
1547 state->ident = V4L2_IDENT_SAA7111; 1578 state->ident = V4L2_IDENT_SAA7111;
1548 v4l_info(client, "WARNING: Chip is not known - Falling back to saa7111\n"); 1579 v4l2_info(sd, "WARNING: Chip is not known - Falling back to saa7111\n");
1549 1580
1550 } 1581 }
1551 1582
1552 state->audclk_freq = 48000; 1583 state->audclk_freq = 48000;
1553 1584
1554 v4l_dbg(1, debug, client, "writing init values\n"); 1585 v4l2_dbg(1, debug, sd, "writing init values\n");
1555 1586
1556 /* init to 60hz/48khz */ 1587 /* init to 60hz/48khz */
1557 state->crystal_freq = SAA7115_FREQ_24_576_MHZ; 1588 state->crystal_freq = SAA7115_FREQ_24_576_MHZ;
1558 switch (state->ident) { 1589 switch (state->ident) {
1559 case V4L2_IDENT_SAA7111: 1590 case V4L2_IDENT_SAA7111:
1560 saa711x_writeregs(client, saa7111_init); 1591 saa711x_writeregs(sd, saa7111_init);
1561 break; 1592 break;
1562 case V4L2_IDENT_SAA7113: 1593 case V4L2_IDENT_SAA7113:
1563 saa711x_writeregs(client, saa7113_init); 1594 saa711x_writeregs(sd, saa7113_init);
1564 break; 1595 break;
1565 default: 1596 default:
1566 state->crystal_freq = SAA7115_FREQ_32_11_MHZ; 1597 state->crystal_freq = SAA7115_FREQ_32_11_MHZ;
1567 saa711x_writeregs(client, saa7115_init_auto_input); 1598 saa711x_writeregs(sd, saa7115_init_auto_input);
1568 } 1599 }
1569 if (state->ident != V4L2_IDENT_SAA7111) 1600 if (state->ident != V4L2_IDENT_SAA7111)
1570 saa711x_writeregs(client, saa7115_init_misc); 1601 saa711x_writeregs(sd, saa7115_init_misc);
1571 saa711x_set_v4lstd(client, V4L2_STD_NTSC); 1602 saa711x_set_v4lstd(sd, V4L2_STD_NTSC);
1572 1603
1573 v4l_dbg(1, debug, client, "status: (1E) 0x%02x, (1F) 0x%02x\n", 1604 v4l2_dbg(1, debug, sd, "status: (1E) 0x%02x, (1F) 0x%02x\n",
1574 saa711x_read(client, R_1E_STATUS_BYTE_1_VD_DEC), saa711x_read(client, R_1F_STATUS_BYTE_2_VD_DEC)); 1605 saa711x_read(sd, R_1E_STATUS_BYTE_1_VD_DEC),
1606 saa711x_read(sd, R_1F_STATUS_BYTE_2_VD_DEC));
1575 return 0; 1607 return 0;
1576} 1608}
1577 1609
1578/* ----------------------------------------------------------------------- */ 1610/* ----------------------------------------------------------------------- */
1579 1611
1580static int saa7115_remove(struct i2c_client *client) 1612static int saa711x_remove(struct i2c_client *client)
1581{ 1613{
1582 kfree(i2c_get_clientdata(client)); 1614 struct v4l2_subdev *sd = i2c_get_clientdata(client);
1615
1616 v4l2_device_unregister_subdev(sd);
1617 kfree(to_state(sd));
1583 return 0; 1618 return 0;
1584} 1619}
1585 1620
@@ -1597,9 +1632,9 @@ MODULE_DEVICE_TABLE(i2c, saa7115_id);
1597static struct v4l2_i2c_driver_data v4l2_i2c_data = { 1632static struct v4l2_i2c_driver_data v4l2_i2c_data = {
1598 .name = "saa7115", 1633 .name = "saa7115",
1599 .driverid = I2C_DRIVERID_SAA711X, 1634 .driverid = I2C_DRIVERID_SAA711X,
1600 .command = saa7115_command, 1635 .command = saa711x_command,
1601 .probe = saa7115_probe, 1636 .probe = saa711x_probe,
1602 .remove = saa7115_remove, 1637 .remove = saa711x_remove,
1603 .legacy_class = I2C_CLASS_TV_ANALOG | I2C_CLASS_TV_DIGITAL, 1638 .legacy_class = I2C_CLASS_TV_ANALOG | I2C_CLASS_TV_DIGITAL,
1604 .id_table = saa7115_id, 1639 .id_table = saa7115_id,
1605}; 1640};
diff --git a/drivers/media/video/saa7127.c b/drivers/media/video/saa7127.c
index cc02fb18efa7..bfc85654795e 100644
--- a/drivers/media/video/saa7127.c
+++ b/drivers/media/video/saa7127.c
@@ -53,7 +53,7 @@
53#include <linux/slab.h> 53#include <linux/slab.h>
54#include <linux/i2c.h> 54#include <linux/i2c.h>
55#include <linux/videodev2.h> 55#include <linux/videodev2.h>
56#include <media/v4l2-common.h> 56#include <media/v4l2-device.h>
57#include <media/v4l2-chip-ident.h> 57#include <media/v4l2-chip-ident.h>
58#include <media/v4l2-i2c-drv.h> 58#include <media/v4l2-i2c-drv.h>
59#include <media/saa7127.h> 59#include <media/saa7127.h>
@@ -231,6 +231,7 @@ static struct i2c_reg_value saa7127_init_config_50hz[] = {
231 */ 231 */
232 232
233struct saa7127_state { 233struct saa7127_state {
234 struct v4l2_subdev sd;
234 v4l2_std_id std; 235 v4l2_std_id std;
235 u32 ident; 236 u32 ident;
236 enum saa7127_input_type input_type; 237 enum saa7127_input_type input_type;
@@ -250,6 +251,11 @@ struct saa7127_state {
250 u8 reg_61; 251 u8 reg_61;
251}; 252};
252 253
254static inline struct saa7127_state *to_state(struct v4l2_subdev *sd)
255{
256 return container_of(sd, struct saa7127_state, sd);
257}
258
253static const char * const output_strs[] = 259static const char * const output_strs[] =
254{ 260{
255 "S-Video + Composite", 261 "S-Video + Composite",
@@ -281,32 +287,35 @@ static const char * const wss_strs[] = {
281 287
282/* ----------------------------------------------------------------------- */ 288/* ----------------------------------------------------------------------- */
283 289
284static int saa7127_read(struct i2c_client *client, u8 reg) 290static int saa7127_read(struct v4l2_subdev *sd, u8 reg)
285{ 291{
292 struct i2c_client *client = v4l2_get_subdevdata(sd);
293
286 return i2c_smbus_read_byte_data(client, reg); 294 return i2c_smbus_read_byte_data(client, reg);
287} 295}
288 296
289/* ----------------------------------------------------------------------- */ 297/* ----------------------------------------------------------------------- */
290 298
291static int saa7127_write(struct i2c_client *client, u8 reg, u8 val) 299static int saa7127_write(struct v4l2_subdev *sd, u8 reg, u8 val)
292{ 300{
301 struct i2c_client *client = v4l2_get_subdevdata(sd);
293 int i; 302 int i;
294 303
295 for (i = 0; i < 3; i++) { 304 for (i = 0; i < 3; i++) {
296 if (i2c_smbus_write_byte_data(client, reg, val) == 0) 305 if (i2c_smbus_write_byte_data(client, reg, val) == 0)
297 return 0; 306 return 0;
298 } 307 }
299 v4l_err(client, "I2C Write Problem\n"); 308 v4l2_err(sd, "I2C Write Problem\n");
300 return -1; 309 return -1;
301} 310}
302 311
303/* ----------------------------------------------------------------------- */ 312/* ----------------------------------------------------------------------- */
304 313
305static int saa7127_write_inittab(struct i2c_client *client, 314static int saa7127_write_inittab(struct v4l2_subdev *sd,
306 const struct i2c_reg_value *regs) 315 const struct i2c_reg_value *regs)
307{ 316{
308 while (regs->reg != 0) { 317 while (regs->reg != 0) {
309 saa7127_write(client, regs->reg, regs->value); 318 saa7127_write(sd, regs->reg, regs->value);
310 regs++; 319 regs++;
311 } 320 }
312 return 0; 321 return 0;
@@ -314,16 +323,16 @@ static int saa7127_write_inittab(struct i2c_client *client,
314 323
315/* ----------------------------------------------------------------------- */ 324/* ----------------------------------------------------------------------- */
316 325
317static int saa7127_set_vps(struct i2c_client *client, struct v4l2_sliced_vbi_data *data) 326static int saa7127_set_vps(struct v4l2_subdev *sd, const struct v4l2_sliced_vbi_data *data)
318{ 327{
319 struct saa7127_state *state = i2c_get_clientdata(client); 328 struct saa7127_state *state = to_state(sd);
320 int enable = (data->line != 0); 329 int enable = (data->line != 0);
321 330
322 if (enable && (data->field != 0 || data->line != 16)) 331 if (enable && (data->field != 0 || data->line != 16))
323 return -EINVAL; 332 return -EINVAL;
324 if (state->vps_enable != enable) { 333 if (state->vps_enable != enable) {
325 v4l_dbg(1, debug, client, "Turn VPS Signal %s\n", enable ? "on" : "off"); 334 v4l2_dbg(1, debug, sd, "Turn VPS Signal %s\n", enable ? "on" : "off");
326 saa7127_write(client, 0x54, enable << 7); 335 saa7127_write(sd, 0x54, enable << 7);
327 state->vps_enable = enable; 336 state->vps_enable = enable;
328 } 337 }
329 if (!enable) 338 if (!enable)
@@ -334,91 +343,91 @@ static int saa7127_set_vps(struct i2c_client *client, struct v4l2_sliced_vbi_dat
334 state->vps_data[2] = data->data[9]; 343 state->vps_data[2] = data->data[9];
335 state->vps_data[3] = data->data[10]; 344 state->vps_data[3] = data->data[10];
336 state->vps_data[4] = data->data[11]; 345 state->vps_data[4] = data->data[11];
337 v4l_dbg(1, debug, client, "Set VPS data %02x %02x %02x %02x %02x\n", 346 v4l2_dbg(1, debug, sd, "Set VPS data %02x %02x %02x %02x %02x\n",
338 state->vps_data[0], state->vps_data[1], 347 state->vps_data[0], state->vps_data[1],
339 state->vps_data[2], state->vps_data[3], 348 state->vps_data[2], state->vps_data[3],
340 state->vps_data[4]); 349 state->vps_data[4]);
341 saa7127_write(client, 0x55, state->vps_data[0]); 350 saa7127_write(sd, 0x55, state->vps_data[0]);
342 saa7127_write(client, 0x56, state->vps_data[1]); 351 saa7127_write(sd, 0x56, state->vps_data[1]);
343 saa7127_write(client, 0x57, state->vps_data[2]); 352 saa7127_write(sd, 0x57, state->vps_data[2]);
344 saa7127_write(client, 0x58, state->vps_data[3]); 353 saa7127_write(sd, 0x58, state->vps_data[3]);
345 saa7127_write(client, 0x59, state->vps_data[4]); 354 saa7127_write(sd, 0x59, state->vps_data[4]);
346 return 0; 355 return 0;
347} 356}
348 357
349/* ----------------------------------------------------------------------- */ 358/* ----------------------------------------------------------------------- */
350 359
351static int saa7127_set_cc(struct i2c_client *client, struct v4l2_sliced_vbi_data *data) 360static int saa7127_set_cc(struct v4l2_subdev *sd, const struct v4l2_sliced_vbi_data *data)
352{ 361{
353 struct saa7127_state *state = i2c_get_clientdata(client); 362 struct saa7127_state *state = to_state(sd);
354 u16 cc = data->data[1] << 8 | data->data[0]; 363 u16 cc = data->data[1] << 8 | data->data[0];
355 int enable = (data->line != 0); 364 int enable = (data->line != 0);
356 365
357 if (enable && (data->field != 0 || data->line != 21)) 366 if (enable && (data->field != 0 || data->line != 21))
358 return -EINVAL; 367 return -EINVAL;
359 if (state->cc_enable != enable) { 368 if (state->cc_enable != enable) {
360 v4l_dbg(1, debug, client, 369 v4l2_dbg(1, debug, sd,
361 "Turn CC %s\n", enable ? "on" : "off"); 370 "Turn CC %s\n", enable ? "on" : "off");
362 saa7127_write(client, SAA7127_REG_CLOSED_CAPTION, 371 saa7127_write(sd, SAA7127_REG_CLOSED_CAPTION,
363 (state->xds_enable << 7) | (enable << 6) | 0x11); 372 (state->xds_enable << 7) | (enable << 6) | 0x11);
364 state->cc_enable = enable; 373 state->cc_enable = enable;
365 } 374 }
366 if (!enable) 375 if (!enable)
367 return 0; 376 return 0;
368 377
369 v4l_dbg(2, debug, client, "CC data: %04x\n", cc); 378 v4l2_dbg(2, debug, sd, "CC data: %04x\n", cc);
370 saa7127_write(client, SAA7127_REG_LINE_21_ODD_0, cc & 0xff); 379 saa7127_write(sd, SAA7127_REG_LINE_21_ODD_0, cc & 0xff);
371 saa7127_write(client, SAA7127_REG_LINE_21_ODD_1, cc >> 8); 380 saa7127_write(sd, SAA7127_REG_LINE_21_ODD_1, cc >> 8);
372 state->cc_data = cc; 381 state->cc_data = cc;
373 return 0; 382 return 0;
374} 383}
375 384
376/* ----------------------------------------------------------------------- */ 385/* ----------------------------------------------------------------------- */
377 386
378static int saa7127_set_xds(struct i2c_client *client, struct v4l2_sliced_vbi_data *data) 387static int saa7127_set_xds(struct v4l2_subdev *sd, const struct v4l2_sliced_vbi_data *data)
379{ 388{
380 struct saa7127_state *state = i2c_get_clientdata(client); 389 struct saa7127_state *state = to_state(sd);
381 u16 xds = data->data[1] << 8 | data->data[0]; 390 u16 xds = data->data[1] << 8 | data->data[0];
382 int enable = (data->line != 0); 391 int enable = (data->line != 0);
383 392
384 if (enable && (data->field != 1 || data->line != 21)) 393 if (enable && (data->field != 1 || data->line != 21))
385 return -EINVAL; 394 return -EINVAL;
386 if (state->xds_enable != enable) { 395 if (state->xds_enable != enable) {
387 v4l_dbg(1, debug, client, "Turn XDS %s\n", enable ? "on" : "off"); 396 v4l2_dbg(1, debug, sd, "Turn XDS %s\n", enable ? "on" : "off");
388 saa7127_write(client, SAA7127_REG_CLOSED_CAPTION, 397 saa7127_write(sd, SAA7127_REG_CLOSED_CAPTION,
389 (enable << 7) | (state->cc_enable << 6) | 0x11); 398 (enable << 7) | (state->cc_enable << 6) | 0x11);
390 state->xds_enable = enable; 399 state->xds_enable = enable;
391 } 400 }
392 if (!enable) 401 if (!enable)
393 return 0; 402 return 0;
394 403
395 v4l_dbg(2, debug, client, "XDS data: %04x\n", xds); 404 v4l2_dbg(2, debug, sd, "XDS data: %04x\n", xds);
396 saa7127_write(client, SAA7127_REG_LINE_21_EVEN_0, xds & 0xff); 405 saa7127_write(sd, SAA7127_REG_LINE_21_EVEN_0, xds & 0xff);
397 saa7127_write(client, SAA7127_REG_LINE_21_EVEN_1, xds >> 8); 406 saa7127_write(sd, SAA7127_REG_LINE_21_EVEN_1, xds >> 8);
398 state->xds_data = xds; 407 state->xds_data = xds;
399 return 0; 408 return 0;
400} 409}
401 410
402/* ----------------------------------------------------------------------- */ 411/* ----------------------------------------------------------------------- */
403 412
404static int saa7127_set_wss(struct i2c_client *client, struct v4l2_sliced_vbi_data *data) 413static int saa7127_set_wss(struct v4l2_subdev *sd, const struct v4l2_sliced_vbi_data *data)
405{ 414{
406 struct saa7127_state *state = i2c_get_clientdata(client); 415 struct saa7127_state *state = to_state(sd);
407 int enable = (data->line != 0); 416 int enable = (data->line != 0);
408 417
409 if (enable && (data->field != 0 || data->line != 23)) 418 if (enable && (data->field != 0 || data->line != 23))
410 return -EINVAL; 419 return -EINVAL;
411 if (state->wss_enable != enable) { 420 if (state->wss_enable != enable) {
412 v4l_dbg(1, debug, client, "Turn WSS %s\n", enable ? "on" : "off"); 421 v4l2_dbg(1, debug, sd, "Turn WSS %s\n", enable ? "on" : "off");
413 saa7127_write(client, 0x27, enable << 7); 422 saa7127_write(sd, 0x27, enable << 7);
414 state->wss_enable = enable; 423 state->wss_enable = enable;
415 } 424 }
416 if (!enable) 425 if (!enable)
417 return 0; 426 return 0;
418 427
419 saa7127_write(client, 0x26, data->data[0]); 428 saa7127_write(sd, 0x26, data->data[0]);
420 saa7127_write(client, 0x27, 0x80 | (data->data[1] & 0x3f)); 429 saa7127_write(sd, 0x27, 0x80 | (data->data[1] & 0x3f));
421 v4l_dbg(1, debug, client, 430 v4l2_dbg(1, debug, sd,
422 "WSS mode: %s\n", wss_strs[data->data[0] & 0xf]); 431 "WSS mode: %s\n", wss_strs[data->data[0] & 0xf]);
423 state->wss_mode = (data->data[1] & 0x3f) << 8 | data->data[0]; 432 state->wss_mode = (data->data[1] & 0x3f) << 8 | data->data[0];
424 return 0; 433 return 0;
@@ -426,18 +435,18 @@ static int saa7127_set_wss(struct i2c_client *client, struct v4l2_sliced_vbi_dat
426 435
427/* ----------------------------------------------------------------------- */ 436/* ----------------------------------------------------------------------- */
428 437
429static int saa7127_set_video_enable(struct i2c_client *client, int enable) 438static int saa7127_set_video_enable(struct v4l2_subdev *sd, int enable)
430{ 439{
431 struct saa7127_state *state = i2c_get_clientdata(client); 440 struct saa7127_state *state = to_state(sd);
432 441
433 if (enable) { 442 if (enable) {
434 v4l_dbg(1, debug, client, "Enable Video Output\n"); 443 v4l2_dbg(1, debug, sd, "Enable Video Output\n");
435 saa7127_write(client, 0x2d, state->reg_2d); 444 saa7127_write(sd, 0x2d, state->reg_2d);
436 saa7127_write(client, 0x61, state->reg_61); 445 saa7127_write(sd, 0x61, state->reg_61);
437 } else { 446 } else {
438 v4l_dbg(1, debug, client, "Disable Video Output\n"); 447 v4l2_dbg(1, debug, sd, "Disable Video Output\n");
439 saa7127_write(client, 0x2d, (state->reg_2d & 0xf0)); 448 saa7127_write(sd, 0x2d, (state->reg_2d & 0xf0));
440 saa7127_write(client, 0x61, (state->reg_61 | 0xc0)); 449 saa7127_write(sd, 0x61, (state->reg_61 | 0xc0));
441 } 450 }
442 state->video_enable = enable; 451 state->video_enable = enable;
443 return 0; 452 return 0;
@@ -445,32 +454,32 @@ static int saa7127_set_video_enable(struct i2c_client *client, int enable)
445 454
446/* ----------------------------------------------------------------------- */ 455/* ----------------------------------------------------------------------- */
447 456
448static int saa7127_set_std(struct i2c_client *client, v4l2_std_id std) 457static int saa7127_set_std(struct v4l2_subdev *sd, v4l2_std_id std)
449{ 458{
450 struct saa7127_state *state = i2c_get_clientdata(client); 459 struct saa7127_state *state = to_state(sd);
451 const struct i2c_reg_value *inittab; 460 const struct i2c_reg_value *inittab;
452 461
453 if (std & V4L2_STD_525_60) { 462 if (std & V4L2_STD_525_60) {
454 v4l_dbg(1, debug, client, "Selecting 60 Hz video Standard\n"); 463 v4l2_dbg(1, debug, sd, "Selecting 60 Hz video Standard\n");
455 inittab = saa7127_init_config_60hz; 464 inittab = saa7127_init_config_60hz;
456 state->reg_61 = SAA7127_60HZ_DAC_CONTROL; 465 state->reg_61 = SAA7127_60HZ_DAC_CONTROL;
457 } else { 466 } else {
458 v4l_dbg(1, debug, client, "Selecting 50 Hz video Standard\n"); 467 v4l2_dbg(1, debug, sd, "Selecting 50 Hz video Standard\n");
459 inittab = saa7127_init_config_50hz; 468 inittab = saa7127_init_config_50hz;
460 state->reg_61 = SAA7127_50HZ_DAC_CONTROL; 469 state->reg_61 = SAA7127_50HZ_DAC_CONTROL;
461 } 470 }
462 471
463 /* Write Table */ 472 /* Write Table */
464 saa7127_write_inittab(client, inittab); 473 saa7127_write_inittab(sd, inittab);
465 state->std = std; 474 state->std = std;
466 return 0; 475 return 0;
467} 476}
468 477
469/* ----------------------------------------------------------------------- */ 478/* ----------------------------------------------------------------------- */
470 479
471static int saa7127_set_output_type(struct i2c_client *client, int output) 480static int saa7127_set_output_type(struct v4l2_subdev *sd, int output)
472{ 481{
473 struct saa7127_state *state = i2c_get_clientdata(client); 482 struct saa7127_state *state = to_state(sd);
474 483
475 switch (output) { 484 switch (output) {
476 case SAA7127_OUTPUT_TYPE_RGB: 485 case SAA7127_OUTPUT_TYPE_RGB:
@@ -506,165 +515,195 @@ static int saa7127_set_output_type(struct i2c_client *client, int output)
506 default: 515 default:
507 return -EINVAL; 516 return -EINVAL;
508 } 517 }
509 v4l_dbg(1, debug, client, 518 v4l2_dbg(1, debug, sd,
510 "Selecting %s output type\n", output_strs[output]); 519 "Selecting %s output type\n", output_strs[output]);
511 520
512 /* Configure Encoder */ 521 /* Configure Encoder */
513 saa7127_write(client, 0x2d, state->reg_2d); 522 saa7127_write(sd, 0x2d, state->reg_2d);
514 saa7127_write(client, 0x3a, state->reg_3a | state->reg_3a_cb); 523 saa7127_write(sd, 0x3a, state->reg_3a | state->reg_3a_cb);
515 state->output_type = output; 524 state->output_type = output;
516 return 0; 525 return 0;
517} 526}
518 527
519/* ----------------------------------------------------------------------- */ 528/* ----------------------------------------------------------------------- */
520 529
521static int saa7127_set_input_type(struct i2c_client *client, int input) 530static int saa7127_set_input_type(struct v4l2_subdev *sd, int input)
522{ 531{
523 struct saa7127_state *state = i2c_get_clientdata(client); 532 struct saa7127_state *state = to_state(sd);
524 533
525 switch (input) { 534 switch (input) {
526 case SAA7127_INPUT_TYPE_NORMAL: /* avia */ 535 case SAA7127_INPUT_TYPE_NORMAL: /* avia */
527 v4l_dbg(1, debug, client, "Selecting Normal Encoder Input\n"); 536 v4l2_dbg(1, debug, sd, "Selecting Normal Encoder Input\n");
528 state->reg_3a_cb = 0; 537 state->reg_3a_cb = 0;
529 break; 538 break;
530 539
531 case SAA7127_INPUT_TYPE_TEST_IMAGE: /* color bar */ 540 case SAA7127_INPUT_TYPE_TEST_IMAGE: /* color bar */
532 v4l_dbg(1, debug, client, "Selecting Color Bar generator\n"); 541 v4l2_dbg(1, debug, sd, "Selecting Color Bar generator\n");
533 state->reg_3a_cb = 0x80; 542 state->reg_3a_cb = 0x80;
534 break; 543 break;
535 544
536 default: 545 default:
537 return -EINVAL; 546 return -EINVAL;
538 } 547 }
539 saa7127_write(client, 0x3a, state->reg_3a | state->reg_3a_cb); 548 saa7127_write(sd, 0x3a, state->reg_3a | state->reg_3a_cb);
540 state->input_type = input; 549 state->input_type = input;
541 return 0; 550 return 0;
542} 551}
543 552
544/* ----------------------------------------------------------------------- */ 553/* ----------------------------------------------------------------------- */
545 554
546static int saa7127_command(struct i2c_client *client, 555static int saa7127_s_std_output(struct v4l2_subdev *sd, v4l2_std_id std)
547 unsigned int cmd, void *arg)
548{ 556{
549 struct saa7127_state *state = i2c_get_clientdata(client); 557 struct saa7127_state *state = to_state(sd);
550 struct v4l2_format *fmt = arg;
551 struct v4l2_routing *route = arg;
552
553 switch (cmd) {
554 case VIDIOC_INT_S_STD_OUTPUT:
555 if (state->std == *(v4l2_std_id *)arg)
556 break;
557 return saa7127_set_std(client, *(v4l2_std_id *)arg);
558
559 case VIDIOC_INT_G_STD_OUTPUT:
560 *(v4l2_std_id *)arg = state->std;
561 break;
562 558
563 case VIDIOC_INT_G_VIDEO_ROUTING: 559 if (state->std == std)
564 route->input = state->input_type; 560 return 0;
565 route->output = state->output_type; 561 return saa7127_set_std(sd, std);
566 break; 562}
567 563
568 case VIDIOC_INT_S_VIDEO_ROUTING: 564static int saa7127_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
569 { 565{
570 int rc = 0; 566 struct saa7127_state *state = to_state(sd);
567 int rc = 0;
568
569 if (state->input_type != route->input)
570 rc = saa7127_set_input_type(sd, route->input);
571 if (rc == 0 && state->output_type != route->output)
572 rc = saa7127_set_output_type(sd, route->output);
573 return rc;
574}
571 575
572 if (state->input_type != route->input) 576static int saa7127_s_stream(struct v4l2_subdev *sd, int enable)
573 rc = saa7127_set_input_type(client, route->input); 577{
574 if (rc == 0 && state->output_type != route->output) 578 struct saa7127_state *state = to_state(sd);
575 rc = saa7127_set_output_type(client, route->output);
576 return rc;
577 }
578 579
579 case VIDIOC_STREAMON: 580 if (state->video_enable == enable)
580 case VIDIOC_STREAMOFF: 581 return 0;
581 if (state->video_enable == (cmd == VIDIOC_STREAMON)) 582 return saa7127_set_video_enable(sd, enable);
582 break; 583}
583 return saa7127_set_video_enable(client, cmd == VIDIOC_STREAMON);
584
585 case VIDIOC_G_FMT:
586 if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE)
587 return -EINVAL;
588
589 memset(&fmt->fmt.sliced, 0, sizeof(fmt->fmt.sliced));
590 if (state->vps_enable)
591 fmt->fmt.sliced.service_lines[0][16] = V4L2_SLICED_VPS;
592 if (state->wss_enable)
593 fmt->fmt.sliced.service_lines[0][23] = V4L2_SLICED_WSS_625;
594 if (state->cc_enable) {
595 fmt->fmt.sliced.service_lines[0][21] = V4L2_SLICED_CAPTION_525;
596 fmt->fmt.sliced.service_lines[1][21] = V4L2_SLICED_CAPTION_525;
597 }
598 fmt->fmt.sliced.service_set =
599 (state->vps_enable ? V4L2_SLICED_VPS : 0) |
600 (state->wss_enable ? V4L2_SLICED_WSS_625 : 0) |
601 (state->cc_enable ? V4L2_SLICED_CAPTION_525 : 0);
602 break;
603 584
604 case VIDIOC_LOG_STATUS: 585static int saa7127_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
605 v4l_info(client, "Standard: %s\n", (state->std & V4L2_STD_525_60) ? "60 Hz" : "50 Hz"); 586{
606 v4l_info(client, "Input: %s\n", state->input_type ? "color bars" : "normal"); 587 struct saa7127_state *state = to_state(sd);
607 v4l_info(client, "Output: %s\n", state->video_enable ?
608 output_strs[state->output_type] : "disabled");
609 v4l_info(client, "WSS: %s\n", state->wss_enable ?
610 wss_strs[state->wss_mode] : "disabled");
611 v4l_info(client, "VPS: %s\n", state->vps_enable ? "enabled" : "disabled");
612 v4l_info(client, "CC: %s\n", state->cc_enable ? "enabled" : "disabled");
613 break;
614 588
615#ifdef CONFIG_VIDEO_ADV_DEBUG 589 if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE)
616 case VIDIOC_DBG_G_REGISTER: 590 return -EINVAL;
617 case VIDIOC_DBG_S_REGISTER:
618 {
619 struct v4l2_register *reg = arg;
620
621 if (!v4l2_chip_match_i2c_client(client,
622 reg->match_type, reg->match_chip))
623 return -EINVAL;
624 if (!capable(CAP_SYS_ADMIN))
625 return -EPERM;
626 if (cmd == VIDIOC_DBG_G_REGISTER)
627 reg->val = saa7127_read(client, reg->reg & 0xff);
628 else
629 saa7127_write(client, reg->reg & 0xff, reg->val & 0xff);
630 break;
631 }
632#endif
633 591
634 case VIDIOC_INT_S_VBI_DATA: 592 memset(&fmt->fmt.sliced, 0, sizeof(fmt->fmt.sliced));
635 { 593 if (state->vps_enable)
636 struct v4l2_sliced_vbi_data *data = arg; 594 fmt->fmt.sliced.service_lines[0][16] = V4L2_SLICED_VPS;
637 595 if (state->wss_enable)
638 switch (data->id) { 596 fmt->fmt.sliced.service_lines[0][23] = V4L2_SLICED_WSS_625;
639 case V4L2_SLICED_WSS_625: 597 if (state->cc_enable) {
640 return saa7127_set_wss(client, data); 598 fmt->fmt.sliced.service_lines[0][21] = V4L2_SLICED_CAPTION_525;
641 case V4L2_SLICED_VPS: 599 fmt->fmt.sliced.service_lines[1][21] = V4L2_SLICED_CAPTION_525;
642 return saa7127_set_vps(client, data);
643 case V4L2_SLICED_CAPTION_525:
644 if (data->field == 0)
645 return saa7127_set_cc(client, data);
646 return saa7127_set_xds(client, data);
647 default:
648 return -EINVAL;
649 }
650 break;
651 } 600 }
601 fmt->fmt.sliced.service_set =
602 (state->vps_enable ? V4L2_SLICED_VPS : 0) |
603 (state->wss_enable ? V4L2_SLICED_WSS_625 : 0) |
604 (state->cc_enable ? V4L2_SLICED_CAPTION_525 : 0);
605 return 0;
606}
652 607
653 case VIDIOC_G_CHIP_IDENT: 608static int saa7127_s_vbi_data(struct v4l2_subdev *sd, const struct v4l2_sliced_vbi_data *data)
654 return v4l2_chip_ident_i2c_client(client, arg, state->ident, 0); 609{
655 610 switch (data->id) {
611 case V4L2_SLICED_WSS_625:
612 return saa7127_set_wss(sd, data);
613 case V4L2_SLICED_VPS:
614 return saa7127_set_vps(sd, data);
615 case V4L2_SLICED_CAPTION_525:
616 if (data->field == 0)
617 return saa7127_set_cc(sd, data);
618 return saa7127_set_xds(sd, data);
656 default: 619 default:
657 return -EINVAL; 620 return -EINVAL;
658 } 621 }
659 return 0; 622 return 0;
660} 623}
661 624
625#ifdef CONFIG_VIDEO_ADV_DEBUG
626static int saa7127_g_register(struct v4l2_subdev *sd, struct v4l2_register *reg)
627{
628 struct i2c_client *client = v4l2_get_subdevdata(sd);
629
630 if (!v4l2_chip_match_i2c_client(client,
631 reg->match_type, reg->match_chip))
632 return -EINVAL;
633 if (!capable(CAP_SYS_ADMIN))
634 return -EPERM;
635 reg->val = saa7127_read(sd, reg->reg & 0xff);
636 return 0;
637}
638
639static int saa7127_s_register(struct v4l2_subdev *sd, struct v4l2_register *reg)
640{
641 struct i2c_client *client = v4l2_get_subdevdata(sd);
642
643 if (!v4l2_chip_match_i2c_client(client,
644 reg->match_type, reg->match_chip))
645 return -EINVAL;
646 if (!capable(CAP_SYS_ADMIN))
647 return -EPERM;
648 saa7127_write(sd, reg->reg & 0xff, reg->val & 0xff);
649 return 0;
650}
651#endif
652
653static int saa7127_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_chip_ident *chip)
654{
655 struct saa7127_state *state = to_state(sd);
656 struct i2c_client *client = v4l2_get_subdevdata(sd);
657
658 return v4l2_chip_ident_i2c_client(client, chip, state->ident, 0);
659}
660
661static int saa7127_log_status(struct v4l2_subdev *sd)
662{
663 struct saa7127_state *state = to_state(sd);
664
665 v4l2_info(sd, "Standard: %s\n", (state->std & V4L2_STD_525_60) ? "60 Hz" : "50 Hz");
666 v4l2_info(sd, "Input: %s\n", state->input_type ? "color bars" : "normal");
667 v4l2_info(sd, "Output: %s\n", state->video_enable ?
668 output_strs[state->output_type] : "disabled");
669 v4l2_info(sd, "WSS: %s\n", state->wss_enable ?
670 wss_strs[state->wss_mode] : "disabled");
671 v4l2_info(sd, "VPS: %s\n", state->vps_enable ? "enabled" : "disabled");
672 v4l2_info(sd, "CC: %s\n", state->cc_enable ? "enabled" : "disabled");
673 return 0;
674}
675
676/* ----------------------------------------------------------------------- */
677
678static const struct v4l2_subdev_core_ops saa7127_core_ops = {
679 .log_status = saa7127_log_status,
680 .g_chip_ident = saa7127_g_chip_ident,
681#ifdef CONFIG_VIDEO_ADV_DEBUG
682 .g_register = saa7127_g_register,
683 .s_register = saa7127_s_register,
684#endif
685};
686
687static const struct v4l2_subdev_video_ops saa7127_video_ops = {
688 .s_vbi_data = saa7127_s_vbi_data,
689 .g_fmt = saa7127_g_fmt,
690 .s_std_output = saa7127_s_std_output,
691 .s_routing = saa7127_s_routing,
692 .s_stream = saa7127_s_stream,
693};
694
695static const struct v4l2_subdev_ops saa7127_ops = {
696 .core = &saa7127_core_ops,
697 .video = &saa7127_video_ops,
698};
699
662/* ----------------------------------------------------------------------- */ 700/* ----------------------------------------------------------------------- */
663 701
664static int saa7127_probe(struct i2c_client *client, 702static int saa7127_probe(struct i2c_client *client,
665 const struct i2c_device_id *id) 703 const struct i2c_device_id *id)
666{ 704{
667 struct saa7127_state *state; 705 struct saa7127_state *state;
706 struct v4l2_subdev *sd;
668 struct v4l2_sliced_vbi_data vbi = { 0, 0, 0, 0 }; /* set to disabled */ 707 struct v4l2_sliced_vbi_data vbi = { 0, 0, 0, 0 }; /* set to disabled */
669 708
670 /* Check if the adapter supports the needed features */ 709 /* Check if the adapter supports the needed features */
@@ -674,40 +713,42 @@ static int saa7127_probe(struct i2c_client *client,
674 v4l_dbg(1, debug, client, "detecting saa7127 client on address 0x%x\n", 713 v4l_dbg(1, debug, client, "detecting saa7127 client on address 0x%x\n",
675 client->addr << 1); 714 client->addr << 1);
676 715
716 state = kzalloc(sizeof(struct saa7127_state), GFP_KERNEL);
717 if (state == NULL)
718 return -ENOMEM;
719
720 sd = &state->sd;
721 v4l2_i2c_subdev_init(sd, client, &saa7127_ops);
722
677 /* First test register 0: Bits 5-7 are a version ID (should be 0), 723 /* First test register 0: Bits 5-7 are a version ID (should be 0),
678 and bit 2 should also be 0. 724 and bit 2 should also be 0.
679 This is rather general, so the second test is more specific and 725 This is rather general, so the second test is more specific and
680 looks at the 'ending point of burst in clock cycles' which is 726 looks at the 'ending point of burst in clock cycles' which is
681 0x1d after a reset and not expected to ever change. */ 727 0x1d after a reset and not expected to ever change. */
682 if ((saa7127_read(client, 0) & 0xe4) != 0 || 728 if ((saa7127_read(sd, 0) & 0xe4) != 0 ||
683 (saa7127_read(client, 0x29) & 0x3f) != 0x1d) { 729 (saa7127_read(sd, 0x29) & 0x3f) != 0x1d) {
684 v4l_dbg(1, debug, client, "saa7127 not found\n"); 730 v4l2_dbg(1, debug, sd, "saa7127 not found\n");
731 kfree(state);
685 return -ENODEV; 732 return -ENODEV;
686 } 733 }
687 state = kzalloc(sizeof(struct saa7127_state), GFP_KERNEL);
688
689 if (state == NULL)
690 return -ENOMEM;
691
692 i2c_set_clientdata(client, state);
693 734
694 /* Configure Encoder */ 735 /* Configure Encoder */
695 736
696 v4l_dbg(1, debug, client, "Configuring encoder\n"); 737 v4l2_dbg(1, debug, sd, "Configuring encoder\n");
697 saa7127_write_inittab(client, saa7127_init_config_common); 738 saa7127_write_inittab(sd, saa7127_init_config_common);
698 saa7127_set_std(client, V4L2_STD_NTSC); 739 saa7127_set_std(sd, V4L2_STD_NTSC);
699 saa7127_set_output_type(client, SAA7127_OUTPUT_TYPE_BOTH); 740 saa7127_set_output_type(sd, SAA7127_OUTPUT_TYPE_BOTH);
700 saa7127_set_vps(client, &vbi); 741 saa7127_set_vps(sd, &vbi);
701 saa7127_set_wss(client, &vbi); 742 saa7127_set_wss(sd, &vbi);
702 saa7127_set_cc(client, &vbi); 743 saa7127_set_cc(sd, &vbi);
703 saa7127_set_xds(client, &vbi); 744 saa7127_set_xds(sd, &vbi);
704 if (test_image == 1) 745 if (test_image == 1)
705 /* The Encoder has an internal Colorbar generator */ 746 /* The Encoder has an internal Colorbar generator */
706 /* This can be used for debugging */ 747 /* This can be used for debugging */
707 saa7127_set_input_type(client, SAA7127_INPUT_TYPE_TEST_IMAGE); 748 saa7127_set_input_type(sd, SAA7127_INPUT_TYPE_TEST_IMAGE);
708 else 749 else
709 saa7127_set_input_type(client, SAA7127_INPUT_TYPE_NORMAL); 750 saa7127_set_input_type(sd, SAA7127_INPUT_TYPE_NORMAL);
710 saa7127_set_video_enable(client, 1); 751 saa7127_set_video_enable(sd, 1);
711 752
712 if (id->driver_data) { /* Chip type is already known */ 753 if (id->driver_data) { /* Chip type is already known */
713 state->ident = id->driver_data; 754 state->ident = id->driver_data;
@@ -715,10 +756,10 @@ static int saa7127_probe(struct i2c_client *client,
715 int read_result; 756 int read_result;
716 757
717 /* Detect if it's an saa7129 */ 758 /* Detect if it's an saa7129 */
718 read_result = saa7127_read(client, SAA7129_REG_FADE_KEY_COL2); 759 read_result = saa7127_read(sd, SAA7129_REG_FADE_KEY_COL2);
719 saa7127_write(client, SAA7129_REG_FADE_KEY_COL2, 0xaa); 760 saa7127_write(sd, SAA7129_REG_FADE_KEY_COL2, 0xaa);
720 if (saa7127_read(client, SAA7129_REG_FADE_KEY_COL2) == 0xaa) { 761 if (saa7127_read(sd, SAA7129_REG_FADE_KEY_COL2) == 0xaa) {
721 saa7127_write(client, SAA7129_REG_FADE_KEY_COL2, 762 saa7127_write(sd, SAA7129_REG_FADE_KEY_COL2,
722 read_result); 763 read_result);
723 state->ident = V4L2_IDENT_SAA7129; 764 state->ident = V4L2_IDENT_SAA7129;
724 strlcpy(client->name, "saa7129", I2C_NAME_SIZE); 765 strlcpy(client->name, "saa7129", I2C_NAME_SIZE);
@@ -728,10 +769,10 @@ static int saa7127_probe(struct i2c_client *client,
728 } 769 }
729 } 770 }
730 771
731 v4l_info(client, "%s found @ 0x%x (%s)\n", client->name, 772 v4l2_info(sd, "%s found @ 0x%x (%s)\n", client->name,
732 client->addr << 1, client->adapter->name); 773 client->addr << 1, client->adapter->name);
733 if (state->ident == V4L2_IDENT_SAA7129) 774 if (state->ident == V4L2_IDENT_SAA7129)
734 saa7127_write_inittab(client, saa7129_init_config_extra); 775 saa7127_write_inittab(sd, saa7129_init_config_extra);
735 return 0; 776 return 0;
736} 777}
737 778
@@ -739,9 +780,12 @@ static int saa7127_probe(struct i2c_client *client,
739 780
740static int saa7127_remove(struct i2c_client *client) 781static int saa7127_remove(struct i2c_client *client)
741{ 782{
783 struct v4l2_subdev *sd = i2c_get_clientdata(client);
784
785 v4l2_device_unregister_subdev(sd);
742 /* Turn off TV output */ 786 /* Turn off TV output */
743 saa7127_set_video_enable(client, 0); 787 saa7127_set_video_enable(sd, 0);
744 kfree(i2c_get_clientdata(client)); 788 kfree(to_state(sd));
745 return 0; 789 return 0;
746} 790}
747 791
@@ -760,7 +804,6 @@ MODULE_DEVICE_TABLE(i2c, saa7127_id);
760static struct v4l2_i2c_driver_data v4l2_i2c_data = { 804static struct v4l2_i2c_driver_data v4l2_i2c_data = {
761 .name = "saa7127", 805 .name = "saa7127",
762 .driverid = I2C_DRIVERID_SAA7127, 806 .driverid = I2C_DRIVERID_SAA7127,
763 .command = saa7127_command,
764 .probe = saa7127_probe, 807 .probe = saa7127_probe,
765 .remove = saa7127_remove, 808 .remove = saa7127_remove,
766 .id_table = saa7127_id, 809 .id_table = saa7127_id,
diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c
index ddc5402c5fb0..a2e3f6729c5b 100644
--- a/drivers/media/video/saa7134/saa7134-cards.c
+++ b/drivers/media/video/saa7134/saa7134-cards.c
@@ -4606,6 +4606,43 @@ struct saa7134_board saa7134_boards[] = {
4606 .gpio = 0x0200000, 4606 .gpio = 0x0200000,
4607 }, 4607 },
4608 }, 4608 },
4609 [SAA7134_BOARD_KWORLD_PLUS_TV_ANALOG] = {
4610 .name = "Kworld Plus TV Analog Lite PCI",
4611 .audio_clock = 0x00187de7,
4612 .tuner_type = TUNER_YMEC_TVF_5533MF,
4613 .radio_type = TUNER_TEA5767,
4614 .tuner_addr = ADDR_UNSET,
4615 .radio_addr = ADDR_UNSET,
4616 .gpiomask = 0x80000700,
4617 .inputs = { {
4618 .name = name_tv,
4619 .vmux = 1,
4620 .amux = LINE2,
4621 .tv = 1,
4622 .gpio = 0x100,
4623 }, {
4624 .name = name_comp1,
4625 .vmux = 3,
4626 .amux = LINE1,
4627 .gpio = 0x200,
4628 }, {
4629 .name = name_svideo,
4630 .vmux = 8,
4631 .amux = LINE1,
4632 .gpio = 0x200,
4633 } },
4634 .radio = {
4635 .name = name_radio,
4636 .vmux = 1,
4637 .amux = LINE1,
4638 .gpio = 0x100,
4639 },
4640 .mute = {
4641 .name = name_mute,
4642 .vmux = 8,
4643 .amux = 2,
4644 },
4645 },
4609}; 4646};
4610 4647
4611const unsigned int saa7134_bcount = ARRAY_SIZE(saa7134_boards); 4648const unsigned int saa7134_bcount = ARRAY_SIZE(saa7134_boards);
@@ -4736,6 +4773,12 @@ struct pci_device_id saa7134_pci_tbl[] = {
4736 .driver_data = SAA7134_BOARD_MD7134, 4773 .driver_data = SAA7134_BOARD_MD7134,
4737 },{ 4774 },{
4738 .vendor = PCI_VENDOR_ID_PHILIPS, 4775 .vendor = PCI_VENDOR_ID_PHILIPS,
4776 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
4777 .subvendor = 0x16be, /* CTX946 analog TV, HW mpeg, DVB-T */
4778 .subdevice = 0x5000, /* only analog TV and DVB-T for now */
4779 .driver_data = SAA7134_BOARD_MD7134,
4780 }, {
4781 .vendor = PCI_VENDOR_ID_PHILIPS,
4739 .device = PCI_DEVICE_ID_PHILIPS_SAA7130, 4782 .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
4740 .subvendor = 0x1048, 4783 .subvendor = 0x1048,
4741 .subdevice = 0x226b, 4784 .subdevice = 0x226b,
@@ -5653,6 +5696,12 @@ struct pci_device_id saa7134_pci_tbl[] = {
5653 .subdevice = 0x4878, /* REV:1.02G */ 5696 .subdevice = 0x4878, /* REV:1.02G */
5654 .driver_data = SAA7134_BOARD_ASUSTeK_TIGER_3IN1, 5697 .driver_data = SAA7134_BOARD_ASUSTeK_TIGER_3IN1,
5655 }, { 5698 }, {
5699 .vendor = PCI_VENDOR_ID_PHILIPS,
5700 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
5701 .subvendor = 0x17de,
5702 .subdevice = 0x7128,
5703 .driver_data = SAA7134_BOARD_KWORLD_PLUS_TV_ANALOG,
5704 }, {
5656 /* --- boards without eeprom + subsystem ID --- */ 5705 /* --- boards without eeprom + subsystem ID --- */
5657 .vendor = PCI_VENDOR_ID_PHILIPS, 5706 .vendor = PCI_VENDOR_ID_PHILIPS,
5658 .device = PCI_DEVICE_ID_PHILIPS_SAA7134, 5707 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
@@ -5880,6 +5929,7 @@ int saa7134_board_init1(struct saa7134_dev *dev)
5880 case SAA7134_BOARD_BEHOLD_507_9FM: 5929 case SAA7134_BOARD_BEHOLD_507_9FM:
5881 case SAA7134_BOARD_GENIUS_TVGO_A11MCE: 5930 case SAA7134_BOARD_GENIUS_TVGO_A11MCE:
5882 case SAA7134_BOARD_REAL_ANGEL_220: 5931 case SAA7134_BOARD_REAL_ANGEL_220:
5932 case SAA7134_BOARD_KWORLD_PLUS_TV_ANALOG:
5883 dev->has_remote = SAA7134_REMOTE_GPIO; 5933 dev->has_remote = SAA7134_REMOTE_GPIO;
5884 break; 5934 break;
5885 case SAA7134_BOARD_FLYDVBS_LR300: 5935 case SAA7134_BOARD_FLYDVBS_LR300:
@@ -6048,7 +6098,7 @@ static void saa7134_tuner_setup(struct saa7134_dev *dev)
6048 struct v4l2_priv_tun_config xc2028_cfg; 6098 struct v4l2_priv_tun_config xc2028_cfg;
6049 struct xc2028_ctrl ctl; 6099 struct xc2028_ctrl ctl;
6050 6100
6051 memset(&xc2028_cfg, 0, sizeof(ctl)); 6101 memset(&xc2028_cfg, 0, sizeof(xc2028_cfg));
6052 memset(&ctl, 0, sizeof(ctl)); 6102 memset(&ctl, 0, sizeof(ctl));
6053 6103
6054 ctl.fname = XC2028_DEFAULT_FIRMWARE; 6104 ctl.fname = XC2028_DEFAULT_FIRMWARE;
diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/video/saa7134/saa7134-dvb.c
index 8c46115d4c79..d9a5652595b5 100644
--- a/drivers/media/video/saa7134/saa7134-dvb.c
+++ b/drivers/media/video/saa7134/saa7134-dvb.c
@@ -954,20 +954,14 @@ static int dvb_init(struct saa7134_dev *dev)
954 /* FIXME: add support for multi-frontend */ 954 /* FIXME: add support for multi-frontend */
955 mutex_init(&dev->frontends.lock); 955 mutex_init(&dev->frontends.lock);
956 INIT_LIST_HEAD(&dev->frontends.felist); 956 INIT_LIST_HEAD(&dev->frontends.felist);
957 dev->frontends.active_fe_id = 0;
958 957
959 printk(KERN_INFO "%s() allocating 1 frontend\n", __func__); 958 printk(KERN_INFO "%s() allocating 1 frontend\n", __func__);
960 959 fe0 = videobuf_dvb_alloc_frontend(&dev->frontends, 1);
961 if (videobuf_dvb_alloc_frontend(&dev->frontends, 1) == NULL) { 960 if (!fe0) {
962 printk(KERN_ERR "%s() failed to alloc\n", __func__); 961 printk(KERN_ERR "%s() failed to alloc\n", __func__);
963 return -ENOMEM; 962 return -ENOMEM;
964 } 963 }
965 964
966 /* Get the first frontend */
967 fe0 = videobuf_dvb_get_frontend(&dev->frontends, 1);
968 if (!fe0)
969 return -EINVAL;
970
971 /* init struct videobuf_dvb */ 965 /* init struct videobuf_dvb */
972 dev->ts.nr_bufs = 32; 966 dev->ts.nr_bufs = 32;
973 dev->ts.nr_packets = 32*4; 967 dev->ts.nr_packets = 32*4;
@@ -1376,7 +1370,7 @@ static int dvb_init(struct saa7134_dev *dev)
1376 }; 1370 };
1377 1371
1378 if (!fe0->dvb.frontend) 1372 if (!fe0->dvb.frontend)
1379 return -1; 1373 goto dettach_frontend;
1380 1374
1381 fe = dvb_attach(xc2028_attach, fe0->dvb.frontend, &cfg); 1375 fe = dvb_attach(xc2028_attach, fe0->dvb.frontend, &cfg);
1382 if (!fe) { 1376 if (!fe) {
@@ -1388,7 +1382,7 @@ static int dvb_init(struct saa7134_dev *dev)
1388 1382
1389 if (NULL == fe0->dvb.frontend) { 1383 if (NULL == fe0->dvb.frontend) {
1390 printk(KERN_ERR "%s/dvb: frontend initialization failed\n", dev->name); 1384 printk(KERN_ERR "%s/dvb: frontend initialization failed\n", dev->name);
1391 return -1; 1385 goto dettach_frontend;
1392 } 1386 }
1393 /* define general-purpose callback pointer */ 1387 /* define general-purpose callback pointer */
1394 fe0->dvb.frontend->callback = saa7134_tuner_callback; 1388 fe0->dvb.frontend->callback = saa7134_tuner_callback;
@@ -1411,11 +1405,8 @@ static int dvb_init(struct saa7134_dev *dev)
1411 return ret; 1405 return ret;
1412 1406
1413dettach_frontend: 1407dettach_frontend:
1414 if (fe0->dvb.frontend) 1408 videobuf_dvb_dealloc_frontends(&dev->frontends);
1415 dvb_frontend_detach(fe0->dvb.frontend); 1409 return -EINVAL;
1416 fe0->dvb.frontend = NULL;
1417
1418 return -1;
1419} 1410}
1420 1411
1421static int dvb_fini(struct saa7134_dev *dev) 1412static int dvb_fini(struct saa7134_dev *dev)
@@ -1454,8 +1445,7 @@ static int dvb_fini(struct saa7134_dev *dev)
1454 } 1445 }
1455 } 1446 }
1456 } 1447 }
1457 if (fe0->dvb.frontend) 1448 videobuf_dvb_unregister_bus(&dev->frontends);
1458 videobuf_dvb_unregister_bus(&dev->frontends);
1459 return 0; 1449 return 0;
1460} 1450}
1461 1451
diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c
index c53fd5f9f6b5..d2124f64e4e2 100644
--- a/drivers/media/video/saa7134/saa7134-input.c
+++ b/drivers/media/video/saa7134/saa7134-input.c
@@ -97,6 +97,15 @@ static int build_key(struct saa7134_dev *dev)
97 dprintk("build_key gpio=0x%x mask=0x%x data=%d\n", 97 dprintk("build_key gpio=0x%x mask=0x%x data=%d\n",
98 gpio, ir->mask_keycode, data); 98 gpio, ir->mask_keycode, data);
99 99
100 switch (dev->board) {
101 case SAA7134_BOARD_KWORLD_PLUS_TV_ANALOG:
102 if (data == ir->mask_keycode)
103 ir_input_nokey(ir->dev, &ir->ir);
104 else
105 ir_input_keydown(ir->dev, &ir->ir, data, data);
106 return 0;
107 }
108
100 if (ir->polling) { 109 if (ir->polling) {
101 if ((ir->mask_keydown && (0 != (gpio & ir->mask_keydown))) || 110 if ((ir->mask_keydown && (0 != (gpio & ir->mask_keydown))) ||
102 (ir->mask_keyup && (0 == (gpio & ir->mask_keyup)))) { 111 (ir->mask_keyup && (0 == (gpio & ir->mask_keyup)))) {
@@ -586,6 +595,11 @@ int saa7134_input_init1(struct saa7134_dev *dev)
586 mask_keyup = 0x4000; 595 mask_keyup = 0x4000;
587 polling = 50; /* ms */ 596 polling = 50; /* ms */
588 break; 597 break;
598 case SAA7134_BOARD_KWORLD_PLUS_TV_ANALOG:
599 ir_codes = ir_codes_kworld_plus_tv_analog;
600 mask_keycode = 0x7f;
601 polling = 40; /* ms */
602 break;
589 } 603 }
590 if (NULL == ir_codes) { 604 if (NULL == ir_codes) {
591 printk("%s: Oops: IR config error [card=%d]\n", 605 printk("%s: Oops: IR config error [card=%d]\n",
diff --git a/drivers/media/video/saa7134/saa7134-tvaudio.c b/drivers/media/video/saa7134/saa7134-tvaudio.c
index c5d0b44c179e..76b16407b01e 100644
--- a/drivers/media/video/saa7134/saa7134-tvaudio.c
+++ b/drivers/media/video/saa7134/saa7134-tvaudio.c
@@ -159,7 +159,7 @@ static struct saa7134_tvaudio tvaudio[] = {
159 .mode = TVAUDIO_FM_MONO, 159 .mode = TVAUDIO_FM_MONO,
160 } 160 }
161}; 161};
162#define TVAUDIO (sizeof(tvaudio)/sizeof(struct saa7134_tvaudio)) 162#define TVAUDIO ARRAY_SIZE(tvaudio)
163 163
164/* ------------------------------------------------------------------ */ 164/* ------------------------------------------------------------------ */
165 165
diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h
index 24096d6e1ef8..f6c1fcc72070 100644
--- a/drivers/media/video/saa7134/saa7134.h
+++ b/drivers/media/video/saa7134/saa7134.h
@@ -275,8 +275,9 @@ struct saa7134_format {
275#define SAA7134_BOARD_REAL_ANGEL_220 150 275#define SAA7134_BOARD_REAL_ANGEL_220 150
276#define SAA7134_BOARD_ADS_INSTANT_HDTV_PCI 151 276#define SAA7134_BOARD_ADS_INSTANT_HDTV_PCI 151
277#define SAA7134_BOARD_ASUSTeK_TIGER 152 277#define SAA7134_BOARD_ASUSTeK_TIGER 152
278#define SAA7134_BOARD_KWORLD_PLUS_TV_ANALOG 153
278 279
279#define SAA7134_MAXBOARDS 8 280#define SAA7134_MAXBOARDS 32
280#define SAA7134_INPUT_MAX 8 281#define SAA7134_INPUT_MAX 8
281 282
282/* ----------------------------------------------------------- */ 283/* ----------------------------------------------------------- */
diff --git a/drivers/media/video/saa717x.c b/drivers/media/video/saa717x.c
index af60ede5310d..9befca65905e 100644
--- a/drivers/media/video/saa717x.c
+++ b/drivers/media/video/saa717x.c
@@ -37,7 +37,7 @@
37 37
38#include <linux/videodev2.h> 38#include <linux/videodev2.h>
39#include <linux/i2c.h> 39#include <linux/i2c.h>
40#include <media/v4l2-common.h> 40#include <media/v4l2-device.h>
41#include <media/v4l2-i2c-drv.h> 41#include <media/v4l2-i2c-drv.h>
42 42
43MODULE_DESCRIPTION("Philips SAA717x audio/video decoder driver"); 43MODULE_DESCRIPTION("Philips SAA717x audio/video decoder driver");
@@ -54,6 +54,7 @@ MODULE_PARM_DESC(debug, "Debug level (0-1)");
54 */ 54 */
55 55
56struct saa717x_state { 56struct saa717x_state {
57 struct v4l2_subdev sd;
57 v4l2_std_id std; 58 v4l2_std_id std;
58 int input; 59 int input;
59 int enable; 60 int enable;
@@ -75,6 +76,11 @@ struct saa717x_state {
75 int audio_input; 76 int audio_input;
76}; 77};
77 78
79static inline struct saa717x_state *to_state(struct v4l2_subdev *sd)
80{
81 return container_of(sd, struct saa717x_state, sd);
82}
83
78/* ----------------------------------------------------------------------- */ 84/* ----------------------------------------------------------------------- */
79 85
80/* for audio mode */ 86/* for audio mode */
@@ -88,8 +94,9 @@ struct saa717x_state {
88 94
89/* ----------------------------------------------------------------------- */ 95/* ----------------------------------------------------------------------- */
90 96
91static int saa717x_write(struct i2c_client *client, u32 reg, u32 value) 97static int saa717x_write(struct v4l2_subdev *sd, u32 reg, u32 value)
92{ 98{
99 struct i2c_client *client = v4l2_get_subdevdata(sd);
93 struct i2c_adapter *adap = client->adapter; 100 struct i2c_adapter *adap = client->adapter;
94 int fw_addr = reg == 0x454 || (reg >= 0x464 && reg <= 0x478) || reg == 0x480 || reg == 0x488; 101 int fw_addr = reg == 0x454 || (reg >= 0x464 && reg <= 0x478) || reg == 0x480 || reg == 0x488;
95 unsigned char mm1[6]; 102 unsigned char mm1[6];
@@ -109,20 +116,21 @@ static int saa717x_write(struct i2c_client *client, u32 reg, u32 value)
109 } 116 }
110 msg.len = fw_addr ? 5 : 3; /* Long Registers have *only* three bytes! */ 117 msg.len = fw_addr ? 5 : 3; /* Long Registers have *only* three bytes! */
111 msg.buf = mm1; 118 msg.buf = mm1;
112 v4l_dbg(2, debug, client, "wrote: reg 0x%03x=%08x\n", reg, value); 119 v4l2_dbg(2, debug, sd, "wrote: reg 0x%03x=%08x\n", reg, value);
113 return i2c_transfer(adap, &msg, 1) == 1; 120 return i2c_transfer(adap, &msg, 1) == 1;
114} 121}
115 122
116static void saa717x_write_regs(struct i2c_client *client, u32 *data) 123static void saa717x_write_regs(struct v4l2_subdev *sd, u32 *data)
117{ 124{
118 while (data[0] || data[1]) { 125 while (data[0] || data[1]) {
119 saa717x_write(client, data[0], data[1]); 126 saa717x_write(sd, data[0], data[1]);
120 data += 2; 127 data += 2;
121 } 128 }
122} 129}
123 130
124static u32 saa717x_read(struct i2c_client *client, u32 reg) 131static u32 saa717x_read(struct v4l2_subdev *sd, u32 reg)
125{ 132{
133 struct i2c_client *client = v4l2_get_subdevdata(sd);
126 struct i2c_adapter *adap = client->adapter; 134 struct i2c_adapter *adap = client->adapter;
127 int fw_addr = (reg >= 0x404 && reg <= 0x4b8) || reg == 0x528; 135 int fw_addr = (reg >= 0x404 && reg <= 0x4b8) || reg == 0x528;
128 unsigned char mm1[2]; 136 unsigned char mm1[2];
@@ -146,7 +154,7 @@ static u32 saa717x_read(struct i2c_client *client, u32 reg)
146 else 154 else
147 value = mm2[0] & 0xff; 155 value = mm2[0] & 0xff;
148 156
149 v4l_dbg(2, debug, client, "read: reg 0x%03x=0x%08x\n", reg, value); 157 v4l2_dbg(2, debug, sd, "read: reg 0x%03x=0x%08x\n", reg, value);
150 return value; 158 return value;
151} 159}
152 160
@@ -680,7 +688,7 @@ static u32 reg_set_audio_template[4][2] =
680 688
681 689
682/* Get detected audio flags (from saa7134 driver) */ 690/* Get detected audio flags (from saa7134 driver) */
683static void get_inf_dev_status(struct i2c_client *client, 691static void get_inf_dev_status(struct v4l2_subdev *sd,
684 int *dual_flag, int *stereo_flag) 692 int *dual_flag, int *stereo_flag)
685{ 693{
686 u32 reg_data3; 694 u32 reg_data3;
@@ -719,13 +727,13 @@ static void get_inf_dev_status(struct i2c_client *client,
719 /* (demdec status: 0x528) */ 727 /* (demdec status: 0x528) */
720 728
721 /* read current status */ 729 /* read current status */
722 reg_data3 = saa717x_read(client, 0x0528); 730 reg_data3 = saa717x_read(sd, 0x0528);
723 731
724 v4l_dbg(1, debug, client, "tvaudio thread status: 0x%x [%s%s%s]\n", 732 v4l2_dbg(1, debug, sd, "tvaudio thread status: 0x%x [%s%s%s]\n",
725 reg_data3, stdres[reg_data3 & 0x1f], 733 reg_data3, stdres[reg_data3 & 0x1f],
726 (reg_data3 & 0x000020) ? ",stereo" : "", 734 (reg_data3 & 0x000020) ? ",stereo" : "",
727 (reg_data3 & 0x000040) ? ",dual" : ""); 735 (reg_data3 & 0x000040) ? ",dual" : "");
728 v4l_dbg(1, debug, client, "detailed status: " 736 v4l2_dbg(1, debug, sd, "detailed status: "
729 "%s#%s#%s#%s#%s#%s#%s#%s#%s#%s#%s#%s#%s#%s\n", 737 "%s#%s#%s#%s#%s#%s#%s#%s#%s#%s#%s#%s#%s#%s\n",
730 (reg_data3 & 0x000080) ? " A2/EIAJ pilot tone " : "", 738 (reg_data3 & 0x000080) ? " A2/EIAJ pilot tone " : "",
731 (reg_data3 & 0x000100) ? " A2/EIAJ dual " : "", 739 (reg_data3 & 0x000100) ? " A2/EIAJ dual " : "",
@@ -746,51 +754,51 @@ static void get_inf_dev_status(struct i2c_client *client,
746 (reg_data3 & 0x100000) ? " init done " : ""); 754 (reg_data3 & 0x100000) ? " init done " : "");
747 755
748 if (reg_data3 & 0x000220) { 756 if (reg_data3 & 0x000220) {
749 v4l_dbg(1, debug, client, "ST!!!\n"); 757 v4l2_dbg(1, debug, sd, "ST!!!\n");
750 *stereo_flag = 1; 758 *stereo_flag = 1;
751 } 759 }
752 760
753 if (reg_data3 & 0x000140) { 761 if (reg_data3 & 0x000140) {
754 v4l_dbg(1, debug, client, "DUAL!!!\n"); 762 v4l2_dbg(1, debug, sd, "DUAL!!!\n");
755 *dual_flag = 1; 763 *dual_flag = 1;
756 } 764 }
757} 765}
758 766
759/* regs write to set audio mode */ 767/* regs write to set audio mode */
760static void set_audio_mode(struct i2c_client *client, int audio_mode) 768static void set_audio_mode(struct v4l2_subdev *sd, int audio_mode)
761{ 769{
762 v4l_dbg(1, debug, client, "writing registers to set audio mode by set %d\n", 770 v4l2_dbg(1, debug, sd, "writing registers to set audio mode by set %d\n",
763 audio_mode); 771 audio_mode);
764 772
765 saa717x_write(client, 0x46c, reg_set_audio_template[audio_mode][0]); 773 saa717x_write(sd, 0x46c, reg_set_audio_template[audio_mode][0]);
766 saa717x_write(client, 0x470, reg_set_audio_template[audio_mode][1]); 774 saa717x_write(sd, 0x470, reg_set_audio_template[audio_mode][1]);
767} 775}
768 776
769/* write regs to video output level (bright,contrast,hue,sat) */ 777/* write regs to video output level (bright,contrast,hue,sat) */
770static void set_video_output_level_regs(struct i2c_client *client, 778static void set_video_output_level_regs(struct v4l2_subdev *sd,
771 struct saa717x_state *decoder) 779 struct saa717x_state *decoder)
772{ 780{
773 /* brightness ffh (bright) - 80h (ITU level) - 00h (dark) */ 781 /* brightness ffh (bright) - 80h (ITU level) - 00h (dark) */
774 saa717x_write(client, 0x10a, decoder->bright); 782 saa717x_write(sd, 0x10a, decoder->bright);
775 783
776 /* contrast 7fh (max: 1.984) - 44h (ITU) - 40h (1.0) - 784 /* contrast 7fh (max: 1.984) - 44h (ITU) - 40h (1.0) -
777 0h (luminance off) 40: i2c dump 785 0h (luminance off) 40: i2c dump
778 c0h (-1.0 inverse chrominance) 786 c0h (-1.0 inverse chrominance)
779 80h (-2.0 inverse chrominance) */ 787 80h (-2.0 inverse chrominance) */
780 saa717x_write(client, 0x10b, decoder->contrast); 788 saa717x_write(sd, 0x10b, decoder->contrast);
781 789
782 /* saturation? 7fh(max)-40h(ITU)-0h(color off) 790 /* saturation? 7fh(max)-40h(ITU)-0h(color off)
783 c0h (-1.0 inverse chrominance) 791 c0h (-1.0 inverse chrominance)
784 80h (-2.0 inverse chrominance) */ 792 80h (-2.0 inverse chrominance) */
785 saa717x_write(client, 0x10c, decoder->sat); 793 saa717x_write(sd, 0x10c, decoder->sat);
786 794
787 /* color hue (phase) control 795 /* color hue (phase) control
788 7fh (+178.6) - 0h (0 normal) - 80h (-180.0) */ 796 7fh (+178.6) - 0h (0 normal) - 80h (-180.0) */
789 saa717x_write(client, 0x10d, decoder->hue); 797 saa717x_write(sd, 0x10d, decoder->hue);
790} 798}
791 799
792/* write regs to set audio volume, bass and treble */ 800/* write regs to set audio volume, bass and treble */
793static int set_audio_regs(struct i2c_client *client, 801static int set_audio_regs(struct v4l2_subdev *sd,
794 struct saa717x_state *decoder) 802 struct saa717x_state *decoder)
795{ 803{
796 u8 mute = 0xac; /* -84 dB */ 804 u8 mute = 0xac; /* -84 dB */
@@ -798,8 +806,8 @@ static int set_audio_regs(struct i2c_client *client,
798 unsigned int work_l, work_r; 806 unsigned int work_l, work_r;
799 807
800 /* set SIF analog I/O select */ 808 /* set SIF analog I/O select */
801 saa717x_write(client, 0x0594, decoder->audio_input); 809 saa717x_write(sd, 0x0594, decoder->audio_input);
802 v4l_dbg(1, debug, client, "set audio input %d\n", 810 v4l2_dbg(1, debug, sd, "set audio input %d\n",
803 decoder->audio_input); 811 decoder->audio_input);
804 812
805 /* normalize ( 65535 to 0 -> 24 to -40 (not -84)) */ 813 /* normalize ( 65535 to 0 -> 24 to -40 (not -84)) */
@@ -819,17 +827,17 @@ static int set_audio_regs(struct i2c_client *client,
819 ((u8)decoder->audio_main_vol_r << 8); 827 ((u8)decoder->audio_main_vol_r << 8);
820 } 828 }
821 829
822 saa717x_write(client, 0x480, val); 830 saa717x_write(sd, 0x480, val);
823 831
824 /* bass and treble; go to another function */ 832 /* bass and treble; go to another function */
825 /* set bass and treble */ 833 /* set bass and treble */
826 val = decoder->audio_main_bass | (decoder->audio_main_treble << 8); 834 val = decoder->audio_main_bass | (decoder->audio_main_treble << 8);
827 saa717x_write(client, 0x488, val); 835 saa717x_write(sd, 0x488, val);
828 return 0; 836 return 0;
829} 837}
830 838
831/********** scaling staff ***********/ 839/********** scaling staff ***********/
832static void set_h_prescale(struct i2c_client *client, 840static void set_h_prescale(struct v4l2_subdev *sd,
833 int task, int prescale) 841 int task, int prescale)
834{ 842{
835 static const struct { 843 static const struct {
@@ -862,107 +870,101 @@ static void set_h_prescale(struct i2c_client *client,
862 return; 870 return;
863 871
864 /* horizonal prescaling */ 872 /* horizonal prescaling */
865 saa717x_write(client, 0x60 + task_shift, vals[i].xpsc); 873 saa717x_write(sd, 0x60 + task_shift, vals[i].xpsc);
866 /* accumulation length */ 874 /* accumulation length */
867 saa717x_write(client, 0x61 + task_shift, vals[i].xacl); 875 saa717x_write(sd, 0x61 + task_shift, vals[i].xacl);
868 /* level control */ 876 /* level control */
869 saa717x_write(client, 0x62 + task_shift, 877 saa717x_write(sd, 0x62 + task_shift,
870 (vals[i].xc2_1 << 3) | vals[i].xdcg); 878 (vals[i].xc2_1 << 3) | vals[i].xdcg);
871 /*FIR prefilter control */ 879 /*FIR prefilter control */
872 saa717x_write(client, 0x63 + task_shift, 880 saa717x_write(sd, 0x63 + task_shift,
873 (vals[i].vpfy << 2) | vals[i].vpfy); 881 (vals[i].vpfy << 2) | vals[i].vpfy);
874} 882}
875 883
876/********** scaling staff ***********/ 884/********** scaling staff ***********/
877static void set_v_scale(struct i2c_client *client, int task, int yscale) 885static void set_v_scale(struct v4l2_subdev *sd, int task, int yscale)
878{ 886{
879 int task_shift; 887 int task_shift;
880 888
881 task_shift = task * 0x40; 889 task_shift = task * 0x40;
882 /* Vertical scaling ratio (LOW) */ 890 /* Vertical scaling ratio (LOW) */
883 saa717x_write(client, 0x70 + task_shift, yscale & 0xff); 891 saa717x_write(sd, 0x70 + task_shift, yscale & 0xff);
884 /* Vertical scaling ratio (HI) */ 892 /* Vertical scaling ratio (HI) */
885 saa717x_write(client, 0x71 + task_shift, yscale >> 8); 893 saa717x_write(sd, 0x71 + task_shift, yscale >> 8);
886}
887
888static int saa717x_set_audio_clock_freq(struct i2c_client *client, u32 freq)
889{
890 /* not yet implament, so saa717x_cfg_??hz_??_audio is not defined. */
891 return 0;
892} 894}
893 895
894static int saa717x_set_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl) 896static int saa717x_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
895{ 897{
896 struct saa717x_state *state = i2c_get_clientdata(client); 898 struct saa717x_state *state = to_state(sd);
897 899
898 switch (ctrl->id) { 900 switch (ctrl->id) {
899 case V4L2_CID_BRIGHTNESS: 901 case V4L2_CID_BRIGHTNESS:
900 if (ctrl->value < 0 || ctrl->value > 255) { 902 if (ctrl->value < 0 || ctrl->value > 255) {
901 v4l_err(client, "invalid brightness setting %d\n", ctrl->value); 903 v4l2_err(sd, "invalid brightness setting %d\n", ctrl->value);
902 return -ERANGE; 904 return -ERANGE;
903 } 905 }
904 906
905 state->bright = ctrl->value; 907 state->bright = ctrl->value;
906 v4l_dbg(1, debug, client, "bright:%d\n", state->bright); 908 v4l2_dbg(1, debug, sd, "bright:%d\n", state->bright);
907 saa717x_write(client, 0x10a, state->bright); 909 saa717x_write(sd, 0x10a, state->bright);
908 break; 910 break;
909 911
910 case V4L2_CID_CONTRAST: 912 case V4L2_CID_CONTRAST:
911 if (ctrl->value < 0 || ctrl->value > 127) { 913 if (ctrl->value < 0 || ctrl->value > 127) {
912 v4l_err(client, "invalid contrast setting %d\n", ctrl->value); 914 v4l2_err(sd, "invalid contrast setting %d\n", ctrl->value);
913 return -ERANGE; 915 return -ERANGE;
914 } 916 }
915 917
916 state->contrast = ctrl->value; 918 state->contrast = ctrl->value;
917 v4l_dbg(1, debug, client, "contrast:%d\n", state->contrast); 919 v4l2_dbg(1, debug, sd, "contrast:%d\n", state->contrast);
918 saa717x_write(client, 0x10b, state->contrast); 920 saa717x_write(sd, 0x10b, state->contrast);
919 break; 921 break;
920 922
921 case V4L2_CID_SATURATION: 923 case V4L2_CID_SATURATION:
922 if (ctrl->value < 0 || ctrl->value > 127) { 924 if (ctrl->value < 0 || ctrl->value > 127) {
923 v4l_err(client, "invalid saturation setting %d\n", ctrl->value); 925 v4l2_err(sd, "invalid saturation setting %d\n", ctrl->value);
924 return -ERANGE; 926 return -ERANGE;
925 } 927 }
926 928
927 state->sat = ctrl->value; 929 state->sat = ctrl->value;
928 v4l_dbg(1, debug, client, "sat:%d\n", state->sat); 930 v4l2_dbg(1, debug, sd, "sat:%d\n", state->sat);
929 saa717x_write(client, 0x10c, state->sat); 931 saa717x_write(sd, 0x10c, state->sat);
930 break; 932 break;
931 933
932 case V4L2_CID_HUE: 934 case V4L2_CID_HUE:
933 if (ctrl->value < -127 || ctrl->value > 127) { 935 if (ctrl->value < -127 || ctrl->value > 127) {
934 v4l_err(client, "invalid hue setting %d\n", ctrl->value); 936 v4l2_err(sd, "invalid hue setting %d\n", ctrl->value);
935 return -ERANGE; 937 return -ERANGE;
936 } 938 }
937 939
938 state->hue = ctrl->value; 940 state->hue = ctrl->value;
939 v4l_dbg(1, debug, client, "hue:%d\n", state->hue); 941 v4l2_dbg(1, debug, sd, "hue:%d\n", state->hue);
940 saa717x_write(client, 0x10d, state->hue); 942 saa717x_write(sd, 0x10d, state->hue);
941 break; 943 break;
942 944
943 case V4L2_CID_AUDIO_MUTE: 945 case V4L2_CID_AUDIO_MUTE:
944 state->audio_main_mute = ctrl->value; 946 state->audio_main_mute = ctrl->value;
945 set_audio_regs(client, state); 947 set_audio_regs(sd, state);
946 break; 948 break;
947 949
948 case V4L2_CID_AUDIO_VOLUME: 950 case V4L2_CID_AUDIO_VOLUME:
949 state->audio_main_volume = ctrl->value; 951 state->audio_main_volume = ctrl->value;
950 set_audio_regs(client, state); 952 set_audio_regs(sd, state);
951 break; 953 break;
952 954
953 case V4L2_CID_AUDIO_BALANCE: 955 case V4L2_CID_AUDIO_BALANCE:
954 state->audio_main_balance = ctrl->value; 956 state->audio_main_balance = ctrl->value;
955 set_audio_regs(client, state); 957 set_audio_regs(sd, state);
956 break; 958 break;
957 959
958 case V4L2_CID_AUDIO_TREBLE: 960 case V4L2_CID_AUDIO_TREBLE:
959 state->audio_main_treble = ctrl->value; 961 state->audio_main_treble = ctrl->value;
960 set_audio_regs(client, state); 962 set_audio_regs(sd, state);
961 break; 963 break;
962 964
963 case V4L2_CID_AUDIO_BASS: 965 case V4L2_CID_AUDIO_BASS:
964 state->audio_main_bass = ctrl->value; 966 state->audio_main_bass = ctrl->value;
965 set_audio_regs(client, state); 967 set_audio_regs(sd, state);
966 break; 968 break;
967 969
968 default: 970 default:
@@ -972,9 +974,9 @@ static int saa717x_set_v4lctrl(struct i2c_client *client, struct v4l2_control *c
972 return 0; 974 return 0;
973} 975}
974 976
975static int saa717x_get_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl) 977static int saa717x_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
976{ 978{
977 struct saa717x_state *state = i2c_get_clientdata(client); 979 struct saa717x_state *state = to_state(sd);
978 980
979 switch (ctrl->id) { 981 switch (ctrl->id) {
980 case V4L2_CID_BRIGHTNESS: 982 case V4L2_CID_BRIGHTNESS:
@@ -1103,13 +1105,15 @@ static struct v4l2_queryctrl saa717x_qctrl[] = {
1103 }, 1105 },
1104}; 1106};
1105 1107
1106static int saa717x_set_video_input(struct i2c_client *client, struct saa717x_state *decoder, int inp) 1108static int saa717x_s_video_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
1107{ 1109{
1110 struct saa717x_state *decoder = to_state(sd);
1111 int inp = route->input;
1108 int is_tuner = inp & 0x80; /* tuner input flag */ 1112 int is_tuner = inp & 0x80; /* tuner input flag */
1109 1113
1110 inp &= 0x7f; 1114 inp &= 0x7f;
1111 1115
1112 v4l_dbg(1, debug, client, "decoder set input (%d)\n", inp); 1116 v4l2_dbg(1, debug, sd, "decoder set input (%d)\n", inp);
1113 /* inputs from 0-9 are available*/ 1117 /* inputs from 0-9 are available*/
1114 /* saa717x have mode0-mode9 but mode5 is reserved. */ 1118 /* saa717x have mode0-mode9 but mode5 is reserved. */
1115 if (inp < 0 || inp > 9 || inp == 5) 1119 if (inp < 0 || inp > 9 || inp == 5)
@@ -1119,222 +1123,197 @@ static int saa717x_set_video_input(struct i2c_client *client, struct saa717x_sta
1119 int input_line = inp; 1123 int input_line = inp;
1120 1124
1121 decoder->input = input_line; 1125 decoder->input = input_line;
1122 v4l_dbg(1, debug, client, "now setting %s input %d\n", 1126 v4l2_dbg(1, debug, sd, "now setting %s input %d\n",
1123 input_line >= 6 ? "S-Video" : "Composite", 1127 input_line >= 6 ? "S-Video" : "Composite",
1124 input_line); 1128 input_line);
1125 1129
1126 /* select mode */ 1130 /* select mode */
1127 saa717x_write(client, 0x102, 1131 saa717x_write(sd, 0x102,
1128 (saa717x_read(client, 0x102) & 0xf0) | 1132 (saa717x_read(sd, 0x102) & 0xf0) |
1129 input_line); 1133 input_line);
1130 1134
1131 /* bypass chrominance trap for modes 6..9 */ 1135 /* bypass chrominance trap for modes 6..9 */
1132 saa717x_write(client, 0x109, 1136 saa717x_write(sd, 0x109,
1133 (saa717x_read(client, 0x109) & 0x7f) | 1137 (saa717x_read(sd, 0x109) & 0x7f) |
1134 (input_line < 6 ? 0x0 : 0x80)); 1138 (input_line < 6 ? 0x0 : 0x80));
1135 1139
1136 /* change audio_mode */ 1140 /* change audio_mode */
1137 if (is_tuner) { 1141 if (is_tuner) {
1138 /* tuner */ 1142 /* tuner */
1139 set_audio_mode(client, decoder->tuner_audio_mode); 1143 set_audio_mode(sd, decoder->tuner_audio_mode);
1140 } else { 1144 } else {
1141 /* Force to STEREO mode if Composite or 1145 /* Force to STEREO mode if Composite or
1142 * S-Video were chosen */ 1146 * S-Video were chosen */
1143 set_audio_mode(client, TUNER_AUDIO_STEREO); 1147 set_audio_mode(sd, TUNER_AUDIO_STEREO);
1144 } 1148 }
1145 /* change initialize procedure (Composite/S-Video) */ 1149 /* change initialize procedure (Composite/S-Video) */
1146 if (is_tuner) 1150 if (is_tuner)
1147 saa717x_write_regs(client, reg_init_tuner_input); 1151 saa717x_write_regs(sd, reg_init_tuner_input);
1148 else if (input_line >= 6) 1152 else if (input_line >= 6)
1149 saa717x_write_regs(client, reg_init_svideo_input); 1153 saa717x_write_regs(sd, reg_init_svideo_input);
1150 else 1154 else
1151 saa717x_write_regs(client, reg_init_composite_input); 1155 saa717x_write_regs(sd, reg_init_composite_input);
1152 } 1156 }
1153 1157
1154 return 0; 1158 return 0;
1155} 1159}
1156 1160
1157static int saa717x_command(struct i2c_client *client, unsigned cmd, void *arg) 1161static int saa717x_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
1158{ 1162{
1159 struct saa717x_state *decoder = i2c_get_clientdata(client); 1163 int i;
1160
1161 v4l_dbg(1, debug, client, "IOCTL: %08x\n", cmd);
1162 1164
1163 switch (cmd) { 1165 for (i = 0; i < ARRAY_SIZE(saa717x_qctrl); i++)
1164 case VIDIOC_INT_AUDIO_CLOCK_FREQ: 1166 if (qc->id && qc->id == saa717x_qctrl[i].id) {
1165 return saa717x_set_audio_clock_freq(client, *(u32 *)arg); 1167 memcpy(qc, &saa717x_qctrl[i], sizeof(*qc));
1168 return 0;
1169 }
1170 return -EINVAL;
1171}
1166 1172
1167 case VIDIOC_G_CTRL: 1173#ifdef CONFIG_VIDEO_ADV_DEBUG
1168 return saa717x_get_v4lctrl(client, (struct v4l2_control *)arg); 1174static int saa717x_g_register(struct v4l2_subdev *sd, struct v4l2_register *reg)
1175{
1176 struct i2c_client *client = v4l2_get_subdevdata(sd);
1169 1177
1170 case VIDIOC_S_CTRL: 1178 if (!v4l2_chip_match_i2c_client(client, reg->match_type, reg->match_chip))
1171 return saa717x_set_v4lctrl(client, (struct v4l2_control *)arg); 1179 return -EINVAL;
1180 if (!capable(CAP_SYS_ADMIN))
1181 return -EPERM;
1182 reg->val = saa717x_read(sd, reg->reg);
1183 return 0;
1184}
1172 1185
1173 case VIDIOC_QUERYCTRL: { 1186static int saa717x_s_register(struct v4l2_subdev *sd, struct v4l2_register *reg)
1174 struct v4l2_queryctrl *qc = arg; 1187{
1175 int i; 1188 struct i2c_client *client = v4l2_get_subdevdata(sd);
1189 u16 addr = reg->reg & 0xffff;
1190 u8 val = reg->val & 0xff;
1176 1191
1177 for (i = 0; i < ARRAY_SIZE(saa717x_qctrl); i++) 1192 if (!v4l2_chip_match_i2c_client(client, reg->match_type, reg->match_chip))
1178 if (qc->id && qc->id == saa717x_qctrl[i].id) {
1179 memcpy(qc, &saa717x_qctrl[i], sizeof(*qc));
1180 return 0;
1181 }
1182 return -EINVAL; 1193 return -EINVAL;
1183 } 1194 if (!capable(CAP_SYS_ADMIN))
1184 1195 return -EPERM;
1185#ifdef CONFIG_VIDEO_ADV_DEBUG 1196 saa717x_write(sd, addr, val);
1186 case VIDIOC_DBG_G_REGISTER: { 1197 return 0;
1187 struct v4l2_register *reg = arg; 1198}
1188 1199#endif
1189 if (!v4l2_chip_match_i2c_client(client, reg->match_type, reg->match_chip))
1190 return -EINVAL;
1191 if (!capable(CAP_SYS_ADMIN))
1192 return -EPERM;
1193 reg->val = saa717x_read(client, reg->reg);
1194 break;
1195 }
1196 1200
1197 case VIDIOC_DBG_S_REGISTER: { 1201static int saa717x_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
1198 struct v4l2_register *reg = arg; 1202{
1199 u16 addr = reg->reg & 0xffff; 1203 struct v4l2_pix_format *pix;
1200 u8 val = reg->val & 0xff; 1204 int prescale, h_scale, v_scale;
1201 1205
1202 if (!v4l2_chip_match_i2c_client(client, reg->match_type, reg->match_chip)) 1206 pix = &fmt->fmt.pix;
1203 return -EINVAL; 1207 v4l2_dbg(1, debug, sd, "decoder set size\n");
1204 if (!capable(CAP_SYS_ADMIN))
1205 return -EPERM;
1206 saa717x_write(client, addr, val);
1207 break;
1208 }
1209#endif
1210 1208
1211 case VIDIOC_S_FMT: { 1209 /* FIXME need better bounds checking here */
1212 struct v4l2_format *fmt = (struct v4l2_format *)arg; 1210 if (pix->width < 1 || pix->width > 1440)
1213 struct v4l2_pix_format *pix; 1211 return -EINVAL;
1214 int prescale, h_scale, v_scale; 1212 if (pix->height < 1 || pix->height > 960)
1215 1213 return -EINVAL;
1216 pix = &fmt->fmt.pix;
1217 v4l_dbg(1, debug, client, "decoder set size\n");
1218
1219 /* FIXME need better bounds checking here */
1220 if (pix->width < 1 || pix->width > 1440)
1221 return -EINVAL;
1222 if (pix->height < 1 || pix->height > 960)
1223 return -EINVAL;
1224
1225 /* scaling setting */
1226 /* NTSC and interlace only */
1227 prescale = SAA717X_NTSC_WIDTH / pix->width;
1228 if (prescale == 0)
1229 prescale = 1;
1230 h_scale = 1024 * SAA717X_NTSC_WIDTH / prescale / pix->width;
1231 /* interlace */
1232 v_scale = 512 * 2 * SAA717X_NTSC_HEIGHT / pix->height;
1233
1234 /* Horizontal prescaling etc */
1235 set_h_prescale(client, 0, prescale);
1236 set_h_prescale(client, 1, prescale);
1237
1238 /* Horizontal scaling increment */
1239 /* TASK A */
1240 saa717x_write(client, 0x6C, (u8)(h_scale & 0xFF));
1241 saa717x_write(client, 0x6D, (u8)((h_scale >> 8) & 0xFF));
1242 /* TASK B */
1243 saa717x_write(client, 0xAC, (u8)(h_scale & 0xFF));
1244 saa717x_write(client, 0xAD, (u8)((h_scale >> 8) & 0xFF));
1245
1246 /* Vertical prescaling etc */
1247 set_v_scale(client, 0, v_scale);
1248 set_v_scale(client, 1, v_scale);
1249
1250 /* set video output size */
1251 /* video number of pixels at output */
1252 /* TASK A */
1253 saa717x_write(client, 0x5C, (u8)(pix->width & 0xFF));
1254 saa717x_write(client, 0x5D, (u8)((pix->width >> 8) & 0xFF));
1255 /* TASK B */
1256 saa717x_write(client, 0x9C, (u8)(pix->width & 0xFF));
1257 saa717x_write(client, 0x9D, (u8)((pix->width >> 8) & 0xFF));
1258
1259 /* video number of lines at output */
1260 /* TASK A */
1261 saa717x_write(client, 0x5E, (u8)(pix->height & 0xFF));
1262 saa717x_write(client, 0x5F, (u8)((pix->height >> 8) & 0xFF));
1263 /* TASK B */
1264 saa717x_write(client, 0x9E, (u8)(pix->height & 0xFF));
1265 saa717x_write(client, 0x9F, (u8)((pix->height >> 8) & 0xFF));
1266 break;
1267 }
1268 1214
1269 case AUDC_SET_RADIO: 1215 /* scaling setting */
1270 decoder->radio = 1; 1216 /* NTSC and interlace only */
1271 break; 1217 prescale = SAA717X_NTSC_WIDTH / pix->width;
1218 if (prescale == 0)
1219 prescale = 1;
1220 h_scale = 1024 * SAA717X_NTSC_WIDTH / prescale / pix->width;
1221 /* interlace */
1222 v_scale = 512 * 2 * SAA717X_NTSC_HEIGHT / pix->height;
1223
1224 /* Horizontal prescaling etc */
1225 set_h_prescale(sd, 0, prescale);
1226 set_h_prescale(sd, 1, prescale);
1227
1228 /* Horizontal scaling increment */
1229 /* TASK A */
1230 saa717x_write(sd, 0x6C, (u8)(h_scale & 0xFF));
1231 saa717x_write(sd, 0x6D, (u8)((h_scale >> 8) & 0xFF));
1232 /* TASK B */
1233 saa717x_write(sd, 0xAC, (u8)(h_scale & 0xFF));
1234 saa717x_write(sd, 0xAD, (u8)((h_scale >> 8) & 0xFF));
1235
1236 /* Vertical prescaling etc */
1237 set_v_scale(sd, 0, v_scale);
1238 set_v_scale(sd, 1, v_scale);
1239
1240 /* set video output size */
1241 /* video number of pixels at output */
1242 /* TASK A */
1243 saa717x_write(sd, 0x5C, (u8)(pix->width & 0xFF));
1244 saa717x_write(sd, 0x5D, (u8)((pix->width >> 8) & 0xFF));
1245 /* TASK B */
1246 saa717x_write(sd, 0x9C, (u8)(pix->width & 0xFF));
1247 saa717x_write(sd, 0x9D, (u8)((pix->width >> 8) & 0xFF));
1248
1249 /* video number of lines at output */
1250 /* TASK A */
1251 saa717x_write(sd, 0x5E, (u8)(pix->height & 0xFF));
1252 saa717x_write(sd, 0x5F, (u8)((pix->height >> 8) & 0xFF));
1253 /* TASK B */
1254 saa717x_write(sd, 0x9E, (u8)(pix->height & 0xFF));
1255 saa717x_write(sd, 0x9F, (u8)((pix->height >> 8) & 0xFF));
1256 return 0;
1257}
1272 1258
1273 case VIDIOC_S_STD: { 1259static int saa717x_s_radio(struct v4l2_subdev *sd)
1274 v4l2_std_id std = *(v4l2_std_id *) arg; 1260{
1261 struct saa717x_state *decoder = to_state(sd);
1275 1262
1276 v4l_dbg(1, debug, client, "decoder set norm "); 1263 decoder->radio = 1;
1277 v4l_dbg(1, debug, client, "(not yet implementd)\n"); 1264 return 0;
1265}
1278 1266
1279 decoder->radio = 0; 1267static int saa717x_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
1280 decoder->std = std; 1268{
1281 break; 1269 struct saa717x_state *decoder = to_state(sd);
1282 }
1283 1270
1284 case VIDIOC_INT_G_AUDIO_ROUTING: { 1271 v4l2_dbg(1, debug, sd, "decoder set norm ");
1285 struct v4l2_routing *route = arg; 1272 v4l2_dbg(1, debug, sd, "(not yet implementd)\n");
1286 1273
1287 route->input = decoder->audio_input; 1274 decoder->radio = 0;
1288 route->output = 0; 1275 decoder->std = std;
1289 break; 1276 return 0;
1290 } 1277}
1291 1278
1292 case VIDIOC_INT_S_AUDIO_ROUTING: { 1279static int saa717x_s_audio_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
1293 struct v4l2_routing *route = arg; 1280{
1281 struct saa717x_state *decoder = to_state(sd);
1294 1282
1295 if (route->input < 3) { /* FIXME! --tadachi */ 1283 if (route->input < 3) { /* FIXME! --tadachi */
1296 decoder->audio_input = route->input; 1284 decoder->audio_input = route->input;
1297 v4l_dbg(1, debug, client, 1285 v4l2_dbg(1, debug, sd,
1298 "set decoder audio input to %d\n", 1286 "set decoder audio input to %d\n",
1299 decoder->audio_input); 1287 decoder->audio_input);
1300 set_audio_regs(client, decoder); 1288 set_audio_regs(sd, decoder);
1301 break; 1289 return 0;
1302 }
1303 return -ERANGE;
1304 }
1305
1306 case VIDIOC_INT_S_VIDEO_ROUTING: {
1307 struct v4l2_routing *route = arg;
1308 int inp = route->input;
1309
1310 return saa717x_set_video_input(client, decoder, inp);
1311 } 1290 }
1291 return -ERANGE;
1292}
1312 1293
1313 case VIDIOC_STREAMON: { 1294static int saa717x_s_stream(struct v4l2_subdev *sd, int enable)
1314 v4l_dbg(1, debug, client, "decoder enable output\n"); 1295{
1315 decoder->enable = 1; 1296 struct saa717x_state *decoder = to_state(sd);
1316 saa717x_write(client, 0x193, 0xa6);
1317 break;
1318 }
1319 1297
1320 case VIDIOC_STREAMOFF: { 1298 v4l2_dbg(1, debug, sd, "decoder %s output\n",
1321 v4l_dbg(1, debug, client, "decoder disable output\n"); 1299 enable ? "enable" : "disable");
1322 decoder->enable = 0; 1300 decoder->enable = enable;
1323 saa717x_write(client, 0x193, 0x26); /* right? FIXME!--tadachi */ 1301 saa717x_write(sd, 0x193, enable ? 0xa6 : 0x26);
1324 break; 1302 return 0;
1325 } 1303}
1326 1304
1327 /* change audio mode */ 1305/* change audio mode */
1328 case VIDIOC_S_TUNER: { 1306static int saa717x_s_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
1329 struct v4l2_tuner *vt = (struct v4l2_tuner *)arg; 1307{
1330 int audio_mode; 1308 struct saa717x_state *decoder = to_state(sd);
1331 char *mes[4] = { 1309 int audio_mode;
1332 "MONO", "STEREO", "LANG1", "LANG2/SAP" 1310 char *mes[4] = {
1333 }; 1311 "MONO", "STEREO", "LANG1", "LANG2/SAP"
1312 };
1334 1313
1335 audio_mode = V4L2_TUNER_MODE_STEREO; 1314 audio_mode = V4L2_TUNER_MODE_STEREO;
1336 1315
1337 switch (vt->audmode) { 1316 switch (vt->audmode) {
1338 case V4L2_TUNER_MODE_MONO: 1317 case V4L2_TUNER_MODE_MONO:
1339 audio_mode = TUNER_AUDIO_MONO; 1318 audio_mode = TUNER_AUDIO_MONO;
1340 break; 1319 break;
@@ -1347,70 +1326,101 @@ static int saa717x_command(struct i2c_client *client, unsigned cmd, void *arg)
1347 case V4L2_TUNER_MODE_LANG1: 1326 case V4L2_TUNER_MODE_LANG1:
1348 audio_mode = TUNER_AUDIO_LANG1; 1327 audio_mode = TUNER_AUDIO_LANG1;
1349 break; 1328 break;
1350 }
1351
1352 v4l_dbg(1, debug, client, "change audio mode to %s\n",
1353 mes[audio_mode]);
1354 decoder->tuner_audio_mode = audio_mode;
1355 /* The registers are not changed here. */
1356 /* See DECODER_ENABLE_OUTPUT section. */
1357 set_audio_mode(client, decoder->tuner_audio_mode);
1358 break;
1359 } 1329 }
1360 1330
1361 case VIDIOC_G_TUNER: { 1331 v4l2_dbg(1, debug, sd, "change audio mode to %s\n",
1362 struct v4l2_tuner *vt = (struct v4l2_tuner *)arg; 1332 mes[audio_mode]);
1363 int dual_f, stereo_f; 1333 decoder->tuner_audio_mode = audio_mode;
1334 /* The registers are not changed here. */
1335 /* See DECODER_ENABLE_OUTPUT section. */
1336 set_audio_mode(sd, decoder->tuner_audio_mode);
1337 return 0;
1338}
1364 1339
1365 if (decoder->radio) 1340static int saa717x_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
1366 break; 1341{
1367 get_inf_dev_status(client, &dual_f, &stereo_f); 1342 struct saa717x_state *decoder = to_state(sd);
1343 int dual_f, stereo_f;
1368 1344
1369 v4l_dbg(1, debug, client, "DETECT==st:%d dual:%d\n", 1345 if (decoder->radio)
1370 stereo_f, dual_f); 1346 return 0;
1347 get_inf_dev_status(sd, &dual_f, &stereo_f);
1371 1348
1372 /* mono */ 1349 v4l2_dbg(1, debug, sd, "DETECT==st:%d dual:%d\n",
1373 if ((dual_f == 0) && (stereo_f == 0)) { 1350 stereo_f, dual_f);
1374 vt->rxsubchans = V4L2_TUNER_SUB_MONO;
1375 v4l_dbg(1, debug, client, "DETECT==MONO\n");
1376 }
1377 1351
1378 /* stereo */ 1352 /* mono */
1379 if (stereo_f == 1) { 1353 if ((dual_f == 0) && (stereo_f == 0)) {
1380 if (vt->audmode == V4L2_TUNER_MODE_STEREO || 1354 vt->rxsubchans = V4L2_TUNER_SUB_MONO;
1381 vt->audmode == V4L2_TUNER_MODE_LANG1) { 1355 v4l2_dbg(1, debug, sd, "DETECT==MONO\n");
1382 vt->rxsubchans = V4L2_TUNER_SUB_STEREO; 1356 }
1383 v4l_dbg(1, debug, client, "DETECT==ST(ST)\n");
1384 } else {
1385 vt->rxsubchans = V4L2_TUNER_SUB_MONO;
1386 v4l_dbg(1, debug, client, "DETECT==ST(MONO)\n");
1387 }
1388 }
1389 1357
1390 /* dual */ 1358 /* stereo */
1391 if (dual_f == 1) { 1359 if (stereo_f == 1) {
1392 if (vt->audmode == V4L2_TUNER_MODE_LANG2) { 1360 if (vt->audmode == V4L2_TUNER_MODE_STEREO ||
1393 vt->rxsubchans = V4L2_TUNER_SUB_LANG2 | V4L2_TUNER_SUB_MONO; 1361 vt->audmode == V4L2_TUNER_MODE_LANG1) {
1394 v4l_dbg(1, debug, client, "DETECT==DUAL1\n"); 1362 vt->rxsubchans = V4L2_TUNER_SUB_STEREO;
1395 } else { 1363 v4l2_dbg(1, debug, sd, "DETECT==ST(ST)\n");
1396 vt->rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_MONO; 1364 } else {
1397 v4l_dbg(1, debug, client, "DETECT==DUAL2\n"); 1365 vt->rxsubchans = V4L2_TUNER_SUB_MONO;
1398 } 1366 v4l2_dbg(1, debug, sd, "DETECT==ST(MONO)\n");
1399 } 1367 }
1400 break;
1401 } 1368 }
1402 1369
1403 case VIDIOC_LOG_STATUS: 1370 /* dual */
1404 /* not yet implemented */ 1371 if (dual_f == 1) {
1405 break; 1372 if (vt->audmode == V4L2_TUNER_MODE_LANG2) {
1406 1373 vt->rxsubchans = V4L2_TUNER_SUB_LANG2 | V4L2_TUNER_SUB_MONO;
1407 default: 1374 v4l2_dbg(1, debug, sd, "DETECT==DUAL1\n");
1408 return -EINVAL; 1375 } else {
1376 vt->rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_MONO;
1377 v4l2_dbg(1, debug, sd, "DETECT==DUAL2\n");
1378 }
1409 } 1379 }
1410
1411 return 0; 1380 return 0;
1412} 1381}
1413 1382
1383static int saa717x_command(struct i2c_client *client, unsigned cmd, void *arg)
1384{
1385 return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
1386}
1387
1388/* ----------------------------------------------------------------------- */
1389
1390static const struct v4l2_subdev_core_ops saa717x_core_ops = {
1391#ifdef CONFIG_VIDEO_ADV_DEBUG
1392 .g_register = saa717x_g_register,
1393 .s_register = saa717x_s_register,
1394#endif
1395 .queryctrl = saa717x_queryctrl,
1396 .g_ctrl = saa717x_g_ctrl,
1397 .s_ctrl = saa717x_s_ctrl,
1398};
1399
1400static const struct v4l2_subdev_tuner_ops saa717x_tuner_ops = {
1401 .g_tuner = saa717x_g_tuner,
1402 .s_tuner = saa717x_s_tuner,
1403 .s_std = saa717x_s_std,
1404 .s_radio = saa717x_s_radio,
1405};
1406
1407static const struct v4l2_subdev_video_ops saa717x_video_ops = {
1408 .s_routing = saa717x_s_video_routing,
1409 .s_fmt = saa717x_s_fmt,
1410 .s_stream = saa717x_s_stream,
1411};
1412
1413static const struct v4l2_subdev_audio_ops saa717x_audio_ops = {
1414 .s_routing = saa717x_s_audio_routing,
1415};
1416
1417static const struct v4l2_subdev_ops saa717x_ops = {
1418 .core = &saa717x_core_ops,
1419 .tuner = &saa717x_tuner_ops,
1420 .audio = &saa717x_audio_ops,
1421 .video = &saa717x_video_ops,
1422};
1423
1414/* ----------------------------------------------------------------------- */ 1424/* ----------------------------------------------------------------------- */
1415 1425
1416 1426
@@ -1421,6 +1431,7 @@ static int saa717x_probe(struct i2c_client *client,
1421 const struct i2c_device_id *did) 1431 const struct i2c_device_id *did)
1422{ 1432{
1423 struct saa717x_state *decoder; 1433 struct saa717x_state *decoder;
1434 struct v4l2_subdev *sd;
1424 u8 id = 0; 1435 u8 id = 0;
1425 char *p = ""; 1436 char *p = "";
1426 1437
@@ -1428,13 +1439,21 @@ static int saa717x_probe(struct i2c_client *client,
1428 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) 1439 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
1429 return -EIO; 1440 return -EIO;
1430 1441
1431 if (saa717x_write(client, 0x5a4, 0xfe) && 1442 decoder = kzalloc(sizeof(struct saa717x_state), GFP_KERNEL);
1432 saa717x_write(client, 0x5a5, 0x0f) && 1443 if (decoder == NULL)
1433 saa717x_write(client, 0x5a6, 0x00) && 1444 return -ENOMEM;
1434 saa717x_write(client, 0x5a7, 0x01)) 1445
1435 id = saa717x_read(client, 0x5a0); 1446 sd = &decoder->sd;
1447 v4l2_i2c_subdev_init(sd, client, &saa717x_ops);
1448
1449 if (saa717x_write(sd, 0x5a4, 0xfe) &&
1450 saa717x_write(sd, 0x5a5, 0x0f) &&
1451 saa717x_write(sd, 0x5a6, 0x00) &&
1452 saa717x_write(sd, 0x5a7, 0x01))
1453 id = saa717x_read(sd, 0x5a0);
1436 if (id != 0xc2 && id != 0x32 && id != 0xf2 && id != 0x6c) { 1454 if (id != 0xc2 && id != 0x32 && id != 0xf2 && id != 0x6c) {
1437 v4l_dbg(1, debug, client, "saa717x not found (id=%02x)\n", id); 1455 v4l2_dbg(1, debug, sd, "saa717x not found (id=%02x)\n", id);
1456 kfree(decoder);
1438 return -ENODEV; 1457 return -ENODEV;
1439 } 1458 }
1440 if (id == 0xc2) 1459 if (id == 0xc2)
@@ -1445,14 +1464,8 @@ static int saa717x_probe(struct i2c_client *client,
1445 p = "saa7174HL"; 1464 p = "saa7174HL";
1446 else 1465 else
1447 p = "saa7171"; 1466 p = "saa7171";
1448 v4l_info(client, "%s found @ 0x%x (%s)\n", p, 1467 v4l2_info(sd, "%s found @ 0x%x (%s)\n", p,
1449 client->addr << 1, client->adapter->name); 1468 client->addr << 1, client->adapter->name);
1450
1451 decoder = kzalloc(sizeof(struct saa717x_state), GFP_KERNEL);
1452 i2c_set_clientdata(client, decoder);
1453
1454 if (decoder == NULL)
1455 return -ENOMEM;
1456 decoder->std = V4L2_STD_NTSC; 1469 decoder->std = V4L2_STD_NTSC;
1457 decoder->input = -1; 1470 decoder->input = -1;
1458 decoder->enable = 1; 1471 decoder->enable = 1;
@@ -1481,15 +1494,15 @@ static int saa717x_probe(struct i2c_client *client,
1481 decoder->audio_main_volume = 1494 decoder->audio_main_volume =
1482 (decoder->audio_main_vol_r + 41) * 65535 / (24 - (-40)); 1495 (decoder->audio_main_vol_r + 41) * 65535 / (24 - (-40));
1483 1496
1484 v4l_dbg(1, debug, client, "writing init values\n"); 1497 v4l2_dbg(1, debug, sd, "writing init values\n");
1485 1498
1486 /* FIXME!! */ 1499 /* FIXME!! */
1487 saa717x_write_regs(client, reg_init_initialize); 1500 saa717x_write_regs(sd, reg_init_initialize);
1488 set_video_output_level_regs(client, decoder); 1501 set_video_output_level_regs(sd, decoder);
1489 /* set bass,treble to 0db 20041101 K.Ohta */ 1502 /* set bass,treble to 0db 20041101 K.Ohta */
1490 decoder->audio_main_bass = 0; 1503 decoder->audio_main_bass = 0;
1491 decoder->audio_main_treble = 0; 1504 decoder->audio_main_treble = 0;
1492 set_audio_regs(client, decoder); 1505 set_audio_regs(sd, decoder);
1493 1506
1494 set_current_state(TASK_INTERRUPTIBLE); 1507 set_current_state(TASK_INTERRUPTIBLE);
1495 schedule_timeout(2*HZ); 1508 schedule_timeout(2*HZ);
@@ -1498,7 +1511,10 @@ static int saa717x_probe(struct i2c_client *client,
1498 1511
1499static int saa717x_remove(struct i2c_client *client) 1512static int saa717x_remove(struct i2c_client *client)
1500{ 1513{
1501 kfree(i2c_get_clientdata(client)); 1514 struct v4l2_subdev *sd = i2c_get_clientdata(client);
1515
1516 v4l2_device_unregister_subdev(sd);
1517 kfree(to_state(sd));
1502 return 0; 1518 return 0;
1503} 1519}
1504 1520
diff --git a/drivers/media/video/se401.c b/drivers/media/video/se401.c
index 044a2e94c34d..d652f25eef0e 100644
--- a/drivers/media/video/se401.c
+++ b/drivers/media/video/se401.c
@@ -975,8 +975,7 @@ static int se401_close(struct inode *inode, struct file *file)
975 return 0; 975 return 0;
976} 976}
977 977
978static int se401_do_ioctl(struct inode *inode, struct file *file, 978static int se401_do_ioctl(struct file *file, unsigned int cmd, void *arg)
979 unsigned int cmd, void *arg)
980{ 979{
981 struct video_device *vdev = file->private_data; 980 struct video_device *vdev = file->private_data;
982 struct usb_se401 *se401 = (struct usb_se401 *)vdev; 981 struct usb_se401 *se401 = (struct usb_se401 *)vdev;
@@ -1142,7 +1141,7 @@ static int se401_do_ioctl(struct inode *inode, struct file *file,
1142static int se401_ioctl(struct inode *inode, struct file *file, 1141static int se401_ioctl(struct inode *inode, struct file *file,
1143 unsigned int cmd, unsigned long arg) 1142 unsigned int cmd, unsigned long arg)
1144{ 1143{
1145 return video_usercopy(inode, file, cmd, arg, se401_do_ioctl); 1144 return video_usercopy(file, cmd, arg, se401_do_ioctl);
1146} 1145}
1147 1146
1148static ssize_t se401_read(struct file *file, char __user *buf, 1147static ssize_t se401_read(struct file *file, char __user *buf,
diff --git a/drivers/media/video/sh_mobile_ceu_camera.c b/drivers/media/video/sh_mobile_ceu_camera.c
index 536b1a9b310c..9a2586b07a05 100644
--- a/drivers/media/video/sh_mobile_ceu_camera.c
+++ b/drivers/media/video/sh_mobile_ceu_camera.c
@@ -29,7 +29,6 @@
29#include <linux/version.h> 29#include <linux/version.h>
30#include <linux/device.h> 30#include <linux/device.h>
31#include <linux/platform_device.h> 31#include <linux/platform_device.h>
32#include <linux/mutex.h>
33#include <linux/videodev2.h> 32#include <linux/videodev2.h>
34#include <linux/clk.h> 33#include <linux/clk.h>
35 34
@@ -75,8 +74,6 @@
75#define CDBYR2 0x98 /* Capture data bottom-field address Y register 2 */ 74#define CDBYR2 0x98 /* Capture data bottom-field address Y register 2 */
76#define CDBCR2 0x9c /* Capture data bottom-field address C register 2 */ 75#define CDBCR2 0x9c /* Capture data bottom-field address C register 2 */
77 76
78static DEFINE_MUTEX(camera_lock);
79
80/* per video frame buffer */ 77/* per video frame buffer */
81struct sh_mobile_ceu_buffer { 78struct sh_mobile_ceu_buffer {
82 struct videobuf_buffer vb; /* v4l buffer must be first */ 79 struct videobuf_buffer vb; /* v4l buffer must be first */
@@ -97,18 +94,20 @@ struct sh_mobile_ceu_dev {
97 spinlock_t lock; 94 spinlock_t lock;
98 struct list_head capture; 95 struct list_head capture;
99 struct videobuf_buffer *active; 96 struct videobuf_buffer *active;
97 int is_interlace;
100 98
101 struct sh_mobile_ceu_info *pdata; 99 struct sh_mobile_ceu_info *pdata;
100
101 const struct soc_camera_data_format *camera_fmt;
102}; 102};
103 103
104static void ceu_write(struct sh_mobile_ceu_dev *priv, 104static void ceu_write(struct sh_mobile_ceu_dev *priv,
105 unsigned long reg_offs, unsigned long data) 105 unsigned long reg_offs, u32 data)
106{ 106{
107 iowrite32(data, priv->base + reg_offs); 107 iowrite32(data, priv->base + reg_offs);
108} 108}
109 109
110static unsigned long ceu_read(struct sh_mobile_ceu_dev *priv, 110static u32 ceu_read(struct sh_mobile_ceu_dev *priv, unsigned long reg_offs)
111 unsigned long reg_offs)
112{ 111{
113 return ioread32(priv->base + reg_offs); 112 return ioread32(priv->base + reg_offs);
114} 113}
@@ -156,21 +155,52 @@ static void free_buffer(struct videobuf_queue *vq,
156 buf->vb.state = VIDEOBUF_NEEDS_INIT; 155 buf->vb.state = VIDEOBUF_NEEDS_INIT;
157} 156}
158 157
158#define CEU_CETCR_MAGIC 0x0317f313 /* acknowledge magical interrupt sources */
159#define CEU_CETCR_IGRW (1 << 4) /* prohibited register access interrupt bit */
160#define CEU_CEIER_CPEIE (1 << 0) /* one-frame capture end interrupt */
161#define CEU_CAPCR_CTNCP (1 << 16) /* continuous capture mode (if set) */
162
163
159static void sh_mobile_ceu_capture(struct sh_mobile_ceu_dev *pcdev) 164static void sh_mobile_ceu_capture(struct sh_mobile_ceu_dev *pcdev)
160{ 165{
161 ceu_write(pcdev, CEIER, ceu_read(pcdev, CEIER) & ~1); 166 struct soc_camera_device *icd = pcdev->icd;
162 ceu_write(pcdev, CETCR, ~ceu_read(pcdev, CETCR) & 0x0317f313); 167 dma_addr_t phys_addr_top, phys_addr_bottom;
163 ceu_write(pcdev, CEIER, ceu_read(pcdev, CEIER) | 1);
164
165 ceu_write(pcdev, CAPCR, ceu_read(pcdev, CAPCR) & ~0x10000);
166 168
167 ceu_write(pcdev, CETCR, 0x0317f313 ^ 0x10); 169 /* The hardware is _very_ picky about this sequence. Especially
170 * the CEU_CETCR_MAGIC value. It seems like we need to acknowledge
171 * several not-so-well documented interrupt sources in CETCR.
172 */
173 ceu_write(pcdev, CEIER, ceu_read(pcdev, CEIER) & ~CEU_CEIER_CPEIE);
174 ceu_write(pcdev, CETCR, ~ceu_read(pcdev, CETCR) & CEU_CETCR_MAGIC);
175 ceu_write(pcdev, CEIER, ceu_read(pcdev, CEIER) | CEU_CEIER_CPEIE);
176 ceu_write(pcdev, CAPCR, ceu_read(pcdev, CAPCR) & ~CEU_CAPCR_CTNCP);
177 ceu_write(pcdev, CETCR, CEU_CETCR_MAGIC ^ CEU_CETCR_IGRW);
178
179 if (!pcdev->active)
180 return;
181
182 phys_addr_top = videobuf_to_dma_contig(pcdev->active);
183 ceu_write(pcdev, CDAYR, phys_addr_top);
184 if (pcdev->is_interlace) {
185 phys_addr_bottom = phys_addr_top + icd->width;
186 ceu_write(pcdev, CDBYR, phys_addr_bottom);
187 }
168 188
169 if (pcdev->active) { 189 switch (icd->current_fmt->fourcc) {
170 pcdev->active->state = VIDEOBUF_ACTIVE; 190 case V4L2_PIX_FMT_NV12:
171 ceu_write(pcdev, CDAYR, videobuf_to_dma_contig(pcdev->active)); 191 case V4L2_PIX_FMT_NV21:
172 ceu_write(pcdev, CAPSR, 0x1); /* start capture */ 192 case V4L2_PIX_FMT_NV16:
193 case V4L2_PIX_FMT_NV61:
194 phys_addr_top += icd->width * icd->height;
195 ceu_write(pcdev, CDACR, phys_addr_top);
196 if (pcdev->is_interlace) {
197 phys_addr_bottom = phys_addr_top + icd->width;
198 ceu_write(pcdev, CDBCR, phys_addr_bottom);
199 }
173 } 200 }
201
202 pcdev->active->state = VIDEOBUF_ACTIVE;
203 ceu_write(pcdev, CAPSR, 0x1); /* start capture */
174} 204}
175 205
176static int sh_mobile_ceu_videobuf_prepare(struct videobuf_queue *vq, 206static int sh_mobile_ceu_videobuf_prepare(struct videobuf_queue *vq,
@@ -292,14 +322,13 @@ static irqreturn_t sh_mobile_ceu_irq(int irq, void *data)
292 return IRQ_HANDLED; 322 return IRQ_HANDLED;
293} 323}
294 324
325/* Called with .video_lock held */
295static int sh_mobile_ceu_add_device(struct soc_camera_device *icd) 326static int sh_mobile_ceu_add_device(struct soc_camera_device *icd)
296{ 327{
297 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 328 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
298 struct sh_mobile_ceu_dev *pcdev = ici->priv; 329 struct sh_mobile_ceu_dev *pcdev = ici->priv;
299 int ret = -EBUSY; 330 int ret = -EBUSY;
300 331
301 mutex_lock(&camera_lock);
302
303 if (pcdev->icd) 332 if (pcdev->icd)
304 goto err; 333 goto err;
305 334
@@ -319,11 +348,10 @@ static int sh_mobile_ceu_add_device(struct soc_camera_device *icd)
319 348
320 pcdev->icd = icd; 349 pcdev->icd = icd;
321err: 350err:
322 mutex_unlock(&camera_lock);
323
324 return ret; 351 return ret;
325} 352}
326 353
354/* Called with .video_lock held */
327static void sh_mobile_ceu_remove_device(struct soc_camera_device *icd) 355static void sh_mobile_ceu_remove_device(struct soc_camera_device *icd)
328{ 356{
329 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 357 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
@@ -362,8 +390,9 @@ static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd,
362{ 390{
363 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 391 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
364 struct sh_mobile_ceu_dev *pcdev = ici->priv; 392 struct sh_mobile_ceu_dev *pcdev = ici->priv;
365 int ret, buswidth, width, cfszr_width, cdwdr_width; 393 int ret, buswidth, width, height, cfszr_width, cdwdr_width;
366 unsigned long camera_flags, common_flags, value; 394 unsigned long camera_flags, common_flags, value;
395 int yuv_mode, yuv_lineskip;
367 396
368 camera_flags = icd->ops->query_bus_param(icd); 397 camera_flags = icd->ops->query_bus_param(icd);
369 common_flags = soc_camera_bus_param_compatible(camera_flags, 398 common_flags = soc_camera_bus_param_compatible(camera_flags,
@@ -389,27 +418,71 @@ static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd,
389 ceu_write(pcdev, CRCNTR, 0); 418 ceu_write(pcdev, CRCNTR, 0);
390 ceu_write(pcdev, CRCMPR, 0); 419 ceu_write(pcdev, CRCMPR, 0);
391 420
392 value = 0x00000010; 421 value = 0x00000010; /* data fetch by default */
393 value |= (common_flags & SOCAM_VSYNC_ACTIVE_LOW) ? (1 << 1) : 0; 422 yuv_mode = yuv_lineskip = 0;
394 value |= (common_flags & SOCAM_HSYNC_ACTIVE_LOW) ? (1 << 0) : 0; 423
395 value |= (buswidth == 16) ? (1 << 12) : 0; 424 switch (icd->current_fmt->fourcc) {
425 case V4L2_PIX_FMT_NV12:
426 case V4L2_PIX_FMT_NV21:
427 yuv_lineskip = 1; /* skip for NV12/21, no skip for NV16/61 */
428 /* fall-through */
429 case V4L2_PIX_FMT_NV16:
430 case V4L2_PIX_FMT_NV61:
431 yuv_mode = 1;
432 switch (pcdev->camera_fmt->fourcc) {
433 case V4L2_PIX_FMT_UYVY:
434 value = 0x00000000; /* Cb0, Y0, Cr0, Y1 */
435 break;
436 case V4L2_PIX_FMT_VYUY:
437 value = 0x00000100; /* Cr0, Y0, Cb0, Y1 */
438 break;
439 case V4L2_PIX_FMT_YUYV:
440 value = 0x00000200; /* Y0, Cb0, Y1, Cr0 */
441 break;
442 case V4L2_PIX_FMT_YVYU:
443 value = 0x00000300; /* Y0, Cr0, Y1, Cb0 */
444 break;
445 default:
446 BUG();
447 }
448 }
449
450 if (icd->current_fmt->fourcc == V4L2_PIX_FMT_NV21 ||
451 icd->current_fmt->fourcc == V4L2_PIX_FMT_NV61)
452 value ^= 0x00000100; /* swap U, V to change from NV1x->NVx1 */
453
454 value |= common_flags & SOCAM_VSYNC_ACTIVE_LOW ? 1 << 1 : 0;
455 value |= common_flags & SOCAM_HSYNC_ACTIVE_LOW ? 1 << 0 : 0;
456 value |= buswidth == 16 ? 1 << 12 : 0;
396 ceu_write(pcdev, CAMCR, value); 457 ceu_write(pcdev, CAMCR, value);
397 458
398 ceu_write(pcdev, CAPCR, 0x00300000); 459 ceu_write(pcdev, CAPCR, 0x00300000);
399 ceu_write(pcdev, CAIFR, 0); 460 ceu_write(pcdev, CAIFR, (pcdev->is_interlace) ? 0x101 : 0);
400 461
401 mdelay(1); 462 mdelay(1);
402 463
403 width = icd->width * (icd->current_fmt->depth / 8); 464 if (yuv_mode) {
404 width = (buswidth == 16) ? width / 2 : width; 465 width = icd->width * 2;
405 cfszr_width = (buswidth == 8) ? width / 2 : width; 466 width = buswidth == 16 ? width / 2 : width;
406 cdwdr_width = (buswidth == 16) ? width * 2 : width; 467 cfszr_width = cdwdr_width = icd->width;
468 } else {
469 width = icd->width * ((icd->current_fmt->depth + 7) >> 3);
470 width = buswidth == 16 ? width / 2 : width;
471 cfszr_width = buswidth == 8 ? width / 2 : width;
472 cdwdr_width = buswidth == 16 ? width * 2 : width;
473 }
474
475 height = icd->height;
476 if (pcdev->is_interlace) {
477 height /= 2;
478 cdwdr_width *= 2;
479 }
407 480
408 ceu_write(pcdev, CAMOR, 0); 481 ceu_write(pcdev, CAMOR, 0);
409 ceu_write(pcdev, CAPWR, (icd->height << 16) | width); 482 ceu_write(pcdev, CAPWR, (height << 16) | width);
410 ceu_write(pcdev, CFLCR, 0); /* data fetch mode - no scaling */ 483 ceu_write(pcdev, CFLCR, 0); /* no scaling */
411 ceu_write(pcdev, CFSZR, (icd->height << 16) | cfszr_width); 484 ceu_write(pcdev, CFSZR, (height << 16) | cfszr_width);
412 ceu_write(pcdev, CLFCR, 0); /* data fetch mode - no lowpass filter */ 485 ceu_write(pcdev, CLFCR, 0); /* no lowpass filter */
413 486
414 /* A few words about byte order (observed in Big Endian mode) 487 /* A few words about byte order (observed in Big Endian mode)
415 * 488 *
@@ -423,19 +496,20 @@ static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd,
423 * using 7 we swap the data bytes to match the incoming order: 496 * using 7 we swap the data bytes to match the incoming order:
424 * D0, D1, D2, D3, D4, D5, D6, D7 497 * D0, D1, D2, D3, D4, D5, D6, D7
425 */ 498 */
426 ceu_write(pcdev, CDOCR, 0x00000017); 499 value = 0x00000017;
500 if (yuv_lineskip)
501 value &= ~0x00000010; /* convert 4:2:2 -> 4:2:0 */
502
503 ceu_write(pcdev, CDOCR, value);
427 504
428 ceu_write(pcdev, CDWDR, cdwdr_width); 505 ceu_write(pcdev, CDWDR, cdwdr_width);
429 ceu_write(pcdev, CFWCR, 0); /* keep "datafetch firewall" disabled */ 506 ceu_write(pcdev, CFWCR, 0); /* keep "datafetch firewall" disabled */
430 507
431 /* not in bundle mode: skip CBDSR, CDAYR2, CDACR2, CDBYR2, CDBCR2 */ 508 /* not in bundle mode: skip CBDSR, CDAYR2, CDACR2, CDBYR2, CDBCR2 */
432 /* in data fetch mode: no need for CDACR, CDBYR, CDBCR */
433
434 return 0; 509 return 0;
435} 510}
436 511
437static int sh_mobile_ceu_try_bus_param(struct soc_camera_device *icd, 512static int sh_mobile_ceu_try_bus_param(struct soc_camera_device *icd)
438 __u32 pixfmt)
439{ 513{
440 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 514 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
441 struct sh_mobile_ceu_dev *pcdev = ici->priv; 515 struct sh_mobile_ceu_dev *pcdev = ici->priv;
@@ -450,15 +524,123 @@ static int sh_mobile_ceu_try_bus_param(struct soc_camera_device *icd,
450 return 0; 524 return 0;
451} 525}
452 526
453static int sh_mobile_ceu_set_fmt_cap(struct soc_camera_device *icd, 527static const struct soc_camera_data_format sh_mobile_ceu_formats[] = {
454 __u32 pixfmt, struct v4l2_rect *rect) 528 {
529 .name = "NV12",
530 .depth = 12,
531 .fourcc = V4L2_PIX_FMT_NV12,
532 .colorspace = V4L2_COLORSPACE_JPEG,
533 },
534 {
535 .name = "NV21",
536 .depth = 12,
537 .fourcc = V4L2_PIX_FMT_NV21,
538 .colorspace = V4L2_COLORSPACE_JPEG,
539 },
540 {
541 .name = "NV16",
542 .depth = 16,
543 .fourcc = V4L2_PIX_FMT_NV16,
544 .colorspace = V4L2_COLORSPACE_JPEG,
545 },
546 {
547 .name = "NV61",
548 .depth = 16,
549 .fourcc = V4L2_PIX_FMT_NV61,
550 .colorspace = V4L2_COLORSPACE_JPEG,
551 },
552};
553
554static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, int idx,
555 struct soc_camera_format_xlate *xlate)
556{
557 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
558 int ret, k, n;
559 int formats = 0;
560
561 ret = sh_mobile_ceu_try_bus_param(icd);
562 if (ret < 0)
563 return 0;
564
565 switch (icd->formats[idx].fourcc) {
566 case V4L2_PIX_FMT_UYVY:
567 case V4L2_PIX_FMT_VYUY:
568 case V4L2_PIX_FMT_YUYV:
569 case V4L2_PIX_FMT_YVYU:
570 n = ARRAY_SIZE(sh_mobile_ceu_formats);
571 formats += n;
572 for (k = 0; xlate && k < n; k++) {
573 xlate->host_fmt = &sh_mobile_ceu_formats[k];
574 xlate->cam_fmt = icd->formats + idx;
575 xlate->buswidth = icd->formats[idx].depth;
576 xlate++;
577 dev_dbg(&ici->dev, "Providing format %s using %s\n",
578 sh_mobile_ceu_formats[k].name,
579 icd->formats[idx].name);
580 }
581 default:
582 /* Generic pass-through */
583 formats++;
584 if (xlate) {
585 xlate->host_fmt = icd->formats + idx;
586 xlate->cam_fmt = icd->formats + idx;
587 xlate->buswidth = icd->formats[idx].depth;
588 xlate++;
589 dev_dbg(&ici->dev,
590 "Providing format %s in pass-through mode\n",
591 icd->formats[idx].name);
592 }
593 }
594
595 return formats;
596}
597
598static int sh_mobile_ceu_set_fmt(struct soc_camera_device *icd,
599 __u32 pixfmt, struct v4l2_rect *rect)
455{ 600{
456 return icd->ops->set_fmt_cap(icd, pixfmt, rect); 601 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
602 struct sh_mobile_ceu_dev *pcdev = ici->priv;
603 const struct soc_camera_format_xlate *xlate;
604 int ret;
605
606 xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
607 if (!xlate) {
608 dev_warn(&ici->dev, "Format %x not found\n", pixfmt);
609 return -EINVAL;
610 }
611
612 switch (pixfmt) {
613 case 0: /* Only geometry change */
614 ret = icd->ops->set_fmt(icd, pixfmt, rect);
615 break;
616 default:
617 ret = icd->ops->set_fmt(icd, xlate->cam_fmt->fourcc, rect);
618 }
619
620 if (pixfmt && !ret) {
621 icd->buswidth = xlate->buswidth;
622 icd->current_fmt = xlate->host_fmt;
623 pcdev->camera_fmt = xlate->cam_fmt;
624 }
625
626 return ret;
457} 627}
458 628
459static int sh_mobile_ceu_try_fmt_cap(struct soc_camera_device *icd, 629static int sh_mobile_ceu_try_fmt(struct soc_camera_device *icd,
460 struct v4l2_format *f) 630 struct v4l2_format *f)
461{ 631{
632 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
633 struct sh_mobile_ceu_dev *pcdev = ici->priv;
634 const struct soc_camera_format_xlate *xlate;
635 __u32 pixfmt = f->fmt.pix.pixelformat;
636 int ret;
637
638 xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
639 if (!xlate) {
640 dev_warn(&ici->dev, "Format %x not found\n", pixfmt);
641 return -EINVAL;
642 }
643
462 /* FIXME: calculate using depth and bus width */ 644 /* FIXME: calculate using depth and bus width */
463 645
464 if (f->fmt.pix.height < 4) 646 if (f->fmt.pix.height < 4)
@@ -472,8 +654,31 @@ static int sh_mobile_ceu_try_fmt_cap(struct soc_camera_device *icd,
472 f->fmt.pix.width &= ~0x01; 654 f->fmt.pix.width &= ~0x01;
473 f->fmt.pix.height &= ~0x03; 655 f->fmt.pix.height &= ~0x03;
474 656
657 f->fmt.pix.bytesperline = f->fmt.pix.width *
658 DIV_ROUND_UP(xlate->host_fmt->depth, 8);
659 f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
660
475 /* limit to sensor capabilities */ 661 /* limit to sensor capabilities */
476 return icd->ops->try_fmt_cap(icd, f); 662 ret = icd->ops->try_fmt(icd, f);
663 if (ret < 0)
664 return ret;
665
666 switch (f->fmt.pix.field) {
667 case V4L2_FIELD_INTERLACED:
668 pcdev->is_interlace = 1;
669 break;
670 case V4L2_FIELD_ANY:
671 f->fmt.pix.field = V4L2_FIELD_NONE;
672 /* fall-through */
673 case V4L2_FIELD_NONE:
674 pcdev->is_interlace = 0;
675 break;
676 default:
677 ret = -EINVAL;
678 break;
679 }
680
681 return ret;
477} 682}
478 683
479static int sh_mobile_ceu_reqbufs(struct soc_camera_file *icf, 684static int sh_mobile_ceu_reqbufs(struct soc_camera_file *icf,
@@ -532,7 +737,7 @@ static void sh_mobile_ceu_init_videobuf(struct videobuf_queue *q,
532 &sh_mobile_ceu_videobuf_ops, 737 &sh_mobile_ceu_videobuf_ops,
533 &ici->dev, &pcdev->lock, 738 &ici->dev, &pcdev->lock,
534 V4L2_BUF_TYPE_VIDEO_CAPTURE, 739 V4L2_BUF_TYPE_VIDEO_CAPTURE,
535 V4L2_FIELD_NONE, 740 V4L2_FIELD_ANY,
536 sizeof(struct sh_mobile_ceu_buffer), 741 sizeof(struct sh_mobile_ceu_buffer),
537 icd); 742 icd);
538} 743}
@@ -541,12 +746,12 @@ static struct soc_camera_host_ops sh_mobile_ceu_host_ops = {
541 .owner = THIS_MODULE, 746 .owner = THIS_MODULE,
542 .add = sh_mobile_ceu_add_device, 747 .add = sh_mobile_ceu_add_device,
543 .remove = sh_mobile_ceu_remove_device, 748 .remove = sh_mobile_ceu_remove_device,
544 .set_fmt_cap = sh_mobile_ceu_set_fmt_cap, 749 .get_formats = sh_mobile_ceu_get_formats,
545 .try_fmt_cap = sh_mobile_ceu_try_fmt_cap, 750 .set_fmt = sh_mobile_ceu_set_fmt,
751 .try_fmt = sh_mobile_ceu_try_fmt,
546 .reqbufs = sh_mobile_ceu_reqbufs, 752 .reqbufs = sh_mobile_ceu_reqbufs,
547 .poll = sh_mobile_ceu_poll, 753 .poll = sh_mobile_ceu_poll,
548 .querycap = sh_mobile_ceu_querycap, 754 .querycap = sh_mobile_ceu_querycap,
549 .try_bus_param = sh_mobile_ceu_try_bus_param,
550 .set_bus_param = sh_mobile_ceu_set_bus_param, 755 .set_bus_param = sh_mobile_ceu_set_bus_param,
551 .init_videobuf = sh_mobile_ceu_init_videobuf, 756 .init_videobuf = sh_mobile_ceu_init_videobuf,
552}; 757};
@@ -616,7 +821,7 @@ static int sh_mobile_ceu_probe(struct platform_device *pdev)
616 821
617 /* request irq */ 822 /* request irq */
618 err = request_irq(pcdev->irq, sh_mobile_ceu_irq, IRQF_DISABLED, 823 err = request_irq(pcdev->irq, sh_mobile_ceu_irq, IRQF_DISABLED,
619 pdev->dev.bus_id, pcdev); 824 dev_name(&pdev->dev), pcdev);
620 if (err) { 825 if (err) {
621 dev_err(&pdev->dev, "Unable to register CEU interrupt.\n"); 826 dev_err(&pdev->dev, "Unable to register CEU interrupt.\n");
622 goto exit_release_mem; 827 goto exit_release_mem;
@@ -633,8 +838,8 @@ static int sh_mobile_ceu_probe(struct platform_device *pdev)
633 pcdev->ici.priv = pcdev; 838 pcdev->ici.priv = pcdev;
634 pcdev->ici.dev.parent = &pdev->dev; 839 pcdev->ici.dev.parent = &pdev->dev;
635 pcdev->ici.nr = pdev->id; 840 pcdev->ici.nr = pdev->id;
636 pcdev->ici.drv_name = pdev->dev.bus_id, 841 pcdev->ici.drv_name = dev_name(&pdev->dev);
637 pcdev->ici.ops = &sh_mobile_ceu_host_ops, 842 pcdev->ici.ops = &sh_mobile_ceu_host_ops;
638 843
639 err = soc_camera_host_register(&pcdev->ici); 844 err = soc_camera_host_register(&pcdev->ici);
640 if (err) 845 if (err)
diff --git a/drivers/media/video/sn9c102/sn9c102_core.c b/drivers/media/video/sn9c102/sn9c102_core.c
index fcd2b62f92c4..01a8efb8deb1 100644
--- a/drivers/media/video/sn9c102/sn9c102_core.c
+++ b/drivers/media/video/sn9c102/sn9c102_core.c
@@ -2162,7 +2162,7 @@ sn9c102_vidioc_querycap(struct sn9c102_device* cam, void __user * arg)
2162 2162
2163 strlcpy(cap.card, cam->v4ldev->name, sizeof(cap.card)); 2163 strlcpy(cap.card, cam->v4ldev->name, sizeof(cap.card));
2164 if (usb_make_path(cam->usbdev, cap.bus_info, sizeof(cap.bus_info)) < 0) 2164 if (usb_make_path(cam->usbdev, cap.bus_info, sizeof(cap.bus_info)) < 0)
2165 strlcpy(cap.bus_info, cam->usbdev->dev.bus_id, 2165 strlcpy(cap.bus_info, dev_name(&cam->usbdev->dev),
2166 sizeof(cap.bus_info)); 2166 sizeof(cap.bus_info));
2167 2167
2168 if (copy_to_user(arg, &cap, sizeof(cap))) 2168 if (copy_to_user(arg, &cap, sizeof(cap)))
diff --git a/drivers/media/video/sn9c102/sn9c102_devtable.h b/drivers/media/video/sn9c102/sn9c102_devtable.h
index e23734f6d6e2..8cb3457e778d 100644
--- a/drivers/media/video/sn9c102/sn9c102_devtable.h
+++ b/drivers/media/video/sn9c102/sn9c102_devtable.h
@@ -55,7 +55,9 @@ static const struct usb_device_id sn9c102_id_table[] = {
55 { SN9C102_USB_DEVICE(0x0c45, 0x6029, BRIDGE_SN9C102), }, 55 { SN9C102_USB_DEVICE(0x0c45, 0x6029, BRIDGE_SN9C102), },
56 { SN9C102_USB_DEVICE(0x0c45, 0x602a, BRIDGE_SN9C102), }, 56 { SN9C102_USB_DEVICE(0x0c45, 0x602a, BRIDGE_SN9C102), },
57 { SN9C102_USB_DEVICE(0x0c45, 0x602b, BRIDGE_SN9C102), }, 57 { SN9C102_USB_DEVICE(0x0c45, 0x602b, BRIDGE_SN9C102), },
58#if !defined CONFIG_USB_GSPCA && !defined CONFIG_USB_GSPCA_MODULE
58 { SN9C102_USB_DEVICE(0x0c45, 0x602c, BRIDGE_SN9C102), }, 59 { SN9C102_USB_DEVICE(0x0c45, 0x602c, BRIDGE_SN9C102), },
60#endif
59/* { SN9C102_USB_DEVICE(0x0c45, 0x602d, BRIDGE_SN9C102), }, HV7131R */ 61/* { SN9C102_USB_DEVICE(0x0c45, 0x602d, BRIDGE_SN9C102), }, HV7131R */
60 { SN9C102_USB_DEVICE(0x0c45, 0x602e, BRIDGE_SN9C102), }, 62 { SN9C102_USB_DEVICE(0x0c45, 0x602e, BRIDGE_SN9C102), },
61 { SN9C102_USB_DEVICE(0x0c45, 0x6030, BRIDGE_SN9C102), }, 63 { SN9C102_USB_DEVICE(0x0c45, 0x6030, BRIDGE_SN9C102), },
@@ -91,10 +93,14 @@ static const struct usb_device_id sn9c102_id_table[] = {
91 { SN9C102_USB_DEVICE(0x0c45, 0x60bc, BRIDGE_SN9C103), }, 93 { SN9C102_USB_DEVICE(0x0c45, 0x60bc, BRIDGE_SN9C103), },
92 { SN9C102_USB_DEVICE(0x0c45, 0x60be, BRIDGE_SN9C103), }, 94 { SN9C102_USB_DEVICE(0x0c45, 0x60be, BRIDGE_SN9C103), },
93 /* SN9C105 */ 95 /* SN9C105 */
96#if !defined CONFIG_USB_GSPCA && !defined CONFIG_USB_GSPCA_MODULE
94 { SN9C102_USB_DEVICE(0x045e, 0x00f5, BRIDGE_SN9C105), }, 97 { SN9C102_USB_DEVICE(0x045e, 0x00f5, BRIDGE_SN9C105), },
95 { SN9C102_USB_DEVICE(0x045e, 0x00f7, BRIDGE_SN9C105), }, 98 { SN9C102_USB_DEVICE(0x045e, 0x00f7, BRIDGE_SN9C105), },
99#endif
96 { SN9C102_USB_DEVICE(0x0471, 0x0327, BRIDGE_SN9C105), }, 100 { SN9C102_USB_DEVICE(0x0471, 0x0327, BRIDGE_SN9C105), },
101#if !defined CONFIG_USB_GSPCA && !defined CONFIG_USB_GSPCA_MODULE
97 { SN9C102_USB_DEVICE(0x0471, 0x0328, BRIDGE_SN9C105), }, 102 { SN9C102_USB_DEVICE(0x0471, 0x0328, BRIDGE_SN9C105), },
103#endif
98 { SN9C102_USB_DEVICE(0x0c45, 0x60c0, BRIDGE_SN9C105), }, 104 { SN9C102_USB_DEVICE(0x0c45, 0x60c0, BRIDGE_SN9C105), },
99 { SN9C102_USB_DEVICE(0x0c45, 0x60c2, BRIDGE_SN9C105), }, 105 { SN9C102_USB_DEVICE(0x0c45, 0x60c2, BRIDGE_SN9C105), },
100 { SN9C102_USB_DEVICE(0x0c45, 0x60c8, BRIDGE_SN9C105), }, 106 { SN9C102_USB_DEVICE(0x0c45, 0x60c8, BRIDGE_SN9C105), },
@@ -113,7 +119,9 @@ static const struct usb_device_id sn9c102_id_table[] = {
113 { SN9C102_USB_DEVICE(0x0c45, 0x610f, BRIDGE_SN9C120), }, 119 { SN9C102_USB_DEVICE(0x0c45, 0x610f, BRIDGE_SN9C120), },
114 { SN9C102_USB_DEVICE(0x0c45, 0x6130, BRIDGE_SN9C120), }, 120 { SN9C102_USB_DEVICE(0x0c45, 0x6130, BRIDGE_SN9C120), },
115/* { SN9C102_USB_DEVICE(0x0c45, 0x6138, BRIDGE_SN9C120), }, MO8000 */ 121/* { SN9C102_USB_DEVICE(0x0c45, 0x6138, BRIDGE_SN9C120), }, MO8000 */
122#if !defined CONFIG_USB_GSPCA && !defined CONFIG_USB_GSPCA_MODULE
116 { SN9C102_USB_DEVICE(0x0c45, 0x613a, BRIDGE_SN9C120), }, 123 { SN9C102_USB_DEVICE(0x0c45, 0x613a, BRIDGE_SN9C120), },
124#endif
117 { SN9C102_USB_DEVICE(0x0c45, 0x613b, BRIDGE_SN9C120), }, 125 { SN9C102_USB_DEVICE(0x0c45, 0x613b, BRIDGE_SN9C120), },
118 { SN9C102_USB_DEVICE(0x0c45, 0x613c, BRIDGE_SN9C120), }, 126 { SN9C102_USB_DEVICE(0x0c45, 0x613c, BRIDGE_SN9C120), },
119 { SN9C102_USB_DEVICE(0x0c45, 0x613e, BRIDGE_SN9C120), }, 127 { SN9C102_USB_DEVICE(0x0c45, 0x613e, BRIDGE_SN9C120), },
diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c
index 66ebe5956a87..90077cb4fe66 100644
--- a/drivers/media/video/soc_camera.c
+++ b/drivers/media/video/soc_camera.c
@@ -33,10 +33,9 @@
33static LIST_HEAD(hosts); 33static LIST_HEAD(hosts);
34static LIST_HEAD(devices); 34static LIST_HEAD(devices);
35static DEFINE_MUTEX(list_lock); 35static DEFINE_MUTEX(list_lock);
36static DEFINE_MUTEX(video_lock);
37 36
38const static struct soc_camera_data_format* 37const struct soc_camera_data_format *soc_camera_format_by_fourcc(
39format_by_fourcc(struct soc_camera_device *icd, unsigned int fourcc) 38 struct soc_camera_device *icd, unsigned int fourcc)
40{ 39{
41 unsigned int i; 40 unsigned int i;
42 41
@@ -45,67 +44,87 @@ format_by_fourcc(struct soc_camera_device *icd, unsigned int fourcc)
45 return icd->formats + i; 44 return icd->formats + i;
46 return NULL; 45 return NULL;
47} 46}
47EXPORT_SYMBOL(soc_camera_format_by_fourcc);
48 48
49static int soc_camera_try_fmt_vid_cap(struct file *file, void *priv, 49const struct soc_camera_format_xlate *soc_camera_xlate_by_fourcc(
50 struct v4l2_format *f) 50 struct soc_camera_device *icd, unsigned int fourcc)
51{ 51{
52 struct soc_camera_file *icf = file->private_data; 52 unsigned int i;
53 struct soc_camera_device *icd = icf->icd;
54 struct soc_camera_host *ici =
55 to_soc_camera_host(icd->dev.parent);
56 enum v4l2_field field;
57 const struct soc_camera_data_format *fmt;
58 int ret;
59 53
60 WARN_ON(priv != file->private_data); 54 for (i = 0; i < icd->num_user_formats; i++)
55 if (icd->user_formats[i].host_fmt->fourcc == fourcc)
56 return icd->user_formats + i;
57 return NULL;
58}
59EXPORT_SYMBOL(soc_camera_xlate_by_fourcc);
61 60
62 fmt = format_by_fourcc(icd, f->fmt.pix.pixelformat); 61/**
63 if (!fmt) { 62 * soc_camera_apply_sensor_flags() - apply platform SOCAM_SENSOR_INVERT_* flags
64 dev_dbg(&icd->dev, "invalid format 0x%08x\n", 63 * @icl: camera platform parameters
65 f->fmt.pix.pixelformat); 64 * @flags: flags to be inverted according to platform configuration
66 return -EINVAL; 65 * @return: resulting flags
67 } 66 */
67unsigned long soc_camera_apply_sensor_flags(struct soc_camera_link *icl,
68 unsigned long flags)
69{
70 unsigned long f;
68 71
69 dev_dbg(&icd->dev, "fmt: 0x%08x\n", fmt->fourcc); 72 /* If only one of the two polarities is supported, switch to the opposite */
73 if (icl->flags & SOCAM_SENSOR_INVERT_HSYNC) {
74 f = flags & (SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_HSYNC_ACTIVE_LOW);
75 if (f == SOCAM_HSYNC_ACTIVE_HIGH || f == SOCAM_HSYNC_ACTIVE_LOW)
76 flags ^= SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_HSYNC_ACTIVE_LOW;
77 }
70 78
71 field = f->fmt.pix.field; 79 if (icl->flags & SOCAM_SENSOR_INVERT_VSYNC) {
80 f = flags & (SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW);
81 if (f == SOCAM_VSYNC_ACTIVE_HIGH || f == SOCAM_VSYNC_ACTIVE_LOW)
82 flags ^= SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW;
83 }
72 84
73 if (field == V4L2_FIELD_ANY) { 85 if (icl->flags & SOCAM_SENSOR_INVERT_PCLK) {
74 field = V4L2_FIELD_NONE; 86 f = flags & (SOCAM_PCLK_SAMPLE_RISING | SOCAM_PCLK_SAMPLE_FALLING);
75 } else if (V4L2_FIELD_NONE != field) { 87 if (f == SOCAM_PCLK_SAMPLE_RISING || f == SOCAM_PCLK_SAMPLE_FALLING)
76 dev_err(&icd->dev, "Field type invalid.\n"); 88 flags ^= SOCAM_PCLK_SAMPLE_RISING | SOCAM_PCLK_SAMPLE_FALLING;
77 return -EINVAL;
78 } 89 }
79 90
80 /* test physical bus parameters */ 91 return flags;
81 ret = ici->ops->try_bus_param(icd, f->fmt.pix.pixelformat); 92}
82 if (ret) 93EXPORT_SYMBOL(soc_camera_apply_sensor_flags);
83 return ret;
84 94
85 /* limit format to hardware capabilities */ 95static int soc_camera_try_fmt_vid_cap(struct file *file, void *priv,
86 ret = ici->ops->try_fmt_cap(icd, f); 96 struct v4l2_format *f)
97{
98 struct soc_camera_file *icf = file->private_data;
99 struct soc_camera_device *icd = icf->icd;
100 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
87 101
88 /* calculate missing fields */ 102 WARN_ON(priv != file->private_data);
89 f->fmt.pix.field = field;
90 f->fmt.pix.bytesperline =
91 (f->fmt.pix.width * fmt->depth) >> 3;
92 f->fmt.pix.sizeimage =
93 f->fmt.pix.height * f->fmt.pix.bytesperline;
94 103
95 return ret; 104 /* limit format to hardware capabilities */
105 return ici->ops->try_fmt(icd, f);
96} 106}
97 107
98static int soc_camera_enum_input(struct file *file, void *priv, 108static int soc_camera_enum_input(struct file *file, void *priv,
99 struct v4l2_input *inp) 109 struct v4l2_input *inp)
100{ 110{
111 struct soc_camera_file *icf = file->private_data;
112 struct soc_camera_device *icd = icf->icd;
113 int ret = 0;
114
101 if (inp->index != 0) 115 if (inp->index != 0)
102 return -EINVAL; 116 return -EINVAL;
103 117
104 inp->type = V4L2_INPUT_TYPE_CAMERA; 118 if (icd->ops->enum_input)
105 inp->std = V4L2_STD_UNKNOWN; 119 ret = icd->ops->enum_input(icd, inp);
106 strcpy(inp->name, "Camera"); 120 else {
121 /* default is camera */
122 inp->type = V4L2_INPUT_TYPE_CAMERA;
123 inp->std = V4L2_STD_UNKNOWN;
124 strcpy(inp->name, "Camera");
125 }
107 126
108 return 0; 127 return ret;
109} 128}
110 129
111static int soc_camera_g_input(struct file *file, void *priv, unsigned int *i) 130static int soc_camera_g_input(struct file *file, void *priv, unsigned int *i)
@@ -125,7 +144,14 @@ static int soc_camera_s_input(struct file *file, void *priv, unsigned int i)
125 144
126static int soc_camera_s_std(struct file *file, void *priv, v4l2_std_id *a) 145static int soc_camera_s_std(struct file *file, void *priv, v4l2_std_id *a)
127{ 146{
128 return 0; 147 struct soc_camera_file *icf = file->private_data;
148 struct soc_camera_device *icd = icf->icd;
149 int ret = 0;
150
151 if (icd->ops->set_std)
152 ret = icd->ops->set_std(icd, a);
153
154 return ret;
129} 155}
130 156
131static int soc_camera_reqbufs(struct file *file, void *priv, 157static int soc_camera_reqbufs(struct file *file, void *priv,
@@ -134,8 +160,7 @@ static int soc_camera_reqbufs(struct file *file, void *priv,
134 int ret; 160 int ret;
135 struct soc_camera_file *icf = file->private_data; 161 struct soc_camera_file *icf = file->private_data;
136 struct soc_camera_device *icd = icf->icd; 162 struct soc_camera_device *icd = icf->icd;
137 struct soc_camera_host *ici = 163 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
138 to_soc_camera_host(icd->dev.parent);
139 164
140 WARN_ON(priv != file->private_data); 165 WARN_ON(priv != file->private_data);
141 166
@@ -178,6 +203,59 @@ static int soc_camera_dqbuf(struct file *file, void *priv,
178 return videobuf_dqbuf(&icf->vb_vidq, p, file->f_flags & O_NONBLOCK); 203 return videobuf_dqbuf(&icf->vb_vidq, p, file->f_flags & O_NONBLOCK);
179} 204}
180 205
206static int soc_camera_init_user_formats(struct soc_camera_device *icd)
207{
208 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
209 int i, fmts = 0;
210
211 if (!ici->ops->get_formats)
212 /*
213 * Fallback mode - the host will have to serve all
214 * sensor-provided formats one-to-one to the user
215 */
216 fmts = icd->num_formats;
217 else
218 /*
219 * First pass - only count formats this host-sensor
220 * configuration can provide
221 */
222 for (i = 0; i < icd->num_formats; i++)
223 fmts += ici->ops->get_formats(icd, i, NULL);
224
225 if (!fmts)
226 return -ENXIO;
227
228 icd->user_formats =
229 vmalloc(fmts * sizeof(struct soc_camera_format_xlate));
230 if (!icd->user_formats)
231 return -ENOMEM;
232
233 icd->num_user_formats = fmts;
234 fmts = 0;
235
236 dev_dbg(&icd->dev, "Found %d supported formats.\n", fmts);
237
238 /* Second pass - actually fill data formats */
239 for (i = 0; i < icd->num_formats; i++)
240 if (!ici->ops->get_formats) {
241 icd->user_formats[i].host_fmt = icd->formats + i;
242 icd->user_formats[i].cam_fmt = icd->formats + i;
243 icd->user_formats[i].buswidth = icd->formats[i].depth;
244 } else {
245 fmts += ici->ops->get_formats(icd, i,
246 &icd->user_formats[fmts]);
247 }
248
249 icd->current_fmt = icd->user_formats[0].host_fmt;
250
251 return 0;
252}
253
254static void soc_camera_free_user_formats(struct soc_camera_device *icd)
255{
256 vfree(icd->user_formats);
257}
258
181static int soc_camera_open(struct inode *inode, struct file *file) 259static int soc_camera_open(struct inode *inode, struct file *file)
182{ 260{
183 struct video_device *vdev; 261 struct video_device *vdev;
@@ -190,8 +268,10 @@ static int soc_camera_open(struct inode *inode, struct file *file)
190 if (!icf) 268 if (!icf)
191 return -ENOMEM; 269 return -ENOMEM;
192 270
193 /* Protect against icd->remove() until we module_get() both drivers. */ 271 /*
194 mutex_lock(&video_lock); 272 * It is safe to dereference these pointers now as long as a user has
273 * the video device open - we are protected by the held cdev reference.
274 */
195 275
196 vdev = video_devdata(file); 276 vdev = video_devdata(file);
197 icd = container_of(vdev->parent, struct soc_camera_device, dev); 277 icd = container_of(vdev->parent, struct soc_camera_device, dev);
@@ -209,20 +289,25 @@ static int soc_camera_open(struct inode *inode, struct file *file)
209 goto emgi; 289 goto emgi;
210 } 290 }
211 291
292 /* Protect against icd->remove() until we module_get() both drivers. */
293 mutex_lock(&icd->video_lock);
294
212 icf->icd = icd; 295 icf->icd = icd;
213 icd->use_count++; 296 icd->use_count++;
214 297
215 /* Now we really have to activate the camera */ 298 /* Now we really have to activate the camera */
216 if (icd->use_count == 1) { 299 if (icd->use_count == 1) {
300 ret = soc_camera_init_user_formats(icd);
301 if (ret < 0)
302 goto eiufmt;
217 ret = ici->ops->add(icd); 303 ret = ici->ops->add(icd);
218 if (ret < 0) { 304 if (ret < 0) {
219 dev_err(&icd->dev, "Couldn't activate the camera: %d\n", ret); 305 dev_err(&icd->dev, "Couldn't activate the camera: %d\n", ret);
220 icd->use_count--;
221 goto eiciadd; 306 goto eiciadd;
222 } 307 }
223 } 308 }
224 309
225 mutex_unlock(&video_lock); 310 mutex_unlock(&icd->video_lock);
226 311
227 file->private_data = icf; 312 file->private_data = icf;
228 dev_dbg(&icd->dev, "camera device open\n"); 313 dev_dbg(&icd->dev, "camera device open\n");
@@ -231,13 +316,16 @@ static int soc_camera_open(struct inode *inode, struct file *file)
231 316
232 return 0; 317 return 0;
233 318
234 /* All errors are entered with the video_lock held */ 319 /* First two errors are entered with the .video_lock held */
235eiciadd: 320eiciadd:
321 soc_camera_free_user_formats(icd);
322eiufmt:
323 icd->use_count--;
324 mutex_unlock(&icd->video_lock);
236 module_put(ici->ops->owner); 325 module_put(ici->ops->owner);
237emgi: 326emgi:
238 module_put(icd->ops->owner); 327 module_put(icd->ops->owner);
239emgd: 328emgd:
240 mutex_unlock(&video_lock);
241 vfree(icf); 329 vfree(icf);
242 return ret; 330 return ret;
243} 331}
@@ -249,13 +337,16 @@ static int soc_camera_close(struct inode *inode, struct file *file)
249 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 337 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
250 struct video_device *vdev = icd->vdev; 338 struct video_device *vdev = icd->vdev;
251 339
252 mutex_lock(&video_lock); 340 mutex_lock(&icd->video_lock);
253 icd->use_count--; 341 icd->use_count--;
254 if (!icd->use_count) 342 if (!icd->use_count) {
255 ici->ops->remove(icd); 343 ici->ops->remove(icd);
344 soc_camera_free_user_formats(icd);
345 }
346 mutex_unlock(&icd->video_lock);
347
256 module_put(icd->ops->owner); 348 module_put(icd->ops->owner);
257 module_put(ici->ops->owner); 349 module_put(ici->ops->owner);
258 mutex_unlock(&video_lock);
259 350
260 vfree(icf); 351 vfree(icf);
261 352
@@ -265,7 +356,7 @@ static int soc_camera_close(struct inode *inode, struct file *file)
265} 356}
266 357
267static ssize_t soc_camera_read(struct file *file, char __user *buf, 358static ssize_t soc_camera_read(struct file *file, char __user *buf,
268 size_t count, loff_t *ppos) 359 size_t count, loff_t *ppos)
269{ 360{
270 struct soc_camera_file *icf = file->private_data; 361 struct soc_camera_file *icf = file->private_data;
271 struct soc_camera_device *icd = icf->icd; 362 struct soc_camera_device *icd = icf->icd;
@@ -299,8 +390,7 @@ static unsigned int soc_camera_poll(struct file *file, poll_table *pt)
299{ 390{
300 struct soc_camera_file *icf = file->private_data; 391 struct soc_camera_file *icf = file->private_data;
301 struct soc_camera_device *icd = icf->icd; 392 struct soc_camera_device *icd = icf->icd;
302 struct soc_camera_host *ici = 393 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
303 to_soc_camera_host(icd->dev.parent);
304 394
305 if (list_empty(&icf->vb_vidq.stream)) { 395 if (list_empty(&icf->vb_vidq.stream)) {
306 dev_err(&icd->dev, "Trying to poll with no queued buffers!\n"); 396 dev_err(&icd->dev, "Trying to poll with no queued buffers!\n");
@@ -310,7 +400,6 @@ static unsigned int soc_camera_poll(struct file *file, poll_table *pt)
310 return ici->ops->poll(file, pt); 400 return ici->ops->poll(file, pt);
311} 401}
312 402
313
314static struct file_operations soc_camera_fops = { 403static struct file_operations soc_camera_fops = {
315 .owner = THIS_MODULE, 404 .owner = THIS_MODULE,
316 .open = soc_camera_open, 405 .open = soc_camera_open,
@@ -322,44 +411,50 @@ static struct file_operations soc_camera_fops = {
322 .llseek = no_llseek, 411 .llseek = no_llseek,
323}; 412};
324 413
325
326static int soc_camera_s_fmt_vid_cap(struct file *file, void *priv, 414static int soc_camera_s_fmt_vid_cap(struct file *file, void *priv,
327 struct v4l2_format *f) 415 struct v4l2_format *f)
328{ 416{
329 struct soc_camera_file *icf = file->private_data; 417 struct soc_camera_file *icf = file->private_data;
330 struct soc_camera_device *icd = icf->icd; 418 struct soc_camera_device *icd = icf->icd;
331 struct soc_camera_host *ici = 419 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
332 to_soc_camera_host(icd->dev.parent); 420 struct v4l2_pix_format *pix = &f->fmt.pix;
421 __u32 pixfmt = pix->pixelformat;
333 int ret; 422 int ret;
334 struct v4l2_rect rect; 423 struct v4l2_rect rect;
335 const static struct soc_camera_data_format *data_fmt;
336 424
337 WARN_ON(priv != file->private_data); 425 WARN_ON(priv != file->private_data);
338 426
339 data_fmt = format_by_fourcc(icd, f->fmt.pix.pixelformat); 427 ret = soc_camera_try_fmt_vid_cap(file, priv, f);
340 if (!data_fmt)
341 return -EINVAL;
342
343 /* buswidth may be further adjusted by the ici */
344 icd->buswidth = data_fmt->depth;
345
346 ret = soc_camera_try_fmt_vid_cap(file, icf, f);
347 if (ret < 0) 428 if (ret < 0)
348 return ret; 429 return ret;
349 430
431 mutex_lock(&icf->vb_vidq.vb_lock);
432
433 if (videobuf_queue_is_busy(&icf->vb_vidq)) {
434 dev_err(&icd->dev, "S_FMT denied: queue busy\n");
435 ret = -EBUSY;
436 goto unlock;
437 }
438
350 rect.left = icd->x_current; 439 rect.left = icd->x_current;
351 rect.top = icd->y_current; 440 rect.top = icd->y_current;
352 rect.width = f->fmt.pix.width; 441 rect.width = pix->width;
353 rect.height = f->fmt.pix.height; 442 rect.height = pix->height;
354 ret = ici->ops->set_fmt_cap(icd, f->fmt.pix.pixelformat, &rect); 443 ret = ici->ops->set_fmt(icd, pix->pixelformat, &rect);
355 if (ret < 0) 444 if (ret < 0) {
356 return ret; 445 goto unlock;
446 } else if (!icd->current_fmt ||
447 icd->current_fmt->fourcc != pixfmt) {
448 dev_err(&ici->dev,
449 "Host driver hasn't set up current format correctly!\n");
450 ret = -EINVAL;
451 goto unlock;
452 }
357 453
358 icd->current_fmt = data_fmt;
359 icd->width = rect.width; 454 icd->width = rect.width;
360 icd->height = rect.height; 455 icd->height = rect.height;
361 icf->vb_vidq.field = f->fmt.pix.field; 456 icf->vb_vidq.field = pix->field;
362 if (V4L2_BUF_TYPE_VIDEO_CAPTURE != f->type) 457 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
363 dev_warn(&icd->dev, "Attention! Wrong buf-type %d\n", 458 dev_warn(&icd->dev, "Attention! Wrong buf-type %d\n",
364 f->type); 459 f->type);
365 460
@@ -367,11 +462,16 @@ static int soc_camera_s_fmt_vid_cap(struct file *file, void *priv,
367 icd->width, icd->height); 462 icd->width, icd->height);
368 463
369 /* set physical bus parameters */ 464 /* set physical bus parameters */
370 return ici->ops->set_bus_param(icd, f->fmt.pix.pixelformat); 465 ret = ici->ops->set_bus_param(icd, pixfmt);
466
467unlock:
468 mutex_unlock(&icf->vb_vidq.vb_lock);
469
470 return ret;
371} 471}
372 472
373static int soc_camera_enum_fmt_vid_cap(struct file *file, void *priv, 473static int soc_camera_enum_fmt_vid_cap(struct file *file, void *priv,
374 struct v4l2_fmtdesc *f) 474 struct v4l2_fmtdesc *f)
375{ 475{
376 struct soc_camera_file *icf = file->private_data; 476 struct soc_camera_file *icf = file->private_data;
377 struct soc_camera_device *icd = icf->icd; 477 struct soc_camera_device *icd = icf->icd;
@@ -379,10 +479,10 @@ static int soc_camera_enum_fmt_vid_cap(struct file *file, void *priv,
379 479
380 WARN_ON(priv != file->private_data); 480 WARN_ON(priv != file->private_data);
381 481
382 if (f->index >= icd->num_formats) 482 if (f->index >= icd->num_user_formats)
383 return -EINVAL; 483 return -EINVAL;
384 484
385 format = &icd->formats[f->index]; 485 format = icd->user_formats[f->index].host_fmt;
386 486
387 strlcpy(f->description, format->name, sizeof(f->description)); 487 strlcpy(f->description, format->name, sizeof(f->description));
388 f->pixelformat = format->fourcc; 488 f->pixelformat = format->fourcc;
@@ -390,21 +490,21 @@ static int soc_camera_enum_fmt_vid_cap(struct file *file, void *priv,
390} 490}
391 491
392static int soc_camera_g_fmt_vid_cap(struct file *file, void *priv, 492static int soc_camera_g_fmt_vid_cap(struct file *file, void *priv,
393 struct v4l2_format *f) 493 struct v4l2_format *f)
394{ 494{
395 struct soc_camera_file *icf = file->private_data; 495 struct soc_camera_file *icf = file->private_data;
396 struct soc_camera_device *icd = icf->icd; 496 struct soc_camera_device *icd = icf->icd;
497 struct v4l2_pix_format *pix = &f->fmt.pix;
397 498
398 WARN_ON(priv != file->private_data); 499 WARN_ON(priv != file->private_data);
399 500
400 f->fmt.pix.width = icd->width; 501 pix->width = icd->width;
401 f->fmt.pix.height = icd->height; 502 pix->height = icd->height;
402 f->fmt.pix.field = icf->vb_vidq.field; 503 pix->field = icf->vb_vidq.field;
403 f->fmt.pix.pixelformat = icd->current_fmt->fourcc; 504 pix->pixelformat = icd->current_fmt->fourcc;
404 f->fmt.pix.bytesperline = 505 pix->bytesperline = pix->width *
405 (f->fmt.pix.width * icd->current_fmt->depth) >> 3; 506 DIV_ROUND_UP(icd->current_fmt->depth, 8);
406 f->fmt.pix.sizeimage = 507 pix->sizeimage = pix->height * pix->bytesperline;
407 f->fmt.pix.height * f->fmt.pix.bytesperline;
408 dev_dbg(&icd->dev, "current_fmt->fourcc: 0x%08x\n", 508 dev_dbg(&icd->dev, "current_fmt->fourcc: 0x%08x\n",
409 icd->current_fmt->fourcc); 509 icd->current_fmt->fourcc);
410 return 0; 510 return 0;
@@ -415,8 +515,7 @@ static int soc_camera_querycap(struct file *file, void *priv,
415{ 515{
416 struct soc_camera_file *icf = file->private_data; 516 struct soc_camera_file *icf = file->private_data;
417 struct soc_camera_device *icd = icf->icd; 517 struct soc_camera_device *icd = icf->icd;
418 struct soc_camera_host *ici = 518 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
419 to_soc_camera_host(icd->dev.parent);
420 519
421 WARN_ON(priv != file->private_data); 520 WARN_ON(priv != file->private_data);
422 521
@@ -429,6 +528,7 @@ static int soc_camera_streamon(struct file *file, void *priv,
429{ 528{
430 struct soc_camera_file *icf = file->private_data; 529 struct soc_camera_file *icf = file->private_data;
431 struct soc_camera_device *icd = icf->icd; 530 struct soc_camera_device *icd = icf->icd;
531 int ret;
432 532
433 WARN_ON(priv != file->private_data); 533 WARN_ON(priv != file->private_data);
434 534
@@ -437,10 +537,16 @@ static int soc_camera_streamon(struct file *file, void *priv,
437 if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE) 537 if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE)
438 return -EINVAL; 538 return -EINVAL;
439 539
540 mutex_lock(&icd->video_lock);
541
440 icd->ops->start_capture(icd); 542 icd->ops->start_capture(icd);
441 543
442 /* This calls buf_queue from host driver's videobuf_queue_ops */ 544 /* This calls buf_queue from host driver's videobuf_queue_ops */
443 return videobuf_streamon(&icf->vb_vidq); 545 ret = videobuf_streamon(&icf->vb_vidq);
546
547 mutex_unlock(&icd->video_lock);
548
549 return ret;
444} 550}
445 551
446static int soc_camera_streamoff(struct file *file, void *priv, 552static int soc_camera_streamoff(struct file *file, void *priv,
@@ -456,12 +562,16 @@ static int soc_camera_streamoff(struct file *file, void *priv,
456 if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE) 562 if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE)
457 return -EINVAL; 563 return -EINVAL;
458 564
565 mutex_lock(&icd->video_lock);
566
459 /* This calls buf_release from host driver's videobuf_queue_ops for all 567 /* This calls buf_release from host driver's videobuf_queue_ops for all
460 * remaining buffers. When the last buffer is freed, stop capture */ 568 * remaining buffers. When the last buffer is freed, stop capture */
461 videobuf_streamoff(&icf->vb_vidq); 569 videobuf_streamoff(&icf->vb_vidq);
462 570
463 icd->ops->stop_capture(icd); 571 icd->ops->stop_capture(icd);
464 572
573 mutex_unlock(&icd->video_lock);
574
465 return 0; 575 return 0;
466} 576}
467 577
@@ -567,14 +677,16 @@ static int soc_camera_s_crop(struct file *file, void *fh,
567{ 677{
568 struct soc_camera_file *icf = file->private_data; 678 struct soc_camera_file *icf = file->private_data;
569 struct soc_camera_device *icd = icf->icd; 679 struct soc_camera_device *icd = icf->icd;
570 struct soc_camera_host *ici = 680 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
571 to_soc_camera_host(icd->dev.parent);
572 int ret; 681 int ret;
573 682
574 if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 683 if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
575 return -EINVAL; 684 return -EINVAL;
576 685
577 ret = ici->ops->set_fmt_cap(icd, 0, &a->c); 686 /* Cropping is allowed during a running capture, guard consistency */
687 mutex_lock(&icf->vb_vidq.vb_lock);
688
689 ret = ici->ops->set_fmt(icd, 0, &a->c);
578 if (!ret) { 690 if (!ret) {
579 icd->width = a->c.width; 691 icd->width = a->c.width;
580 icd->height = a->c.height; 692 icd->height = a->c.height;
@@ -582,6 +694,8 @@ static int soc_camera_s_crop(struct file *file, void *fh,
582 icd->y_current = a->c.top; 694 icd->y_current = a->c.top;
583 } 695 }
584 696
697 mutex_unlock(&icf->vb_vidq.vb_lock);
698
585 return ret; 699 return ret;
586} 700}
587 701
@@ -692,18 +806,35 @@ static int scan_add_device(struct soc_camera_device *icd)
692static int soc_camera_probe(struct device *dev) 806static int soc_camera_probe(struct device *dev)
693{ 807{
694 struct soc_camera_device *icd = to_soc_camera_dev(dev); 808 struct soc_camera_device *icd = to_soc_camera_dev(dev);
695 struct soc_camera_host *ici = 809 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
696 to_soc_camera_host(icd->dev.parent);
697 int ret; 810 int ret;
698 811
699 if (!icd->ops->probe) 812 /*
700 return -ENODEV; 813 * Possible race scenario:
814 * modprobe <camera-host-driver> triggers __func__
815 * at this moment respective <camera-sensor-driver> gets rmmod'ed
816 * to protect take module references.
817 */
818
819 if (!try_module_get(icd->ops->owner)) {
820 dev_err(&icd->dev, "Couldn't lock sensor driver.\n");
821 ret = -EINVAL;
822 goto emgd;
823 }
824
825 if (!try_module_get(ici->ops->owner)) {
826 dev_err(&icd->dev, "Couldn't lock capture bus driver.\n");
827 ret = -EINVAL;
828 goto emgi;
829 }
830
831 mutex_lock(&icd->video_lock);
701 832
702 /* We only call ->add() here to activate and probe the camera. 833 /* We only call ->add() here to activate and probe the camera.
703 * We shall ->remove() and deactivate it immediately afterwards. */ 834 * We shall ->remove() and deactivate it immediately afterwards. */
704 ret = ici->ops->add(icd); 835 ret = ici->ops->add(icd);
705 if (ret < 0) 836 if (ret < 0)
706 return ret; 837 goto eiadd;
707 838
708 ret = icd->ops->probe(icd); 839 ret = icd->ops->probe(icd);
709 if (ret >= 0) { 840 if (ret >= 0) {
@@ -717,6 +848,12 @@ static int soc_camera_probe(struct device *dev)
717 } 848 }
718 ici->ops->remove(icd); 849 ici->ops->remove(icd);
719 850
851eiadd:
852 mutex_unlock(&icd->video_lock);
853 module_put(ici->ops->owner);
854emgi:
855 module_put(icd->ops->owner);
856emgd:
720 return ret; 857 return ret;
721} 858}
722 859
@@ -779,11 +916,20 @@ int soc_camera_host_register(struct soc_camera_host *ici)
779 int ret; 916 int ret;
780 struct soc_camera_host *ix; 917 struct soc_camera_host *ix;
781 918
782 if (!ici->ops->init_videobuf || !ici->ops->add || !ici->ops->remove) 919 if (!ici || !ici->ops ||
920 !ici->ops->try_fmt ||
921 !ici->ops->set_fmt ||
922 !ici->ops->set_bus_param ||
923 !ici->ops->querycap ||
924 !ici->ops->init_videobuf ||
925 !ici->ops->reqbufs ||
926 !ici->ops->add ||
927 !ici->ops->remove ||
928 !ici->ops->poll)
783 return -EINVAL; 929 return -EINVAL;
784 930
785 /* Number might be equal to the platform device ID */ 931 /* Number might be equal to the platform device ID */
786 sprintf(ici->dev.bus_id, "camera_host%d", ici->nr); 932 dev_set_name(&ici->dev, "camera_host%d", ici->nr);
787 933
788 mutex_lock(&list_lock); 934 mutex_lock(&list_lock);
789 list_for_each_entry(ix, &hosts, list) { 935 list_for_each_entry(ix, &hosts, list) {
@@ -847,7 +993,16 @@ int soc_camera_device_register(struct soc_camera_device *icd)
847 struct soc_camera_device *ix; 993 struct soc_camera_device *ix;
848 int num = -1, i; 994 int num = -1, i;
849 995
850 if (!icd) 996 if (!icd || !icd->ops ||
997 !icd->ops->probe ||
998 !icd->ops->init ||
999 !icd->ops->release ||
1000 !icd->ops->start_capture ||
1001 !icd->ops->stop_capture ||
1002 !icd->ops->set_fmt ||
1003 !icd->ops->try_fmt ||
1004 !icd->ops->query_bus_param ||
1005 !icd->ops->set_bus_param)
851 return -EINVAL; 1006 return -EINVAL;
852 1007
853 for (i = 0; i < 256 && num < 0; i++) { 1008 for (i = 0; i < 256 && num < 0; i++) {
@@ -867,10 +1022,12 @@ int soc_camera_device_register(struct soc_camera_device *icd)
867 1022
868 icd->devnum = num; 1023 icd->devnum = num;
869 icd->dev.bus = &soc_camera_bus_type; 1024 icd->dev.bus = &soc_camera_bus_type;
870 snprintf(icd->dev.bus_id, sizeof(icd->dev.bus_id), 1025 dev_set_name(&icd->dev, "%u-%u", icd->iface, icd->devnum);
871 "%u-%u", icd->iface, icd->devnum);
872 1026
873 icd->dev.release = dummy_release; 1027 icd->dev.release = dummy_release;
1028 icd->use_count = 0;
1029 icd->host_priv = NULL;
1030 mutex_init(&icd->video_lock);
874 1031
875 return scan_add_device(icd); 1032 return scan_add_device(icd);
876} 1033}
@@ -917,6 +1074,10 @@ static const struct v4l2_ioctl_ops soc_camera_ioctl_ops = {
917#endif 1074#endif
918}; 1075};
919 1076
1077/*
1078 * Usually called from the struct soc_camera_ops .probe() method, i.e., from
1079 * soc_camera_probe() above with .video_lock held
1080 */
920int soc_camera_video_start(struct soc_camera_device *icd) 1081int soc_camera_video_start(struct soc_camera_device *icd)
921{ 1082{
922 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 1083 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
@@ -932,7 +1093,7 @@ int soc_camera_video_start(struct soc_camera_device *icd)
932 dev_dbg(&ici->dev, "Allocated video_device %p\n", vdev); 1093 dev_dbg(&ici->dev, "Allocated video_device %p\n", vdev);
933 1094
934 strlcpy(vdev->name, ici->drv_name, sizeof(vdev->name)); 1095 strlcpy(vdev->name, ici->drv_name, sizeof(vdev->name));
935 /* Maybe better &ici->dev */ 1096
936 vdev->parent = &icd->dev; 1097 vdev->parent = &icd->dev;
937 vdev->current_norm = V4L2_STD_UNKNOWN; 1098 vdev->current_norm = V4L2_STD_UNKNOWN;
938 vdev->fops = &soc_camera_fops; 1099 vdev->fops = &soc_camera_fops;
@@ -941,8 +1102,6 @@ int soc_camera_video_start(struct soc_camera_device *icd)
941 vdev->minor = -1; 1102 vdev->minor = -1;
942 vdev->tvnorms = V4L2_STD_UNKNOWN, 1103 vdev->tvnorms = V4L2_STD_UNKNOWN,
943 1104
944 icd->current_fmt = &icd->formats[0];
945
946 err = video_register_device(vdev, VFL_TYPE_GRABBER, vdev->minor); 1105 err = video_register_device(vdev, VFL_TYPE_GRABBER, vdev->minor);
947 if (err < 0) { 1106 if (err < 0) {
948 dev_err(vdev->parent, "video_register_device failed\n"); 1107 dev_err(vdev->parent, "video_register_device failed\n");
@@ -968,10 +1127,10 @@ void soc_camera_video_stop(struct soc_camera_device *icd)
968 if (!icd->dev.parent || !vdev) 1127 if (!icd->dev.parent || !vdev)
969 return; 1128 return;
970 1129
971 mutex_lock(&video_lock); 1130 mutex_lock(&icd->video_lock);
972 video_unregister_device(vdev); 1131 video_unregister_device(vdev);
973 icd->vdev = NULL; 1132 icd->vdev = NULL;
974 mutex_unlock(&video_lock); 1133 mutex_unlock(&icd->video_lock);
975} 1134}
976EXPORT_SYMBOL(soc_camera_video_stop); 1135EXPORT_SYMBOL(soc_camera_video_stop);
977 1136
diff --git a/drivers/media/video/soc_camera_platform.c b/drivers/media/video/soc_camera_platform.c
index bb7a9d480e8f..013ab06e3180 100644
--- a/drivers/media/video/soc_camera_platform.c
+++ b/drivers/media/video/soc_camera_platform.c
@@ -79,19 +79,20 @@ soc_camera_platform_query_bus_param(struct soc_camera_device *icd)
79 return p->bus_param; 79 return p->bus_param;
80} 80}
81 81
82static int soc_camera_platform_set_fmt_cap(struct soc_camera_device *icd, 82static int soc_camera_platform_set_fmt(struct soc_camera_device *icd,
83 __u32 pixfmt, struct v4l2_rect *rect) 83 __u32 pixfmt, struct v4l2_rect *rect)
84{ 84{
85 return 0; 85 return 0;
86} 86}
87 87
88static int soc_camera_platform_try_fmt_cap(struct soc_camera_device *icd, 88static int soc_camera_platform_try_fmt(struct soc_camera_device *icd,
89 struct v4l2_format *f) 89 struct v4l2_format *f)
90{ 90{
91 struct soc_camera_platform_info *p = soc_camera_platform_get_info(icd); 91 struct soc_camera_platform_info *p = soc_camera_platform_get_info(icd);
92 struct v4l2_pix_format *pix = &f->fmt.pix;
92 93
93 f->fmt.pix.width = p->format.width; 94 pix->width = p->format.width;
94 f->fmt.pix.height = p->format.height; 95 pix->height = p->format.height;
95 return 0; 96 return 0;
96} 97}
97 98
@@ -124,8 +125,8 @@ static struct soc_camera_ops soc_camera_platform_ops = {
124 .release = soc_camera_platform_release, 125 .release = soc_camera_platform_release,
125 .start_capture = soc_camera_platform_start_capture, 126 .start_capture = soc_camera_platform_start_capture,
126 .stop_capture = soc_camera_platform_stop_capture, 127 .stop_capture = soc_camera_platform_stop_capture,
127 .set_fmt_cap = soc_camera_platform_set_fmt_cap, 128 .set_fmt = soc_camera_platform_set_fmt,
128 .try_fmt_cap = soc_camera_platform_try_fmt_cap, 129 .try_fmt = soc_camera_platform_try_fmt,
129 .set_bus_param = soc_camera_platform_set_bus_param, 130 .set_bus_param = soc_camera_platform_set_bus_param,
130 .query_bus_param = soc_camera_platform_query_bus_param, 131 .query_bus_param = soc_camera_platform_query_bus_param,
131}; 132};
diff --git a/drivers/media/video/stk-webcam.c b/drivers/media/video/stk-webcam.c
index e9eb6d754d5c..f9516d0f3c11 100644
--- a/drivers/media/video/stk-webcam.c
+++ b/drivers/media/video/stk-webcam.c
@@ -1262,6 +1262,25 @@ static int stk_vidioc_g_parm(struct file *filp,
1262 return 0; 1262 return 0;
1263} 1263}
1264 1264
1265static int stk_vidioc_enum_framesizes(struct file *filp,
1266 void *priv, struct v4l2_frmsizeenum *frms)
1267{
1268 if (frms->index >= ARRAY_SIZE(stk_sizes))
1269 return -EINVAL;
1270 switch (frms->pixel_format) {
1271 case V4L2_PIX_FMT_RGB565:
1272 case V4L2_PIX_FMT_RGB565X:
1273 case V4L2_PIX_FMT_UYVY:
1274 case V4L2_PIX_FMT_YUYV:
1275 case V4L2_PIX_FMT_SBGGR8:
1276 frms->type = V4L2_FRMSIZE_TYPE_DISCRETE;
1277 frms->discrete.width = stk_sizes[frms->index].w;
1278 frms->discrete.height = stk_sizes[frms->index].h;
1279 return 0;
1280 default: return -EINVAL;
1281 }
1282}
1283
1265static struct file_operations v4l_stk_fops = { 1284static struct file_operations v4l_stk_fops = {
1266 .owner = THIS_MODULE, 1285 .owner = THIS_MODULE,
1267 .open = v4l_stk_open, 1286 .open = v4l_stk_open,
@@ -1296,6 +1315,7 @@ static const struct v4l2_ioctl_ops v4l_stk_ioctl_ops = {
1296 .vidioc_g_ctrl = stk_vidioc_g_ctrl, 1315 .vidioc_g_ctrl = stk_vidioc_g_ctrl,
1297 .vidioc_s_ctrl = stk_vidioc_s_ctrl, 1316 .vidioc_s_ctrl = stk_vidioc_s_ctrl,
1298 .vidioc_g_parm = stk_vidioc_g_parm, 1317 .vidioc_g_parm = stk_vidioc_g_parm,
1318 .vidioc_enum_framesizes = stk_vidioc_enum_framesizes,
1299}; 1319};
1300 1320
1301static void stk_v4l_dev_release(struct video_device *vd) 1321static void stk_v4l_dev_release(struct video_device *vd)
@@ -1376,12 +1396,9 @@ static int stk_camera_probe(struct usb_interface *interface,
1376 endpoint = &iface_desc->endpoint[i].desc; 1396 endpoint = &iface_desc->endpoint[i].desc;
1377 1397
1378 if (!dev->isoc_ep 1398 if (!dev->isoc_ep
1379 && ((endpoint->bEndpointAddress 1399 && usb_endpoint_is_isoc_in(endpoint)) {
1380 & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN)
1381 && ((endpoint->bmAttributes
1382 & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_ISOC)) {
1383 /* we found an isoc in endpoint */ 1400 /* we found an isoc in endpoint */
1384 dev->isoc_ep = (endpoint->bEndpointAddress & 0xF); 1401 dev->isoc_ep = usb_endpoint_num(endpoint);
1385 break; 1402 break;
1386 } 1403 }
1387 } 1404 }
diff --git a/drivers/media/video/stv680.c b/drivers/media/video/stv680.c
index 328c41b1517d..42acc92c182d 100644
--- a/drivers/media/video/stv680.c
+++ b/drivers/media/video/stv680.c
@@ -1132,8 +1132,7 @@ static int stv_close (struct inode *inode, struct file *file)
1132 return 0; 1132 return 0;
1133} 1133}
1134 1134
1135static int stv680_do_ioctl (struct inode *inode, struct file *file, 1135static int stv680_do_ioctl(struct file *file, unsigned int cmd, void *arg)
1136 unsigned int cmd, void *arg)
1137{ 1136{
1138 struct video_device *vdev = file->private_data; 1137 struct video_device *vdev = file->private_data;
1139 struct usb_stv *stv680 = video_get_drvdata(vdev); 1138 struct usb_stv *stv680 = video_get_drvdata(vdev);
@@ -1303,7 +1302,7 @@ static int stv680_do_ioctl (struct inode *inode, struct file *file,
1303static int stv680_ioctl(struct inode *inode, struct file *file, 1302static int stv680_ioctl(struct inode *inode, struct file *file,
1304 unsigned int cmd, unsigned long arg) 1303 unsigned int cmd, unsigned long arg)
1305{ 1304{
1306 return video_usercopy(inode, file, cmd, arg, stv680_do_ioctl); 1305 return video_usercopy(file, cmd, arg, stv680_do_ioctl);
1307} 1306}
1308 1307
1309static int stv680_mmap (struct file *file, struct vm_area_struct *vma) 1308static int stv680_mmap (struct file *file, struct vm_area_struct *vma)
diff --git a/drivers/media/video/tda7432.c b/drivers/media/video/tda7432.c
index 4963d4264880..0c020585fffb 100644
--- a/drivers/media/video/tda7432.c
+++ b/drivers/media/video/tda7432.c
@@ -47,9 +47,10 @@
47#include <linux/videodev2.h> 47#include <linux/videodev2.h>
48#include <linux/i2c.h> 48#include <linux/i2c.h>
49 49
50#include <media/v4l2-common.h> 50#include <media/v4l2-device.h>
51#include <media/v4l2-ioctl.h> 51#include <media/v4l2-ioctl.h>
52#include <media/i2c-addr.h> 52#include <media/i2c-addr.h>
53#include <media/v4l2-i2c-drv-legacy.h>
53 54
54#ifndef VIDEO_AUDIO_BALANCE 55#ifndef VIDEO_AUDIO_BALANCE
55# define VIDEO_AUDIO_BALANCE 32 56# define VIDEO_AUDIO_BALANCE 32
@@ -79,6 +80,7 @@ I2C_CLIENT_INSMOD;
79/* Structure of address and subaddresses for the tda7432 */ 80/* Structure of address and subaddresses for the tda7432 */
80 81
81struct tda7432 { 82struct tda7432 {
83 struct v4l2_subdev sd;
82 int addr; 84 int addr;
83 int input; 85 int input;
84 int volume; 86 int volume;
@@ -86,10 +88,12 @@ struct tda7432 {
86 int bass, treble; 88 int bass, treble;
87 int lf, lr, rf, rr; 89 int lf, lr, rf, rr;
88 int loud; 90 int loud;
89 struct i2c_client c;
90}; 91};
91static struct i2c_driver driver; 92
92static struct i2c_client client_template; 93static inline struct tda7432 *to_state(struct v4l2_subdev *sd)
94{
95 return container_of(sd, struct tda7432, sd);
96}
93 97
94/* The TDA7432 is made by STS-Thompson 98/* The TDA7432 is made by STS-Thompson
95 * http://www.st.com 99 * http://www.st.com
@@ -224,32 +228,33 @@ static struct i2c_client client_template;
224 228
225/* Begin code */ 229/* Begin code */
226 230
227static int tda7432_write(struct i2c_client *client, int subaddr, int val) 231static int tda7432_write(struct v4l2_subdev *sd, int subaddr, int val)
228{ 232{
233 struct i2c_client *client = v4l2_get_subdevdata(sd);
229 unsigned char buffer[2]; 234 unsigned char buffer[2];
230 v4l_dbg(2, debug,client,"In tda7432_write\n"); 235
231 v4l_dbg(1, debug,client,"Writing %d 0x%x\n", subaddr, val); 236 v4l2_dbg(2, debug, sd, "In tda7432_write\n");
237 v4l2_dbg(1, debug, sd, "Writing %d 0x%x\n", subaddr, val);
232 buffer[0] = subaddr; 238 buffer[0] = subaddr;
233 buffer[1] = val; 239 buffer[1] = val;
234 if (2 != i2c_master_send(client,buffer,2)) { 240 if (2 != i2c_master_send(client, buffer, 2)) {
235 v4l_err(client,"I/O error, trying (write %d 0x%x)\n", 241 v4l2_err(sd, "I/O error, trying (write %d 0x%x)\n",
236 subaddr, val); 242 subaddr, val);
237 return -1; 243 return -1;
238 } 244 }
239 return 0; 245 return 0;
240} 246}
241 247
242/* I don't think we ever actually _read_ the chip... */ 248static int tda7432_set(struct v4l2_subdev *sd)
243
244static int tda7432_set(struct i2c_client *client)
245{ 249{
246 struct tda7432 *t = i2c_get_clientdata(client); 250 struct i2c_client *client = v4l2_get_subdevdata(sd);
251 struct tda7432 *t = to_state(sd);
247 unsigned char buf[16]; 252 unsigned char buf[16];
248 v4l_dbg(2, debug,client,"In tda7432_set\n");
249 253
250 v4l_dbg(1, debug,client, 254 v4l2_dbg(1, debug, sd,
251 "tda7432: 7432_set(0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x)\n", 255 "tda7432: 7432_set(0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x)\n",
252 t->input,t->volume,t->bass,t->treble,t->lf,t->lr,t->rf,t->rr,t->loud); 256 t->input, t->volume, t->bass, t->treble, t->lf, t->lr,
257 t->rf, t->rr, t->loud);
253 buf[0] = TDA7432_IN; 258 buf[0] = TDA7432_IN;
254 buf[1] = t->input; 259 buf[1] = t->input;
255 buf[2] = t->volume; 260 buf[2] = t->volume;
@@ -260,18 +265,19 @@ static int tda7432_set(struct i2c_client *client)
260 buf[7] = t->rf; 265 buf[7] = t->rf;
261 buf[8] = t->rr; 266 buf[8] = t->rr;
262 buf[9] = t->loud; 267 buf[9] = t->loud;
263 if (10 != i2c_master_send(client,buf,10)) { 268 if (10 != i2c_master_send(client, buf, 10)) {
264 v4l_err(client,"I/O error, trying tda7432_set\n"); 269 v4l2_err(sd, "I/O error, trying tda7432_set\n");
265 return -1; 270 return -1;
266 } 271 }
267 272
268 return 0; 273 return 0;
269} 274}
270 275
271static void do_tda7432_init(struct i2c_client *client) 276static void do_tda7432_init(struct v4l2_subdev *sd)
272{ 277{
273 struct tda7432 *t = i2c_get_clientdata(client); 278 struct tda7432 *t = to_state(sd);
274 v4l_dbg(2, debug,client,"In tda7432_init\n"); 279
280 v4l2_dbg(2, debug, sd, "In tda7432_init\n");
275 281
276 t->input = TDA7432_STEREO_IN | /* Main (stereo) input */ 282 t->input = TDA7432_STEREO_IN | /* Main (stereo) input */
277 TDA7432_BASS_SYM | /* Symmetric bass cut */ 283 TDA7432_BASS_SYM | /* Symmetric bass cut */
@@ -288,57 +294,12 @@ static void do_tda7432_init(struct i2c_client *client)
288 t->rr = TDA7432_ATTEN_0DB; /* 0dB attenuation */ 294 t->rr = TDA7432_ATTEN_0DB; /* 0dB attenuation */
289 t->loud = loudness; /* insmod parameter */ 295 t->loud = loudness; /* insmod parameter */
290 296
291 tda7432_set(client); 297 tda7432_set(sd);
292} 298}
293 299
294/* *********************** * 300static int tda7432_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
295 * i2c interface functions *
296 * *********************** */
297
298static int tda7432_attach(struct i2c_adapter *adap, int addr, int kind)
299{ 301{
300 struct tda7432 *t; 302 struct tda7432 *t = to_state(sd);
301 struct i2c_client *client;
302
303 t = kzalloc(sizeof *t,GFP_KERNEL);
304 if (!t)
305 return -ENOMEM;
306
307 client = &t->c;
308 memcpy(client,&client_template,sizeof(struct i2c_client));
309 client->adapter = adap;
310 client->addr = addr;
311 i2c_set_clientdata(client, t);
312
313 do_tda7432_init(client);
314 i2c_attach_client(client);
315
316 v4l_info(client, "chip found @ 0x%x (%s)\n", addr << 1, adap->name);
317 return 0;
318}
319
320static int tda7432_probe(struct i2c_adapter *adap)
321{
322 if (adap->class & I2C_CLASS_TV_ANALOG)
323 return i2c_probe(adap, &addr_data, tda7432_attach);
324 return 0;
325}
326
327static int tda7432_detach(struct i2c_client *client)
328{
329 struct tda7432 *t = i2c_get_clientdata(client);
330
331 do_tda7432_init(client);
332 i2c_detach_client(client);
333
334 kfree(t);
335 return 0;
336}
337
338static int tda7432_get_ctrl(struct i2c_client *client,
339 struct v4l2_control *ctrl)
340{
341 struct tda7432 *t = i2c_get_clientdata(client);
342 303
343 switch (ctrl->id) { 304 switch (ctrl->id) {
344 case V4L2_CID_AUDIO_MUTE: 305 case V4L2_CID_AUDIO_MUTE:
@@ -382,10 +343,9 @@ static int tda7432_get_ctrl(struct i2c_client *client,
382 return -EINVAL; 343 return -EINVAL;
383} 344}
384 345
385static int tda7432_set_ctrl(struct i2c_client *client, 346static int tda7432_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
386 struct v4l2_control *ctrl)
387{ 347{
388 struct tda7432 *t = i2c_get_clientdata(client); 348 struct tda7432 *t = to_state(sd);
389 349
390 switch (ctrl->id) { 350 switch (ctrl->id) {
391 case V4L2_CID_AUDIO_MUTE: 351 case V4L2_CID_AUDIO_MUTE:
@@ -400,7 +360,7 @@ static int tda7432_set_ctrl(struct i2c_client *client,
400 if (loudness) /* Turn on the loudness bit */ 360 if (loudness) /* Turn on the loudness bit */
401 t->volume |= TDA7432_LD_ON; 361 t->volume |= TDA7432_LD_ON;
402 362
403 tda7432_write(client,TDA7432_VL, t->volume); 363 tda7432_write(sd, TDA7432_VL, t->volume);
404 return 0; 364 return 0;
405 case V4L2_CID_AUDIO_BALANCE: 365 case V4L2_CID_AUDIO_BALANCE:
406 if (ctrl->value < 32768) { 366 if (ctrl->value < 32768) {
@@ -428,14 +388,14 @@ static int tda7432_set_ctrl(struct i2c_client *client,
428 if(t->bass>= 0x8) 388 if(t->bass>= 0x8)
429 t->bass = (~t->bass & 0xf) + 0x8 ; 389 t->bass = (~t->bass & 0xf) + 0x8 ;
430 390
431 tda7432_write(client,TDA7432_TN, 0x10 | (t->bass << 4) | t->treble ); 391 tda7432_write(sd, TDA7432_TN, 0x10 | (t->bass << 4) | t->treble);
432 return 0; 392 return 0;
433 case V4L2_CID_AUDIO_TREBLE: 393 case V4L2_CID_AUDIO_TREBLE:
434 t->treble= ctrl->value >> 12; 394 t->treble= ctrl->value >> 12;
435 if(t->treble>= 0x8) 395 if(t->treble>= 0x8)
436 t->treble = (~t->treble & 0xf) + 0x8 ; 396 t->treble = (~t->treble & 0xf) + 0x8 ;
437 397
438 tda7432_write(client,TDA7432_TN, 0x10 | (t->bass << 4) | t->treble ); 398 tda7432_write(sd, TDA7432_TN, 0x10 | (t->bass << 4) | t->treble);
439 return 0; 399 return 0;
440 default: 400 default:
441 return -EINVAL; 401 return -EINVAL;
@@ -445,92 +405,102 @@ static int tda7432_set_ctrl(struct i2c_client *client,
445 if (t->muted) 405 if (t->muted)
446 { 406 {
447 /* Mute & update balance*/ 407 /* Mute & update balance*/
448 tda7432_write(client,TDA7432_LF, t->lf | TDA7432_MUTE); 408 tda7432_write(sd, TDA7432_LF, t->lf | TDA7432_MUTE);
449 tda7432_write(client,TDA7432_LR, t->lr | TDA7432_MUTE); 409 tda7432_write(sd, TDA7432_LR, t->lr | TDA7432_MUTE);
450 tda7432_write(client,TDA7432_RF, t->rf | TDA7432_MUTE); 410 tda7432_write(sd, TDA7432_RF, t->rf | TDA7432_MUTE);
451 tda7432_write(client,TDA7432_RR, t->rr | TDA7432_MUTE); 411 tda7432_write(sd, TDA7432_RR, t->rr | TDA7432_MUTE);
452 } else { 412 } else {
453 tda7432_write(client,TDA7432_LF, t->lf); 413 tda7432_write(sd, TDA7432_LF, t->lf);
454 tda7432_write(client,TDA7432_LR, t->lr); 414 tda7432_write(sd, TDA7432_LR, t->lr);
455 tda7432_write(client,TDA7432_RF, t->rf); 415 tda7432_write(sd, TDA7432_RF, t->rf);
456 tda7432_write(client,TDA7432_RR, t->rr); 416 tda7432_write(sd, TDA7432_RR, t->rr);
457 } 417 }
458 return 0; 418 return 0;
459} 419}
460 420
461static int tda7432_command(struct i2c_client *client, 421static int tda7432_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
462 unsigned int cmd, void *arg)
463{ 422{
464 v4l_dbg(2, debug,client,"In tda7432_command\n"); 423 switch (qc->id) {
465 if (debug>1) 424 case V4L2_CID_AUDIO_MUTE:
466 v4l_i2c_print_ioctl(client,cmd); 425 case V4L2_CID_AUDIO_VOLUME:
467 426 case V4L2_CID_AUDIO_BALANCE:
468 switch (cmd) { 427 case V4L2_CID_AUDIO_BASS:
469 /* --- v4l ioctls --- */ 428 case V4L2_CID_AUDIO_TREBLE:
470 /* take care: bttv does userspace copying, we'll get a
471 kernel pointer here... */
472 case VIDIOC_QUERYCTRL:
473 {
474 struct v4l2_queryctrl *qc = arg;
475
476 switch (qc->id) {
477 case V4L2_CID_AUDIO_MUTE:
478 case V4L2_CID_AUDIO_VOLUME:
479 case V4L2_CID_AUDIO_BALANCE:
480 case V4L2_CID_AUDIO_BASS:
481 case V4L2_CID_AUDIO_TREBLE:
482 default:
483 return -EINVAL;
484 }
485 return v4l2_ctrl_query_fill_std(qc); 429 return v4l2_ctrl_query_fill_std(qc);
486 } 430 }
487 case VIDIOC_S_CTRL: 431 return -EINVAL;
488 return tda7432_set_ctrl(client, arg); 432}
489
490 case VIDIOC_G_CTRL:
491 return tda7432_get_ctrl(client, arg);
492
493 } /* end of (cmd) switch */
494 433
495 return 0; 434static int tda7432_command(struct i2c_client *client, unsigned cmd, void *arg)
435{
436 return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
496} 437}
497 438
498static struct i2c_driver driver = { 439/* ----------------------------------------------------------------------- */
499 .driver = { 440
500 .name = "tda7432", 441static const struct v4l2_subdev_core_ops tda7432_core_ops = {
501 }, 442 .queryctrl = tda7432_queryctrl,
502 .id = I2C_DRIVERID_TDA7432, 443 .g_ctrl = tda7432_g_ctrl,
503 .attach_adapter = tda7432_probe, 444 .s_ctrl = tda7432_s_ctrl,
504 .detach_client = tda7432_detach,
505 .command = tda7432_command,
506}; 445};
507 446
508static struct i2c_client client_template = 447static const struct v4l2_subdev_ops tda7432_ops = {
509{ 448 .core = &tda7432_core_ops,
510 .name = "tda7432",
511 .driver = &driver,
512}; 449};
513 450
514static int __init tda7432_init(void) 451/* ----------------------------------------------------------------------- */
452
453/* *********************** *
454 * i2c interface functions *
455 * *********************** */
456
457static int tda7432_probe(struct i2c_client *client,
458 const struct i2c_device_id *id)
515{ 459{
516 if ( (loudness < 0) || (loudness > 15) ) { 460 struct tda7432 *t;
517 printk(KERN_ERR "loudness parameter must be between 0 and 15\n"); 461 struct v4l2_subdev *sd;
518 return -EINVAL; 462
463 v4l_info(client, "chip found @ 0x%02x (%s)\n",
464 client->addr << 1, client->adapter->name);
465
466 t = kzalloc(sizeof(*t), GFP_KERNEL);
467 if (!t)
468 return -ENOMEM;
469 sd = &t->sd;
470 v4l2_i2c_subdev_init(sd, client, &tda7432_ops);
471 if (loudness < 0 || loudness > 15) {
472 v4l2_warn(sd, "loudness parameter must be between 0 and 15\n");
473 if (loudness < 0)
474 loudness = 0;
475 if (loudness > 15)
476 loudness = 15;
519 } 477 }
520 478
521 return i2c_add_driver(&driver); 479 do_tda7432_init(sd);
480 return 0;
522} 481}
523 482
524static void __exit tda7432_fini(void) 483static int tda7432_remove(struct i2c_client *client)
525{ 484{
526 i2c_del_driver(&driver); 485 struct v4l2_subdev *sd = i2c_get_clientdata(client);
527}
528 486
529module_init(tda7432_init); 487 do_tda7432_init(sd);
530module_exit(tda7432_fini); 488 v4l2_device_unregister_subdev(sd);
489 kfree(to_state(sd));
490 return 0;
491}
531 492
532/* 493static const struct i2c_device_id tda7432_id[] = {
533 * Local variables: 494 { "tda7432", 0 },
534 * c-basic-offset: 8 495 { }
535 * End: 496};
536 */ 497MODULE_DEVICE_TABLE(i2c, tda7432_id);
498
499static struct v4l2_i2c_driver_data v4l2_i2c_data = {
500 .name = "tda7432",
501 .driverid = I2C_DRIVERID_TDA7432,
502 .command = tda7432_command,
503 .probe = tda7432_probe,
504 .remove = tda7432_remove,
505 .id_table = tda7432_id,
506};
diff --git a/drivers/media/video/tda9840.c b/drivers/media/video/tda9840.c
index 1c391f0328fd..2644e0dc9251 100644
--- a/drivers/media/video/tda9840.c
+++ b/drivers/media/video/tda9840.c
@@ -29,7 +29,7 @@
29#include <linux/module.h> 29#include <linux/module.h>
30#include <linux/ioctl.h> 30#include <linux/ioctl.h>
31#include <linux/i2c.h> 31#include <linux/i2c.h>
32#include <media/v4l2-common.h> 32#include <media/v4l2-device.h>
33#include <media/v4l2-i2c-drv-legacy.h> 33#include <media/v4l2-i2c-drv-legacy.h>
34#include "tda9840.h" 34#include "tda9840.h"
35 35
@@ -62,85 +62,89 @@ static unsigned short normal_i2c[] = { I2C_ADDR_TDA9840, I2C_CLIENT_END };
62/* magic definition of all other variables and things */ 62/* magic definition of all other variables and things */
63I2C_CLIENT_INSMOD; 63I2C_CLIENT_INSMOD;
64 64
65static void tda9840_write(struct i2c_client *client, u8 reg, u8 val) 65static void tda9840_write(struct v4l2_subdev *sd, u8 reg, u8 val)
66{ 66{
67 struct i2c_client *client = v4l2_get_subdevdata(sd);
68
67 if (i2c_smbus_write_byte_data(client, reg, val)) 69 if (i2c_smbus_write_byte_data(client, reg, val))
68 v4l_dbg(1, debug, client, "error writing %02x to %02x\n", 70 v4l2_dbg(1, debug, sd, "error writing %02x to %02x\n",
69 val, reg); 71 val, reg);
70} 72}
71 73
72static int tda9840_command(struct i2c_client *client, unsigned cmd, void *arg) 74static int tda9840_s_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *t)
73{ 75{
74 int byte = *(int *)arg; 76 int byte;
75
76 switch (cmd) {
77 case VIDIOC_S_TUNER: {
78 struct v4l2_tuner *t = arg;
79 int byte;
80 77
81 if (t->index) 78 if (t->index)
82 return -EINVAL; 79 return -EINVAL;
83 80
84 switch (t->audmode) { 81 switch (t->audmode) {
85 case V4L2_TUNER_MODE_STEREO: 82 case V4L2_TUNER_MODE_STEREO:
86 byte = TDA9840_SET_STEREO; 83 byte = TDA9840_SET_STEREO;
87 break;
88 case V4L2_TUNER_MODE_LANG1_LANG2:
89 byte = TDA9840_SET_BOTH;
90 break;
91 case V4L2_TUNER_MODE_LANG1:
92 byte = TDA9840_SET_LANG1;
93 break;
94 case V4L2_TUNER_MODE_LANG2:
95 byte = TDA9840_SET_LANG2;
96 break;
97 default:
98 byte = TDA9840_SET_MONO;
99 break;
100 }
101 v4l_dbg(1, debug, client, "TDA9840_SWITCH: 0x%02x\n", byte);
102 tda9840_write(client, SWITCH, byte);
103 break; 84 break;
85 case V4L2_TUNER_MODE_LANG1_LANG2:
86 byte = TDA9840_SET_BOTH;
87 break;
88 case V4L2_TUNER_MODE_LANG1:
89 byte = TDA9840_SET_LANG1;
90 break;
91 case V4L2_TUNER_MODE_LANG2:
92 byte = TDA9840_SET_LANG2;
93 break;
94 default:
95 byte = TDA9840_SET_MONO;
96 break;
97 }
98 v4l2_dbg(1, debug, sd, "TDA9840_SWITCH: 0x%02x\n", byte);
99 tda9840_write(sd, SWITCH, byte);
100 return 0;
101}
102
103static int tda9840_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *t)
104{
105 struct i2c_client *client = v4l2_get_subdevdata(sd);
106 u8 byte;
107
108 t->rxsubchans = V4L2_TUNER_SUB_MONO;
109 if (1 != i2c_master_recv(client, &byte, 1)) {
110 v4l2_dbg(1, debug, sd,
111 "i2c_master_recv() failed\n");
112 return -EIO;
113 }
114
115 if (byte & 0x80) {
116 v4l2_dbg(1, debug, sd,
117 "TDA9840_DETECT: register contents invalid\n");
118 return -EINVAL;
104 } 119 }
105 120
106 case VIDIOC_G_TUNER: { 121 v4l2_dbg(1, debug, sd, "TDA9840_DETECT: byte: 0x%02x\n", byte);
107 struct v4l2_tuner *t = arg;
108 u8 byte;
109 122
123 switch (byte & 0x60) {
124 case 0x00:
110 t->rxsubchans = V4L2_TUNER_SUB_MONO; 125 t->rxsubchans = V4L2_TUNER_SUB_MONO;
111 if (1 != i2c_master_recv(client, &byte, 1)) { 126 break;
112 v4l_dbg(1, debug, client, 127 case 0x20:
113 "i2c_master_recv() failed\n"); 128 t->rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
114 return -EIO; 129 break;
115 } 130 case 0x40:
116 131 t->rxsubchans = V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_MONO;
117 if (byte & 0x80) { 132 break;
118 v4l_dbg(1, debug, client, 133 default: /* Incorrect detect */
119 "TDA9840_DETECT: register contents invalid\n"); 134 t->rxsubchans = V4L2_TUNER_MODE_MONO;
120 return -EINVAL;
121 }
122
123 v4l_dbg(1, debug, client, "TDA9840_DETECT: byte: 0x%02x\n", byte);
124
125 switch (byte & 0x60) {
126 case 0x00:
127 t->rxsubchans = V4L2_TUNER_SUB_MONO;
128 break;
129 case 0x20:
130 t->rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
131 break;
132 case 0x40:
133 t->rxsubchans = V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_MONO;
134 break;
135 default: /* Incorrect detect */
136 t->rxsubchans = V4L2_TUNER_MODE_MONO;
137 break;
138 }
139 break; 135 break;
140 } 136 }
137 return 0;
138}
141 139
140static int tda9840_ioctl(struct v4l2_subdev *sd, unsigned cmd, void *arg)
141{
142 int byte;
143
144 switch (cmd) {
142 case TDA9840_LEVEL_ADJUST: 145 case TDA9840_LEVEL_ADJUST:
143 v4l_dbg(1, debug, client, "TDA9840_LEVEL_ADJUST: %d\n", byte); 146 byte = *(int *)arg;
147 v4l2_dbg(1, debug, sd, "TDA9840_LEVEL_ADJUST: %d\n", byte);
144 148
145 /* check for correct range */ 149 /* check for correct range */
146 if (byte > 25 || byte < -20) 150 if (byte > 25 || byte < -20)
@@ -152,11 +156,12 @@ static int tda9840_command(struct i2c_client *client, unsigned cmd, void *arg)
152 byte += 0x8; 156 byte += 0x8;
153 else 157 else
154 byte = -byte; 158 byte = -byte;
155 tda9840_write(client, LEVEL_ADJUST, byte); 159 tda9840_write(sd, LEVEL_ADJUST, byte);
156 break; 160 break;
157 161
158 case TDA9840_STEREO_ADJUST: 162 case TDA9840_STEREO_ADJUST:
159 v4l_dbg(1, debug, client, "TDA9840_STEREO_ADJUST: %d\n", byte); 163 byte = *(int *)arg;
164 v4l2_dbg(1, debug, sd, "TDA9840_STEREO_ADJUST: %d\n", byte);
160 165
161 /* check for correct range */ 166 /* check for correct range */
162 if (byte > 25 || byte < -24) 167 if (byte > 25 || byte < -24)
@@ -169,18 +174,41 @@ static int tda9840_command(struct i2c_client *client, unsigned cmd, void *arg)
169 else 174 else
170 byte = -byte; 175 byte = -byte;
171 176
172 tda9840_write(client, STEREO_ADJUST, byte); 177 tda9840_write(sd, STEREO_ADJUST, byte);
173 break; 178 break;
174 default: 179 default:
175 return -ENOIOCTLCMD; 180 return -ENOIOCTLCMD;
176 } 181 }
177
178 return 0; 182 return 0;
179} 183}
180 184
185static int tda9840_command(struct i2c_client *client, unsigned cmd, void *arg)
186{
187 return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
188}
189
190/* ----------------------------------------------------------------------- */
191
192static const struct v4l2_subdev_core_ops tda9840_core_ops = {
193 .ioctl = tda9840_ioctl,
194};
195
196static const struct v4l2_subdev_tuner_ops tda9840_tuner_ops = {
197 .s_tuner = tda9840_s_tuner,
198 .g_tuner = tda9840_g_tuner,
199};
200
201static const struct v4l2_subdev_ops tda9840_ops = {
202 .core = &tda9840_core_ops,
203 .tuner = &tda9840_tuner_ops,
204};
205
206/* ----------------------------------------------------------------------- */
207
181static int tda9840_probe(struct i2c_client *client, 208static int tda9840_probe(struct i2c_client *client,
182 const struct i2c_device_id *id) 209 const struct i2c_device_id *id)
183{ 210{
211 struct v4l2_subdev *sd;
184 int result; 212 int result;
185 int byte; 213 int byte;
186 214
@@ -188,23 +216,38 @@ static int tda9840_probe(struct i2c_client *client,
188 if (!i2c_check_functionality(client->adapter, 216 if (!i2c_check_functionality(client->adapter,
189 I2C_FUNC_SMBUS_READ_BYTE_DATA | 217 I2C_FUNC_SMBUS_READ_BYTE_DATA |
190 I2C_FUNC_SMBUS_WRITE_BYTE_DATA)) 218 I2C_FUNC_SMBUS_WRITE_BYTE_DATA))
191 return 0; 219 return -EIO;
192 220
193 v4l_info(client, "chip found @ 0x%x (%s)\n", 221 v4l_info(client, "chip found @ 0x%x (%s)\n",
194 client->addr << 1, client->adapter->name); 222 client->addr << 1, client->adapter->name);
195 223
224 sd = kmalloc(sizeof(struct v4l2_subdev), GFP_KERNEL);
225 if (sd == NULL)
226 return -ENOMEM;
227 v4l2_i2c_subdev_init(sd, client, &tda9840_ops);
228
196 /* set initial values for level & stereo - adjustment, mode */ 229 /* set initial values for level & stereo - adjustment, mode */
197 byte = 0; 230 byte = 0;
198 result = tda9840_command(client, TDA9840_LEVEL_ADJUST, &byte); 231 result = tda9840_ioctl(sd, TDA9840_LEVEL_ADJUST, &byte);
199 result += tda9840_command(client, TDA9840_STEREO_ADJUST, &byte); 232 result |= tda9840_ioctl(sd, TDA9840_STEREO_ADJUST, &byte);
200 tda9840_write(client, SWITCH, TDA9840_SET_STEREO); 233 tda9840_write(sd, SWITCH, TDA9840_SET_STEREO);
201 if (result) { 234 if (result) {
202 v4l_dbg(1, debug, client, "could not initialize tda9840\n"); 235 v4l2_dbg(1, debug, sd, "could not initialize tda9840\n");
236 kfree(sd);
203 return -ENODEV; 237 return -ENODEV;
204 } 238 }
205 return 0; 239 return 0;
206} 240}
207 241
242static int tda9840_remove(struct i2c_client *client)
243{
244 struct v4l2_subdev *sd = i2c_get_clientdata(client);
245
246 v4l2_device_unregister_subdev(sd);
247 kfree(sd);
248 return 0;
249}
250
208static int tda9840_legacy_probe(struct i2c_adapter *adapter) 251static int tda9840_legacy_probe(struct i2c_adapter *adapter)
209{ 252{
210 /* Let's see whether this is a known adapter we can attach to. 253 /* Let's see whether this is a known adapter we can attach to.
@@ -222,6 +265,7 @@ static struct v4l2_i2c_driver_data v4l2_i2c_data = {
222 .driverid = I2C_DRIVERID_TDA9840, 265 .driverid = I2C_DRIVERID_TDA9840,
223 .command = tda9840_command, 266 .command = tda9840_command,
224 .probe = tda9840_probe, 267 .probe = tda9840_probe,
268 .remove = tda9840_remove,
225 .legacy_probe = tda9840_legacy_probe, 269 .legacy_probe = tda9840_legacy_probe,
226 .id_table = tda9840_id, 270 .id_table = tda9840_id,
227}; 271};
diff --git a/drivers/media/video/tda9875.c b/drivers/media/video/tda9875.c
index 792f0b079909..56f0c0eb500f 100644
--- a/drivers/media/video/tda9875.c
+++ b/drivers/media/video/tda9875.c
@@ -25,11 +25,10 @@
25#include <linux/delay.h> 25#include <linux/delay.h>
26#include <linux/errno.h> 26#include <linux/errno.h>
27#include <linux/slab.h> 27#include <linux/slab.h>
28#include <linux/videodev2.h>
29#include <media/v4l2-common.h>
30#include <linux/i2c.h> 28#include <linux/i2c.h>
31#include <linux/init.h> 29#include <linux/videodev2.h>
32 30#include <media/v4l2-device.h>
31#include <media/v4l2-i2c-drv-legacy.h>
33#include <media/i2c-addr.h> 32#include <media/i2c-addr.h>
34 33
35static int debug; /* insmod parameter */ 34static int debug; /* insmod parameter */
@@ -46,13 +45,15 @@ I2C_CLIENT_INSMOD;
46 45
47/* This is a superset of the TDA9875 */ 46/* This is a superset of the TDA9875 */
48struct tda9875 { 47struct tda9875 {
48 struct v4l2_subdev sd;
49 int rvol, lvol; 49 int rvol, lvol;
50 int bass, treble; 50 int bass, treble;
51 struct i2c_client c;
52}; 51};
53 52
54static struct i2c_driver driver; 53static inline struct tda9875 *to_state(struct v4l2_subdev *sd)
55static struct i2c_client client_template; 54{
55 return container_of(sd, struct tda9875, sd);
56}
56 57
57#define dprintk if (debug) printk 58#define dprintk if (debug) printk
58 59
@@ -105,15 +106,16 @@ static struct i2c_client client_template;
105 106
106/* Begin code */ 107/* Begin code */
107 108
108static int tda9875_write(struct i2c_client *client, int subaddr, unsigned char val) 109static int tda9875_write(struct v4l2_subdev *sd, int subaddr, unsigned char val)
109{ 110{
111 struct i2c_client *client = v4l2_get_subdevdata(sd);
110 unsigned char buffer[2]; 112 unsigned char buffer[2];
111 dprintk("In tda9875_write\n"); 113
112 dprintk("Writing %d 0x%x\n", subaddr, val); 114 v4l2_dbg(1, debug, sd, "Writing %d 0x%x\n", subaddr, val);
113 buffer[0] = subaddr; 115 buffer[0] = subaddr;
114 buffer[1] = val; 116 buffer[1] = val;
115 if (2 != i2c_master_send(client,buffer,2)) { 117 if (2 != i2c_master_send(client, buffer, 2)) {
116 printk(KERN_WARNING "tda9875: I/O error, trying (write %d 0x%x)\n", 118 v4l2_warn(sd, "I/O error, trying (write %d 0x%x)\n",
117 subaddr, val); 119 subaddr, val);
118 return -1; 120 return -1;
119 } 121 }
@@ -121,7 +123,7 @@ static int tda9875_write(struct i2c_client *client, int subaddr, unsigned char v
121} 123}
122 124
123 125
124static int i2c_read_register(struct i2c_adapter *adap, int addr, int reg) 126static int i2c_read_register(struct i2c_client *client, int addr, int reg)
125{ 127{
126 unsigned char write[1]; 128 unsigned char write[1];
127 unsigned char read[1]; 129 unsigned char read[1];
@@ -129,150 +131,83 @@ static int i2c_read_register(struct i2c_adapter *adap, int addr, int reg)
129 { addr, 0, 1, write }, 131 { addr, 0, 1, write },
130 { addr, I2C_M_RD, 1, read } 132 { addr, I2C_M_RD, 1, read }
131 }; 133 };
134
132 write[0] = reg; 135 write[0] = reg;
133 136
134 if (2 != i2c_transfer(adap,msgs,2)) { 137 if (2 != i2c_transfer(client->adapter, msgs, 2)) {
135 printk(KERN_WARNING "tda9875: I/O error (read2)\n"); 138 v4l_warn(client, "I/O error (read2)\n");
136 return -1; 139 return -1;
137 } 140 }
138 dprintk("tda9875: chip_read2: reg%d=0x%x\n",reg,read[0]); 141 v4l_dbg(1, debug, client, "chip_read2: reg%d=0x%x\n", reg, read[0]);
139 return read[0]; 142 return read[0];
140} 143}
141 144
142static void tda9875_set(struct i2c_client *client) 145static void tda9875_set(struct v4l2_subdev *sd)
143{ 146{
144 struct tda9875 *tda = i2c_get_clientdata(client); 147 struct tda9875 *tda = to_state(sd);
145 unsigned char a; 148 unsigned char a;
146 149
147 dprintk(KERN_DEBUG "tda9875_set(%04x,%04x,%04x,%04x)\n", 150 v4l2_dbg(1, debug, sd, "tda9875_set(%04x,%04x,%04x,%04x)\n",
148 tda->lvol,tda->rvol,tda->bass,tda->treble); 151 tda->lvol, tda->rvol, tda->bass, tda->treble);
149
150 152
151 a = tda->lvol & 0xff; 153 a = tda->lvol & 0xff;
152 tda9875_write(client, TDA9875_MVL, a); 154 tda9875_write(sd, TDA9875_MVL, a);
153 a =tda->rvol & 0xff; 155 a =tda->rvol & 0xff;
154 tda9875_write(client, TDA9875_MVR, a); 156 tda9875_write(sd, TDA9875_MVR, a);
155 a =tda->bass & 0xff; 157 a =tda->bass & 0xff;
156 tda9875_write(client, TDA9875_MBA, a); 158 tda9875_write(sd, TDA9875_MBA, a);
157 a =tda->treble & 0xff; 159 a =tda->treble & 0xff;
158 tda9875_write(client, TDA9875_MTR, a); 160 tda9875_write(sd, TDA9875_MTR, a);
159} 161}
160 162
161static void do_tda9875_init(struct i2c_client *client) 163static void do_tda9875_init(struct v4l2_subdev *sd)
162{ 164{
163 struct tda9875 *t = i2c_get_clientdata(client); 165 struct tda9875 *t = to_state(sd);
164 dprintk("In tda9875_init\n"); 166
165 tda9875_write(client, TDA9875_CFG, 0xd0 ); /*reg de config 0 (reset)*/ 167 v4l2_dbg(1, debug, sd, "In tda9875_init\n");
166 tda9875_write(client, TDA9875_MSR, 0x03 ); /* Monitor 0b00000XXX*/ 168 tda9875_write(sd, TDA9875_CFG, 0xd0); /*reg de config 0 (reset)*/
167 tda9875_write(client, TDA9875_C1MSB, 0x00 ); /*Car1(FM) MSB XMHz*/ 169 tda9875_write(sd, TDA9875_MSR, 0x03); /* Monitor 0b00000XXX*/
168 tda9875_write(client, TDA9875_C1MIB, 0x00 ); /*Car1(FM) MIB XMHz*/ 170 tda9875_write(sd, TDA9875_C1MSB, 0x00); /*Car1(FM) MSB XMHz*/
169 tda9875_write(client, TDA9875_C1LSB, 0x00 ); /*Car1(FM) LSB XMHz*/ 171 tda9875_write(sd, TDA9875_C1MIB, 0x00); /*Car1(FM) MIB XMHz*/
170 tda9875_write(client, TDA9875_C2MSB, 0x00 ); /*Car2(NICAM) MSB XMHz*/ 172 tda9875_write(sd, TDA9875_C1LSB, 0x00); /*Car1(FM) LSB XMHz*/
171 tda9875_write(client, TDA9875_C2MIB, 0x00 ); /*Car2(NICAM) MIB XMHz*/ 173 tda9875_write(sd, TDA9875_C2MSB, 0x00); /*Car2(NICAM) MSB XMHz*/
172 tda9875_write(client, TDA9875_C2LSB, 0x00 ); /*Car2(NICAM) LSB XMHz*/ 174 tda9875_write(sd, TDA9875_C2MIB, 0x00); /*Car2(NICAM) MIB XMHz*/
173 tda9875_write(client, TDA9875_DCR, 0x00 ); /*Demod config 0x00*/ 175 tda9875_write(sd, TDA9875_C2LSB, 0x00); /*Car2(NICAM) LSB XMHz*/
174 tda9875_write(client, TDA9875_DEEM, 0x44 ); /*DE-Emph 0b0100 0100*/ 176 tda9875_write(sd, TDA9875_DCR, 0x00); /*Demod config 0x00*/
175 tda9875_write(client, TDA9875_FMAT, 0x00 ); /*FM Matrix reg 0x00*/ 177 tda9875_write(sd, TDA9875_DEEM, 0x44); /*DE-Emph 0b0100 0100*/
176 tda9875_write(client, TDA9875_SC1, 0x00 ); /* SCART 1 (SC1)*/ 178 tda9875_write(sd, TDA9875_FMAT, 0x00); /*FM Matrix reg 0x00*/
177 tda9875_write(client, TDA9875_SC2, 0x01 ); /* SCART 2 (sc2)*/ 179 tda9875_write(sd, TDA9875_SC1, 0x00); /* SCART 1 (SC1)*/
178 180 tda9875_write(sd, TDA9875_SC2, 0x01); /* SCART 2 (sc2)*/
179 tda9875_write(client, TDA9875_CH1V, 0x10 ); /* Channel volume 1 mute*/ 181
180 tda9875_write(client, TDA9875_CH2V, 0x10 ); /* Channel volume 2 mute */ 182 tda9875_write(sd, TDA9875_CH1V, 0x10); /* Channel volume 1 mute*/
181 tda9875_write(client, TDA9875_DACOS, 0x02 ); /* sig DAC i/o(in:nicam)*/ 183 tda9875_write(sd, TDA9875_CH2V, 0x10); /* Channel volume 2 mute */
182 tda9875_write(client, TDA9875_ADCIS, 0x6f ); /* sig ADC input(in:mono)*/ 184 tda9875_write(sd, TDA9875_DACOS, 0x02); /* sig DAC i/o(in:nicam)*/
183 tda9875_write(client, TDA9875_LOSR, 0x00 ); /* line out (in:mono)*/ 185 tda9875_write(sd, TDA9875_ADCIS, 0x6f); /* sig ADC input(in:mono)*/
184 tda9875_write(client, TDA9875_AER, 0x00 ); /*06 Effect (AVL+PSEUDO) */ 186 tda9875_write(sd, TDA9875_LOSR, 0x00); /* line out (in:mono)*/
185 tda9875_write(client, TDA9875_MCS, 0x44 ); /* Main ch select (DAC) */ 187 tda9875_write(sd, TDA9875_AER, 0x00); /*06 Effect (AVL+PSEUDO) */
186 tda9875_write(client, TDA9875_MVL, 0x03 ); /* Vol Main left 10dB */ 188 tda9875_write(sd, TDA9875_MCS, 0x44); /* Main ch select (DAC) */
187 tda9875_write(client, TDA9875_MVR, 0x03 ); /* Vol Main right 10dB*/ 189 tda9875_write(sd, TDA9875_MVL, 0x03); /* Vol Main left 10dB */
188 tda9875_write(client, TDA9875_MBA, 0x00 ); /* Main Bass Main 0dB*/ 190 tda9875_write(sd, TDA9875_MVR, 0x03); /* Vol Main right 10dB*/
189 tda9875_write(client, TDA9875_MTR, 0x00 ); /* Main Treble Main 0dB*/ 191 tda9875_write(sd, TDA9875_MBA, 0x00); /* Main Bass Main 0dB*/
190 tda9875_write(client, TDA9875_ACS, 0x44 ); /* Aux chan select (dac)*/ 192 tda9875_write(sd, TDA9875_MTR, 0x00); /* Main Treble Main 0dB*/
191 tda9875_write(client, TDA9875_AVL, 0x00 ); /* Vol Aux left 0dB*/ 193 tda9875_write(sd, TDA9875_ACS, 0x44); /* Aux chan select (dac)*/
192 tda9875_write(client, TDA9875_AVR, 0x00 ); /* Vol Aux right 0dB*/ 194 tda9875_write(sd, TDA9875_AVL, 0x00); /* Vol Aux left 0dB*/
193 tda9875_write(client, TDA9875_ABA, 0x00 ); /* Aux Bass Main 0dB*/ 195 tda9875_write(sd, TDA9875_AVR, 0x00); /* Vol Aux right 0dB*/
194 tda9875_write(client, TDA9875_ATR, 0x00 ); /* Aux Aigus Main 0dB*/ 196 tda9875_write(sd, TDA9875_ABA, 0x00); /* Aux Bass Main 0dB*/
195 197 tda9875_write(sd, TDA9875_ATR, 0x00); /* Aux Aigus Main 0dB*/
196 tda9875_write(client, TDA9875_MUT, 0xcc ); /* General mute */ 198
197 199 tda9875_write(sd, TDA9875_MUT, 0xcc); /* General mute */
198 t->lvol=t->rvol =0; /* 0dB */ 200
199 t->bass=0; /* 0dB */ 201 t->lvol = t->rvol = 0; /* 0dB */
200 t->treble=0; /* 0dB */ 202 t->bass = 0; /* 0dB */
201 tda9875_set(client); 203 t->treble = 0; /* 0dB */
202 204 tda9875_set(sd);
203} 205}
204 206
205 207
206/* *********************** * 208static int tda9875_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
207 * i2c interface functions *
208 * *********************** */
209
210static int tda9875_checkit(struct i2c_adapter *adap, int addr)
211{
212 int dic,rev;
213
214 dic=i2c_read_register(adap,addr,254);
215 rev=i2c_read_register(adap,addr,255);
216
217 if(dic==0 || dic==2) { // tda9875 and tda9875A
218 printk("tda9875: TDA9875%s Rev.%d detected at 0x%x\n",
219 dic==0?"":"A", rev,addr<<1);
220 return 1;
221 }
222 printk("tda9875: no such chip at 0x%x (dic=0x%x rev=0x%x)\n",addr<<1,dic,rev);
223 return(0);
224}
225
226static int tda9875_attach(struct i2c_adapter *adap, int addr, int kind)
227{ 209{
228 struct tda9875 *t; 210 struct tda9875 *t = to_state(sd);
229 struct i2c_client *client;
230 dprintk("In tda9875_attach\n");
231
232 t = kzalloc(sizeof *t,GFP_KERNEL);
233 if (!t)
234 return -ENOMEM;
235
236 client = &t->c;
237 memcpy(client,&client_template,sizeof(struct i2c_client));
238 client->adapter = adap;
239 client->addr = addr;
240 i2c_set_clientdata(client, t);
241
242 if(!tda9875_checkit(adap,addr)) {
243 kfree(t);
244 return 1;
245 }
246
247 do_tda9875_init(client);
248 printk(KERN_INFO "tda9875: init\n");
249
250 i2c_attach_client(client);
251 return 0;
252}
253
254static int tda9875_probe(struct i2c_adapter *adap)
255{
256 if (adap->class & I2C_CLASS_TV_ANALOG)
257 return i2c_probe(adap, &addr_data, tda9875_attach);
258 return 0;
259}
260
261static int tda9875_detach(struct i2c_client *client)
262{
263 struct tda9875 *t = i2c_get_clientdata(client);
264
265 do_tda9875_init(client);
266 i2c_detach_client(client);
267
268 kfree(t);
269 return 0;
270}
271
272static int tda9875_get_ctrl(struct i2c_client *client,
273 struct v4l2_control *ctrl)
274{
275 struct tda9875 *t = i2c_get_clientdata(client);
276 211
277 switch (ctrl->id) { 212 switch (ctrl->id) {
278 case V4L2_CID_AUDIO_VOLUME: 213 case V4L2_CID_AUDIO_VOLUME:
@@ -304,10 +239,9 @@ static int tda9875_get_ctrl(struct i2c_client *client,
304 return -EINVAL; 239 return -EINVAL;
305} 240}
306 241
307static int tda9875_set_ctrl(struct i2c_client *client, 242static int tda9875_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
308 struct v4l2_control *ctrl)
309{ 243{
310 struct tda9875 *t = i2c_get_clientdata(client); 244 struct tda9875 *t = to_state(sd);
311 int chvol=0, volume, balance, left, right; 245 int chvol=0, volume, balance, left, right;
312 246
313 switch (ctrl->id) { 247 switch (ctrl->id) {
@@ -371,85 +305,105 @@ static int tda9875_set_ctrl(struct i2c_client *client,
371 t->rvol = -84 & 0xff; 305 t->rvol = -84 & 0xff;
372 } 306 }
373 307
374//printk("tda9875 bal:%04x vol:%04x bass:%04x treble:%04x\n",va->balance,va->volume,va->bass,va->treble); 308 tda9875_set(sd);
375
376 tda9875_set(client);
377
378 return 0; 309 return 0;
379} 310}
380 311
381 312static int tda9875_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
382static int tda9875_command(struct i2c_client *client,
383 unsigned int cmd, void *arg)
384{ 313{
385 dprintk("In tda9875_command...\n"); 314 switch (qc->id) {
386 315 case V4L2_CID_AUDIO_VOLUME:
387 switch (cmd) { 316 case V4L2_CID_AUDIO_BASS:
388 /* --- v4l ioctls --- */ 317 case V4L2_CID_AUDIO_TREBLE:
389 /* take care: bttv does userspace copying, we'll get a
390 kernel pointer here... */
391 case VIDIOC_QUERYCTRL:
392 {
393 struct v4l2_queryctrl *qc = arg;
394
395 switch (qc->id) {
396 case V4L2_CID_AUDIO_VOLUME:
397 case V4L2_CID_AUDIO_BASS:
398 case V4L2_CID_AUDIO_TREBLE:
399 default:
400 return -EINVAL;
401 }
402 return v4l2_ctrl_query_fill_std(qc); 318 return v4l2_ctrl_query_fill_std(qc);
403 } 319 }
404 case VIDIOC_S_CTRL: 320 return -EINVAL;
405 return tda9875_set_ctrl(client, arg); 321}
406 322
407 case VIDIOC_G_CTRL: 323static int tda9875_command(struct i2c_client *client, unsigned cmd, void *arg)
408 return tda9875_get_ctrl(client, arg); 324{
325 return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
326}
409 327
410 default: /* Not VIDEOCGAUDIO or VIDEOCSAUDIO */ 328/* ----------------------------------------------------------------------- */
411 329
412 /* nothing */ 330static const struct v4l2_subdev_core_ops tda9875_core_ops = {
413 dprintk("Default\n"); 331 .queryctrl = tda9875_queryctrl,
332 .g_ctrl = tda9875_g_ctrl,
333 .s_ctrl = tda9875_s_ctrl,
334};
414 335
415 } /* end of (cmd) switch */ 336static const struct v4l2_subdev_ops tda9875_ops = {
337 .core = &tda9875_core_ops,
338};
416 339
417 return 0; 340/* ----------------------------------------------------------------------- */
418}
419 341
420 342
421static struct i2c_driver driver = { 343/* *********************** *
422 .driver = { 344 * i2c interface functions *
423 .name = "tda9875", 345 * *********************** */
424 },
425 .id = I2C_DRIVERID_TDA9875,
426 .attach_adapter = tda9875_probe,
427 .detach_client = tda9875_detach,
428 .command = tda9875_command,
429};
430 346
431static struct i2c_client client_template = 347static int tda9875_checkit(struct i2c_client *client, int addr)
432{ 348{
433 .name = "tda9875", 349 int dic, rev;
434 .driver = &driver,
435};
436 350
437static int __init tda9875_init(void) 351 dic = i2c_read_register(client, addr, 254);
438{ 352 rev = i2c_read_register(client, addr, 255);
439 return i2c_add_driver(&driver); 353
354 if (dic == 0 || dic == 2) { /* tda9875 and tda9875A */
355 v4l_info(client, "tda9875%s rev. %d detected at 0x%02x\n",
356 dic == 0 ? "" : "A", rev, addr << 1);
357 return 1;
358 }
359 v4l_info(client, "no such chip at 0x%02x (dic=0x%x rev=0x%x)\n",
360 addr << 1, dic, rev);
361 return 0;
440} 362}
441 363
442static void __exit tda9875_fini(void) 364static int tda9875_probe(struct i2c_client *client,
365 const struct i2c_device_id *id)
443{ 366{
444 i2c_del_driver(&driver); 367 struct tda9875 *t;
368 struct v4l2_subdev *sd;
369
370 v4l_info(client, "chip found @ 0x%02x (%s)\n",
371 client->addr << 1, client->adapter->name);
372
373 if (!tda9875_checkit(client, client->addr))
374 return -ENODEV;
375
376 t = kzalloc(sizeof(*t), GFP_KERNEL);
377 if (!t)
378 return -ENOMEM;
379 sd = &t->sd;
380 v4l2_i2c_subdev_init(sd, client, &tda9875_ops);
381
382 do_tda9875_init(sd);
383 return 0;
445} 384}
446 385
447module_init(tda9875_init); 386static int tda9875_remove(struct i2c_client *client)
448module_exit(tda9875_fini); 387{
388 struct v4l2_subdev *sd = i2c_get_clientdata(client);
449 389
450/* 390 do_tda9875_init(sd);
451 * Local variables: 391 v4l2_device_unregister_subdev(sd);
452 * c-basic-offset: 8 392 kfree(to_state(sd));
453 * End: 393 return 0;
454 */ 394}
455 395
396static const struct i2c_device_id tda9875_id[] = {
397 { "tda9875", 0 },
398 { }
399};
400MODULE_DEVICE_TABLE(i2c, tda9875_id);
401
402static struct v4l2_i2c_driver_data v4l2_i2c_data = {
403 .name = "tda9875",
404 .driverid = I2C_DRIVERID_TDA9875,
405 .command = tda9875_command,
406 .probe = tda9875_probe,
407 .remove = tda9875_remove,
408 .id_table = tda9875_id,
409};
diff --git a/drivers/media/video/tea6415c.c b/drivers/media/video/tea6415c.c
index cde092adbb5a..31dde86f2df4 100644
--- a/drivers/media/video/tea6415c.c
+++ b/drivers/media/video/tea6415c.c
@@ -31,7 +31,7 @@
31#include <linux/module.h> 31#include <linux/module.h>
32#include <linux/ioctl.h> 32#include <linux/ioctl.h>
33#include <linux/i2c.h> 33#include <linux/i2c.h>
34#include <media/v4l2-common.h> 34#include <media/v4l2-device.h>
35#include <media/v4l2-i2c-drv-legacy.h> 35#include <media/v4l2-i2c-drv-legacy.h>
36#include "tea6415c.h" 36#include "tea6415c.h"
37 37
@@ -122,31 +122,57 @@ static int switch_matrix(struct i2c_client *client, int i, int o)
122 return ret; 122 return ret;
123} 123}
124 124
125static int tea6415c_command(struct i2c_client *client, unsigned cmd, void *arg) 125static int tea6415c_ioctl(struct v4l2_subdev *sd, unsigned cmd, void *arg)
126{ 126{
127 struct tea6415c_multiplex *v = (struct tea6415c_multiplex *)arg; 127 if (cmd == TEA6415C_SWITCH) {
128 int result = 0; 128 struct i2c_client *client = v4l2_get_subdevdata(sd);
129 struct tea6415c_multiplex *v = (struct tea6415c_multiplex *)arg;
129 130
130 switch (cmd) { 131 return switch_matrix(client, v->in, v->out);
131 case TEA6415C_SWITCH:
132 result = switch_matrix(client, v->in, v->out);
133 break;
134 default:
135 return -ENOIOCTLCMD;
136 } 132 }
137 return result; 133 return -ENOIOCTLCMD;
138} 134}
139 135
136static int tea6415c_command(struct i2c_client *client, unsigned cmd, void *arg)
137{
138 return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
139}
140
141/* ----------------------------------------------------------------------- */
142
143static const struct v4l2_subdev_core_ops tea6415c_core_ops = {
144 .ioctl = tea6415c_ioctl,
145};
146
147static const struct v4l2_subdev_ops tea6415c_ops = {
148 .core = &tea6415c_core_ops,
149};
150
140/* this function is called by i2c_probe */ 151/* this function is called by i2c_probe */
141static int tea6415c_probe(struct i2c_client *client, 152static int tea6415c_probe(struct i2c_client *client,
142 const struct i2c_device_id *id) 153 const struct i2c_device_id *id)
143{ 154{
155 struct v4l2_subdev *sd;
156
144 /* let's see whether this adapter can support what we need */ 157 /* let's see whether this adapter can support what we need */
145 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_WRITE_BYTE)) 158 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_WRITE_BYTE))
146 return 0; 159 return 0;
147 160
148 v4l_info(client, "chip found @ 0x%x (%s)\n", 161 v4l_info(client, "chip found @ 0x%x (%s)\n",
149 client->addr << 1, client->adapter->name); 162 client->addr << 1, client->adapter->name);
163 sd = kmalloc(sizeof(struct v4l2_subdev), GFP_KERNEL);
164 if (sd == NULL)
165 return -ENOMEM;
166 v4l2_i2c_subdev_init(sd, client, &tea6415c_ops);
167 return 0;
168}
169
170static int tea6415c_remove(struct i2c_client *client)
171{
172 struct v4l2_subdev *sd = i2c_get_clientdata(client);
173
174 v4l2_device_unregister_subdev(sd);
175 kfree(sd);
150 return 0; 176 return 0;
151} 177}
152 178
@@ -168,6 +194,7 @@ static struct v4l2_i2c_driver_data v4l2_i2c_data = {
168 .driverid = I2C_DRIVERID_TEA6415C, 194 .driverid = I2C_DRIVERID_TEA6415C,
169 .command = tea6415c_command, 195 .command = tea6415c_command,
170 .probe = tea6415c_probe, 196 .probe = tea6415c_probe,
197 .remove = tea6415c_remove,
171 .legacy_probe = tea6415c_legacy_probe, 198 .legacy_probe = tea6415c_legacy_probe,
172 .id_table = tea6415c_id, 199 .id_table = tea6415c_id,
173}; 200};
diff --git a/drivers/media/video/tea6420.c b/drivers/media/video/tea6420.c
index e50820969e64..38e519f04bde 100644
--- a/drivers/media/video/tea6420.c
+++ b/drivers/media/video/tea6420.c
@@ -31,7 +31,7 @@
31#include <linux/module.h> 31#include <linux/module.h>
32#include <linux/ioctl.h> 32#include <linux/ioctl.h>
33#include <linux/i2c.h> 33#include <linux/i2c.h>
34#include <media/v4l2-common.h> 34#include <media/v4l2-device.h>
35#include <media/v4l2-i2c-drv-legacy.h> 35#include <media/v4l2-i2c-drv-legacy.h>
36#include "tea6420.h" 36#include "tea6420.h"
37 37
@@ -90,26 +90,37 @@ static int tea6420_switch(struct i2c_client *client, int i, int o, int g)
90 return 0; 90 return 0;
91} 91}
92 92
93static int tea6420_command(struct i2c_client *client, unsigned cmd, void *arg) 93static int tea6420_ioctl(struct v4l2_subdev *sd, unsigned cmd, void *arg)
94{ 94{
95 struct tea6420_multiplex *a = (struct tea6420_multiplex *)arg; 95 if (cmd == TEA6420_SWITCH) {
96 int result = 0; 96 struct i2c_client *client = v4l2_get_subdevdata(sd);
97 struct tea6420_multiplex *a = (struct tea6420_multiplex *)arg;
97 98
98 switch (cmd) { 99 return tea6420_switch(client, a->in, a->out, a->gain);
99 case TEA6420_SWITCH:
100 result = tea6420_switch(client, a->in, a->out, a->gain);
101 break;
102 default:
103 return -ENOIOCTLCMD;
104 } 100 }
101 return -ENOIOCTLCMD;
102}
105 103
106 return result; 104static int tea6420_command(struct i2c_client *client, unsigned cmd, void *arg)
105{
106 return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
107} 107}
108 108
109/* ----------------------------------------------------------------------- */
110
111static const struct v4l2_subdev_core_ops tea6420_core_ops = {
112 .ioctl = tea6420_ioctl,
113};
114
115static const struct v4l2_subdev_ops tea6420_ops = {
116 .core = &tea6420_core_ops,
117};
118
109/* this function is called by i2c_probe */ 119/* this function is called by i2c_probe */
110static int tea6420_probe(struct i2c_client *client, 120static int tea6420_probe(struct i2c_client *client,
111 const struct i2c_device_id *id) 121 const struct i2c_device_id *id)
112{ 122{
123 struct v4l2_subdev *sd;
113 int err, i; 124 int err, i;
114 125
115 /* let's see whether this adapter can support what we need */ 126 /* let's see whether this adapter can support what we need */
@@ -126,9 +137,22 @@ static int tea6420_probe(struct i2c_client *client,
126 } 137 }
127 if (err) { 138 if (err) {
128 v4l_dbg(1, debug, client, "could not initialize tea6420\n"); 139 v4l_dbg(1, debug, client, "could not initialize tea6420\n");
129 kfree(client);
130 return -ENODEV; 140 return -ENODEV;
131 } 141 }
142
143 sd = kmalloc(sizeof(struct v4l2_subdev), GFP_KERNEL);
144 if (sd == NULL)
145 return -ENOMEM;
146 v4l2_i2c_subdev_init(sd, client, &tea6420_ops);
147 return 0;
148}
149
150static int tea6420_remove(struct i2c_client *client)
151{
152 struct v4l2_subdev *sd = i2c_get_clientdata(client);
153
154 v4l2_device_unregister_subdev(sd);
155 kfree(sd);
132 return 0; 156 return 0;
133} 157}
134 158
@@ -150,6 +174,7 @@ static struct v4l2_i2c_driver_data v4l2_i2c_data = {
150 .driverid = I2C_DRIVERID_TEA6420, 174 .driverid = I2C_DRIVERID_TEA6420,
151 .command = tea6420_command, 175 .command = tea6420_command,
152 .probe = tea6420_probe, 176 .probe = tea6420_probe,
177 .remove = tea6420_remove,
153 .legacy_probe = tea6420_legacy_probe, 178 .legacy_probe = tea6420_legacy_probe,
154 .id_table = tea6420_id, 179 .id_table = tea6420_id,
155}; 180};
diff --git a/drivers/media/video/tlv320aic23b.c b/drivers/media/video/tlv320aic23b.c
index 281065b9dd2d..5c95ecd09dc2 100644
--- a/drivers/media/video/tlv320aic23b.c
+++ b/drivers/media/video/tlv320aic23b.c
@@ -30,7 +30,7 @@
30#include <linux/i2c.h> 30#include <linux/i2c.h>
31#include <linux/i2c-id.h> 31#include <linux/i2c-id.h>
32#include <linux/videodev2.h> 32#include <linux/videodev2.h>
33#include <media/v4l2-common.h> 33#include <media/v4l2-device.h>
34#include <media/v4l2-i2c-drv-legacy.h> 34#include <media/v4l2-i2c-drv-legacy.h>
35 35
36MODULE_DESCRIPTION("tlv320aic23b driver"); 36MODULE_DESCRIPTION("tlv320aic23b driver");
@@ -44,15 +44,22 @@ I2C_CLIENT_INSMOD;
44/* ----------------------------------------------------------------------- */ 44/* ----------------------------------------------------------------------- */
45 45
46struct tlv320aic23b_state { 46struct tlv320aic23b_state {
47 struct v4l2_subdev sd;
47 u8 muted; 48 u8 muted;
48}; 49};
49 50
50static int tlv320aic23b_write(struct i2c_client *client, int reg, u16 val) 51static inline struct tlv320aic23b_state *to_state(struct v4l2_subdev *sd)
51{ 52{
53 return container_of(sd, struct tlv320aic23b_state, sd);
54}
55
56static int tlv320aic23b_write(struct v4l2_subdev *sd, int reg, u16 val)
57{
58 struct i2c_client *client = v4l2_get_subdevdata(sd);
52 int i; 59 int i;
53 60
54 if ((reg < 0 || reg > 9) && (reg != 15)) { 61 if ((reg < 0 || reg > 9) && (reg != 15)) {
55 v4l_err(client, "Invalid register R%d\n", reg); 62 v4l2_err(sd, "Invalid register R%d\n", reg);
56 return -1; 63 return -1;
57 } 64 }
58 65
@@ -60,61 +67,82 @@ static int tlv320aic23b_write(struct i2c_client *client, int reg, u16 val)
60 if (i2c_smbus_write_byte_data(client, 67 if (i2c_smbus_write_byte_data(client,
61 (reg << 1) | (val >> 8), val & 0xff) == 0) 68 (reg << 1) | (val >> 8), val & 0xff) == 0)
62 return 0; 69 return 0;
63 v4l_err(client, "I2C: cannot write %03x to register R%d\n", val, reg); 70 v4l2_err(sd, "I2C: cannot write %03x to register R%d\n", val, reg);
64 return -1; 71 return -1;
65} 72}
66 73
67static int tlv320aic23b_command(struct i2c_client *client, 74static int tlv320aic23b_s_clock_freq(struct v4l2_subdev *sd, u32 freq)
68 unsigned int cmd, void *arg)
69{ 75{
70 struct tlv320aic23b_state *state = i2c_get_clientdata(client); 76 switch (freq) {
71 struct v4l2_control *ctrl = arg; 77 case 32000: /* set sample rate to 32 kHz */
72 u32 *freq = arg; 78 tlv320aic23b_write(sd, 8, 0x018);
73
74 switch (cmd) {
75 case VIDIOC_INT_AUDIO_CLOCK_FREQ:
76 switch (*freq) {
77 case 32000: /* set sample rate to 32 kHz */
78 tlv320aic23b_write(client, 8, 0x018);
79 break;
80 case 44100: /* set sample rate to 44.1 kHz */
81 tlv320aic23b_write(client, 8, 0x022);
82 break;
83 case 48000: /* set sample rate to 48 kHz */
84 tlv320aic23b_write(client, 8, 0x000);
85 break;
86 default:
87 return -EINVAL;
88 }
89 break;
90
91 case VIDIOC_G_CTRL:
92 if (ctrl->id != V4L2_CID_AUDIO_MUTE)
93 return -EINVAL;
94 ctrl->value = state->muted;
95 break; 79 break;
96 80 case 44100: /* set sample rate to 44.1 kHz */
97 case VIDIOC_S_CTRL: 81 tlv320aic23b_write(sd, 8, 0x022);
98 if (ctrl->id != V4L2_CID_AUDIO_MUTE)
99 return -EINVAL;
100 state->muted = ctrl->value;
101 tlv320aic23b_write(client, 0, 0x180); /* mute both channels */
102 /* set gain on both channels to +3.0 dB */
103 if (!state->muted)
104 tlv320aic23b_write(client, 0, 0x119);
105 break; 82 break;
106 83 case 48000: /* set sample rate to 48 kHz */
107 case VIDIOC_LOG_STATUS: 84 tlv320aic23b_write(sd, 8, 0x000);
108 v4l_info(client, "Input: %s\n",
109 state->muted ? "muted" : "active");
110 break; 85 break;
111
112 default: 86 default:
113 return -EINVAL; 87 return -EINVAL;
114 } 88 }
115 return 0; 89 return 0;
116} 90}
117 91
92static int tlv320aic23b_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
93{
94 struct tlv320aic23b_state *state = to_state(sd);
95
96 if (ctrl->id != V4L2_CID_AUDIO_MUTE)
97 return -EINVAL;
98 ctrl->value = state->muted;
99 return 0;
100}
101
102static int tlv320aic23b_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
103{
104 struct tlv320aic23b_state *state = to_state(sd);
105
106 if (ctrl->id != V4L2_CID_AUDIO_MUTE)
107 return -EINVAL;
108 state->muted = ctrl->value;
109 tlv320aic23b_write(sd, 0, 0x180); /* mute both channels */
110 /* set gain on both channels to +3.0 dB */
111 if (!state->muted)
112 tlv320aic23b_write(sd, 0, 0x119);
113 return 0;
114}
115
116static int tlv320aic23b_log_status(struct v4l2_subdev *sd)
117{
118 struct tlv320aic23b_state *state = to_state(sd);
119
120 v4l2_info(sd, "Input: %s\n", state->muted ? "muted" : "active");
121 return 0;
122}
123
124static int tlv320aic23b_command(struct i2c_client *client, unsigned cmd, void *arg)
125{
126 return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
127}
128
129/* ----------------------------------------------------------------------- */
130
131static const struct v4l2_subdev_core_ops tlv320aic23b_core_ops = {
132 .log_status = tlv320aic23b_log_status,
133 .g_ctrl = tlv320aic23b_g_ctrl,
134 .s_ctrl = tlv320aic23b_s_ctrl,
135};
136
137static const struct v4l2_subdev_audio_ops tlv320aic23b_audio_ops = {
138 .s_clock_freq = tlv320aic23b_s_clock_freq,
139};
140
141static const struct v4l2_subdev_ops tlv320aic23b_ops = {
142 .core = &tlv320aic23b_core_ops,
143 .audio = &tlv320aic23b_audio_ops,
144};
145
118/* ----------------------------------------------------------------------- */ 146/* ----------------------------------------------------------------------- */
119 147
120/* i2c implementation */ 148/* i2c implementation */
@@ -128,6 +156,7 @@ static int tlv320aic23b_probe(struct i2c_client *client,
128 const struct i2c_device_id *id) 156 const struct i2c_device_id *id)
129{ 157{
130 struct tlv320aic23b_state *state; 158 struct tlv320aic23b_state *state;
159 struct v4l2_subdev *sd;
131 160
132 /* Check if the adapter supports the needed features */ 161 /* Check if the adapter supports the needed features */
133 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) 162 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
@@ -136,32 +165,36 @@ static int tlv320aic23b_probe(struct i2c_client *client,
136 v4l_info(client, "chip found @ 0x%x (%s)\n", 165 v4l_info(client, "chip found @ 0x%x (%s)\n",
137 client->addr << 1, client->adapter->name); 166 client->addr << 1, client->adapter->name);
138 167
139 state = kmalloc(sizeof(struct tlv320aic23b_state), GFP_KERNEL); 168 state = kzalloc(sizeof(struct tlv320aic23b_state), GFP_KERNEL);
140 if (state == NULL) 169 if (state == NULL)
141 return -ENOMEM; 170 return -ENOMEM;
171 sd = &state->sd;
172 v4l2_i2c_subdev_init(sd, client, &tlv320aic23b_ops);
142 state->muted = 0; 173 state->muted = 0;
143 i2c_set_clientdata(client, state);
144 174
145 /* Initialize tlv320aic23b */ 175 /* Initialize tlv320aic23b */
146 176
147 /* RESET */ 177 /* RESET */
148 tlv320aic23b_write(client, 15, 0x000); 178 tlv320aic23b_write(sd, 15, 0x000);
149 /* turn off DAC & mic input */ 179 /* turn off DAC & mic input */
150 tlv320aic23b_write(client, 6, 0x00A); 180 tlv320aic23b_write(sd, 6, 0x00A);
151 /* left-justified, 24-bit, master mode */ 181 /* left-justified, 24-bit, master mode */
152 tlv320aic23b_write(client, 7, 0x049); 182 tlv320aic23b_write(sd, 7, 0x049);
153 /* set gain on both channels to +3.0 dB */ 183 /* set gain on both channels to +3.0 dB */
154 tlv320aic23b_write(client, 0, 0x119); 184 tlv320aic23b_write(sd, 0, 0x119);
155 /* set sample rate to 48 kHz */ 185 /* set sample rate to 48 kHz */
156 tlv320aic23b_write(client, 8, 0x000); 186 tlv320aic23b_write(sd, 8, 0x000);
157 /* activate digital interface */ 187 /* activate digital interface */
158 tlv320aic23b_write(client, 9, 0x001); 188 tlv320aic23b_write(sd, 9, 0x001);
159 return 0; 189 return 0;
160} 190}
161 191
162static int tlv320aic23b_remove(struct i2c_client *client) 192static int tlv320aic23b_remove(struct i2c_client *client)
163{ 193{
164 kfree(i2c_get_clientdata(client)); 194 struct v4l2_subdev *sd = i2c_get_clientdata(client);
195
196 v4l2_device_unregister_subdev(sd);
197 kfree(to_state(sd));
165 return 0; 198 return 0;
166} 199}
167 200
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c
index 4a7735c6c1a6..97d7509d212f 100644
--- a/drivers/media/video/tuner-core.c
+++ b/drivers/media/video/tuner-core.c
@@ -18,7 +18,7 @@
18#include <linux/videodev.h> 18#include <linux/videodev.h>
19#include <media/tuner.h> 19#include <media/tuner.h>
20#include <media/tuner-types.h> 20#include <media/tuner-types.h>
21#include <media/v4l2-common.h> 21#include <media/v4l2-device.h>
22#include <media/v4l2-ioctl.h> 22#include <media/v4l2-ioctl.h>
23#include <media/v4l2-i2c-drv-legacy.h> 23#include <media/v4l2-i2c-drv-legacy.h>
24#include "mt20xx.h" 24#include "mt20xx.h"
@@ -78,6 +78,7 @@ struct tuner {
78 /* device */ 78 /* device */
79 struct dvb_frontend fe; 79 struct dvb_frontend fe;
80 struct i2c_client *i2c; 80 struct i2c_client *i2c;
81 struct v4l2_subdev sd;
81 struct list_head list; 82 struct list_head list;
82 unsigned int using_v4l2:1; 83 unsigned int using_v4l2:1;
83 84
@@ -95,6 +96,11 @@ struct tuner {
95 const char *name; 96 const char *name;
96}; 97};
97 98
99static inline struct tuner *to_tuner(struct v4l2_subdev *sd)
100{
101 return container_of(sd, struct tuner, sd);
102}
103
98/* standard i2c insmod options */ 104/* standard i2c insmod options */
99static unsigned short normal_i2c[] = { 105static unsigned short normal_i2c[] = {
100#if defined(CONFIG_MEDIA_TUNER_TEA5761) || (defined(CONFIG_MEDIA_TUNER_TEA5761_MODULE) && defined(MODULE)) 106#if defined(CONFIG_MEDIA_TUNER_TEA5761) || (defined(CONFIG_MEDIA_TUNER_TEA5761_MODULE) && defined(MODULE))
@@ -213,7 +219,7 @@ static int fe_set_config(struct dvb_frontend *fe, void *priv_cfg)
213 219
214static void tuner_status(struct dvb_frontend *fe); 220static void tuner_status(struct dvb_frontend *fe);
215 221
216static struct analog_demod_ops tuner_core_ops = { 222static struct analog_demod_ops tuner_analog_ops = {
217 .set_params = fe_set_params, 223 .set_params = fe_set_params,
218 .standby = fe_standby, 224 .standby = fe_standby,
219 .has_signal = fe_has_signal, 225 .has_signal = fe_has_signal,
@@ -224,7 +230,7 @@ static struct analog_demod_ops tuner_core_ops = {
224/* Set tuner frequency, freq in Units of 62.5kHz = 1/16MHz */ 230/* Set tuner frequency, freq in Units of 62.5kHz = 1/16MHz */
225static void set_tv_freq(struct i2c_client *c, unsigned int freq) 231static void set_tv_freq(struct i2c_client *c, unsigned int freq)
226{ 232{
227 struct tuner *t = i2c_get_clientdata(c); 233 struct tuner *t = to_tuner(i2c_get_clientdata(c));
228 struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops; 234 struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops;
229 235
230 struct analog_parameters params = { 236 struct analog_parameters params = {
@@ -259,7 +265,7 @@ static void set_tv_freq(struct i2c_client *c, unsigned int freq)
259 265
260static void set_radio_freq(struct i2c_client *c, unsigned int freq) 266static void set_radio_freq(struct i2c_client *c, unsigned int freq)
261{ 267{
262 struct tuner *t = i2c_get_clientdata(c); 268 struct tuner *t = to_tuner(i2c_get_clientdata(c));
263 struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops; 269 struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops;
264 270
265 struct analog_parameters params = { 271 struct analog_parameters params = {
@@ -294,7 +300,7 @@ static void set_radio_freq(struct i2c_client *c, unsigned int freq)
294 300
295static void set_freq(struct i2c_client *c, unsigned long freq) 301static void set_freq(struct i2c_client *c, unsigned long freq)
296{ 302{
297 struct tuner *t = i2c_get_clientdata(c); 303 struct tuner *t = to_tuner(i2c_get_clientdata(c));
298 304
299 switch (t->mode) { 305 switch (t->mode) {
300 case V4L2_TUNER_RADIO: 306 case V4L2_TUNER_RADIO:
@@ -347,7 +353,7 @@ static void set_type(struct i2c_client *c, unsigned int type,
347 unsigned int new_mode_mask, unsigned int new_config, 353 unsigned int new_mode_mask, unsigned int new_config,
348 int (*tuner_callback) (void *dev, int component, int cmd, int arg)) 354 int (*tuner_callback) (void *dev, int component, int cmd, int arg))
349{ 355{
350 struct tuner *t = i2c_get_clientdata(c); 356 struct tuner *t = to_tuner(i2c_get_clientdata(c));
351 struct dvb_tuner_ops *fe_tuner_ops = &t->fe.ops.tuner_ops; 357 struct dvb_tuner_ops *fe_tuner_ops = &t->fe.ops.tuner_ops;
352 struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops; 358 struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops;
353 unsigned char buffer[4]; 359 unsigned char buffer[4];
@@ -470,7 +476,7 @@ static void set_type(struct i2c_client *c, unsigned int type,
470 t->name = fe_tuner_ops->info.name; 476 t->name = fe_tuner_ops->info.name;
471 477
472 t->fe.analog_demod_priv = t; 478 t->fe.analog_demod_priv = t;
473 memcpy(analog_ops, &tuner_core_ops, 479 memcpy(analog_ops, &tuner_analog_ops,
474 sizeof(struct analog_demod_ops)); 480 sizeof(struct analog_demod_ops));
475 481
476 } else { 482 } else {
@@ -515,7 +521,7 @@ attach_failed:
515 521
516static void set_addr(struct i2c_client *c, struct tuner_setup *tun_setup) 522static void set_addr(struct i2c_client *c, struct tuner_setup *tun_setup)
517{ 523{
518 struct tuner *t = i2c_get_clientdata(c); 524 struct tuner *t = to_tuner(i2c_get_clientdata(c));
519 525
520 if ( (t->type == UNSET && ((tun_setup->addr == ADDR_UNSET) && 526 if ( (t->type == UNSET && ((tun_setup->addr == ADDR_UNSET) &&
521 (t->mode_mask & tun_setup->mode_mask))) || 527 (t->mode_mask & tun_setup->mode_mask))) ||
@@ -727,6 +733,8 @@ static inline int set_mode(struct i2c_client *client, struct tuner *t, int mode,
727 t->mode = mode; 733 t->mode = mode;
728 734
729 if (check_mode(t, cmd) == -EINVAL) { 735 if (check_mode(t, cmd) == -EINVAL) {
736 tuner_dbg("Tuner doesn't support this mode. "
737 "Putting tuner to sleep\n");
730 t->mode = T_STANDBY; 738 t->mode = T_STANDBY;
731 if (analog_ops->standby) 739 if (analog_ops->standby)
732 analog_ops->standby(&t->fe); 740 analog_ops->standby(&t->fe);
@@ -748,43 +756,58 @@ static inline int check_v4l2(struct tuner *t)
748 return 0; 756 return 0;
749} 757}
750 758
751static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) 759static int tuner_s_type_addr(struct v4l2_subdev *sd, struct tuner_setup *type)
752{ 760{
753 struct tuner *t = i2c_get_clientdata(client); 761 struct tuner *t = to_tuner(sd);
754 struct dvb_tuner_ops *fe_tuner_ops = &t->fe.ops.tuner_ops; 762 struct i2c_client *client = v4l2_get_subdevdata(sd);
763
764 tuner_dbg("Calling set_type_addr for type=%d, addr=0x%02x, mode=0x%02x, config=0x%02x\n",
765 type->type,
766 type->addr,
767 type->mode_mask,
768 type->config);
769
770 set_addr(client, type);
771 return 0;
772}
773
774static int tuner_s_radio(struct v4l2_subdev *sd)
775{
776 struct tuner *t = to_tuner(sd);
777 struct i2c_client *client = v4l2_get_subdevdata(sd);
778
779 if (set_mode(client, t, V4L2_TUNER_RADIO, "AUDC_SET_RADIO")
780 == -EINVAL)
781 return 0;
782 if (t->radio_freq)
783 set_freq(client, t->radio_freq);
784 return 0;
785}
786
787static int tuner_s_standby(struct v4l2_subdev *sd, u32 standby)
788{
789 struct tuner *t = to_tuner(sd);
755 struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops; 790 struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops;
756 791
757 if (tuner_debug > 1) { 792 tuner_dbg("Putting tuner to sleep\n");
758 v4l_i2c_print_ioctl(client,cmd); 793
759 printk("\n"); 794 if (check_mode(t, "TUNER_SET_STANDBY") == -EINVAL)
760 } 795 return 0;
796 t->mode = T_STANDBY;
797 if (analog_ops->standby)
798 analog_ops->standby(&t->fe);
799 return 0;
800}
761 801
762 switch (cmd) {
763 /* --- configuration --- */
764 case TUNER_SET_TYPE_ADDR:
765 tuner_dbg ("Calling set_type_addr for type=%d, addr=0x%02x, mode=0x%02x, config=0x%02x\n",
766 ((struct tuner_setup *)arg)->type,
767 ((struct tuner_setup *)arg)->addr,
768 ((struct tuner_setup *)arg)->mode_mask,
769 ((struct tuner_setup *)arg)->config);
770
771 set_addr(client, (struct tuner_setup *)arg);
772 break;
773 case AUDC_SET_RADIO:
774 if (set_mode(client, t, V4L2_TUNER_RADIO, "AUDC_SET_RADIO")
775 == -EINVAL)
776 return 0;
777 if (t->radio_freq)
778 set_freq(client, t->radio_freq);
779 break;
780 case TUNER_SET_STANDBY:
781 if (check_mode(t, "TUNER_SET_STANDBY") == -EINVAL)
782 return 0;
783 t->mode = T_STANDBY;
784 if (analog_ops->standby)
785 analog_ops->standby(&t->fe);
786 break;
787#ifdef CONFIG_VIDEO_ALLOW_V4L1 802#ifdef CONFIG_VIDEO_ALLOW_V4L1
803static int tuner_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
804{
805 struct tuner *t = to_tuner(sd);
806 struct i2c_client *client = v4l2_get_subdevdata(sd);
807 struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops;
808 struct dvb_tuner_ops *fe_tuner_ops = &t->fe.ops.tuner_ops;
809
810 switch (cmd) {
788 case VIDIOCSAUDIO: 811 case VIDIOCSAUDIO:
789 if (check_mode(t, "VIDIOCSAUDIO") == -EINVAL) 812 if (check_mode(t, "VIDIOCSAUDIO") == -EINVAL)
790 return 0; 813 return 0;
@@ -897,149 +920,172 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
897 } 920 }
898 return 0; 921 return 0;
899 } 922 }
923 }
924 return -ENOIOCTLCMD;
925}
900#endif 926#endif
901 case TUNER_SET_CONFIG:
902 {
903 struct v4l2_priv_tun_config *cfg = arg;
904 927
905 if (t->type != cfg->tuner) 928static int tuner_s_config(struct v4l2_subdev *sd, const struct v4l2_priv_tun_config *cfg)
906 break; 929{
930 struct tuner *t = to_tuner(sd);
931 struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops;
907 932
908 if (analog_ops->set_config) { 933 if (t->type != cfg->tuner)
909 analog_ops->set_config(&t->fe, cfg->priv); 934 return 0;
910 break;
911 }
912 935
913 tuner_dbg("Tuner frontend module has no way to set config\n"); 936 if (analog_ops->set_config) {
914 break; 937 analog_ops->set_config(&t->fe, cfg->priv);
938 return 0;
915 } 939 }
916 /* --- v4l ioctls --- */
917 /* take care: bttv does userspace copying, we'll get a
918 kernel pointer here... */
919 case VIDIOC_S_STD:
920 {
921 v4l2_std_id *id = arg;
922 940
923 if (set_mode (client, t, V4L2_TUNER_ANALOG_TV, "VIDIOC_S_STD") 941 tuner_dbg("Tuner frontend module has no way to set config\n");
924 == -EINVAL) 942 return 0;
925 return 0; 943}
926 944
927 switch_v4l2(); 945/* --- v4l ioctls --- */
946/* take care: bttv does userspace copying, we'll get a
947 kernel pointer here... */
948static int tuner_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
949{
950 struct tuner *t = to_tuner(sd);
951 struct i2c_client *client = v4l2_get_subdevdata(sd);
928 952
929 t->std = *id; 953 if (set_mode(client, t, V4L2_TUNER_ANALOG_TV, "VIDIOC_S_STD")
930 tuner_fixup_std(t); 954 == -EINVAL)
931 if (t->tv_freq) 955 return 0;
932 set_freq(client, t->tv_freq);
933 break;
934 }
935 case VIDIOC_S_FREQUENCY:
936 {
937 struct v4l2_frequency *f = arg;
938 956
939 if (set_mode (client, t, f->type, "VIDIOC_S_FREQUENCY") 957 switch_v4l2();
940 == -EINVAL)
941 return 0;
942 switch_v4l2();
943 set_freq(client,f->frequency);
944 958
945 break; 959 t->std = std;
946 } 960 tuner_fixup_std(t);
947 case VIDIOC_G_FREQUENCY: 961 if (t->tv_freq)
948 { 962 set_freq(client, t->tv_freq);
949 struct v4l2_frequency *f = arg; 963 return 0;
964}
950 965
951 if (check_mode(t, "VIDIOC_G_FREQUENCY") == -EINVAL) 966static int tuner_s_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *f)
952 return 0; 967{
953 switch_v4l2(); 968 struct tuner *t = to_tuner(sd);
954 f->type = t->mode; 969 struct i2c_client *client = v4l2_get_subdevdata(sd);
955 if (fe_tuner_ops->get_frequency) {
956 u32 abs_freq;
957
958 fe_tuner_ops->get_frequency(&t->fe, &abs_freq);
959 f->frequency = (V4L2_TUNER_RADIO == t->mode) ?
960 (abs_freq * 2 + 125/2) / 125 :
961 (abs_freq + 62500/2) / 62500;
962 break;
963 }
964 f->frequency = (V4L2_TUNER_RADIO == t->mode) ?
965 t->radio_freq : t->tv_freq;
966 break;
967 }
968 case VIDIOC_G_TUNER:
969 {
970 struct v4l2_tuner *tuner = arg;
971 970
972 if (check_mode(t, "VIDIOC_G_TUNER") == -EINVAL) 971 if (set_mode(client, t, f->type, "VIDIOC_S_FREQUENCY")
973 return 0; 972 == -EINVAL)
974 switch_v4l2(); 973 return 0;
975 974 switch_v4l2();
976 tuner->type = t->mode; 975 set_freq(client, f->frequency);
977 if (analog_ops->get_afc)
978 tuner->afc = analog_ops->get_afc(&t->fe);
979 if (t->mode == V4L2_TUNER_ANALOG_TV)
980 tuner->capability |= V4L2_TUNER_CAP_NORM;
981 if (t->mode != V4L2_TUNER_RADIO) {
982 tuner->rangelow = tv_range[0] * 16;
983 tuner->rangehigh = tv_range[1] * 16;
984 break;
985 }
986 976
987 /* radio mode */ 977 return 0;
988 tuner->rxsubchans = 978}
989 V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
990 if (fe_tuner_ops->get_status) {
991 u32 tuner_status;
992
993 fe_tuner_ops->get_status(&t->fe, &tuner_status);
994 tuner->rxsubchans =
995 (tuner_status & TUNER_STATUS_STEREO) ?
996 V4L2_TUNER_SUB_STEREO :
997 V4L2_TUNER_SUB_MONO;
998 } else {
999 if (analog_ops->is_stereo) {
1000 tuner->rxsubchans =
1001 analog_ops->is_stereo(&t->fe) ?
1002 V4L2_TUNER_SUB_STEREO :
1003 V4L2_TUNER_SUB_MONO;
1004 }
1005 }
1006 if (analog_ops->has_signal)
1007 tuner->signal = analog_ops->has_signal(&t->fe);
1008 tuner->capability |=
1009 V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO;
1010 tuner->audmode = t->audmode;
1011 tuner->rangelow = radio_range[0] * 16000;
1012 tuner->rangehigh = radio_range[1] * 16000;
1013 break;
1014 }
1015 case VIDIOC_S_TUNER:
1016 {
1017 struct v4l2_tuner *tuner = arg;
1018 979
1019 if (check_mode(t, "VIDIOC_S_TUNER") == -EINVAL) 980static int tuner_g_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *f)
1020 return 0; 981{
982 struct tuner *t = to_tuner(sd);
983 struct dvb_tuner_ops *fe_tuner_ops = &t->fe.ops.tuner_ops;
1021 984
1022 switch_v4l2(); 985 if (check_mode(t, "VIDIOC_G_FREQUENCY") == -EINVAL)
986 return 0;
987 switch_v4l2();
988 f->type = t->mode;
989 if (fe_tuner_ops->get_frequency) {
990 u32 abs_freq;
991
992 fe_tuner_ops->get_frequency(&t->fe, &abs_freq);
993 f->frequency = (V4L2_TUNER_RADIO == t->mode) ?
994 (abs_freq * 2 + 125/2) / 125 :
995 (abs_freq + 62500/2) / 62500;
996 return 0;
997 }
998 f->frequency = (V4L2_TUNER_RADIO == t->mode) ?
999 t->radio_freq : t->tv_freq;
1000 return 0;
1001}
1023 1002
1024 /* do nothing unless we're a radio tuner */ 1003static int tuner_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
1025 if (t->mode != V4L2_TUNER_RADIO) 1004{
1026 break; 1005 struct tuner *t = to_tuner(sd);
1027 t->audmode = tuner->audmode; 1006 struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops;
1028 set_radio_freq(client, t->radio_freq); 1007 struct dvb_tuner_ops *fe_tuner_ops = &t->fe.ops.tuner_ops;
1029 break; 1008
1009 if (check_mode(t, "VIDIOC_G_TUNER") == -EINVAL)
1010 return 0;
1011 switch_v4l2();
1012
1013 vt->type = t->mode;
1014 if (analog_ops->get_afc)
1015 vt->afc = analog_ops->get_afc(&t->fe);
1016 if (t->mode == V4L2_TUNER_ANALOG_TV)
1017 vt->capability |= V4L2_TUNER_CAP_NORM;
1018 if (t->mode != V4L2_TUNER_RADIO) {
1019 vt->rangelow = tv_range[0] * 16;
1020 vt->rangehigh = tv_range[1] * 16;
1021 return 0;
1022 }
1023
1024 /* radio mode */
1025 vt->rxsubchans =
1026 V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
1027 if (fe_tuner_ops->get_status) {
1028 u32 tuner_status;
1029
1030 fe_tuner_ops->get_status(&t->fe, &tuner_status);
1031 vt->rxsubchans =
1032 (tuner_status & TUNER_STATUS_STEREO) ?
1033 V4L2_TUNER_SUB_STEREO :
1034 V4L2_TUNER_SUB_MONO;
1035 } else {
1036 if (analog_ops->is_stereo) {
1037 vt->rxsubchans =
1038 analog_ops->is_stereo(&t->fe) ?
1039 V4L2_TUNER_SUB_STEREO :
1040 V4L2_TUNER_SUB_MONO;
1030 } 1041 }
1031 case VIDIOC_LOG_STATUS:
1032 if (analog_ops->tuner_status)
1033 analog_ops->tuner_status(&t->fe);
1034 break;
1035 } 1042 }
1043 if (analog_ops->has_signal)
1044 vt->signal = analog_ops->has_signal(&t->fe);
1045 vt->capability |=
1046 V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO;
1047 vt->audmode = t->audmode;
1048 vt->rangelow = radio_range[0] * 16000;
1049 vt->rangehigh = radio_range[1] * 16000;
1050 return 0;
1051}
1052
1053static int tuner_s_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
1054{
1055 struct tuner *t = to_tuner(sd);
1056 struct i2c_client *client = v4l2_get_subdevdata(sd);
1036 1057
1058 if (check_mode(t, "VIDIOC_S_TUNER") == -EINVAL)
1059 return 0;
1060
1061 switch_v4l2();
1062
1063 /* do nothing unless we're a radio tuner */
1064 if (t->mode != V4L2_TUNER_RADIO)
1065 return 0;
1066 t->audmode = vt->audmode;
1067 set_radio_freq(client, t->radio_freq);
1037 return 0; 1068 return 0;
1038} 1069}
1039 1070
1071static int tuner_log_status(struct v4l2_subdev *sd)
1072{
1073 struct tuner *t = to_tuner(sd);
1074 struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops;
1075
1076 if (analog_ops->tuner_status)
1077 analog_ops->tuner_status(&t->fe);
1078 return 0;
1079}
1080
1081static int tuner_command(struct i2c_client *client, unsigned cmd, void *arg)
1082{
1083 return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
1084}
1085
1040static int tuner_suspend(struct i2c_client *c, pm_message_t state) 1086static int tuner_suspend(struct i2c_client *c, pm_message_t state)
1041{ 1087{
1042 struct tuner *t = i2c_get_clientdata(c); 1088 struct tuner *t = to_tuner(i2c_get_clientdata(c));
1043 1089
1044 tuner_dbg("suspend\n"); 1090 tuner_dbg("suspend\n");
1045 /* FIXME: power down ??? */ 1091 /* FIXME: power down ??? */
@@ -1048,7 +1094,7 @@ static int tuner_suspend(struct i2c_client *c, pm_message_t state)
1048 1094
1049static int tuner_resume(struct i2c_client *c) 1095static int tuner_resume(struct i2c_client *c)
1050{ 1096{
1051 struct tuner *t = i2c_get_clientdata(c); 1097 struct tuner *t = to_tuner(i2c_get_clientdata(c));
1052 1098
1053 tuner_dbg("resume\n"); 1099 tuner_dbg("resume\n");
1054 if (V4L2_TUNER_RADIO == t->mode) { 1100 if (V4L2_TUNER_RADIO == t->mode) {
@@ -1061,6 +1107,32 @@ static int tuner_resume(struct i2c_client *c)
1061 return 0; 1107 return 0;
1062} 1108}
1063 1109
1110/* ----------------------------------------------------------------------- */
1111
1112static const struct v4l2_subdev_core_ops tuner_core_ops = {
1113 .log_status = tuner_log_status,
1114 .s_standby = tuner_s_standby,
1115#ifdef CONFIG_VIDEO_ALLOW_V4L1
1116 .ioctl = tuner_ioctl,
1117#endif
1118};
1119
1120static const struct v4l2_subdev_tuner_ops tuner_tuner_ops = {
1121 .s_std = tuner_s_std,
1122 .s_radio = tuner_s_radio,
1123 .g_tuner = tuner_g_tuner,
1124 .s_tuner = tuner_s_tuner,
1125 .s_frequency = tuner_s_frequency,
1126 .g_frequency = tuner_g_frequency,
1127 .s_type_addr = tuner_s_type_addr,
1128 .s_config = tuner_s_config,
1129};
1130
1131static const struct v4l2_subdev_ops tuner_ops = {
1132 .core = &tuner_core_ops,
1133 .tuner = &tuner_tuner_ops,
1134};
1135
1064/* ---------------------------------------------------------------------- */ 1136/* ---------------------------------------------------------------------- */
1065 1137
1066static LIST_HEAD(tuner_list); 1138static LIST_HEAD(tuner_list);
@@ -1109,9 +1181,9 @@ static int tuner_probe(struct i2c_client *client,
1109 t = kzalloc(sizeof(struct tuner), GFP_KERNEL); 1181 t = kzalloc(sizeof(struct tuner), GFP_KERNEL);
1110 if (NULL == t) 1182 if (NULL == t)
1111 return -ENOMEM; 1183 return -ENOMEM;
1184 v4l2_i2c_subdev_init(&t->sd, client, &tuner_ops);
1112 t->i2c = client; 1185 t->i2c = client;
1113 t->name = "(tuner unset)"; 1186 t->name = "(tuner unset)";
1114 i2c_set_clientdata(client, t);
1115 t->type = UNSET; 1187 t->type = UNSET;
1116 t->audmode = V4L2_TUNER_MODE_STEREO; 1188 t->audmode = V4L2_TUNER_MODE_STEREO;
1117 t->mode_mask = T_UNINITIALIZED; 1189 t->mode_mask = T_UNINITIALIZED;
@@ -1261,8 +1333,9 @@ static int tuner_legacy_probe(struct i2c_adapter *adap)
1261 1333
1262static int tuner_remove(struct i2c_client *client) 1334static int tuner_remove(struct i2c_client *client)
1263{ 1335{
1264 struct tuner *t = i2c_get_clientdata(client); 1336 struct tuner *t = to_tuner(i2c_get_clientdata(client));
1265 1337
1338 v4l2_device_unregister_subdev(&t->sd);
1266 tuner_detach(&t->fe); 1339 tuner_detach(&t->fe);
1267 t->fe.analog_demod_priv = NULL; 1340 t->fe.analog_demod_priv = NULL;
1268 1341
diff --git a/drivers/media/video/tvaudio.c b/drivers/media/video/tvaudio.c
index 3720f0e03a16..d0c794da735b 100644
--- a/drivers/media/video/tvaudio.c
+++ b/drivers/media/video/tvaudio.c
@@ -33,8 +33,7 @@
33#include <linux/freezer.h> 33#include <linux/freezer.h>
34 34
35#include <media/tvaudio.h> 35#include <media/tvaudio.h>
36#include <media/v4l2-common.h> 36#include <media/v4l2-device.h>
37#include <media/v4l2-ioctl.h>
38#include <media/v4l2-chip-ident.h> 37#include <media/v4l2-chip-ident.h>
39#include <media/v4l2-i2c-drv-legacy.h> 38#include <media/v4l2-i2c-drv-legacy.h>
40 39
@@ -110,7 +109,7 @@ struct CHIPDESC {
110 109
111/* current state of the chip */ 110/* current state of the chip */
112struct CHIPSTATE { 111struct CHIPSTATE {
113 struct i2c_client *c; 112 struct v4l2_subdev sd;
114 113
115 /* chip-specific description - should point to 114 /* chip-specific description - should point to
116 an entry at CHIPDESC table */ 115 an entry at CHIPDESC table */
@@ -132,6 +131,11 @@ struct CHIPSTATE {
132 int audmode; 131 int audmode;
133}; 132};
134 133
134static inline struct CHIPSTATE *to_state(struct v4l2_subdev *sd)
135{
136 return container_of(sd, struct CHIPSTATE, sd);
137}
138
135/* ---------------------------------------------------------------------- */ 139/* ---------------------------------------------------------------------- */
136/* i2c addresses */ 140/* i2c addresses */
137 141
@@ -152,34 +156,34 @@ I2C_CLIENT_INSMOD;
152 156
153static int chip_write(struct CHIPSTATE *chip, int subaddr, int val) 157static int chip_write(struct CHIPSTATE *chip, int subaddr, int val)
154{ 158{
159 struct v4l2_subdev *sd = &chip->sd;
160 struct i2c_client *c = v4l2_get_subdevdata(sd);
155 unsigned char buffer[2]; 161 unsigned char buffer[2];
156 162
157 if (subaddr < 0) { 163 if (subaddr < 0) {
158 v4l_dbg(1, debug, chip->c, "%s: chip_write: 0x%x\n", 164 v4l2_dbg(1, debug, sd, "chip_write: 0x%x\n", val);
159 chip->c->name, val);
160 chip->shadow.bytes[1] = val; 165 chip->shadow.bytes[1] = val;
161 buffer[0] = val; 166 buffer[0] = val;
162 if (1 != i2c_master_send(chip->c,buffer,1)) { 167 if (1 != i2c_master_send(c, buffer, 1)) {
163 v4l_warn(chip->c, "%s: I/O error (write 0x%x)\n", 168 v4l2_warn(sd, "I/O error (write 0x%x)\n", val);
164 chip->c->name, val);
165 return -1; 169 return -1;
166 } 170 }
167 } else { 171 } else {
168 if (subaddr + 1 >= ARRAY_SIZE(chip->shadow.bytes)) { 172 if (subaddr + 1 >= ARRAY_SIZE(chip->shadow.bytes)) {
169 v4l_info(chip->c, 173 v4l2_info(sd,
170 "Tried to access a non-existent register: %d\n", 174 "Tried to access a non-existent register: %d\n",
171 subaddr); 175 subaddr);
172 return -EINVAL; 176 return -EINVAL;
173 } 177 }
174 178
175 v4l_dbg(1, debug, chip->c, "%s: chip_write: reg%d=0x%x\n", 179 v4l2_dbg(1, debug, sd, "chip_write: reg%d=0x%x\n",
176 chip->c->name, subaddr, val); 180 subaddr, val);
177 chip->shadow.bytes[subaddr+1] = val; 181 chip->shadow.bytes[subaddr+1] = val;
178 buffer[0] = subaddr; 182 buffer[0] = subaddr;
179 buffer[1] = val; 183 buffer[1] = val;
180 if (2 != i2c_master_send(chip->c,buffer,2)) { 184 if (2 != i2c_master_send(c, buffer, 2)) {
181 v4l_warn(chip->c, "%s: I/O error (write reg%d=0x%x)\n", 185 v4l2_warn(sd, "I/O error (write reg%d=0x%x)\n",
182 chip->c->name, subaddr, val); 186 subaddr, val);
183 return -1; 187 return -1;
184 } 188 }
185 } 189 }
@@ -189,12 +193,14 @@ static int chip_write(struct CHIPSTATE *chip, int subaddr, int val)
189static int chip_write_masked(struct CHIPSTATE *chip, 193static int chip_write_masked(struct CHIPSTATE *chip,
190 int subaddr, int val, int mask) 194 int subaddr, int val, int mask)
191{ 195{
196 struct v4l2_subdev *sd = &chip->sd;
197
192 if (mask != 0) { 198 if (mask != 0) {
193 if (subaddr < 0) { 199 if (subaddr < 0) {
194 val = (chip->shadow.bytes[1] & ~mask) | (val & mask); 200 val = (chip->shadow.bytes[1] & ~mask) | (val & mask);
195 } else { 201 } else {
196 if (subaddr + 1 >= ARRAY_SIZE(chip->shadow.bytes)) { 202 if (subaddr + 1 >= ARRAY_SIZE(chip->shadow.bytes)) {
197 v4l_info(chip->c, 203 v4l2_info(sd,
198 "Tried to access a non-existent register: %d\n", 204 "Tried to access a non-existent register: %d\n",
199 subaddr); 205 subaddr);
200 return -EINVAL; 206 return -EINVAL;
@@ -208,45 +214,51 @@ static int chip_write_masked(struct CHIPSTATE *chip,
208 214
209static int chip_read(struct CHIPSTATE *chip) 215static int chip_read(struct CHIPSTATE *chip)
210{ 216{
217 struct v4l2_subdev *sd = &chip->sd;
218 struct i2c_client *c = v4l2_get_subdevdata(sd);
211 unsigned char buffer; 219 unsigned char buffer;
212 220
213 if (1 != i2c_master_recv(chip->c,&buffer,1)) { 221 if (1 != i2c_master_recv(c, &buffer, 1)) {
214 v4l_warn(chip->c, "%s: I/O error (read)\n", 222 v4l2_warn(sd, "I/O error (read)\n");
215 chip->c->name);
216 return -1; 223 return -1;
217 } 224 }
218 v4l_dbg(1, debug, chip->c, "%s: chip_read: 0x%x\n",chip->c->name, buffer); 225 v4l2_dbg(1, debug, sd, "chip_read: 0x%x\n", buffer);
219 return buffer; 226 return buffer;
220} 227}
221 228
222static int chip_read2(struct CHIPSTATE *chip, int subaddr) 229static int chip_read2(struct CHIPSTATE *chip, int subaddr)
223{ 230{
231 struct v4l2_subdev *sd = &chip->sd;
232 struct i2c_client *c = v4l2_get_subdevdata(sd);
224 unsigned char write[1]; 233 unsigned char write[1];
225 unsigned char read[1]; 234 unsigned char read[1];
226 struct i2c_msg msgs[2] = { 235 struct i2c_msg msgs[2] = {
227 { chip->c->addr, 0, 1, write }, 236 { c->addr, 0, 1, write },
228 { chip->c->addr, I2C_M_RD, 1, read } 237 { c->addr, I2C_M_RD, 1, read }
229 }; 238 };
239
230 write[0] = subaddr; 240 write[0] = subaddr;
231 241
232 if (2 != i2c_transfer(chip->c->adapter,msgs,2)) { 242 if (2 != i2c_transfer(c->adapter, msgs, 2)) {
233 v4l_warn(chip->c, "%s: I/O error (read2)\n", chip->c->name); 243 v4l2_warn(sd, "I/O error (read2)\n");
234 return -1; 244 return -1;
235 } 245 }
236 v4l_dbg(1, debug, chip->c, "%s: chip_read2: reg%d=0x%x\n", 246 v4l2_dbg(1, debug, sd, "chip_read2: reg%d=0x%x\n",
237 chip->c->name, subaddr,read[0]); 247 subaddr, read[0]);
238 return read[0]; 248 return read[0];
239} 249}
240 250
241static int chip_cmd(struct CHIPSTATE *chip, char *name, audiocmd *cmd) 251static int chip_cmd(struct CHIPSTATE *chip, char *name, audiocmd *cmd)
242{ 252{
253 struct v4l2_subdev *sd = &chip->sd;
254 struct i2c_client *c = v4l2_get_subdevdata(sd);
243 int i; 255 int i;
244 256
245 if (0 == cmd->count) 257 if (0 == cmd->count)
246 return 0; 258 return 0;
247 259
248 if (cmd->count + cmd->bytes[0] - 1 >= ARRAY_SIZE(chip->shadow.bytes)) { 260 if (cmd->count + cmd->bytes[0] - 1 >= ARRAY_SIZE(chip->shadow.bytes)) {
249 v4l_info(chip->c, 261 v4l2_info(sd,
250 "Tried to access a non-existent register range: %d to %d\n", 262 "Tried to access a non-existent register range: %d to %d\n",
251 cmd->bytes[0] + 1, cmd->bytes[0] + cmd->count - 1); 263 cmd->bytes[0] + 1, cmd->bytes[0] + cmd->count - 1);
252 return -EINVAL; 264 return -EINVAL;
@@ -255,19 +267,19 @@ static int chip_cmd(struct CHIPSTATE *chip, char *name, audiocmd *cmd)
255 /* FIXME: it seems that the shadow bytes are wrong bellow !*/ 267 /* FIXME: it seems that the shadow bytes are wrong bellow !*/
256 268
257 /* update our shadow register set; print bytes if (debug > 0) */ 269 /* update our shadow register set; print bytes if (debug > 0) */
258 v4l_dbg(1, debug, chip->c, "%s: chip_cmd(%s): reg=%d, data:", 270 v4l2_dbg(1, debug, sd, "chip_cmd(%s): reg=%d, data:",
259 chip->c->name, name,cmd->bytes[0]); 271 name, cmd->bytes[0]);
260 for (i = 1; i < cmd->count; i++) { 272 for (i = 1; i < cmd->count; i++) {
261 if (debug) 273 if (debug)
262 printk(" 0x%x",cmd->bytes[i]); 274 printk(KERN_CONT " 0x%x", cmd->bytes[i]);
263 chip->shadow.bytes[i+cmd->bytes[0]] = cmd->bytes[i]; 275 chip->shadow.bytes[i+cmd->bytes[0]] = cmd->bytes[i];
264 } 276 }
265 if (debug) 277 if (debug)
266 printk("\n"); 278 printk(KERN_CONT "\n");
267 279
268 /* send data to the chip */ 280 /* send data to the chip */
269 if (cmd->count != i2c_master_send(chip->c,cmd->bytes,cmd->count)) { 281 if (cmd->count != i2c_master_send(c, cmd->bytes, cmd->count)) {
270 v4l_warn(chip->c, "%s: I/O error (%s)\n", chip->c->name, name); 282 v4l2_warn(sd, "I/O error (%s)\n", name);
271 return -1; 283 return -1;
272 } 284 }
273 return 0; 285 return 0;
@@ -290,9 +302,10 @@ static int chip_thread(void *data)
290{ 302{
291 struct CHIPSTATE *chip = data; 303 struct CHIPSTATE *chip = data;
292 struct CHIPDESC *desc = chip->desc; 304 struct CHIPDESC *desc = chip->desc;
305 struct v4l2_subdev *sd = &chip->sd;
293 int mode; 306 int mode;
294 307
295 v4l_dbg(1, debug, chip->c, "%s: thread started\n", chip->c->name); 308 v4l2_dbg(1, debug, sd, "thread started\n");
296 set_freezable(); 309 set_freezable();
297 for (;;) { 310 for (;;) {
298 set_current_state(TASK_INTERRUPTIBLE); 311 set_current_state(TASK_INTERRUPTIBLE);
@@ -302,7 +315,7 @@ static int chip_thread(void *data)
302 try_to_freeze(); 315 try_to_freeze();
303 if (kthread_should_stop()) 316 if (kthread_should_stop())
304 break; 317 break;
305 v4l_dbg(1, debug, chip->c, "%s: thread wakeup\n", chip->c->name); 318 v4l2_dbg(1, debug, sd, "thread wakeup\n");
306 319
307 /* don't do anything for radio or if mode != auto */ 320 /* don't do anything for radio or if mode != auto */
308 if (chip->radio || chip->mode != 0) 321 if (chip->radio || chip->mode != 0)
@@ -314,8 +327,7 @@ static int chip_thread(void *data)
314 continue; 327 continue;
315 328
316 /* chip detected a new audio mode - set it */ 329 /* chip detected a new audio mode - set it */
317 v4l_dbg(1, debug, chip->c, "%s: thread checkmode\n", 330 v4l2_dbg(1, debug, sd, "thread checkmode\n");
318 chip->c->name);
319 331
320 chip->prevmode = mode; 332 chip->prevmode = mode;
321 333
@@ -334,7 +346,7 @@ static int chip_thread(void *data)
334 mod_timer(&chip->wt, jiffies+msecs_to_jiffies(2000)); 346 mod_timer(&chip->wt, jiffies+msecs_to_jiffies(2000));
335 } 347 }
336 348
337 v4l_dbg(1, debug, chip->c, "%s: thread exiting\n", chip->c->name); 349 v4l2_dbg(1, debug, sd, "thread exiting\n");
338 return 0; 350 return 0;
339} 351}
340 352
@@ -363,6 +375,7 @@ static int chip_thread(void *data)
363 375
364static int tda9840_getmode(struct CHIPSTATE *chip) 376static int tda9840_getmode(struct CHIPSTATE *chip)
365{ 377{
378 struct v4l2_subdev *sd = &chip->sd;
366 int val, mode; 379 int val, mode;
367 380
368 val = chip_read(chip); 381 val = chip_read(chip);
@@ -372,7 +385,7 @@ static int tda9840_getmode(struct CHIPSTATE *chip)
372 if (val & TDA9840_ST_STEREO) 385 if (val & TDA9840_ST_STEREO)
373 mode |= V4L2_TUNER_MODE_STEREO; 386 mode |= V4L2_TUNER_MODE_STEREO;
374 387
375 v4l_dbg(1, debug, chip->c, "tda9840_getmode(): raw chip read: %d, return: %d\n", 388 v4l2_dbg(1, debug, sd, "tda9840_getmode(): raw chip read: %d, return: %d\n",
376 val, mode); 389 val, mode);
377 return mode; 390 return mode;
378} 391}
@@ -668,6 +681,7 @@ static void tda985x_setmode(struct CHIPSTATE *chip, int mode)
668 681
669static int tda9873_getmode(struct CHIPSTATE *chip) 682static int tda9873_getmode(struct CHIPSTATE *chip)
670{ 683{
684 struct v4l2_subdev *sd = &chip->sd;
671 int val,mode; 685 int val,mode;
672 686
673 val = chip_read(chip); 687 val = chip_read(chip);
@@ -676,23 +690,24 @@ static int tda9873_getmode(struct CHIPSTATE *chip)
676 mode |= V4L2_TUNER_MODE_STEREO; 690 mode |= V4L2_TUNER_MODE_STEREO;
677 if (val & TDA9873_DUAL) 691 if (val & TDA9873_DUAL)
678 mode |= V4L2_TUNER_MODE_LANG1 | V4L2_TUNER_MODE_LANG2; 692 mode |= V4L2_TUNER_MODE_LANG1 | V4L2_TUNER_MODE_LANG2;
679 v4l_dbg(1, debug, chip->c, "tda9873_getmode(): raw chip read: %d, return: %d\n", 693 v4l2_dbg(1, debug, sd, "tda9873_getmode(): raw chip read: %d, return: %d\n",
680 val, mode); 694 val, mode);
681 return mode; 695 return mode;
682} 696}
683 697
684static void tda9873_setmode(struct CHIPSTATE *chip, int mode) 698static void tda9873_setmode(struct CHIPSTATE *chip, int mode)
685{ 699{
700 struct v4l2_subdev *sd = &chip->sd;
686 int sw_data = chip->shadow.bytes[TDA9873_SW+1] & ~ TDA9873_TR_MASK; 701 int sw_data = chip->shadow.bytes[TDA9873_SW+1] & ~ TDA9873_TR_MASK;
687 /* int adj_data = chip->shadow.bytes[TDA9873_AD+1] ; */ 702 /* int adj_data = chip->shadow.bytes[TDA9873_AD+1] ; */
688 703
689 if ((sw_data & TDA9873_INP_MASK) != TDA9873_INTERNAL) { 704 if ((sw_data & TDA9873_INP_MASK) != TDA9873_INTERNAL) {
690 v4l_dbg(1, debug, chip->c, "tda9873_setmode(): external input\n"); 705 v4l2_dbg(1, debug, sd, "tda9873_setmode(): external input\n");
691 return; 706 return;
692 } 707 }
693 708
694 v4l_dbg(1, debug, chip->c, "tda9873_setmode(): chip->shadow.bytes[%d] = %d\n", TDA9873_SW+1, chip->shadow.bytes[TDA9873_SW+1]); 709 v4l2_dbg(1, debug, sd, "tda9873_setmode(): chip->shadow.bytes[%d] = %d\n", TDA9873_SW+1, chip->shadow.bytes[TDA9873_SW+1]);
695 v4l_dbg(1, debug, chip->c, "tda9873_setmode(): sw_data = %d\n", sw_data); 710 v4l2_dbg(1, debug, sd, "tda9873_setmode(): sw_data = %d\n", sw_data);
696 711
697 switch (mode) { 712 switch (mode) {
698 case V4L2_TUNER_MODE_MONO: 713 case V4L2_TUNER_MODE_MONO:
@@ -713,7 +728,7 @@ static void tda9873_setmode(struct CHIPSTATE *chip, int mode)
713 } 728 }
714 729
715 chip_write(chip, TDA9873_SW, sw_data); 730 chip_write(chip, TDA9873_SW, sw_data);
716 v4l_dbg(1, debug, chip->c, "tda9873_setmode(): req. mode %d; chip_write: %d\n", 731 v4l2_dbg(1, debug, sd, "tda9873_setmode(): req. mode %d; chip_write: %d\n",
717 mode, sw_data); 732 mode, sw_data);
718} 733}
719 734
@@ -822,6 +837,8 @@ static struct tda9874a_MODES {
822 837
823static int tda9874a_setup(struct CHIPSTATE *chip) 838static int tda9874a_setup(struct CHIPSTATE *chip)
824{ 839{
840 struct v4l2_subdev *sd = &chip->sd;
841
825 chip_write(chip, TDA9874A_AGCGR, 0x00); /* 0 dB */ 842 chip_write(chip, TDA9874A_AGCGR, 0x00); /* 0 dB */
826 chip_write(chip, TDA9874A_GCONR, tda9874a_GCONR); 843 chip_write(chip, TDA9874A_GCONR, tda9874a_GCONR);
827 chip_write(chip, TDA9874A_MSR, (tda9874a_mode) ? 0x03:0x02); 844 chip_write(chip, TDA9874A_MSR, (tda9874a_mode) ? 0x03:0x02);
@@ -852,13 +869,14 @@ static int tda9874a_setup(struct CHIPSTATE *chip)
852 chip_write(chip, TDA9874A_SDACOSR, (tda9874a_mode) ? 0x81:0x80); 869 chip_write(chip, TDA9874A_SDACOSR, (tda9874a_mode) ? 0x81:0x80);
853 chip_write(chip, TDA9874A_AOSR, 0x00); /* or 0x10 */ 870 chip_write(chip, TDA9874A_AOSR, 0x00); /* or 0x10 */
854 } 871 }
855 v4l_dbg(1, debug, chip->c, "tda9874a_setup(): %s [0x%02X].\n", 872 v4l2_dbg(1, debug, sd, "tda9874a_setup(): %s [0x%02X].\n",
856 tda9874a_modelist[tda9874a_STD].name,tda9874a_STD); 873 tda9874a_modelist[tda9874a_STD].name,tda9874a_STD);
857 return 1; 874 return 1;
858} 875}
859 876
860static int tda9874a_getmode(struct CHIPSTATE *chip) 877static int tda9874a_getmode(struct CHIPSTATE *chip)
861{ 878{
879 struct v4l2_subdev *sd = &chip->sd;
862 int dsr,nsr,mode; 880 int dsr,nsr,mode;
863 int necr; /* just for debugging */ 881 int necr; /* just for debugging */
864 882
@@ -895,16 +913,18 @@ static int tda9874a_getmode(struct CHIPSTATE *chip)
895 mode |= V4L2_TUNER_MODE_LANG1 | V4L2_TUNER_MODE_LANG2; 913 mode |= V4L2_TUNER_MODE_LANG1 | V4L2_TUNER_MODE_LANG2;
896 } 914 }
897 915
898 v4l_dbg(1, debug, chip->c, "tda9874a_getmode(): DSR=0x%X, NSR=0x%X, NECR=0x%X, return: %d.\n", 916 v4l2_dbg(1, debug, sd, "tda9874a_getmode(): DSR=0x%X, NSR=0x%X, NECR=0x%X, return: %d.\n",
899 dsr, nsr, necr, mode); 917 dsr, nsr, necr, mode);
900 return mode; 918 return mode;
901} 919}
902 920
903static void tda9874a_setmode(struct CHIPSTATE *chip, int mode) 921static void tda9874a_setmode(struct CHIPSTATE *chip, int mode)
904{ 922{
923 struct v4l2_subdev *sd = &chip->sd;
924
905 /* Disable/enable NICAM auto-muting (based on DSR.RSSF status bit). */ 925 /* Disable/enable NICAM auto-muting (based on DSR.RSSF status bit). */
906 /* If auto-muting is disabled, we can hear a signal of degrading quality. */ 926 /* If auto-muting is disabled, we can hear a signal of degrading quality. */
907 if(tda9874a_mode) { 927 if (tda9874a_mode) {
908 if(chip->shadow.bytes[MAXREGS-2] & 0x20) /* DSR.RSSF=1 */ 928 if(chip->shadow.bytes[MAXREGS-2] & 0x20) /* DSR.RSSF=1 */
909 tda9874a_NCONR &= 0xfe; /* enable */ 929 tda9874a_NCONR &= 0xfe; /* enable */
910 else 930 else
@@ -941,7 +961,7 @@ static void tda9874a_setmode(struct CHIPSTATE *chip, int mode)
941 chip_write(chip, TDA9874A_AOSR, aosr); 961 chip_write(chip, TDA9874A_AOSR, aosr);
942 chip_write(chip, TDA9874A_MDACOSR, mdacosr); 962 chip_write(chip, TDA9874A_MDACOSR, mdacosr);
943 963
944 v4l_dbg(1, debug, chip->c, "tda9874a_setmode(): req. mode %d; AOSR=0x%X, MDACOSR=0x%X.\n", 964 v4l2_dbg(1, debug, sd, "tda9874a_setmode(): req. mode %d; AOSR=0x%X, MDACOSR=0x%X.\n",
945 mode, aosr, mdacosr); 965 mode, aosr, mdacosr);
946 966
947 } else { /* dic == 0x07 */ 967 } else { /* dic == 0x07 */
@@ -976,13 +996,14 @@ static void tda9874a_setmode(struct CHIPSTATE *chip, int mode)
976 chip_write(chip, TDA9874A_FMMR, fmmr); 996 chip_write(chip, TDA9874A_FMMR, fmmr);
977 chip_write(chip, TDA9874A_AOSR, aosr); 997 chip_write(chip, TDA9874A_AOSR, aosr);
978 998
979 v4l_dbg(1, debug, chip->c, "tda9874a_setmode(): req. mode %d; FMMR=0x%X, AOSR=0x%X.\n", 999 v4l2_dbg(1, debug, sd, "tda9874a_setmode(): req. mode %d; FMMR=0x%X, AOSR=0x%X.\n",
980 mode, fmmr, aosr); 1000 mode, fmmr, aosr);
981 } 1001 }
982} 1002}
983 1003
984static int tda9874a_checkit(struct CHIPSTATE *chip) 1004static int tda9874a_checkit(struct CHIPSTATE *chip)
985{ 1005{
1006 struct v4l2_subdev *sd = &chip->sd;
986 int dic,sic; /* device id. and software id. codes */ 1007 int dic,sic; /* device id. and software id. codes */
987 1008
988 if(-1 == (dic = chip_read2(chip,TDA9874A_DIC))) 1009 if(-1 == (dic = chip_read2(chip,TDA9874A_DIC)))
@@ -990,10 +1011,10 @@ static int tda9874a_checkit(struct CHIPSTATE *chip)
990 if(-1 == (sic = chip_read2(chip,TDA9874A_SIC))) 1011 if(-1 == (sic = chip_read2(chip,TDA9874A_SIC)))
991 return 0; 1012 return 0;
992 1013
993 v4l_dbg(1, debug, chip->c, "tda9874a_checkit(): DIC=0x%X, SIC=0x%X.\n", dic, sic); 1014 v4l2_dbg(1, debug, sd, "tda9874a_checkit(): DIC=0x%X, SIC=0x%X.\n", dic, sic);
994 1015
995 if((dic == 0x11)||(dic == 0x07)) { 1016 if((dic == 0x11)||(dic == 0x07)) {
996 v4l_info(chip->c, "found tda9874%s.\n", (dic == 0x11) ? "a":"h"); 1017 v4l2_info(sd, "found tda9874%s.\n", (dic == 0x11) ? "a" : "h");
997 tda9874a_dic = dic; /* remember device id. */ 1018 tda9874a_dic = dic; /* remember device id. */
998 return 1; 1019 return 1;
999 } 1020 }
@@ -1113,12 +1134,12 @@ static int tda8425_shift12(int val) { return (val >> 12) | 0xf0; }
1113static int tda8425_initialize(struct CHIPSTATE *chip) 1134static int tda8425_initialize(struct CHIPSTATE *chip)
1114{ 1135{
1115 struct CHIPDESC *desc = chip->desc; 1136 struct CHIPDESC *desc = chip->desc;
1137 struct i2c_client *c = v4l2_get_subdevdata(&chip->sd);
1116 int inputmap[4] = { /* tuner */ TDA8425_S1_CH2, /* radio */ TDA8425_S1_CH1, 1138 int inputmap[4] = { /* tuner */ TDA8425_S1_CH2, /* radio */ TDA8425_S1_CH1,
1117 /* extern */ TDA8425_S1_CH1, /* intern */ TDA8425_S1_OFF}; 1139 /* extern */ TDA8425_S1_CH1, /* intern */ TDA8425_S1_OFF};
1118 1140
1119 if (chip->c->adapter->id == I2C_HW_B_RIVA) { 1141 if (c->adapter->id == I2C_HW_B_RIVA)
1120 memcpy (desc->inputmap, inputmap, sizeof (inputmap)); 1142 memcpy(desc->inputmap, inputmap, sizeof(inputmap));
1121 }
1122 return 0; 1143 return 0;
1123} 1144}
1124 1145
@@ -1215,9 +1236,11 @@ static audiocmd ta8874z_sub = {2, { TA8874Z_MODE_SUB, TA8874Z_SEPARATION_DEFAULT
1215 1236
1216static void ta8874z_setmode(struct CHIPSTATE *chip, int mode) 1237static void ta8874z_setmode(struct CHIPSTATE *chip, int mode)
1217{ 1238{
1239 struct v4l2_subdev *sd = &chip->sd;
1218 int update = 1; 1240 int update = 1;
1219 audiocmd *t = NULL; 1241 audiocmd *t = NULL;
1220 v4l_dbg(1, debug, chip->c, "ta8874z_setmode(): mode: 0x%02x\n", mode); 1242
1243 v4l2_dbg(1, debug, sd, "ta8874z_setmode(): mode: 0x%02x\n", mode);
1221 1244
1222 switch(mode){ 1245 switch(mode){
1223 case V4L2_TUNER_MODE_MONO: 1246 case V4L2_TUNER_MODE_MONO:
@@ -1479,142 +1502,11 @@ static struct CHIPDESC chiplist[] = {
1479 1502
1480 1503
1481/* ---------------------------------------------------------------------- */ 1504/* ---------------------------------------------------------------------- */
1482/* i2c registration */
1483
1484static int chip_probe(struct i2c_client *client, const struct i2c_device_id *id)
1485{
1486 struct CHIPSTATE *chip;
1487 struct CHIPDESC *desc;
1488
1489 if (debug) {
1490 printk(KERN_INFO "tvaudio: TV audio decoder + audio/video mux driver\n");
1491 printk(KERN_INFO "tvaudio: known chips: ");
1492 for (desc = chiplist; desc->name != NULL; desc++)
1493 printk("%s%s", (desc == chiplist) ? "" : ", ", desc->name);
1494 printk("\n");
1495 }
1496
1497 chip = kzalloc(sizeof(*chip),GFP_KERNEL);
1498 if (!chip)
1499 return -ENOMEM;
1500 chip->c = client;
1501 i2c_set_clientdata(client, chip);
1502 1505
1503 /* find description for the chip */ 1506static int tvaudio_g_ctrl(struct v4l2_subdev *sd,
1504 v4l_dbg(1, debug, client, "chip found @ 0x%x\n", client->addr<<1);
1505 for (desc = chiplist; desc->name != NULL; desc++) {
1506 if (0 == *(desc->insmodopt))
1507 continue;
1508 if (client->addr < desc->addr_lo ||
1509 client->addr > desc->addr_hi)
1510 continue;
1511 if (desc->checkit && !desc->checkit(chip))
1512 continue;
1513 break;
1514 }
1515 if (desc->name == NULL) {
1516 v4l_dbg(1, debug, client, "no matching chip description found\n");
1517 kfree(chip);
1518 return -EIO;
1519 }
1520 v4l_info(client, "%s found @ 0x%x (%s)\n", desc->name, client->addr<<1, client->adapter->name);
1521 if (desc->flags) {
1522 v4l_dbg(1, debug, client, "matches:%s%s%s.\n",
1523 (desc->flags & CHIP_HAS_VOLUME) ? " volume" : "",
1524 (desc->flags & CHIP_HAS_BASSTREBLE) ? " bass/treble" : "",
1525 (desc->flags & CHIP_HAS_INPUTSEL) ? " audiomux" : "");
1526 }
1527
1528 /* fill required data structures */
1529 if (!id)
1530 strlcpy(client->name, desc->name, I2C_NAME_SIZE);
1531 chip->desc = desc;
1532 chip->shadow.count = desc->registers+1;
1533 chip->prevmode = -1;
1534 chip->audmode = V4L2_TUNER_MODE_LANG1;
1535
1536 /* initialization */
1537 if (desc->initialize != NULL)
1538 desc->initialize(chip);
1539 else
1540 chip_cmd(chip,"init",&desc->init);
1541
1542 if (desc->flags & CHIP_HAS_VOLUME) {
1543 if (!desc->volfunc) {
1544 /* This shouldn't be happen. Warn user, but keep working
1545 without volume controls
1546 */
1547 v4l_info(chip->c, "volume callback undefined!\n");
1548 desc->flags &= ~CHIP_HAS_VOLUME;
1549 } else {
1550 chip->left = desc->leftinit ? desc->leftinit : 65535;
1551 chip->right = desc->rightinit ? desc->rightinit : 65535;
1552 chip_write(chip, desc->leftreg,
1553 desc->volfunc(chip->left));
1554 chip_write(chip, desc->rightreg,
1555 desc->volfunc(chip->right));
1556 }
1557 }
1558 if (desc->flags & CHIP_HAS_BASSTREBLE) {
1559 if (!desc->bassfunc || !desc->treblefunc) {
1560 /* This shouldn't be happen. Warn user, but keep working
1561 without bass/treble controls
1562 */
1563 v4l_info(chip->c, "bass/treble callbacks undefined!\n");
1564 desc->flags &= ~CHIP_HAS_BASSTREBLE;
1565 } else {
1566 chip->treble = desc->trebleinit ?
1567 desc->trebleinit : 32768;
1568 chip->bass = desc->bassinit ?
1569 desc->bassinit : 32768;
1570 chip_write(chip, desc->bassreg,
1571 desc->bassfunc(chip->bass));
1572 chip_write(chip, desc->treblereg,
1573 desc->treblefunc(chip->treble));
1574 }
1575 }
1576
1577 chip->thread = NULL;
1578 if (desc->flags & CHIP_NEED_CHECKMODE) {
1579 if (!desc->getmode || !desc->setmode) {
1580 /* This shouldn't be happen. Warn user, but keep working
1581 without kthread
1582 */
1583 v4l_info(chip->c, "set/get mode callbacks undefined!\n");
1584 return 0;
1585 }
1586 /* start async thread */
1587 init_timer(&chip->wt);
1588 chip->wt.function = chip_thread_wake;
1589 chip->wt.data = (unsigned long)chip;
1590 chip->thread = kthread_run(chip_thread, chip, chip->c->name);
1591 if (IS_ERR(chip->thread)) {
1592 v4l_warn(chip->c, "%s: failed to create kthread\n",
1593 chip->c->name);
1594 chip->thread = NULL;
1595 }
1596 }
1597 return 0;
1598}
1599
1600static int chip_remove(struct i2c_client *client)
1601{
1602 struct CHIPSTATE *chip = i2c_get_clientdata(client);
1603
1604 del_timer_sync(&chip->wt);
1605 if (chip->thread) {
1606 /* shutdown async thread */
1607 kthread_stop(chip->thread);
1608 chip->thread = NULL;
1609 }
1610
1611 kfree(chip);
1612 return 0;
1613}
1614
1615static int tvaudio_get_ctrl(struct CHIPSTATE *chip,
1616 struct v4l2_control *ctrl) 1507 struct v4l2_control *ctrl)
1617{ 1508{
1509 struct CHIPSTATE *chip = to_state(sd);
1618 struct CHIPDESC *desc = chip->desc; 1510 struct CHIPDESC *desc = chip->desc;
1619 1511
1620 switch (ctrl->id) { 1512 switch (ctrl->id) {
@@ -1652,9 +1544,10 @@ static int tvaudio_get_ctrl(struct CHIPSTATE *chip,
1652 return -EINVAL; 1544 return -EINVAL;
1653} 1545}
1654 1546
1655static int tvaudio_set_ctrl(struct CHIPSTATE *chip, 1547static int tvaudio_s_ctrl(struct v4l2_subdev *sd,
1656 struct v4l2_control *ctrl) 1548 struct v4l2_control *ctrl)
1657{ 1549{
1550 struct CHIPSTATE *chip = to_state(sd);
1658 struct CHIPDESC *desc = chip->desc; 1551 struct CHIPDESC *desc = chip->desc;
1659 1552
1660 switch (ctrl->id) { 1553 switch (ctrl->id) {
@@ -1726,161 +1619,327 @@ static int tvaudio_set_ctrl(struct CHIPSTATE *chip,
1726/* ---------------------------------------------------------------------- */ 1619/* ---------------------------------------------------------------------- */
1727/* video4linux interface */ 1620/* video4linux interface */
1728 1621
1729static int chip_command(struct i2c_client *client, 1622static int tvaudio_s_radio(struct v4l2_subdev *sd)
1730 unsigned int cmd, void *arg)
1731{ 1623{
1732 struct CHIPSTATE *chip = i2c_get_clientdata(client); 1624 struct CHIPSTATE *chip = to_state(sd);
1733 struct CHIPDESC *desc = chip->desc;
1734 1625
1735 if (debug > 0) { 1626 chip->radio = 1;
1736 v4l_i2c_print_ioctl(chip->c, cmd); 1627 chip->watch_stereo = 0;
1737 printk("\n"); 1628 /* del_timer(&chip->wt); */
1629 return 0;
1630}
1631
1632static int tvaudio_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
1633{
1634 struct CHIPSTATE *chip = to_state(sd);
1635 struct CHIPDESC *desc = chip->desc;
1636
1637 switch (qc->id) {
1638 case V4L2_CID_AUDIO_MUTE:
1639 break;
1640 case V4L2_CID_AUDIO_VOLUME:
1641 case V4L2_CID_AUDIO_BALANCE:
1642 if (!(desc->flags & CHIP_HAS_VOLUME))
1643 return -EINVAL;
1644 break;
1645 case V4L2_CID_AUDIO_BASS:
1646 case V4L2_CID_AUDIO_TREBLE:
1647 if (!(desc->flags & CHIP_HAS_BASSTREBLE))
1648 return -EINVAL;
1649 break;
1650 default:
1651 return -EINVAL;
1738 } 1652 }
1653 return v4l2_ctrl_query_fill_std(qc);
1654}
1655
1656static int tvaudio_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *rt)
1657{
1658 struct CHIPSTATE *chip = to_state(sd);
1659 struct CHIPDESC *desc = chip->desc;
1739 1660
1740 switch (cmd) { 1661 if (!(desc->flags & CHIP_HAS_INPUTSEL) || rt->input >= 4)
1741 case AUDC_SET_RADIO: 1662 return -EINVAL;
1742 chip->radio = 1; 1663 /* There are four inputs: tuner, radio, extern and intern. */
1664 chip->input = rt->input;
1665 if (chip->muted)
1666 return 0;
1667 chip_write_masked(chip, desc->inputreg,
1668 desc->inputmap[chip->input], desc->inputmask);
1669 return 0;
1670}
1671
1672static int tvaudio_s_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
1673{
1674 struct CHIPSTATE *chip = to_state(sd);
1675 struct CHIPDESC *desc = chip->desc;
1676 int mode = 0;
1677
1678 if (chip->radio)
1679 return 0;
1680 switch (vt->audmode) {
1681 case V4L2_TUNER_MODE_MONO:
1682 case V4L2_TUNER_MODE_STEREO:
1683 case V4L2_TUNER_MODE_LANG1:
1684 case V4L2_TUNER_MODE_LANG2:
1685 mode = vt->audmode;
1686 break;
1687 case V4L2_TUNER_MODE_LANG1_LANG2:
1688 mode = V4L2_TUNER_MODE_STEREO;
1689 break;
1690 default:
1691 return -EINVAL;
1692 }
1693 chip->audmode = vt->audmode;
1694
1695 if (desc->setmode && mode) {
1743 chip->watch_stereo = 0; 1696 chip->watch_stereo = 0;
1744 /* del_timer(&chip->wt); */ 1697 /* del_timer(&chip->wt); */
1745 break; 1698 chip->mode = mode;
1746 /* --- v4l ioctls --- */ 1699 desc->setmode(chip, mode);
1747 /* take care: bttv does userspace copying, we'll get a
1748 kernel pointer here... */
1749 case VIDIOC_QUERYCTRL:
1750 {
1751 struct v4l2_queryctrl *qc = arg;
1752
1753 switch (qc->id) {
1754 case V4L2_CID_AUDIO_MUTE:
1755 break;
1756 case V4L2_CID_AUDIO_VOLUME:
1757 case V4L2_CID_AUDIO_BALANCE:
1758 if (!(desc->flags & CHIP_HAS_VOLUME))
1759 return -EINVAL;
1760 break;
1761 case V4L2_CID_AUDIO_BASS:
1762 case V4L2_CID_AUDIO_TREBLE:
1763 if (!(desc->flags & CHIP_HAS_BASSTREBLE))
1764 return -EINVAL;
1765 break;
1766 default:
1767 return -EINVAL;
1768 }
1769 return v4l2_ctrl_query_fill_std(qc);
1770 } 1700 }
1771 case VIDIOC_S_CTRL: 1701 return 0;
1772 return tvaudio_set_ctrl(chip, arg); 1702}
1773 1703
1774 case VIDIOC_G_CTRL: 1704static int tvaudio_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
1775 return tvaudio_get_ctrl(chip, arg); 1705{
1776 case VIDIOC_INT_G_AUDIO_ROUTING: 1706 struct CHIPSTATE *chip = to_state(sd);
1777 { 1707 struct CHIPDESC *desc = chip->desc;
1778 struct v4l2_routing *rt = arg; 1708 int mode = V4L2_TUNER_MODE_MONO;
1779 1709
1780 rt->input = chip->input; 1710 if (chip->radio)
1781 rt->output = 0; 1711 return 0;
1782 break; 1712 vt->audmode = chip->audmode;
1713 vt->rxsubchans = 0;
1714 vt->capability = V4L2_TUNER_CAP_STEREO |
1715 V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2;
1716
1717 if (desc->getmode)
1718 mode = desc->getmode(chip);
1719
1720 if (mode & V4L2_TUNER_MODE_MONO)
1721 vt->rxsubchans |= V4L2_TUNER_SUB_MONO;
1722 if (mode & V4L2_TUNER_MODE_STEREO)
1723 vt->rxsubchans |= V4L2_TUNER_SUB_STEREO;
1724 /* Note: for SAP it should be mono/lang2 or stereo/lang2.
1725 When this module is converted fully to v4l2, then this
1726 should change for those chips that can detect SAP. */
1727 if (mode & V4L2_TUNER_MODE_LANG1)
1728 vt->rxsubchans = V4L2_TUNER_SUB_LANG1 |
1729 V4L2_TUNER_SUB_LANG2;
1730 return 0;
1731}
1732
1733static int tvaudio_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
1734{
1735 struct CHIPSTATE *chip = to_state(sd);
1736
1737 chip->radio = 0;
1738 return 0;
1739}
1740
1741static int tvaudio_s_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *freq)
1742{
1743 struct CHIPSTATE *chip = to_state(sd);
1744 struct CHIPDESC *desc = chip->desc;
1745
1746 chip->mode = 0; /* automatic */
1747
1748 /* For chips that provide getmode and setmode, and doesn't
1749 automatically follows the stereo carrier, a kthread is
1750 created to set the audio standard. In this case, when then
1751 the video channel is changed, tvaudio starts on MONO mode.
1752 After waiting for 2 seconds, the kernel thread is called,
1753 to follow whatever audio standard is pointed by the
1754 audio carrier.
1755 */
1756 if (chip->thread) {
1757 desc->setmode(chip, V4L2_TUNER_MODE_MONO);
1758 if (chip->prevmode != V4L2_TUNER_MODE_MONO)
1759 chip->prevmode = -1; /* reset previous mode */
1760 mod_timer(&chip->wt, jiffies+msecs_to_jiffies(2000));
1783 } 1761 }
1784 case VIDIOC_INT_S_AUDIO_ROUTING: 1762 return 0;
1785 { 1763}
1786 struct v4l2_routing *rt = arg;
1787 1764
1788 if (!(desc->flags & CHIP_HAS_INPUTSEL) || rt->input >= 4) 1765static int tvaudio_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_chip_ident *chip)
1789 return -EINVAL; 1766{
1790 /* There are four inputs: tuner, radio, extern and intern. */ 1767 struct i2c_client *client = v4l2_get_subdevdata(sd);
1791 chip->input = rt->input; 1768
1792 if (chip->muted) 1769 return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_TVAUDIO, 0);
1793 break; 1770}
1794 chip_write_masked(chip, desc->inputreg, 1771
1795 desc->inputmap[chip->input], desc->inputmask); 1772static int tvaudio_command(struct i2c_client *client, unsigned cmd, void *arg)
1796 break; 1773{
1774 return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
1775}
1776
1777/* ----------------------------------------------------------------------- */
1778
1779static const struct v4l2_subdev_core_ops tvaudio_core_ops = {
1780 .g_chip_ident = tvaudio_g_chip_ident,
1781 .queryctrl = tvaudio_queryctrl,
1782 .g_ctrl = tvaudio_g_ctrl,
1783 .s_ctrl = tvaudio_s_ctrl,
1784};
1785
1786static const struct v4l2_subdev_tuner_ops tvaudio_tuner_ops = {
1787 .s_radio = tvaudio_s_radio,
1788 .s_frequency = tvaudio_s_frequency,
1789 .s_std = tvaudio_s_std,
1790 .s_tuner = tvaudio_s_tuner,
1791 .s_tuner = tvaudio_g_tuner,
1792};
1793
1794static const struct v4l2_subdev_audio_ops tvaudio_audio_ops = {
1795 .s_routing = tvaudio_s_routing,
1796};
1797
1798static const struct v4l2_subdev_ops tvaudio_ops = {
1799 .core = &tvaudio_core_ops,
1800 .tuner = &tvaudio_tuner_ops,
1801 .audio = &tvaudio_audio_ops,
1802};
1803
1804/* ----------------------------------------------------------------------- */
1805
1806
1807/* i2c registration */
1808
1809static int tvaudio_probe(struct i2c_client *client, const struct i2c_device_id *id)
1810{
1811 struct CHIPSTATE *chip;
1812 struct CHIPDESC *desc;
1813 struct v4l2_subdev *sd;
1814
1815 if (debug) {
1816 printk(KERN_INFO "tvaudio: TV audio decoder + audio/video mux driver\n");
1817 printk(KERN_INFO "tvaudio: known chips: ");
1818 for (desc = chiplist; desc->name != NULL; desc++)
1819 printk("%s%s", (desc == chiplist) ? "" : ", ", desc->name);
1820 printk("\n");
1797 } 1821 }
1798 case VIDIOC_S_TUNER:
1799 {
1800 struct v4l2_tuner *vt = arg;
1801 int mode = 0;
1802 1822
1803 if (chip->radio) 1823 chip = kzalloc(sizeof(*chip), GFP_KERNEL);
1804 break; 1824 if (!chip)
1805 switch (vt->audmode) { 1825 return -ENOMEM;
1806 case V4L2_TUNER_MODE_MONO: 1826 sd = &chip->sd;
1807 case V4L2_TUNER_MODE_STEREO: 1827 v4l2_i2c_subdev_init(sd, client, &tvaudio_ops);
1808 case V4L2_TUNER_MODE_LANG1:
1809 case V4L2_TUNER_MODE_LANG2:
1810 mode = vt->audmode;
1811 break;
1812 case V4L2_TUNER_MODE_LANG1_LANG2:
1813 mode = V4L2_TUNER_MODE_STEREO;
1814 break;
1815 default:
1816 return -EINVAL;
1817 }
1818 chip->audmode = vt->audmode;
1819 1828
1820 if (desc->setmode && mode) { 1829 /* find description for the chip */
1821 chip->watch_stereo = 0; 1830 v4l2_dbg(1, debug, sd, "chip found @ 0x%x\n", client->addr<<1);
1822 /* del_timer(&chip->wt); */ 1831 for (desc = chiplist; desc->name != NULL; desc++) {
1823 chip->mode = mode; 1832 if (0 == *(desc->insmodopt))
1824 desc->setmode(chip, mode); 1833 continue;
1825 } 1834 if (client->addr < desc->addr_lo ||
1835 client->addr > desc->addr_hi)
1836 continue;
1837 if (desc->checkit && !desc->checkit(chip))
1838 continue;
1826 break; 1839 break;
1827 } 1840 }
1828 case VIDIOC_G_TUNER: 1841 if (desc->name == NULL) {
1829 { 1842 v4l2_dbg(1, debug, sd, "no matching chip description found\n");
1830 struct v4l2_tuner *vt = arg; 1843 kfree(chip);
1831 int mode = V4L2_TUNER_MODE_MONO; 1844 return -EIO;
1845 }
1846 v4l2_info(sd, "%s found @ 0x%x (%s)\n", desc->name, client->addr<<1, client->adapter->name);
1847 if (desc->flags) {
1848 v4l2_dbg(1, debug, sd, "matches:%s%s%s.\n",
1849 (desc->flags & CHIP_HAS_VOLUME) ? " volume" : "",
1850 (desc->flags & CHIP_HAS_BASSTREBLE) ? " bass/treble" : "",
1851 (desc->flags & CHIP_HAS_INPUTSEL) ? " audiomux" : "");
1852 }
1832 1853
1833 if (chip->radio) 1854 /* fill required data structures */
1834 break; 1855 if (!id)
1835 vt->audmode = chip->audmode; 1856 strlcpy(client->name, desc->name, I2C_NAME_SIZE);
1836 vt->rxsubchans = 0; 1857 chip->desc = desc;
1837 vt->capability = V4L2_TUNER_CAP_STEREO | 1858 chip->shadow.count = desc->registers+1;
1838 V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2; 1859 chip->prevmode = -1;
1860 chip->audmode = V4L2_TUNER_MODE_LANG1;
1839 1861
1840 if (desc->getmode) 1862 /* initialization */
1841 mode = desc->getmode(chip); 1863 if (desc->initialize != NULL)
1864 desc->initialize(chip);
1865 else
1866 chip_cmd(chip, "init", &desc->init);
1842 1867
1843 if (mode & V4L2_TUNER_MODE_MONO) 1868 if (desc->flags & CHIP_HAS_VOLUME) {
1844 vt->rxsubchans |= V4L2_TUNER_SUB_MONO; 1869 if (!desc->volfunc) {
1845 if (mode & V4L2_TUNER_MODE_STEREO) 1870 /* This shouldn't be happen. Warn user, but keep working
1846 vt->rxsubchans |= V4L2_TUNER_SUB_STEREO; 1871 without volume controls
1847 /* Note: for SAP it should be mono/lang2 or stereo/lang2. 1872 */
1848 When this module is converted fully to v4l2, then this 1873 v4l2_info(sd, "volume callback undefined!\n");
1849 should change for those chips that can detect SAP. */ 1874 desc->flags &= ~CHIP_HAS_VOLUME;
1850 if (mode & V4L2_TUNER_MODE_LANG1) 1875 } else {
1851 vt->rxsubchans = V4L2_TUNER_SUB_LANG1 | 1876 chip->left = desc->leftinit ? desc->leftinit : 65535;
1852 V4L2_TUNER_SUB_LANG2; 1877 chip->right = desc->rightinit ? desc->rightinit : 65535;
1853 break; 1878 chip_write(chip, desc->leftreg,
1879 desc->volfunc(chip->left));
1880 chip_write(chip, desc->rightreg,
1881 desc->volfunc(chip->right));
1882 }
1854 } 1883 }
1855 case VIDIOC_S_STD: 1884 if (desc->flags & CHIP_HAS_BASSTREBLE) {
1856 chip->radio = 0; 1885 if (!desc->bassfunc || !desc->treblefunc) {
1857 break; 1886 /* This shouldn't be happen. Warn user, but keep working
1858 case VIDIOC_S_FREQUENCY: 1887 without bass/treble controls
1859 chip->mode = 0; /* automatic */ 1888 */
1860 1889 v4l2_info(sd, "bass/treble callbacks undefined!\n");
1861 /* For chips that provide getmode and setmode, and doesn't 1890 desc->flags &= ~CHIP_HAS_BASSTREBLE;
1862 automatically follows the stereo carrier, a kthread is 1891 } else {
1863 created to set the audio standard. In this case, when then 1892 chip->treble = desc->trebleinit ?
1864 the video channel is changed, tvaudio starts on MONO mode. 1893 desc->trebleinit : 32768;
1865 After waiting for 2 seconds, the kernel thread is called, 1894 chip->bass = desc->bassinit ?
1866 to follow whatever audio standard is pointed by the 1895 desc->bassinit : 32768;
1867 audio carrier. 1896 chip_write(chip, desc->bassreg,
1868 */ 1897 desc->bassfunc(chip->bass));
1869 if (chip->thread) { 1898 chip_write(chip, desc->treblereg,
1870 desc->setmode(chip,V4L2_TUNER_MODE_MONO); 1899 desc->treblefunc(chip->treble));
1871 if (chip->prevmode != V4L2_TUNER_MODE_MONO)
1872 chip->prevmode = -1; /* reset previous mode */
1873 mod_timer(&chip->wt, jiffies+msecs_to_jiffies(2000));
1874 } 1900 }
1875 break; 1901 }
1876 1902
1877 case VIDIOC_G_CHIP_IDENT: 1903 chip->thread = NULL;
1878 return v4l2_chip_ident_i2c_client(client, arg, V4L2_IDENT_TVAUDIO, 0); 1904 if (desc->flags & CHIP_NEED_CHECKMODE) {
1905 if (!desc->getmode || !desc->setmode) {
1906 /* This shouldn't be happen. Warn user, but keep working
1907 without kthread
1908 */
1909 v4l2_info(sd, "set/get mode callbacks undefined!\n");
1910 return 0;
1911 }
1912 /* start async thread */
1913 init_timer(&chip->wt);
1914 chip->wt.function = chip_thread_wake;
1915 chip->wt.data = (unsigned long)chip;
1916 chip->thread = kthread_run(chip_thread, chip, client->name);
1917 if (IS_ERR(chip->thread)) {
1918 v4l2_warn(sd, "failed to create kthread\n");
1919 chip->thread = NULL;
1920 }
1879 } 1921 }
1880 return 0; 1922 return 0;
1881} 1923}
1882 1924
1883static int chip_legacy_probe(struct i2c_adapter *adap) 1925static int tvaudio_remove(struct i2c_client *client)
1926{
1927 struct v4l2_subdev *sd = i2c_get_clientdata(client);
1928 struct CHIPSTATE *chip = to_state(sd);
1929
1930 del_timer_sync(&chip->wt);
1931 if (chip->thread) {
1932 /* shutdown async thread */
1933 kthread_stop(chip->thread);
1934 chip->thread = NULL;
1935 }
1936
1937 v4l2_device_unregister_subdev(sd);
1938 kfree(chip);
1939 return 0;
1940}
1941
1942static int tvaudio_legacy_probe(struct i2c_adapter *adap)
1884{ 1943{
1885 /* don't attach on saa7146 based cards, 1944 /* don't attach on saa7146 based cards,
1886 because dedicated drivers are used */ 1945 because dedicated drivers are used */
@@ -1894,18 +1953,18 @@ static int chip_legacy_probe(struct i2c_adapter *adap)
1894/* This driver supports many devices and the idea is to let the driver 1953/* This driver supports many devices and the idea is to let the driver
1895 detect which device is present. So rather than listing all supported 1954 detect which device is present. So rather than listing all supported
1896 devices here, we pretend to support a single, fake device type. */ 1955 devices here, we pretend to support a single, fake device type. */
1897static const struct i2c_device_id chip_id[] = { 1956static const struct i2c_device_id tvaudio_id[] = {
1898 { "tvaudio", 0 }, 1957 { "tvaudio", 0 },
1899 { } 1958 { }
1900}; 1959};
1901MODULE_DEVICE_TABLE(i2c, chip_id); 1960MODULE_DEVICE_TABLE(i2c, tvaudio_id);
1902 1961
1903static struct v4l2_i2c_driver_data v4l2_i2c_data = { 1962static struct v4l2_i2c_driver_data v4l2_i2c_data = {
1904 .name = "tvaudio", 1963 .name = "tvaudio",
1905 .driverid = I2C_DRIVERID_TVAUDIO, 1964 .driverid = I2C_DRIVERID_TVAUDIO,
1906 .command = chip_command, 1965 .command = tvaudio_command,
1907 .probe = chip_probe, 1966 .probe = tvaudio_probe,
1908 .remove = chip_remove, 1967 .remove = tvaudio_remove,
1909 .legacy_probe = chip_legacy_probe, 1968 .legacy_probe = tvaudio_legacy_probe,
1910 .id_table = chip_id, 1969 .id_table = tvaudio_id,
1911}; 1970};
diff --git a/drivers/media/video/tvp514x.c b/drivers/media/video/tvp514x.c
new file mode 100644
index 000000000000..ac9aa40d09f6
--- /dev/null
+++ b/drivers/media/video/tvp514x.c
@@ -0,0 +1,1569 @@
1/*
2 * drivers/media/video/tvp514x.c
3 *
4 * TI TVP5146/47 decoder driver
5 *
6 * Copyright (C) 2008 Texas Instruments Inc
7 * Author: Vaibhav Hiremath <hvaibhav@ti.com>
8 *
9 * Contributors:
10 * Sivaraj R <sivaraj@ti.com>
11 * Brijesh R Jadav <brijesh.j@ti.com>
12 * Hardik Shah <hardik.shah@ti.com>
13 * Manjunath Hadli <mrh@ti.com>
14 * Karicheri Muralidharan <m-karicheri2@ti.com>
15 *
16 * This package is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License version 2 as
18 * published by the Free Software Foundation.
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 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28 *
29 */
30
31#include <linux/i2c.h>
32#include <linux/delay.h>
33#include <linux/videodev2.h>
34#include <media/v4l2-int-device.h>
35#include <media/tvp514x.h>
36
37#include "tvp514x_regs.h"
38
39/* Module Name */
40#define TVP514X_MODULE_NAME "tvp514x"
41
42/* Private macros for TVP */
43#define I2C_RETRY_COUNT (5)
44#define LOCK_RETRY_COUNT (5)
45#define LOCK_RETRY_DELAY (200)
46
47/* Debug functions */
48static int debug;
49module_param(debug, bool, 0644);
50MODULE_PARM_DESC(debug, "Debug level (0-1)");
51
52#define dump_reg(client, reg, val) \
53 do { \
54 val = tvp514x_read_reg(client, reg); \
55 v4l_info(client, "Reg(0x%.2X): 0x%.2X\n", reg, val); \
56 } while (0)
57
58/**
59 * enum tvp514x_std - enum for supported standards
60 */
61enum tvp514x_std {
62 STD_NTSC_MJ = 0,
63 STD_PAL_BDGHIN,
64 STD_INVALID
65};
66
67/**
68 * enum tvp514x_state - enum for different decoder states
69 */
70enum tvp514x_state {
71 STATE_NOT_DETECTED,
72 STATE_DETECTED
73};
74
75/**
76 * struct tvp514x_std_info - Structure to store standard informations
77 * @width: Line width in pixels
78 * @height:Number of active lines
79 * @video_std: Value to write in REG_VIDEO_STD register
80 * @standard: v4l2 standard structure information
81 */
82struct tvp514x_std_info {
83 unsigned long width;
84 unsigned long height;
85 u8 video_std;
86 struct v4l2_standard standard;
87};
88
89/**
90 * struct tvp514x_decoded - TVP5146/47 decoder object
91 * @v4l2_int_device: Slave handle
92 * @pdata: Board specific
93 * @client: I2C client data
94 * @id: Entry from I2C table
95 * @ver: Chip version
96 * @state: TVP5146/47 decoder state - detected or not-detected
97 * @pix: Current pixel format
98 * @num_fmts: Number of formats
99 * @fmt_list: Format list
100 * @current_std: Current standard
101 * @num_stds: Number of standards
102 * @std_list: Standards list
103 * @route: input and output routing at chip level
104 */
105struct tvp514x_decoder {
106 struct v4l2_int_device *v4l2_int_device;
107 const struct tvp514x_platform_data *pdata;
108 struct i2c_client *client;
109
110 struct i2c_device_id *id;
111
112 int ver;
113 enum tvp514x_state state;
114
115 struct v4l2_pix_format pix;
116 int num_fmts;
117 const struct v4l2_fmtdesc *fmt_list;
118
119 enum tvp514x_std current_std;
120 int num_stds;
121 struct tvp514x_std_info *std_list;
122
123 struct v4l2_routing route;
124};
125
126/* TVP514x default register values */
127static struct tvp514x_reg tvp514x_reg_list[] = {
128 {TOK_WRITE, REG_INPUT_SEL, 0x05}, /* Composite selected */
129 {TOK_WRITE, REG_AFE_GAIN_CTRL, 0x0F},
130 {TOK_WRITE, REG_VIDEO_STD, 0x00}, /* Auto mode */
131 {TOK_WRITE, REG_OPERATION_MODE, 0x00},
132 {TOK_SKIP, REG_AUTOSWITCH_MASK, 0x3F},
133 {TOK_WRITE, REG_COLOR_KILLER, 0x10},
134 {TOK_WRITE, REG_LUMA_CONTROL1, 0x00},
135 {TOK_WRITE, REG_LUMA_CONTROL2, 0x00},
136 {TOK_WRITE, REG_LUMA_CONTROL3, 0x02},
137 {TOK_WRITE, REG_BRIGHTNESS, 0x80},
138 {TOK_WRITE, REG_CONTRAST, 0x80},
139 {TOK_WRITE, REG_SATURATION, 0x80},
140 {TOK_WRITE, REG_HUE, 0x00},
141 {TOK_WRITE, REG_CHROMA_CONTROL1, 0x00},
142 {TOK_WRITE, REG_CHROMA_CONTROL2, 0x0E},
143 {TOK_SKIP, 0x0F, 0x00}, /* Reserved */
144 {TOK_WRITE, REG_COMP_PR_SATURATION, 0x80},
145 {TOK_WRITE, REG_COMP_Y_CONTRAST, 0x80},
146 {TOK_WRITE, REG_COMP_PB_SATURATION, 0x80},
147 {TOK_SKIP, 0x13, 0x00}, /* Reserved */
148 {TOK_WRITE, REG_COMP_Y_BRIGHTNESS, 0x80},
149 {TOK_SKIP, 0x15, 0x00}, /* Reserved */
150 {TOK_SKIP, REG_AVID_START_PIXEL_LSB, 0x55}, /* NTSC timing */
151 {TOK_SKIP, REG_AVID_START_PIXEL_MSB, 0x00},
152 {TOK_SKIP, REG_AVID_STOP_PIXEL_LSB, 0x25},
153 {TOK_SKIP, REG_AVID_STOP_PIXEL_MSB, 0x03},
154 {TOK_SKIP, REG_HSYNC_START_PIXEL_LSB, 0x00}, /* NTSC timing */
155 {TOK_SKIP, REG_HSYNC_START_PIXEL_MSB, 0x00},
156 {TOK_SKIP, REG_HSYNC_STOP_PIXEL_LSB, 0x40},
157 {TOK_SKIP, REG_HSYNC_STOP_PIXEL_MSB, 0x00},
158 {TOK_SKIP, REG_VSYNC_START_LINE_LSB, 0x04}, /* NTSC timing */
159 {TOK_SKIP, REG_VSYNC_START_LINE_MSB, 0x00},
160 {TOK_SKIP, REG_VSYNC_STOP_LINE_LSB, 0x07},
161 {TOK_SKIP, REG_VSYNC_STOP_LINE_MSB, 0x00},
162 {TOK_SKIP, REG_VBLK_START_LINE_LSB, 0x01}, /* NTSC timing */
163 {TOK_SKIP, REG_VBLK_START_LINE_MSB, 0x00},
164 {TOK_SKIP, REG_VBLK_STOP_LINE_LSB, 0x15},
165 {TOK_SKIP, REG_VBLK_STOP_LINE_MSB, 0x00},
166 {TOK_SKIP, 0x26, 0x00}, /* Reserved */
167 {TOK_SKIP, 0x27, 0x00}, /* Reserved */
168 {TOK_SKIP, REG_FAST_SWTICH_CONTROL, 0xCC},
169 {TOK_SKIP, 0x29, 0x00}, /* Reserved */
170 {TOK_SKIP, REG_FAST_SWTICH_SCART_DELAY, 0x00},
171 {TOK_SKIP, 0x2B, 0x00}, /* Reserved */
172 {TOK_SKIP, REG_SCART_DELAY, 0x00},
173 {TOK_SKIP, REG_CTI_DELAY, 0x00},
174 {TOK_SKIP, REG_CTI_CONTROL, 0x00},
175 {TOK_SKIP, 0x2F, 0x00}, /* Reserved */
176 {TOK_SKIP, 0x30, 0x00}, /* Reserved */
177 {TOK_SKIP, 0x31, 0x00}, /* Reserved */
178 {TOK_WRITE, REG_SYNC_CONTROL, 0x00}, /* HS, VS active high */
179 {TOK_WRITE, REG_OUTPUT_FORMATTER1, 0x00}, /* 10-bit BT.656 */
180 {TOK_WRITE, REG_OUTPUT_FORMATTER2, 0x11}, /* Enable clk & data */
181 {TOK_WRITE, REG_OUTPUT_FORMATTER3, 0xEE}, /* Enable AVID & FLD */
182 {TOK_WRITE, REG_OUTPUT_FORMATTER4, 0xAF}, /* Enable VS & HS */
183 {TOK_WRITE, REG_OUTPUT_FORMATTER5, 0xFF},
184 {TOK_WRITE, REG_OUTPUT_FORMATTER6, 0xFF},
185 {TOK_WRITE, REG_CLEAR_LOST_LOCK, 0x01}, /* Clear status */
186 {TOK_TERM, 0, 0},
187};
188
189/* List of image formats supported by TVP5146/47 decoder
190 * Currently we are using 8 bit mode only, but can be
191 * extended to 10/20 bit mode.
192 */
193static const struct v4l2_fmtdesc tvp514x_fmt_list[] = {
194 {
195 .index = 0,
196 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
197 .flags = 0,
198 .description = "8-bit UYVY 4:2:2 Format",
199 .pixelformat = V4L2_PIX_FMT_UYVY,
200 },
201};
202
203/*
204 * Supported standards -
205 *
206 * Currently supports two standards only, need to add support for rest of the
207 * modes, like SECAM, etc...
208 */
209static struct tvp514x_std_info tvp514x_std_list[] = {
210 /* Standard: STD_NTSC_MJ */
211 [STD_NTSC_MJ] = {
212 .width = NTSC_NUM_ACTIVE_PIXELS,
213 .height = NTSC_NUM_ACTIVE_LINES,
214 .video_std = VIDEO_STD_NTSC_MJ_BIT,
215 .standard = {
216 .index = 0,
217 .id = V4L2_STD_NTSC,
218 .name = "NTSC",
219 .frameperiod = {1001, 30000},
220 .framelines = 525
221 },
222 /* Standard: STD_PAL_BDGHIN */
223 },
224 [STD_PAL_BDGHIN] = {
225 .width = PAL_NUM_ACTIVE_PIXELS,
226 .height = PAL_NUM_ACTIVE_LINES,
227 .video_std = VIDEO_STD_PAL_BDGHIN_BIT,
228 .standard = {
229 .index = 1,
230 .id = V4L2_STD_PAL,
231 .name = "PAL",
232 .frameperiod = {1, 25},
233 .framelines = 625
234 },
235 },
236 /* Standard: need to add for additional standard */
237};
238/*
239 * Control structure for Auto Gain
240 * This is temporary data, will get replaced once
241 * v4l2_ctrl_query_fill supports it.
242 */
243static const struct v4l2_queryctrl tvp514x_autogain_ctrl = {
244 .id = V4L2_CID_AUTOGAIN,
245 .name = "Gain, Automatic",
246 .type = V4L2_CTRL_TYPE_BOOLEAN,
247 .minimum = 0,
248 .maximum = 1,
249 .step = 1,
250 .default_value = 1,
251};
252
253/*
254 * Read a value from a register in an TVP5146/47 decoder device.
255 * Returns value read if successful, or non-zero (-1) otherwise.
256 */
257static int tvp514x_read_reg(struct i2c_client *client, u8 reg)
258{
259 int err;
260 int retry = 0;
261read_again:
262
263 err = i2c_smbus_read_byte_data(client, reg);
264 if (err == -1) {
265 if (retry <= I2C_RETRY_COUNT) {
266 v4l_warn(client, "Read: retry ... %d\n", retry);
267 retry++;
268 msleep_interruptible(10);
269 goto read_again;
270 }
271 }
272
273 return err;
274}
275
276/*
277 * Write a value to a register in an TVP5146/47 decoder device.
278 * Returns zero if successful, or non-zero otherwise.
279 */
280static int tvp514x_write_reg(struct i2c_client *client, u8 reg, u8 val)
281{
282 int err;
283 int retry = 0;
284write_again:
285
286 err = i2c_smbus_write_byte_data(client, reg, val);
287 if (err) {
288 if (retry <= I2C_RETRY_COUNT) {
289 v4l_warn(client, "Write: retry ... %d\n", retry);
290 retry++;
291 msleep_interruptible(10);
292 goto write_again;
293 }
294 }
295
296 return err;
297}
298
299/*
300 * tvp514x_write_regs : Initializes a list of TVP5146/47 registers
301 * if token is TOK_TERM, then entire write operation terminates
302 * if token is TOK_DELAY, then a delay of 'val' msec is introduced
303 * if token is TOK_SKIP, then the register write is skipped
304 * if token is TOK_WRITE, then the register write is performed
305 *
306 * reglist - list of registers to be written
307 * Returns zero if successful, or non-zero otherwise.
308 */
309static int tvp514x_write_regs(struct i2c_client *client,
310 const struct tvp514x_reg reglist[])
311{
312 int err;
313 const struct tvp514x_reg *next = reglist;
314
315 for (; next->token != TOK_TERM; next++) {
316 if (next->token == TOK_DELAY) {
317 msleep(next->val);
318 continue;
319 }
320
321 if (next->token == TOK_SKIP)
322 continue;
323
324 err = tvp514x_write_reg(client, next->reg, (u8) next->val);
325 if (err) {
326 v4l_err(client, "Write failed. Err[%d]\n", err);
327 return err;
328 }
329 }
330 return 0;
331}
332
333/*
334 * tvp514x_get_current_std:
335 * Returns the current standard detected by TVP5146/47
336 */
337static enum tvp514x_std tvp514x_get_current_std(struct tvp514x_decoder
338 *decoder)
339{
340 u8 std, std_status;
341
342 std = tvp514x_read_reg(decoder->client, REG_VIDEO_STD);
343 if ((std & VIDEO_STD_MASK) == VIDEO_STD_AUTO_SWITCH_BIT) {
344 /* use the standard status register */
345 std_status = tvp514x_read_reg(decoder->client,
346 REG_VIDEO_STD_STATUS);
347 } else
348 std_status = std; /* use the standard register itself */
349
350 switch (std_status & VIDEO_STD_MASK) {
351 case VIDEO_STD_NTSC_MJ_BIT:
352 return STD_NTSC_MJ;
353
354 case VIDEO_STD_PAL_BDGHIN_BIT:
355 return STD_PAL_BDGHIN;
356
357 default:
358 return STD_INVALID;
359 }
360
361 return STD_INVALID;
362}
363
364/*
365 * TVP5146/47 register dump function
366 */
367static void tvp514x_reg_dump(struct tvp514x_decoder *decoder)
368{
369 u8 value;
370
371 dump_reg(decoder->client, REG_INPUT_SEL, value);
372 dump_reg(decoder->client, REG_AFE_GAIN_CTRL, value);
373 dump_reg(decoder->client, REG_VIDEO_STD, value);
374 dump_reg(decoder->client, REG_OPERATION_MODE, value);
375 dump_reg(decoder->client, REG_COLOR_KILLER, value);
376 dump_reg(decoder->client, REG_LUMA_CONTROL1, value);
377 dump_reg(decoder->client, REG_LUMA_CONTROL2, value);
378 dump_reg(decoder->client, REG_LUMA_CONTROL3, value);
379 dump_reg(decoder->client, REG_BRIGHTNESS, value);
380 dump_reg(decoder->client, REG_CONTRAST, value);
381 dump_reg(decoder->client, REG_SATURATION, value);
382 dump_reg(decoder->client, REG_HUE, value);
383 dump_reg(decoder->client, REG_CHROMA_CONTROL1, value);
384 dump_reg(decoder->client, REG_CHROMA_CONTROL2, value);
385 dump_reg(decoder->client, REG_COMP_PR_SATURATION, value);
386 dump_reg(decoder->client, REG_COMP_Y_CONTRAST, value);
387 dump_reg(decoder->client, REG_COMP_PB_SATURATION, value);
388 dump_reg(decoder->client, REG_COMP_Y_BRIGHTNESS, value);
389 dump_reg(decoder->client, REG_AVID_START_PIXEL_LSB, value);
390 dump_reg(decoder->client, REG_AVID_START_PIXEL_MSB, value);
391 dump_reg(decoder->client, REG_AVID_STOP_PIXEL_LSB, value);
392 dump_reg(decoder->client, REG_AVID_STOP_PIXEL_MSB, value);
393 dump_reg(decoder->client, REG_HSYNC_START_PIXEL_LSB, value);
394 dump_reg(decoder->client, REG_HSYNC_START_PIXEL_MSB, value);
395 dump_reg(decoder->client, REG_HSYNC_STOP_PIXEL_LSB, value);
396 dump_reg(decoder->client, REG_HSYNC_STOP_PIXEL_MSB, value);
397 dump_reg(decoder->client, REG_VSYNC_START_LINE_LSB, value);
398 dump_reg(decoder->client, REG_VSYNC_START_LINE_MSB, value);
399 dump_reg(decoder->client, REG_VSYNC_STOP_LINE_LSB, value);
400 dump_reg(decoder->client, REG_VSYNC_STOP_LINE_MSB, value);
401 dump_reg(decoder->client, REG_VBLK_START_LINE_LSB, value);
402 dump_reg(decoder->client, REG_VBLK_START_LINE_MSB, value);
403 dump_reg(decoder->client, REG_VBLK_STOP_LINE_LSB, value);
404 dump_reg(decoder->client, REG_VBLK_STOP_LINE_MSB, value);
405 dump_reg(decoder->client, REG_SYNC_CONTROL, value);
406 dump_reg(decoder->client, REG_OUTPUT_FORMATTER1, value);
407 dump_reg(decoder->client, REG_OUTPUT_FORMATTER2, value);
408 dump_reg(decoder->client, REG_OUTPUT_FORMATTER3, value);
409 dump_reg(decoder->client, REG_OUTPUT_FORMATTER4, value);
410 dump_reg(decoder->client, REG_OUTPUT_FORMATTER5, value);
411 dump_reg(decoder->client, REG_OUTPUT_FORMATTER6, value);
412 dump_reg(decoder->client, REG_CLEAR_LOST_LOCK, value);
413}
414
415/*
416 * Configure the TVP5146/47 with the current register settings
417 * Returns zero if successful, or non-zero otherwise.
418 */
419static int tvp514x_configure(struct tvp514x_decoder *decoder)
420{
421 int err;
422
423 /* common register initialization */
424 err =
425 tvp514x_write_regs(decoder->client, tvp514x_reg_list);
426 if (err)
427 return err;
428
429 if (debug)
430 tvp514x_reg_dump(decoder);
431
432 return 0;
433}
434
435/*
436 * Detect if an tvp514x is present, and if so which revision.
437 * A device is considered to be detected if the chip ID (LSB and MSB)
438 * registers match the expected values.
439 * Any value of the rom version register is accepted.
440 * Returns ENODEV error number if no device is detected, or zero
441 * if a device is detected.
442 */
443static int tvp514x_detect(struct tvp514x_decoder *decoder)
444{
445 u8 chip_id_msb, chip_id_lsb, rom_ver;
446
447 chip_id_msb = tvp514x_read_reg(decoder->client, REG_CHIP_ID_MSB);
448 chip_id_lsb = tvp514x_read_reg(decoder->client, REG_CHIP_ID_LSB);
449 rom_ver = tvp514x_read_reg(decoder->client, REG_ROM_VERSION);
450
451 v4l_dbg(1, debug, decoder->client,
452 "chip id detected msb:0x%x lsb:0x%x rom version:0x%x\n",
453 chip_id_msb, chip_id_lsb, rom_ver);
454 if ((chip_id_msb != TVP514X_CHIP_ID_MSB)
455 || ((chip_id_lsb != TVP5146_CHIP_ID_LSB)
456 && (chip_id_lsb != TVP5147_CHIP_ID_LSB))) {
457 /* We didn't read the values we expected, so this must not be
458 * an TVP5146/47.
459 */
460 v4l_err(decoder->client,
461 "chip id mismatch msb:0x%x lsb:0x%x\n",
462 chip_id_msb, chip_id_lsb);
463 return -ENODEV;
464 }
465
466 decoder->ver = rom_ver;
467 decoder->state = STATE_DETECTED;
468
469 v4l_info(decoder->client,
470 "%s found at 0x%x (%s)\n", decoder->client->name,
471 decoder->client->addr << 1,
472 decoder->client->adapter->name);
473 return 0;
474}
475
476/*
477 * Following are decoder interface functions implemented by
478 * TVP5146/47 decoder driver.
479 */
480
481/**
482 * ioctl_querystd - V4L2 decoder interface handler for VIDIOC_QUERYSTD ioctl
483 * @s: pointer to standard V4L2 device structure
484 * @std_id: standard V4L2 std_id ioctl enum
485 *
486 * Returns the current standard detected by TVP5146/47. If no active input is
487 * detected, returns -EINVAL
488 */
489static int ioctl_querystd(struct v4l2_int_device *s, v4l2_std_id *std_id)
490{
491 struct tvp514x_decoder *decoder = s->priv;
492 enum tvp514x_std current_std;
493 enum tvp514x_input input_sel;
494 u8 sync_lock_status, lock_mask;
495
496 if (std_id == NULL)
497 return -EINVAL;
498
499 /* get the current standard */
500 current_std = tvp514x_get_current_std(decoder);
501 if (current_std == STD_INVALID)
502 return -EINVAL;
503
504 input_sel = decoder->route.input;
505
506 switch (input_sel) {
507 case INPUT_CVBS_VI1A:
508 case INPUT_CVBS_VI1B:
509 case INPUT_CVBS_VI1C:
510 case INPUT_CVBS_VI2A:
511 case INPUT_CVBS_VI2B:
512 case INPUT_CVBS_VI2C:
513 case INPUT_CVBS_VI3A:
514 case INPUT_CVBS_VI3B:
515 case INPUT_CVBS_VI3C:
516 case INPUT_CVBS_VI4A:
517 lock_mask = STATUS_CLR_SUBCAR_LOCK_BIT |
518 STATUS_HORZ_SYNC_LOCK_BIT |
519 STATUS_VIRT_SYNC_LOCK_BIT;
520 break;
521
522 case INPUT_SVIDEO_VI2A_VI1A:
523 case INPUT_SVIDEO_VI2B_VI1B:
524 case INPUT_SVIDEO_VI2C_VI1C:
525 case INPUT_SVIDEO_VI2A_VI3A:
526 case INPUT_SVIDEO_VI2B_VI3B:
527 case INPUT_SVIDEO_VI2C_VI3C:
528 case INPUT_SVIDEO_VI4A_VI1A:
529 case INPUT_SVIDEO_VI4A_VI1B:
530 case INPUT_SVIDEO_VI4A_VI1C:
531 case INPUT_SVIDEO_VI4A_VI3A:
532 case INPUT_SVIDEO_VI4A_VI3B:
533 case INPUT_SVIDEO_VI4A_VI3C:
534 lock_mask = STATUS_HORZ_SYNC_LOCK_BIT |
535 STATUS_VIRT_SYNC_LOCK_BIT;
536 break;
537 /*Need to add other interfaces*/
538 default:
539 return -EINVAL;
540 }
541 /* check whether signal is locked */
542 sync_lock_status = tvp514x_read_reg(decoder->client, REG_STATUS1);
543 if (lock_mask != (sync_lock_status & lock_mask))
544 return -EINVAL; /* No input detected */
545
546 decoder->current_std = current_std;
547 *std_id = decoder->std_list[current_std].standard.id;
548
549 v4l_dbg(1, debug, decoder->client, "Current STD: %s",
550 decoder->std_list[current_std].standard.name);
551 return 0;
552}
553
554/**
555 * ioctl_s_std - V4L2 decoder interface handler for VIDIOC_S_STD ioctl
556 * @s: pointer to standard V4L2 device structure
557 * @std_id: standard V4L2 v4l2_std_id ioctl enum
558 *
559 * If std_id is supported, sets the requested standard. Otherwise, returns
560 * -EINVAL
561 */
562static int ioctl_s_std(struct v4l2_int_device *s, v4l2_std_id *std_id)
563{
564 struct tvp514x_decoder *decoder = s->priv;
565 int err, i;
566
567 if (std_id == NULL)
568 return -EINVAL;
569
570 for (i = 0; i < decoder->num_stds; i++)
571 if (*std_id & decoder->std_list[i].standard.id)
572 break;
573
574 if ((i == decoder->num_stds) || (i == STD_INVALID))
575 return -EINVAL;
576
577 err = tvp514x_write_reg(decoder->client, REG_VIDEO_STD,
578 decoder->std_list[i].video_std);
579 if (err)
580 return err;
581
582 decoder->current_std = i;
583 tvp514x_reg_list[REG_VIDEO_STD].val = decoder->std_list[i].video_std;
584
585 v4l_dbg(1, debug, decoder->client, "Standard set to: %s",
586 decoder->std_list[i].standard.name);
587 return 0;
588}
589
590/**
591 * ioctl_s_routing - V4L2 decoder interface handler for VIDIOC_S_INPUT ioctl
592 * @s: pointer to standard V4L2 device structure
593 * @index: number of the input
594 *
595 * If index is valid, selects the requested input. Otherwise, returns -EINVAL if
596 * the input is not supported or there is no active signal present in the
597 * selected input.
598 */
599static int ioctl_s_routing(struct v4l2_int_device *s,
600 struct v4l2_routing *route)
601{
602 struct tvp514x_decoder *decoder = s->priv;
603 int err;
604 enum tvp514x_input input_sel;
605 enum tvp514x_output output_sel;
606 enum tvp514x_std current_std = STD_INVALID;
607 u8 sync_lock_status, lock_mask;
608 int try_count = LOCK_RETRY_COUNT;
609
610 if ((!route) || (route->input >= INPUT_INVALID) ||
611 (route->output >= OUTPUT_INVALID))
612 return -EINVAL; /* Index out of bound */
613
614 input_sel = route->input;
615 output_sel = route->output;
616
617 err = tvp514x_write_reg(decoder->client, REG_INPUT_SEL, input_sel);
618 if (err)
619 return err;
620
621 output_sel |= tvp514x_read_reg(decoder->client,
622 REG_OUTPUT_FORMATTER1) & 0x7;
623 err = tvp514x_write_reg(decoder->client, REG_OUTPUT_FORMATTER1,
624 output_sel);
625 if (err)
626 return err;
627
628 tvp514x_reg_list[REG_INPUT_SEL].val = input_sel;
629 tvp514x_reg_list[REG_OUTPUT_FORMATTER1].val = output_sel;
630
631 /* Clear status */
632 msleep(LOCK_RETRY_DELAY);
633 err =
634 tvp514x_write_reg(decoder->client, REG_CLEAR_LOST_LOCK, 0x01);
635 if (err)
636 return err;
637
638 switch (input_sel) {
639 case INPUT_CVBS_VI1A:
640 case INPUT_CVBS_VI1B:
641 case INPUT_CVBS_VI1C:
642 case INPUT_CVBS_VI2A:
643 case INPUT_CVBS_VI2B:
644 case INPUT_CVBS_VI2C:
645 case INPUT_CVBS_VI3A:
646 case INPUT_CVBS_VI3B:
647 case INPUT_CVBS_VI3C:
648 case INPUT_CVBS_VI4A:
649 lock_mask = STATUS_CLR_SUBCAR_LOCK_BIT |
650 STATUS_HORZ_SYNC_LOCK_BIT |
651 STATUS_VIRT_SYNC_LOCK_BIT;
652 break;
653
654 case INPUT_SVIDEO_VI2A_VI1A:
655 case INPUT_SVIDEO_VI2B_VI1B:
656 case INPUT_SVIDEO_VI2C_VI1C:
657 case INPUT_SVIDEO_VI2A_VI3A:
658 case INPUT_SVIDEO_VI2B_VI3B:
659 case INPUT_SVIDEO_VI2C_VI3C:
660 case INPUT_SVIDEO_VI4A_VI1A:
661 case INPUT_SVIDEO_VI4A_VI1B:
662 case INPUT_SVIDEO_VI4A_VI1C:
663 case INPUT_SVIDEO_VI4A_VI3A:
664 case INPUT_SVIDEO_VI4A_VI3B:
665 case INPUT_SVIDEO_VI4A_VI3C:
666 lock_mask = STATUS_HORZ_SYNC_LOCK_BIT |
667 STATUS_VIRT_SYNC_LOCK_BIT;
668 break;
669 /*Need to add other interfaces*/
670 default:
671 return -EINVAL;
672 }
673
674 while (try_count-- > 0) {
675 /* Allow decoder to sync up with new input */
676 msleep(LOCK_RETRY_DELAY);
677
678 /* get the current standard for future reference */
679 current_std = tvp514x_get_current_std(decoder);
680 if (current_std == STD_INVALID)
681 continue;
682
683 sync_lock_status = tvp514x_read_reg(decoder->client,
684 REG_STATUS1);
685 if (lock_mask == (sync_lock_status & lock_mask))
686 break; /* Input detected */
687 }
688
689 if ((current_std == STD_INVALID) || (try_count < 0))
690 return -EINVAL;
691
692 decoder->current_std = current_std;
693 decoder->route.input = route->input;
694 decoder->route.output = route->output;
695
696 v4l_dbg(1, debug, decoder->client,
697 "Input set to: %d, std : %d",
698 input_sel, current_std);
699
700 return 0;
701}
702
703/**
704 * ioctl_queryctrl - V4L2 decoder interface handler for VIDIOC_QUERYCTRL ioctl
705 * @s: pointer to standard V4L2 device structure
706 * @qctrl: standard V4L2 v4l2_queryctrl structure
707 *
708 * If the requested control is supported, returns the control information.
709 * Otherwise, returns -EINVAL if the control is not supported.
710 */
711static int
712ioctl_queryctrl(struct v4l2_int_device *s, struct v4l2_queryctrl *qctrl)
713{
714 struct tvp514x_decoder *decoder = s->priv;
715 int err = -EINVAL;
716
717 if (qctrl == NULL)
718 return err;
719
720 switch (qctrl->id) {
721 case V4L2_CID_BRIGHTNESS:
722 /* Brightness supported is same as standard one (0-255),
723 * so make use of standard API provided.
724 */
725 err = v4l2_ctrl_query_fill_std(qctrl);
726 break;
727 case V4L2_CID_CONTRAST:
728 case V4L2_CID_SATURATION:
729 /* Saturation and Contrast supported is -
730 * Contrast: 0 - 255 (Default - 128)
731 * Saturation: 0 - 255 (Default - 128)
732 */
733 err = v4l2_ctrl_query_fill(qctrl, 0, 255, 1, 128);
734 break;
735 case V4L2_CID_HUE:
736 /* Hue Supported is -
737 * Hue - -180 - +180 (Default - 0, Step - +180)
738 */
739 err = v4l2_ctrl_query_fill(qctrl, -180, 180, 180, 0);
740 break;
741 case V4L2_CID_AUTOGAIN:
742 /* Autogain is either 0 or 1*/
743 memcpy(qctrl, &tvp514x_autogain_ctrl,
744 sizeof(struct v4l2_queryctrl));
745 err = 0;
746 break;
747 default:
748 v4l_err(decoder->client,
749 "invalid control id %d\n", qctrl->id);
750 return err;
751 }
752
753 v4l_dbg(1, debug, decoder->client,
754 "Query Control: %s : Min - %d, Max - %d, Def - %d",
755 qctrl->name,
756 qctrl->minimum,
757 qctrl->maximum,
758 qctrl->default_value);
759
760 return err;
761}
762
763/**
764 * ioctl_g_ctrl - V4L2 decoder interface handler for VIDIOC_G_CTRL ioctl
765 * @s: pointer to standard V4L2 device structure
766 * @ctrl: pointer to v4l2_control structure
767 *
768 * If the requested control is supported, returns the control's current
769 * value from the decoder. Otherwise, returns -EINVAL if the control is not
770 * supported.
771 */
772static int
773ioctl_g_ctrl(struct v4l2_int_device *s, struct v4l2_control *ctrl)
774{
775 struct tvp514x_decoder *decoder = s->priv;
776
777 if (ctrl == NULL)
778 return -EINVAL;
779
780 switch (ctrl->id) {
781 case V4L2_CID_BRIGHTNESS:
782 ctrl->value = tvp514x_reg_list[REG_BRIGHTNESS].val;
783 break;
784 case V4L2_CID_CONTRAST:
785 ctrl->value = tvp514x_reg_list[REG_CONTRAST].val;
786 break;
787 case V4L2_CID_SATURATION:
788 ctrl->value = tvp514x_reg_list[REG_SATURATION].val;
789 break;
790 case V4L2_CID_HUE:
791 ctrl->value = tvp514x_reg_list[REG_HUE].val;
792 if (ctrl->value == 0x7F)
793 ctrl->value = 180;
794 else if (ctrl->value == 0x80)
795 ctrl->value = -180;
796 else
797 ctrl->value = 0;
798
799 break;
800 case V4L2_CID_AUTOGAIN:
801 ctrl->value = tvp514x_reg_list[REG_AFE_GAIN_CTRL].val;
802 if ((ctrl->value & 0x3) == 3)
803 ctrl->value = 1;
804 else
805 ctrl->value = 0;
806
807 break;
808 default:
809 v4l_err(decoder->client,
810 "invalid control id %d\n", ctrl->id);
811 return -EINVAL;
812 }
813
814 v4l_dbg(1, debug, decoder->client,
815 "Get Control: ID - %d - %d",
816 ctrl->id, ctrl->value);
817 return 0;
818}
819
820/**
821 * ioctl_s_ctrl - V4L2 decoder interface handler for VIDIOC_S_CTRL ioctl
822 * @s: pointer to standard V4L2 device structure
823 * @ctrl: pointer to v4l2_control structure
824 *
825 * If the requested control is supported, sets the control's current
826 * value in HW. Otherwise, returns -EINVAL if the control is not supported.
827 */
828static int
829ioctl_s_ctrl(struct v4l2_int_device *s, struct v4l2_control *ctrl)
830{
831 struct tvp514x_decoder *decoder = s->priv;
832 int err = -EINVAL, value;
833
834 if (ctrl == NULL)
835 return err;
836
837 value = (__s32) ctrl->value;
838
839 switch (ctrl->id) {
840 case V4L2_CID_BRIGHTNESS:
841 if (ctrl->value < 0 || ctrl->value > 255) {
842 v4l_err(decoder->client,
843 "invalid brightness setting %d\n",
844 ctrl->value);
845 return -ERANGE;
846 }
847 err = tvp514x_write_reg(decoder->client, REG_BRIGHTNESS,
848 value);
849 if (err)
850 return err;
851 tvp514x_reg_list[REG_BRIGHTNESS].val = value;
852 break;
853 case V4L2_CID_CONTRAST:
854 if (ctrl->value < 0 || ctrl->value > 255) {
855 v4l_err(decoder->client,
856 "invalid contrast setting %d\n",
857 ctrl->value);
858 return -ERANGE;
859 }
860 err = tvp514x_write_reg(decoder->client, REG_CONTRAST,
861 value);
862 if (err)
863 return err;
864 tvp514x_reg_list[REG_CONTRAST].val = value;
865 break;
866 case V4L2_CID_SATURATION:
867 if (ctrl->value < 0 || ctrl->value > 255) {
868 v4l_err(decoder->client,
869 "invalid saturation setting %d\n",
870 ctrl->value);
871 return -ERANGE;
872 }
873 err = tvp514x_write_reg(decoder->client, REG_SATURATION,
874 value);
875 if (err)
876 return err;
877 tvp514x_reg_list[REG_SATURATION].val = value;
878 break;
879 case V4L2_CID_HUE:
880 if (value == 180)
881 value = 0x7F;
882 else if (value == -180)
883 value = 0x80;
884 else if (value == 0)
885 value = 0;
886 else {
887 v4l_err(decoder->client,
888 "invalid hue setting %d\n",
889 ctrl->value);
890 return -ERANGE;
891 }
892 err = tvp514x_write_reg(decoder->client, REG_HUE,
893 value);
894 if (err)
895 return err;
896 tvp514x_reg_list[REG_HUE].val = value;
897 break;
898 case V4L2_CID_AUTOGAIN:
899 if (value == 1)
900 value = 0x0F;
901 else if (value == 0)
902 value = 0x0C;
903 else {
904 v4l_err(decoder->client,
905 "invalid auto gain setting %d\n",
906 ctrl->value);
907 return -ERANGE;
908 }
909 err = tvp514x_write_reg(decoder->client, REG_AFE_GAIN_CTRL,
910 value);
911 if (err)
912 return err;
913 tvp514x_reg_list[REG_AFE_GAIN_CTRL].val = value;
914 break;
915 default:
916 v4l_err(decoder->client,
917 "invalid control id %d\n", ctrl->id);
918 return err;
919 }
920
921 v4l_dbg(1, debug, decoder->client,
922 "Set Control: ID - %d - %d",
923 ctrl->id, ctrl->value);
924
925 return err;
926}
927
928/**
929 * ioctl_enum_fmt_cap - Implement the CAPTURE buffer VIDIOC_ENUM_FMT ioctl
930 * @s: pointer to standard V4L2 device structure
931 * @fmt: standard V4L2 VIDIOC_ENUM_FMT ioctl structure
932 *
933 * Implement the VIDIOC_ENUM_FMT ioctl to enumerate supported formats
934 */
935static int
936ioctl_enum_fmt_cap(struct v4l2_int_device *s, struct v4l2_fmtdesc *fmt)
937{
938 struct tvp514x_decoder *decoder = s->priv;
939 int index;
940
941 if (fmt == NULL)
942 return -EINVAL;
943
944 index = fmt->index;
945 if ((index >= decoder->num_fmts) || (index < 0))
946 return -EINVAL; /* Index out of bound */
947
948 if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
949 return -EINVAL; /* only capture is supported */
950
951 memcpy(fmt, &decoder->fmt_list[index],
952 sizeof(struct v4l2_fmtdesc));
953
954 v4l_dbg(1, debug, decoder->client,
955 "Current FMT: index - %d (%s)",
956 decoder->fmt_list[index].index,
957 decoder->fmt_list[index].description);
958 return 0;
959}
960
961/**
962 * ioctl_try_fmt_cap - Implement the CAPTURE buffer VIDIOC_TRY_FMT ioctl
963 * @s: pointer to standard V4L2 device structure
964 * @f: pointer to standard V4L2 VIDIOC_TRY_FMT ioctl structure
965 *
966 * Implement the VIDIOC_TRY_FMT ioctl for the CAPTURE buffer type. This
967 * ioctl is used to negotiate the image capture size and pixel format
968 * without actually making it take effect.
969 */
970static int
971ioctl_try_fmt_cap(struct v4l2_int_device *s, struct v4l2_format *f)
972{
973 struct tvp514x_decoder *decoder = s->priv;
974 int ifmt;
975 struct v4l2_pix_format *pix;
976 enum tvp514x_std current_std;
977
978 if (f == NULL)
979 return -EINVAL;
980
981 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
982 f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
983
984 pix = &f->fmt.pix;
985
986 /* Calculate height and width based on current standard */
987 current_std = tvp514x_get_current_std(decoder);
988 if (current_std == STD_INVALID)
989 return -EINVAL;
990
991 decoder->current_std = current_std;
992 pix->width = decoder->std_list[current_std].width;
993 pix->height = decoder->std_list[current_std].height;
994
995 for (ifmt = 0; ifmt < decoder->num_fmts; ifmt++) {
996 if (pix->pixelformat ==
997 decoder->fmt_list[ifmt].pixelformat)
998 break;
999 }
1000 if (ifmt == decoder->num_fmts)
1001 ifmt = 0; /* None of the format matched, select default */
1002 pix->pixelformat = decoder->fmt_list[ifmt].pixelformat;
1003
1004 pix->field = V4L2_FIELD_INTERLACED;
1005 pix->bytesperline = pix->width * 2;
1006 pix->sizeimage = pix->bytesperline * pix->height;
1007 pix->colorspace = V4L2_COLORSPACE_SMPTE170M;
1008 pix->priv = 0;
1009
1010 v4l_dbg(1, debug, decoder->client,
1011 "Try FMT: pixelformat - %s, bytesperline - %d"
1012 "Width - %d, Height - %d",
1013 decoder->fmt_list[ifmt].description, pix->bytesperline,
1014 pix->width, pix->height);
1015 return 0;
1016}
1017
1018/**
1019 * ioctl_s_fmt_cap - V4L2 decoder interface handler for VIDIOC_S_FMT ioctl
1020 * @s: pointer to standard V4L2 device structure
1021 * @f: pointer to standard V4L2 VIDIOC_S_FMT ioctl structure
1022 *
1023 * If the requested format is supported, configures the HW to use that
1024 * format, returns error code if format not supported or HW can't be
1025 * correctly configured.
1026 */
1027static int
1028ioctl_s_fmt_cap(struct v4l2_int_device *s, struct v4l2_format *f)
1029{
1030 struct tvp514x_decoder *decoder = s->priv;
1031 struct v4l2_pix_format *pix;
1032 int rval;
1033
1034 if (f == NULL)
1035 return -EINVAL;
1036
1037 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1038 return -EINVAL; /* only capture is supported */
1039
1040 pix = &f->fmt.pix;
1041 rval = ioctl_try_fmt_cap(s, f);
1042 if (rval)
1043 return rval;
1044
1045 decoder->pix = *pix;
1046
1047 return rval;
1048}
1049
1050/**
1051 * ioctl_g_fmt_cap - V4L2 decoder interface handler for ioctl_g_fmt_cap
1052 * @s: pointer to standard V4L2 device structure
1053 * @f: pointer to standard V4L2 v4l2_format structure
1054 *
1055 * Returns the decoder's current pixel format in the v4l2_format
1056 * parameter.
1057 */
1058static int
1059ioctl_g_fmt_cap(struct v4l2_int_device *s, struct v4l2_format *f)
1060{
1061 struct tvp514x_decoder *decoder = s->priv;
1062
1063 if (f == NULL)
1064 return -EINVAL;
1065
1066 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1067 return -EINVAL; /* only capture is supported */
1068
1069 f->fmt.pix = decoder->pix;
1070
1071 v4l_dbg(1, debug, decoder->client,
1072 "Current FMT: bytesperline - %d"
1073 "Width - %d, Height - %d",
1074 decoder->pix.bytesperline,
1075 decoder->pix.width, decoder->pix.height);
1076 return 0;
1077}
1078
1079/**
1080 * ioctl_g_parm - V4L2 decoder interface handler for VIDIOC_G_PARM ioctl
1081 * @s: pointer to standard V4L2 device structure
1082 * @a: pointer to standard V4L2 VIDIOC_G_PARM ioctl structure
1083 *
1084 * Returns the decoder's video CAPTURE parameters.
1085 */
1086static int
1087ioctl_g_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a)
1088{
1089 struct tvp514x_decoder *decoder = s->priv;
1090 struct v4l2_captureparm *cparm;
1091 enum tvp514x_std current_std;
1092
1093 if (a == NULL)
1094 return -EINVAL;
1095
1096 if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1097 return -EINVAL; /* only capture is supported */
1098
1099 memset(a, 0, sizeof(*a));
1100 a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1101
1102 /* get the current standard */
1103 current_std = tvp514x_get_current_std(decoder);
1104 if (current_std == STD_INVALID)
1105 return -EINVAL;
1106
1107 decoder->current_std = current_std;
1108
1109 cparm = &a->parm.capture;
1110 cparm->capability = V4L2_CAP_TIMEPERFRAME;
1111 cparm->timeperframe =
1112 decoder->std_list[current_std].standard.frameperiod;
1113
1114 return 0;
1115}
1116
1117/**
1118 * ioctl_s_parm - V4L2 decoder interface handler for VIDIOC_S_PARM ioctl
1119 * @s: pointer to standard V4L2 device structure
1120 * @a: pointer to standard V4L2 VIDIOC_S_PARM ioctl structure
1121 *
1122 * Configures the decoder to use the input parameters, if possible. If
1123 * not possible, returns the appropriate error code.
1124 */
1125static int
1126ioctl_s_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a)
1127{
1128 struct tvp514x_decoder *decoder = s->priv;
1129 struct v4l2_fract *timeperframe;
1130 enum tvp514x_std current_std;
1131
1132 if (a == NULL)
1133 return -EINVAL;
1134
1135 if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1136 return -EINVAL; /* only capture is supported */
1137
1138 timeperframe = &a->parm.capture.timeperframe;
1139
1140 /* get the current standard */
1141 current_std = tvp514x_get_current_std(decoder);
1142 if (current_std == STD_INVALID)
1143 return -EINVAL;
1144
1145 decoder->current_std = current_std;
1146
1147 *timeperframe =
1148 decoder->std_list[current_std].standard.frameperiod;
1149
1150 return 0;
1151}
1152
1153/**
1154 * ioctl_g_ifparm - V4L2 decoder interface handler for vidioc_int_g_ifparm_num
1155 * @s: pointer to standard V4L2 device structure
1156 * @p: pointer to standard V4L2 vidioc_int_g_ifparm_num ioctl structure
1157 *
1158 * Gets slave interface parameters.
1159 * Calculates the required xclk value to support the requested
1160 * clock parameters in p. This value is returned in the p
1161 * parameter.
1162 */
1163static int ioctl_g_ifparm(struct v4l2_int_device *s, struct v4l2_ifparm *p)
1164{
1165 struct tvp514x_decoder *decoder = s->priv;
1166 int rval;
1167
1168 if (p == NULL)
1169 return -EINVAL;
1170
1171 if (NULL == decoder->pdata->ifparm)
1172 return -EINVAL;
1173
1174 rval = decoder->pdata->ifparm(p);
1175 if (rval) {
1176 v4l_err(decoder->client, "g_ifparm.Err[%d]\n", rval);
1177 return rval;
1178 }
1179
1180 p->u.bt656.clock_curr = TVP514X_XCLK_BT656;
1181
1182 return 0;
1183}
1184
1185/**
1186 * ioctl_g_priv - V4L2 decoder interface handler for vidioc_int_g_priv_num
1187 * @s: pointer to standard V4L2 device structure
1188 * @p: void pointer to hold decoder's private data address
1189 *
1190 * Returns device's (decoder's) private data area address in p parameter
1191 */
1192static int ioctl_g_priv(struct v4l2_int_device *s, void *p)
1193{
1194 struct tvp514x_decoder *decoder = s->priv;
1195
1196 if (NULL == decoder->pdata->priv_data_set)
1197 return -EINVAL;
1198
1199 return decoder->pdata->priv_data_set(p);
1200}
1201
1202/**
1203 * ioctl_s_power - V4L2 decoder interface handler for vidioc_int_s_power_num
1204 * @s: pointer to standard V4L2 device structure
1205 * @on: power state to which device is to be set
1206 *
1207 * Sets devices power state to requrested state, if possible.
1208 */
1209static int ioctl_s_power(struct v4l2_int_device *s, enum v4l2_power on)
1210{
1211 struct tvp514x_decoder *decoder = s->priv;
1212 int err = 0;
1213
1214 switch (on) {
1215 case V4L2_POWER_OFF:
1216 /* Power Down Sequence */
1217 err =
1218 tvp514x_write_reg(decoder->client, REG_OPERATION_MODE,
1219 0x01);
1220 /* Disable mux for TVP5146/47 decoder data path */
1221 if (decoder->pdata->power_set)
1222 err |= decoder->pdata->power_set(on);
1223 decoder->state = STATE_NOT_DETECTED;
1224 break;
1225
1226 case V4L2_POWER_STANDBY:
1227 if (decoder->pdata->power_set)
1228 err = decoder->pdata->power_set(on);
1229 break;
1230
1231 case V4L2_POWER_ON:
1232 /* Enable mux for TVP5146/47 decoder data path */
1233 if ((decoder->pdata->power_set) &&
1234 (decoder->state == STATE_NOT_DETECTED)) {
1235 int i;
1236 struct tvp514x_init_seq *int_seq =
1237 (struct tvp514x_init_seq *)
1238 decoder->id->driver_data;
1239
1240 err = decoder->pdata->power_set(on);
1241
1242 /* Power Up Sequence */
1243 for (i = 0; i < int_seq->no_regs; i++) {
1244 err |= tvp514x_write_reg(decoder->client,
1245 int_seq->init_reg_seq[i].reg,
1246 int_seq->init_reg_seq[i].val);
1247 }
1248 /* Detect the sensor is not already detected */
1249 err |= tvp514x_detect(decoder);
1250 if (err) {
1251 v4l_err(decoder->client,
1252 "Unable to detect decoder\n");
1253 return err;
1254 }
1255 }
1256 err |= tvp514x_configure(decoder);
1257 break;
1258
1259 default:
1260 err = -ENODEV;
1261 break;
1262 }
1263
1264 return err;
1265}
1266
1267/**
1268 * ioctl_init - V4L2 decoder interface handler for VIDIOC_INT_INIT
1269 * @s: pointer to standard V4L2 device structure
1270 *
1271 * Initialize the decoder device (calls tvp514x_configure())
1272 */
1273static int ioctl_init(struct v4l2_int_device *s)
1274{
1275 struct tvp514x_decoder *decoder = s->priv;
1276
1277 /* Set default standard to auto */
1278 tvp514x_reg_list[REG_VIDEO_STD].val =
1279 VIDEO_STD_AUTO_SWITCH_BIT;
1280
1281 return tvp514x_configure(decoder);
1282}
1283
1284/**
1285 * ioctl_dev_exit - V4L2 decoder interface handler for vidioc_int_dev_exit_num
1286 * @s: pointer to standard V4L2 device structure
1287 *
1288 * Delinitialise the dev. at slave detach. The complement of ioctl_dev_init.
1289 */
1290static int ioctl_dev_exit(struct v4l2_int_device *s)
1291{
1292 return 0;
1293}
1294
1295/**
1296 * ioctl_dev_init - V4L2 decoder interface handler for vidioc_int_dev_init_num
1297 * @s: pointer to standard V4L2 device structure
1298 *
1299 * Initialise the device when slave attaches to the master. Returns 0 if
1300 * TVP5146/47 device could be found, otherwise returns appropriate error.
1301 */
1302static int ioctl_dev_init(struct v4l2_int_device *s)
1303{
1304 struct tvp514x_decoder *decoder = s->priv;
1305 int err;
1306
1307 err = tvp514x_detect(decoder);
1308 if (err < 0) {
1309 v4l_err(decoder->client,
1310 "Unable to detect decoder\n");
1311 return err;
1312 }
1313
1314 v4l_info(decoder->client,
1315 "chip version 0x%.2x detected\n", decoder->ver);
1316
1317 return 0;
1318}
1319
1320static struct v4l2_int_ioctl_desc tvp514x_ioctl_desc[] = {
1321 {vidioc_int_dev_init_num, (v4l2_int_ioctl_func*) ioctl_dev_init},
1322 {vidioc_int_dev_exit_num, (v4l2_int_ioctl_func*) ioctl_dev_exit},
1323 {vidioc_int_s_power_num, (v4l2_int_ioctl_func*) ioctl_s_power},
1324 {vidioc_int_g_priv_num, (v4l2_int_ioctl_func*) ioctl_g_priv},
1325 {vidioc_int_g_ifparm_num, (v4l2_int_ioctl_func*) ioctl_g_ifparm},
1326 {vidioc_int_init_num, (v4l2_int_ioctl_func*) ioctl_init},
1327 {vidioc_int_enum_fmt_cap_num,
1328 (v4l2_int_ioctl_func *) ioctl_enum_fmt_cap},
1329 {vidioc_int_try_fmt_cap_num,
1330 (v4l2_int_ioctl_func *) ioctl_try_fmt_cap},
1331 {vidioc_int_g_fmt_cap_num,
1332 (v4l2_int_ioctl_func *) ioctl_g_fmt_cap},
1333 {vidioc_int_s_fmt_cap_num,
1334 (v4l2_int_ioctl_func *) ioctl_s_fmt_cap},
1335 {vidioc_int_g_parm_num, (v4l2_int_ioctl_func *) ioctl_g_parm},
1336 {vidioc_int_s_parm_num, (v4l2_int_ioctl_func *) ioctl_s_parm},
1337 {vidioc_int_queryctrl_num,
1338 (v4l2_int_ioctl_func *) ioctl_queryctrl},
1339 {vidioc_int_g_ctrl_num, (v4l2_int_ioctl_func *) ioctl_g_ctrl},
1340 {vidioc_int_s_ctrl_num, (v4l2_int_ioctl_func *) ioctl_s_ctrl},
1341 {vidioc_int_querystd_num, (v4l2_int_ioctl_func *) ioctl_querystd},
1342 {vidioc_int_s_std_num, (v4l2_int_ioctl_func *) ioctl_s_std},
1343 {vidioc_int_s_video_routing_num,
1344 (v4l2_int_ioctl_func *) ioctl_s_routing},
1345};
1346
1347static struct v4l2_int_slave tvp514x_slave = {
1348 .ioctls = tvp514x_ioctl_desc,
1349 .num_ioctls = ARRAY_SIZE(tvp514x_ioctl_desc),
1350};
1351
1352static struct tvp514x_decoder tvp514x_dev = {
1353 .state = STATE_NOT_DETECTED,
1354
1355 .fmt_list = tvp514x_fmt_list,
1356 .num_fmts = ARRAY_SIZE(tvp514x_fmt_list),
1357
1358 .pix = { /* Default to NTSC 8-bit YUV 422 */
1359 .width = NTSC_NUM_ACTIVE_PIXELS,
1360 .height = NTSC_NUM_ACTIVE_LINES,
1361 .pixelformat = V4L2_PIX_FMT_UYVY,
1362 .field = V4L2_FIELD_INTERLACED,
1363 .bytesperline = NTSC_NUM_ACTIVE_PIXELS * 2,
1364 .sizeimage =
1365 NTSC_NUM_ACTIVE_PIXELS * 2 * NTSC_NUM_ACTIVE_LINES,
1366 .colorspace = V4L2_COLORSPACE_SMPTE170M,
1367 },
1368
1369 .current_std = STD_NTSC_MJ,
1370 .std_list = tvp514x_std_list,
1371 .num_stds = ARRAY_SIZE(tvp514x_std_list),
1372
1373};
1374
1375static struct v4l2_int_device tvp514x_int_device = {
1376 .module = THIS_MODULE,
1377 .name = TVP514X_MODULE_NAME,
1378 .priv = &tvp514x_dev,
1379 .type = v4l2_int_type_slave,
1380 .u = {
1381 .slave = &tvp514x_slave,
1382 },
1383};
1384
1385/**
1386 * tvp514x_probe - decoder driver i2c probe handler
1387 * @client: i2c driver client device structure
1388 *
1389 * Register decoder as an i2c client device and V4L2
1390 * device.
1391 */
1392static int
1393tvp514x_probe(struct i2c_client *client, const struct i2c_device_id *id)
1394{
1395 struct tvp514x_decoder *decoder = &tvp514x_dev;
1396 int err;
1397
1398 /* Check if the adapter supports the needed features */
1399 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
1400 return -EIO;
1401
1402 decoder->pdata = client->dev.platform_data;
1403 if (!decoder->pdata) {
1404 v4l_err(client, "No platform data\n!!");
1405 return -ENODEV;
1406 }
1407 /*
1408 * Fetch platform specific data, and configure the
1409 * tvp514x_reg_list[] accordingly. Since this is one
1410 * time configuration, no need to preserve.
1411 */
1412 tvp514x_reg_list[REG_OUTPUT_FORMATTER2].val |=
1413 (decoder->pdata->clk_polarity << 1);
1414 tvp514x_reg_list[REG_SYNC_CONTROL].val |=
1415 ((decoder->pdata->hs_polarity << 2) |
1416 (decoder->pdata->vs_polarity << 3));
1417 /*
1418 * Save the id data, required for power up sequence
1419 */
1420 decoder->id = (struct i2c_device_id *)id;
1421 /* Attach to Master */
1422 strcpy(tvp514x_int_device.u.slave->attach_to, decoder->pdata->master);
1423 decoder->v4l2_int_device = &tvp514x_int_device;
1424 decoder->client = client;
1425 i2c_set_clientdata(client, decoder);
1426
1427 /* Register with V4L2 layer as slave device */
1428 err = v4l2_int_device_register(decoder->v4l2_int_device);
1429 if (err) {
1430 i2c_set_clientdata(client, NULL);
1431 v4l_err(client,
1432 "Unable to register to v4l2. Err[%d]\n", err);
1433
1434 } else
1435 v4l_info(client, "Registered to v4l2 master %s!!\n",
1436 decoder->pdata->master);
1437
1438 return 0;
1439}
1440
1441/**
1442 * tvp514x_remove - decoder driver i2c remove handler
1443 * @client: i2c driver client device structure
1444 *
1445 * Unregister decoder as an i2c client device and V4L2
1446 * device. Complement of tvp514x_probe().
1447 */
1448static int __exit tvp514x_remove(struct i2c_client *client)
1449{
1450 struct tvp514x_decoder *decoder = i2c_get_clientdata(client);
1451
1452 if (!client->adapter)
1453 return -ENODEV; /* our client isn't attached */
1454
1455 v4l2_int_device_unregister(decoder->v4l2_int_device);
1456 i2c_set_clientdata(client, NULL);
1457
1458 return 0;
1459}
1460/*
1461 * TVP5146 Init/Power on Sequence
1462 */
1463static const struct tvp514x_reg tvp5146_init_reg_seq[] = {
1464 {TOK_WRITE, REG_VBUS_ADDRESS_ACCESS1, 0x02},
1465 {TOK_WRITE, REG_VBUS_ADDRESS_ACCESS2, 0x00},
1466 {TOK_WRITE, REG_VBUS_ADDRESS_ACCESS3, 0x80},
1467 {TOK_WRITE, REG_VBUS_DATA_ACCESS_NO_VBUS_ADDR_INCR, 0x01},
1468 {TOK_WRITE, REG_VBUS_ADDRESS_ACCESS1, 0x60},
1469 {TOK_WRITE, REG_VBUS_ADDRESS_ACCESS2, 0x00},
1470 {TOK_WRITE, REG_VBUS_ADDRESS_ACCESS3, 0xB0},
1471 {TOK_WRITE, REG_VBUS_DATA_ACCESS_NO_VBUS_ADDR_INCR, 0x01},
1472 {TOK_WRITE, REG_VBUS_DATA_ACCESS_NO_VBUS_ADDR_INCR, 0x00},
1473 {TOK_WRITE, REG_OPERATION_MODE, 0x01},
1474 {TOK_WRITE, REG_OPERATION_MODE, 0x00},
1475};
1476static const struct tvp514x_init_seq tvp5146_init = {
1477 .no_regs = ARRAY_SIZE(tvp5146_init_reg_seq),
1478 .init_reg_seq = tvp5146_init_reg_seq,
1479};
1480/*
1481 * TVP5147 Init/Power on Sequence
1482 */
1483static const struct tvp514x_reg tvp5147_init_reg_seq[] = {
1484 {TOK_WRITE, REG_VBUS_ADDRESS_ACCESS1, 0x02},
1485 {TOK_WRITE, REG_VBUS_ADDRESS_ACCESS2, 0x00},
1486 {TOK_WRITE, REG_VBUS_ADDRESS_ACCESS3, 0x80},
1487 {TOK_WRITE, REG_VBUS_DATA_ACCESS_NO_VBUS_ADDR_INCR, 0x01},
1488 {TOK_WRITE, REG_VBUS_ADDRESS_ACCESS1, 0x60},
1489 {TOK_WRITE, REG_VBUS_ADDRESS_ACCESS2, 0x00},
1490 {TOK_WRITE, REG_VBUS_ADDRESS_ACCESS3, 0xB0},
1491 {TOK_WRITE, REG_VBUS_DATA_ACCESS_NO_VBUS_ADDR_INCR, 0x01},
1492 {TOK_WRITE, REG_VBUS_ADDRESS_ACCESS1, 0x16},
1493 {TOK_WRITE, REG_VBUS_ADDRESS_ACCESS2, 0x00},
1494 {TOK_WRITE, REG_VBUS_ADDRESS_ACCESS3, 0xA0},
1495 {TOK_WRITE, REG_VBUS_DATA_ACCESS_NO_VBUS_ADDR_INCR, 0x16},
1496 {TOK_WRITE, REG_VBUS_ADDRESS_ACCESS1, 0x60},
1497 {TOK_WRITE, REG_VBUS_ADDRESS_ACCESS2, 0x00},
1498 {TOK_WRITE, REG_VBUS_ADDRESS_ACCESS3, 0xB0},
1499 {TOK_WRITE, REG_VBUS_DATA_ACCESS_NO_VBUS_ADDR_INCR, 0x00},
1500 {TOK_WRITE, REG_OPERATION_MODE, 0x01},
1501 {TOK_WRITE, REG_OPERATION_MODE, 0x00},
1502};
1503static const struct tvp514x_init_seq tvp5147_init = {
1504 .no_regs = ARRAY_SIZE(tvp5147_init_reg_seq),
1505 .init_reg_seq = tvp5147_init_reg_seq,
1506};
1507/*
1508 * TVP5146M2/TVP5147M1 Init/Power on Sequence
1509 */
1510static const struct tvp514x_reg tvp514xm_init_reg_seq[] = {
1511 {TOK_WRITE, REG_OPERATION_MODE, 0x01},
1512 {TOK_WRITE, REG_OPERATION_MODE, 0x00},
1513};
1514static const struct tvp514x_init_seq tvp514xm_init = {
1515 .no_regs = ARRAY_SIZE(tvp514xm_init_reg_seq),
1516 .init_reg_seq = tvp514xm_init_reg_seq,
1517};
1518/*
1519 * I2C Device Table -
1520 *
1521 * name - Name of the actual device/chip.
1522 * driver_data - Driver data
1523 */
1524static const struct i2c_device_id tvp514x_id[] = {
1525 {"tvp5146", (unsigned long)&tvp5146_init},
1526 {"tvp5146m2", (unsigned long)&tvp514xm_init},
1527 {"tvp5147", (unsigned long)&tvp5147_init},
1528 {"tvp5147m1", (unsigned long)&tvp514xm_init},
1529 {},
1530};
1531
1532MODULE_DEVICE_TABLE(i2c, tvp514x_id);
1533
1534static struct i2c_driver tvp514x_i2c_driver = {
1535 .driver = {
1536 .name = TVP514X_MODULE_NAME,
1537 .owner = THIS_MODULE,
1538 },
1539 .probe = tvp514x_probe,
1540 .remove = __exit_p(tvp514x_remove),
1541 .id_table = tvp514x_id,
1542};
1543
1544/**
1545 * tvp514x_init
1546 *
1547 * Module init function
1548 */
1549static int __init tvp514x_init(void)
1550{
1551 return i2c_add_driver(&tvp514x_i2c_driver);
1552}
1553
1554/**
1555 * tvp514x_cleanup
1556 *
1557 * Module exit function
1558 */
1559static void __exit tvp514x_cleanup(void)
1560{
1561 i2c_del_driver(&tvp514x_i2c_driver);
1562}
1563
1564module_init(tvp514x_init);
1565module_exit(tvp514x_cleanup);
1566
1567MODULE_AUTHOR("Texas Instruments");
1568MODULE_DESCRIPTION("TVP514X linux decoder driver");
1569MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/tvp514x_regs.h b/drivers/media/video/tvp514x_regs.h
new file mode 100644
index 000000000000..351620aeecc2
--- /dev/null
+++ b/drivers/media/video/tvp514x_regs.h
@@ -0,0 +1,297 @@
1/*
2 * drivers/media/video/tvp514x_regs.h
3 *
4 * Copyright (C) 2008 Texas Instruments Inc
5 * Author: Vaibhav Hiremath <hvaibhav@ti.com>
6 *
7 * Contributors:
8 * Sivaraj R <sivaraj@ti.com>
9 * Brijesh R Jadav <brijesh.j@ti.com>
10 * Hardik Shah <hardik.shah@ti.com>
11 * Manjunath Hadli <mrh@ti.com>
12 * Karicheri Muralidharan <m-karicheri2@ti.com>
13 *
14 * This package is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License version 2 as
16 * published by the Free Software Foundation.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 *
27 */
28
29#ifndef _TVP514X_REGS_H
30#define _TVP514X_REGS_H
31
32/*
33 * TVP5146/47 registers
34 */
35#define REG_INPUT_SEL (0x00)
36#define REG_AFE_GAIN_CTRL (0x01)
37#define REG_VIDEO_STD (0x02)
38#define REG_OPERATION_MODE (0x03)
39#define REG_AUTOSWITCH_MASK (0x04)
40
41#define REG_COLOR_KILLER (0x05)
42#define REG_LUMA_CONTROL1 (0x06)
43#define REG_LUMA_CONTROL2 (0x07)
44#define REG_LUMA_CONTROL3 (0x08)
45
46#define REG_BRIGHTNESS (0x09)
47#define REG_CONTRAST (0x0A)
48#define REG_SATURATION (0x0B)
49#define REG_HUE (0x0C)
50
51#define REG_CHROMA_CONTROL1 (0x0D)
52#define REG_CHROMA_CONTROL2 (0x0E)
53
54/* 0x0F Reserved */
55
56#define REG_COMP_PR_SATURATION (0x10)
57#define REG_COMP_Y_CONTRAST (0x11)
58#define REG_COMP_PB_SATURATION (0x12)
59
60/* 0x13 Reserved */
61
62#define REG_COMP_Y_BRIGHTNESS (0x14)
63
64/* 0x15 Reserved */
65
66#define REG_AVID_START_PIXEL_LSB (0x16)
67#define REG_AVID_START_PIXEL_MSB (0x17)
68#define REG_AVID_STOP_PIXEL_LSB (0x18)
69#define REG_AVID_STOP_PIXEL_MSB (0x19)
70
71#define REG_HSYNC_START_PIXEL_LSB (0x1A)
72#define REG_HSYNC_START_PIXEL_MSB (0x1B)
73#define REG_HSYNC_STOP_PIXEL_LSB (0x1C)
74#define REG_HSYNC_STOP_PIXEL_MSB (0x1D)
75
76#define REG_VSYNC_START_LINE_LSB (0x1E)
77#define REG_VSYNC_START_LINE_MSB (0x1F)
78#define REG_VSYNC_STOP_LINE_LSB (0x20)
79#define REG_VSYNC_STOP_LINE_MSB (0x21)
80
81#define REG_VBLK_START_LINE_LSB (0x22)
82#define REG_VBLK_START_LINE_MSB (0x23)
83#define REG_VBLK_STOP_LINE_LSB (0x24)
84#define REG_VBLK_STOP_LINE_MSB (0x25)
85
86/* 0x26 - 0x27 Reserved */
87
88#define REG_FAST_SWTICH_CONTROL (0x28)
89
90/* 0x29 Reserved */
91
92#define REG_FAST_SWTICH_SCART_DELAY (0x2A)
93
94/* 0x2B Reserved */
95
96#define REG_SCART_DELAY (0x2C)
97#define REG_CTI_DELAY (0x2D)
98#define REG_CTI_CONTROL (0x2E)
99
100/* 0x2F - 0x31 Reserved */
101
102#define REG_SYNC_CONTROL (0x32)
103#define REG_OUTPUT_FORMATTER1 (0x33)
104#define REG_OUTPUT_FORMATTER2 (0x34)
105#define REG_OUTPUT_FORMATTER3 (0x35)
106#define REG_OUTPUT_FORMATTER4 (0x36)
107#define REG_OUTPUT_FORMATTER5 (0x37)
108#define REG_OUTPUT_FORMATTER6 (0x38)
109#define REG_CLEAR_LOST_LOCK (0x39)
110
111#define REG_STATUS1 (0x3A)
112#define REG_STATUS2 (0x3B)
113
114#define REG_AGC_GAIN_STATUS_LSB (0x3C)
115#define REG_AGC_GAIN_STATUS_MSB (0x3D)
116
117/* 0x3E Reserved */
118
119#define REG_VIDEO_STD_STATUS (0x3F)
120#define REG_GPIO_INPUT1 (0x40)
121#define REG_GPIO_INPUT2 (0x41)
122
123/* 0x42 - 0x45 Reserved */
124
125#define REG_AFE_COARSE_GAIN_CH1 (0x46)
126#define REG_AFE_COARSE_GAIN_CH2 (0x47)
127#define REG_AFE_COARSE_GAIN_CH3 (0x48)
128#define REG_AFE_COARSE_GAIN_CH4 (0x49)
129
130#define REG_AFE_FINE_GAIN_PB_B_LSB (0x4A)
131#define REG_AFE_FINE_GAIN_PB_B_MSB (0x4B)
132#define REG_AFE_FINE_GAIN_Y_G_CHROMA_LSB (0x4C)
133#define REG_AFE_FINE_GAIN_Y_G_CHROMA_MSB (0x4D)
134#define REG_AFE_FINE_GAIN_PR_R_LSB (0x4E)
135#define REG_AFE_FINE_GAIN_PR_R_MSB (0x4F)
136#define REG_AFE_FINE_GAIN_CVBS_LUMA_LSB (0x50)
137#define REG_AFE_FINE_GAIN_CVBS_LUMA_MSB (0x51)
138
139/* 0x52 - 0x68 Reserved */
140
141#define REG_FBIT_VBIT_CONTROL1 (0x69)
142
143/* 0x6A - 0x6B Reserved */
144
145#define REG_BACKEND_AGC_CONTROL (0x6C)
146
147/* 0x6D - 0x6E Reserved */
148
149#define REG_AGC_DECREMENT_SPEED_CONTROL (0x6F)
150#define REG_ROM_VERSION (0x70)
151
152/* 0x71 - 0x73 Reserved */
153
154#define REG_AGC_WHITE_PEAK_PROCESSING (0x74)
155#define REG_FBIT_VBIT_CONTROL2 (0x75)
156#define REG_VCR_TRICK_MODE_CONTROL (0x76)
157#define REG_HORIZONTAL_SHAKE_INCREMENT (0x77)
158#define REG_AGC_INCREMENT_SPEED (0x78)
159#define REG_AGC_INCREMENT_DELAY (0x79)
160
161/* 0x7A - 0x7F Reserved */
162
163#define REG_CHIP_ID_MSB (0x80)
164#define REG_CHIP_ID_LSB (0x81)
165
166/* 0x82 Reserved */
167
168#define REG_CPLL_SPEED_CONTROL (0x83)
169
170/* 0x84 - 0x96 Reserved */
171
172#define REG_STATUS_REQUEST (0x97)
173
174/* 0x98 - 0x99 Reserved */
175
176#define REG_VERTICAL_LINE_COUNT_LSB (0x9A)
177#define REG_VERTICAL_LINE_COUNT_MSB (0x9B)
178
179/* 0x9C - 0x9D Reserved */
180
181#define REG_AGC_DECREMENT_DELAY (0x9E)
182
183/* 0x9F - 0xB0 Reserved */
184
185#define REG_VDP_TTX_FILTER_1_MASK1 (0xB1)
186#define REG_VDP_TTX_FILTER_1_MASK2 (0xB2)
187#define REG_VDP_TTX_FILTER_1_MASK3 (0xB3)
188#define REG_VDP_TTX_FILTER_1_MASK4 (0xB4)
189#define REG_VDP_TTX_FILTER_1_MASK5 (0xB5)
190#define REG_VDP_TTX_FILTER_2_MASK1 (0xB6)
191#define REG_VDP_TTX_FILTER_2_MASK2 (0xB7)
192#define REG_VDP_TTX_FILTER_2_MASK3 (0xB8)
193#define REG_VDP_TTX_FILTER_2_MASK4 (0xB9)
194#define REG_VDP_TTX_FILTER_2_MASK5 (0xBA)
195#define REG_VDP_TTX_FILTER_CONTROL (0xBB)
196#define REG_VDP_FIFO_WORD_COUNT (0xBC)
197#define REG_VDP_FIFO_INTERRUPT_THRLD (0xBD)
198
199/* 0xBE Reserved */
200
201#define REG_VDP_FIFO_RESET (0xBF)
202#define REG_VDP_FIFO_OUTPUT_CONTROL (0xC0)
203#define REG_VDP_LINE_NUMBER_INTERRUPT (0xC1)
204#define REG_VDP_PIXEL_ALIGNMENT_LSB (0xC2)
205#define REG_VDP_PIXEL_ALIGNMENT_MSB (0xC3)
206
207/* 0xC4 - 0xD5 Reserved */
208
209#define REG_VDP_LINE_START (0xD6)
210#define REG_VDP_LINE_STOP (0xD7)
211#define REG_VDP_GLOBAL_LINE_MODE (0xD8)
212#define REG_VDP_FULL_FIELD_ENABLE (0xD9)
213#define REG_VDP_FULL_FIELD_MODE (0xDA)
214
215/* 0xDB - 0xDF Reserved */
216
217#define REG_VBUS_DATA_ACCESS_NO_VBUS_ADDR_INCR (0xE0)
218#define REG_VBUS_DATA_ACCESS_VBUS_ADDR_INCR (0xE1)
219#define REG_FIFO_READ_DATA (0xE2)
220
221/* 0xE3 - 0xE7 Reserved */
222
223#define REG_VBUS_ADDRESS_ACCESS1 (0xE8)
224#define REG_VBUS_ADDRESS_ACCESS2 (0xE9)
225#define REG_VBUS_ADDRESS_ACCESS3 (0xEA)
226
227/* 0xEB - 0xEF Reserved */
228
229#define REG_INTERRUPT_RAW_STATUS0 (0xF0)
230#define REG_INTERRUPT_RAW_STATUS1 (0xF1)
231#define REG_INTERRUPT_STATUS0 (0xF2)
232#define REG_INTERRUPT_STATUS1 (0xF3)
233#define REG_INTERRUPT_MASK0 (0xF4)
234#define REG_INTERRUPT_MASK1 (0xF5)
235#define REG_INTERRUPT_CLEAR0 (0xF6)
236#define REG_INTERRUPT_CLEAR1 (0xF7)
237
238/* 0xF8 - 0xFF Reserved */
239
240/*
241 * Mask and bit definitions of TVP5146/47 registers
242 */
243/* The ID values we are looking for */
244#define TVP514X_CHIP_ID_MSB (0x51)
245#define TVP5146_CHIP_ID_LSB (0x46)
246#define TVP5147_CHIP_ID_LSB (0x47)
247
248#define VIDEO_STD_MASK (0x07)
249#define VIDEO_STD_AUTO_SWITCH_BIT (0x00)
250#define VIDEO_STD_NTSC_MJ_BIT (0x01)
251#define VIDEO_STD_PAL_BDGHIN_BIT (0x02)
252#define VIDEO_STD_PAL_M_BIT (0x03)
253#define VIDEO_STD_PAL_COMBINATION_N_BIT (0x04)
254#define VIDEO_STD_NTSC_4_43_BIT (0x05)
255#define VIDEO_STD_SECAM_BIT (0x06)
256#define VIDEO_STD_PAL_60_BIT (0x07)
257
258/*
259 * Status bit
260 */
261#define STATUS_TV_VCR_BIT (1<<0)
262#define STATUS_HORZ_SYNC_LOCK_BIT (1<<1)
263#define STATUS_VIRT_SYNC_LOCK_BIT (1<<2)
264#define STATUS_CLR_SUBCAR_LOCK_BIT (1<<3)
265#define STATUS_LOST_LOCK_DETECT_BIT (1<<4)
266#define STATUS_FEILD_RATE_BIT (1<<5)
267#define STATUS_LINE_ALTERNATING_BIT (1<<6)
268#define STATUS_PEAK_WHITE_DETECT_BIT (1<<7)
269
270/* Tokens for register write */
271#define TOK_WRITE (0) /* token for write operation */
272#define TOK_TERM (1) /* terminating token */
273#define TOK_DELAY (2) /* delay token for reg list */
274#define TOK_SKIP (3) /* token to skip a register */
275/**
276 * struct tvp514x_reg - Structure for TVP5146/47 register initialization values
277 * @token - Token: TOK_WRITE, TOK_TERM etc..
278 * @reg - Register offset
279 * @val - Register Value for TOK_WRITE or delay in ms for TOK_DELAY
280 */
281struct tvp514x_reg {
282 u8 token;
283 u8 reg;
284 u32 val;
285};
286
287/**
288 * struct tvp514x_init_seq - Structure for TVP5146/47/46M2/47M1 power up
289 * Sequence.
290 * @ no_regs - Number of registers to write for power up sequence.
291 * @ init_reg_seq - Array of registers and respective value to write.
292 */
293struct tvp514x_init_seq {
294 unsigned int no_regs;
295 const struct tvp514x_reg *init_reg_seq;
296};
297#endif /* ifndef _TVP514X_REGS_H */
diff --git a/drivers/media/video/tvp5150.c b/drivers/media/video/tvp5150.c
index 28af5ce5560d..a388a9f0cb18 100644
--- a/drivers/media/video/tvp5150.c
+++ b/drivers/media/video/tvp5150.c
@@ -9,8 +9,10 @@
9#include <linux/videodev2.h> 9#include <linux/videodev2.h>
10#include <linux/delay.h> 10#include <linux/delay.h>
11#include <linux/video_decoder.h> 11#include <linux/video_decoder.h>
12#include <media/v4l2-common.h> 12#include <media/v4l2-device.h>
13#include <media/tvp5150.h> 13#include <media/tvp5150.h>
14#include <media/v4l2-i2c-drv-legacy.h>
15#include <media/v4l2-chip-ident.h>
14 16
15#include "tvp5150_reg.h" 17#include "tvp5150_reg.h"
16 18
@@ -29,21 +31,7 @@ I2C_CLIENT_INSMOD;
29 31
30static int debug; 32static int debug;
31module_param(debug, int, 0); 33module_param(debug, int, 0);
32MODULE_PARM_DESC(debug, "Debug level (0-1)"); 34MODULE_PARM_DESC(debug, "Debug level (0-2)");
33
34#define tvp5150_err(fmt, arg...) do { \
35 printk(KERN_ERR "%s %d-%04x: " fmt, c->driver->driver.name, \
36 i2c_adapter_id(c->adapter), c->addr , ## arg); } while (0)
37#define tvp5150_info(fmt, arg...) do { \
38 printk(KERN_INFO "%s %d-%04x: " fmt, c->driver->driver.name, \
39 i2c_adapter_id(c->adapter), c->addr , ## arg); } while (0)
40#define tvp5150_dbg(num, fmt, arg...) \
41 do { \
42 if (debug >= num) \
43 printk(KERN_DEBUG "%s debug %d-%04x: " fmt,\
44 c->driver->driver.name, \
45 i2c_adapter_id(c->adapter), \
46 c->addr , ## arg); } while (0)
47 35
48/* supported controls */ 36/* supported controls */
49static struct v4l2_queryctrl tvp5150_qctrl[] = { 37static struct v4l2_queryctrl tvp5150_qctrl[] = {
@@ -87,7 +75,7 @@ static struct v4l2_queryctrl tvp5150_qctrl[] = {
87}; 75};
88 76
89struct tvp5150 { 77struct tvp5150 {
90 struct i2c_client *client; 78 struct v4l2_subdev sd;
91 79
92 v4l2_std_id norm; /* Current set standard */ 80 v4l2_std_id norm; /* Current set standard */
93 struct v4l2_routing route; 81 struct v4l2_routing route;
@@ -98,49 +86,57 @@ struct tvp5150 {
98 int sat; 86 int sat;
99}; 87};
100 88
101static int tvp5150_read(struct i2c_client *c, unsigned char addr) 89static inline struct tvp5150 *to_tvp5150(struct v4l2_subdev *sd)
102{ 90{
91 return container_of(sd, struct tvp5150, sd);
92}
93
94static int tvp5150_read(struct v4l2_subdev *sd, unsigned char addr)
95{
96 struct i2c_client *c = v4l2_get_subdevdata(sd);
103 unsigned char buffer[1]; 97 unsigned char buffer[1];
104 int rc; 98 int rc;
105 99
106 buffer[0] = addr; 100 buffer[0] = addr;
107 if (1 != (rc = i2c_master_send(c, buffer, 1))) 101 if (1 != (rc = i2c_master_send(c, buffer, 1)))
108 tvp5150_dbg(0, "i2c i/o error: rc == %d (should be 1)\n", rc); 102 v4l2_dbg(0, debug, sd, "i2c i/o error: rc == %d (should be 1)\n", rc);
109 103
110 msleep(10); 104 msleep(10);
111 105
112 if (1 != (rc = i2c_master_recv(c, buffer, 1))) 106 if (1 != (rc = i2c_master_recv(c, buffer, 1)))
113 tvp5150_dbg(0, "i2c i/o error: rc == %d (should be 1)\n", rc); 107 v4l2_dbg(0, debug, sd, "i2c i/o error: rc == %d (should be 1)\n", rc);
114 108
115 tvp5150_dbg(2, "tvp5150: read 0x%02x = 0x%02x\n", addr, buffer[0]); 109 v4l2_dbg(2, debug, sd, "tvp5150: read 0x%02x = 0x%02x\n", addr, buffer[0]);
116 110
117 return (buffer[0]); 111 return (buffer[0]);
118} 112}
119 113
120static inline void tvp5150_write(struct i2c_client *c, unsigned char addr, 114static inline void tvp5150_write(struct v4l2_subdev *sd, unsigned char addr,
121 unsigned char value) 115 unsigned char value)
122{ 116{
117 struct i2c_client *c = v4l2_get_subdevdata(sd);
123 unsigned char buffer[2]; 118 unsigned char buffer[2];
124 int rc; 119 int rc;
125 120
126 buffer[0] = addr; 121 buffer[0] = addr;
127 buffer[1] = value; 122 buffer[1] = value;
128 tvp5150_dbg(2, "tvp5150: writing 0x%02x 0x%02x\n", buffer[0], buffer[1]); 123 v4l2_dbg(2, debug, sd, "tvp5150: writing 0x%02x 0x%02x\n", buffer[0], buffer[1]);
129 if (2 != (rc = i2c_master_send(c, buffer, 2))) 124 if (2 != (rc = i2c_master_send(c, buffer, 2)))
130 tvp5150_dbg(0, "i2c i/o error: rc == %d (should be 2)\n", rc); 125 v4l2_dbg(0, debug, sd, "i2c i/o error: rc == %d (should be 2)\n", rc);
131} 126}
132 127
133static void dump_reg_range(struct i2c_client *c, char *s, u8 init, const u8 end,int max_line) 128static void dump_reg_range(struct v4l2_subdev *sd, char *s, u8 init,
129 const u8 end, int max_line)
134{ 130{
135 int i=0; 131 int i = 0;
136 132
137 while (init!=(u8)(end+1)) { 133 while (init != (u8)(end + 1)) {
138 if ((i%max_line) == 0) { 134 if ((i % max_line) == 0) {
139 if (i>0) 135 if (i > 0)
140 printk("\n"); 136 printk("\n");
141 printk("tvp5150: %s reg 0x%02x = ",s,init); 137 printk("tvp5150: %s reg 0x%02x = ", s, init);
142 } 138 }
143 printk("%02x ",tvp5150_read(c, init)); 139 printk("%02x ", tvp5150_read(sd, init));
144 140
145 init++; 141 init++;
146 i++; 142 i++;
@@ -148,147 +144,148 @@ static void dump_reg_range(struct i2c_client *c, char *s, u8 init, const u8 end,
148 printk("\n"); 144 printk("\n");
149} 145}
150 146
151static void dump_reg(struct i2c_client *c) 147static int tvp5150_log_status(struct v4l2_subdev *sd)
152{ 148{
153 printk("tvp5150: Video input source selection #1 = 0x%02x\n", 149 printk("tvp5150: Video input source selection #1 = 0x%02x\n",
154 tvp5150_read(c, TVP5150_VD_IN_SRC_SEL_1)); 150 tvp5150_read(sd, TVP5150_VD_IN_SRC_SEL_1));
155 printk("tvp5150: Analog channel controls = 0x%02x\n", 151 printk("tvp5150: Analog channel controls = 0x%02x\n",
156 tvp5150_read(c, TVP5150_ANAL_CHL_CTL)); 152 tvp5150_read(sd, TVP5150_ANAL_CHL_CTL));
157 printk("tvp5150: Operation mode controls = 0x%02x\n", 153 printk("tvp5150: Operation mode controls = 0x%02x\n",
158 tvp5150_read(c, TVP5150_OP_MODE_CTL)); 154 tvp5150_read(sd, TVP5150_OP_MODE_CTL));
159 printk("tvp5150: Miscellaneous controls = 0x%02x\n", 155 printk("tvp5150: Miscellaneous controls = 0x%02x\n",
160 tvp5150_read(c, TVP5150_MISC_CTL)); 156 tvp5150_read(sd, TVP5150_MISC_CTL));
161 printk("tvp5150: Autoswitch mask= 0x%02x\n", 157 printk("tvp5150: Autoswitch mask= 0x%02x\n",
162 tvp5150_read(c, TVP5150_AUTOSW_MSK)); 158 tvp5150_read(sd, TVP5150_AUTOSW_MSK));
163 printk("tvp5150: Color killer threshold control = 0x%02x\n", 159 printk("tvp5150: Color killer threshold control = 0x%02x\n",
164 tvp5150_read(c, TVP5150_COLOR_KIL_THSH_CTL)); 160 tvp5150_read(sd, TVP5150_COLOR_KIL_THSH_CTL));
165 printk("tvp5150: Luminance processing controls #1 #2 and #3 = %02x %02x %02x\n", 161 printk("tvp5150: Luminance processing controls #1 #2 and #3 = %02x %02x %02x\n",
166 tvp5150_read(c, TVP5150_LUMA_PROC_CTL_1), 162 tvp5150_read(sd, TVP5150_LUMA_PROC_CTL_1),
167 tvp5150_read(c, TVP5150_LUMA_PROC_CTL_2), 163 tvp5150_read(sd, TVP5150_LUMA_PROC_CTL_2),
168 tvp5150_read(c, TVP5150_LUMA_PROC_CTL_3)); 164 tvp5150_read(sd, TVP5150_LUMA_PROC_CTL_3));
169 printk("tvp5150: Brightness control = 0x%02x\n", 165 printk("tvp5150: Brightness control = 0x%02x\n",
170 tvp5150_read(c, TVP5150_BRIGHT_CTL)); 166 tvp5150_read(sd, TVP5150_BRIGHT_CTL));
171 printk("tvp5150: Color saturation control = 0x%02x\n", 167 printk("tvp5150: Color saturation control = 0x%02x\n",
172 tvp5150_read(c, TVP5150_SATURATION_CTL)); 168 tvp5150_read(sd, TVP5150_SATURATION_CTL));
173 printk("tvp5150: Hue control = 0x%02x\n", 169 printk("tvp5150: Hue control = 0x%02x\n",
174 tvp5150_read(c, TVP5150_HUE_CTL)); 170 tvp5150_read(sd, TVP5150_HUE_CTL));
175 printk("tvp5150: Contrast control = 0x%02x\n", 171 printk("tvp5150: Contrast control = 0x%02x\n",
176 tvp5150_read(c, TVP5150_CONTRAST_CTL)); 172 tvp5150_read(sd, TVP5150_CONTRAST_CTL));
177 printk("tvp5150: Outputs and data rates select = 0x%02x\n", 173 printk("tvp5150: Outputs and data rates select = 0x%02x\n",
178 tvp5150_read(c, TVP5150_DATA_RATE_SEL)); 174 tvp5150_read(sd, TVP5150_DATA_RATE_SEL));
179 printk("tvp5150: Configuration shared pins = 0x%02x\n", 175 printk("tvp5150: Configuration shared pins = 0x%02x\n",
180 tvp5150_read(c, TVP5150_CONF_SHARED_PIN)); 176 tvp5150_read(sd, TVP5150_CONF_SHARED_PIN));
181 printk("tvp5150: Active video cropping start = 0x%02x%02x\n", 177 printk("tvp5150: Active video cropping start = 0x%02x%02x\n",
182 tvp5150_read(c, TVP5150_ACT_VD_CROP_ST_MSB), 178 tvp5150_read(sd, TVP5150_ACT_VD_CROP_ST_MSB),
183 tvp5150_read(c, TVP5150_ACT_VD_CROP_ST_LSB)); 179 tvp5150_read(sd, TVP5150_ACT_VD_CROP_ST_LSB));
184 printk("tvp5150: Active video cropping stop = 0x%02x%02x\n", 180 printk("tvp5150: Active video cropping stop = 0x%02x%02x\n",
185 tvp5150_read(c, TVP5150_ACT_VD_CROP_STP_MSB), 181 tvp5150_read(sd, TVP5150_ACT_VD_CROP_STP_MSB),
186 tvp5150_read(c, TVP5150_ACT_VD_CROP_STP_LSB)); 182 tvp5150_read(sd, TVP5150_ACT_VD_CROP_STP_LSB));
187 printk("tvp5150: Genlock/RTC = 0x%02x\n", 183 printk("tvp5150: Genlock/RTC = 0x%02x\n",
188 tvp5150_read(c, TVP5150_GENLOCK)); 184 tvp5150_read(sd, TVP5150_GENLOCK));
189 printk("tvp5150: Horizontal sync start = 0x%02x\n", 185 printk("tvp5150: Horizontal sync start = 0x%02x\n",
190 tvp5150_read(c, TVP5150_HORIZ_SYNC_START)); 186 tvp5150_read(sd, TVP5150_HORIZ_SYNC_START));
191 printk("tvp5150: Vertical blanking start = 0x%02x\n", 187 printk("tvp5150: Vertical blanking start = 0x%02x\n",
192 tvp5150_read(c, TVP5150_VERT_BLANKING_START)); 188 tvp5150_read(sd, TVP5150_VERT_BLANKING_START));
193 printk("tvp5150: Vertical blanking stop = 0x%02x\n", 189 printk("tvp5150: Vertical blanking stop = 0x%02x\n",
194 tvp5150_read(c, TVP5150_VERT_BLANKING_STOP)); 190 tvp5150_read(sd, TVP5150_VERT_BLANKING_STOP));
195 printk("tvp5150: Chrominance processing control #1 and #2 = %02x %02x\n", 191 printk("tvp5150: Chrominance processing control #1 and #2 = %02x %02x\n",
196 tvp5150_read(c, TVP5150_CHROMA_PROC_CTL_1), 192 tvp5150_read(sd, TVP5150_CHROMA_PROC_CTL_1),
197 tvp5150_read(c, TVP5150_CHROMA_PROC_CTL_2)); 193 tvp5150_read(sd, TVP5150_CHROMA_PROC_CTL_2));
198 printk("tvp5150: Interrupt reset register B = 0x%02x\n", 194 printk("tvp5150: Interrupt reset register B = 0x%02x\n",
199 tvp5150_read(c, TVP5150_INT_RESET_REG_B)); 195 tvp5150_read(sd, TVP5150_INT_RESET_REG_B));
200 printk("tvp5150: Interrupt enable register B = 0x%02x\n", 196 printk("tvp5150: Interrupt enable register B = 0x%02x\n",
201 tvp5150_read(c, TVP5150_INT_ENABLE_REG_B)); 197 tvp5150_read(sd, TVP5150_INT_ENABLE_REG_B));
202 printk("tvp5150: Interrupt configuration register B = 0x%02x\n", 198 printk("tvp5150: Interrupt configuration register B = 0x%02x\n",
203 tvp5150_read(c, TVP5150_INTT_CONFIG_REG_B)); 199 tvp5150_read(sd, TVP5150_INTT_CONFIG_REG_B));
204 printk("tvp5150: Video standard = 0x%02x\n", 200 printk("tvp5150: Video standard = 0x%02x\n",
205 tvp5150_read(c, TVP5150_VIDEO_STD)); 201 tvp5150_read(sd, TVP5150_VIDEO_STD));
206 printk("tvp5150: Chroma gain factor: Cb=0x%02x Cr=0x%02x\n", 202 printk("tvp5150: Chroma gain factor: Cb=0x%02x Cr=0x%02x\n",
207 tvp5150_read(c, TVP5150_CB_GAIN_FACT), 203 tvp5150_read(sd, TVP5150_CB_GAIN_FACT),
208 tvp5150_read(c, TVP5150_CR_GAIN_FACTOR)); 204 tvp5150_read(sd, TVP5150_CR_GAIN_FACTOR));
209 printk("tvp5150: Macrovision on counter = 0x%02x\n", 205 printk("tvp5150: Macrovision on counter = 0x%02x\n",
210 tvp5150_read(c, TVP5150_MACROVISION_ON_CTR)); 206 tvp5150_read(sd, TVP5150_MACROVISION_ON_CTR));
211 printk("tvp5150: Macrovision off counter = 0x%02x\n", 207 printk("tvp5150: Macrovision off counter = 0x%02x\n",
212 tvp5150_read(c, TVP5150_MACROVISION_OFF_CTR)); 208 tvp5150_read(sd, TVP5150_MACROVISION_OFF_CTR));
213 printk("tvp5150: ITU-R BT.656.%d timing(TVP5150AM1 only)\n", 209 printk("tvp5150: ITU-R BT.656.%d timing(TVP5150AM1 only)\n",
214 (tvp5150_read(c, TVP5150_REV_SELECT)&1)?3:4); 210 (tvp5150_read(sd, TVP5150_REV_SELECT) & 1) ? 3 : 4);
215 printk("tvp5150: Device ID = %02x%02x\n", 211 printk("tvp5150: Device ID = %02x%02x\n",
216 tvp5150_read(c, TVP5150_MSB_DEV_ID), 212 tvp5150_read(sd, TVP5150_MSB_DEV_ID),
217 tvp5150_read(c, TVP5150_LSB_DEV_ID)); 213 tvp5150_read(sd, TVP5150_LSB_DEV_ID));
218 printk("tvp5150: ROM version = (hex) %02x.%02x\n", 214 printk("tvp5150: ROM version = (hex) %02x.%02x\n",
219 tvp5150_read(c, TVP5150_ROM_MAJOR_VER), 215 tvp5150_read(sd, TVP5150_ROM_MAJOR_VER),
220 tvp5150_read(c, TVP5150_ROM_MINOR_VER)); 216 tvp5150_read(sd, TVP5150_ROM_MINOR_VER));
221 printk("tvp5150: Vertical line count = 0x%02x%02x\n", 217 printk("tvp5150: Vertical line count = 0x%02x%02x\n",
222 tvp5150_read(c, TVP5150_VERT_LN_COUNT_MSB), 218 tvp5150_read(sd, TVP5150_VERT_LN_COUNT_MSB),
223 tvp5150_read(c, TVP5150_VERT_LN_COUNT_LSB)); 219 tvp5150_read(sd, TVP5150_VERT_LN_COUNT_LSB));
224 printk("tvp5150: Interrupt status register B = 0x%02x\n", 220 printk("tvp5150: Interrupt status register B = 0x%02x\n",
225 tvp5150_read(c, TVP5150_INT_STATUS_REG_B)); 221 tvp5150_read(sd, TVP5150_INT_STATUS_REG_B));
226 printk("tvp5150: Interrupt active register B = 0x%02x\n", 222 printk("tvp5150: Interrupt active register B = 0x%02x\n",
227 tvp5150_read(c, TVP5150_INT_ACTIVE_REG_B)); 223 tvp5150_read(sd, TVP5150_INT_ACTIVE_REG_B));
228 printk("tvp5150: Status regs #1 to #5 = %02x %02x %02x %02x %02x\n", 224 printk("tvp5150: Status regs #1 to #5 = %02x %02x %02x %02x %02x\n",
229 tvp5150_read(c, TVP5150_STATUS_REG_1), 225 tvp5150_read(sd, TVP5150_STATUS_REG_1),
230 tvp5150_read(c, TVP5150_STATUS_REG_2), 226 tvp5150_read(sd, TVP5150_STATUS_REG_2),
231 tvp5150_read(c, TVP5150_STATUS_REG_3), 227 tvp5150_read(sd, TVP5150_STATUS_REG_3),
232 tvp5150_read(c, TVP5150_STATUS_REG_4), 228 tvp5150_read(sd, TVP5150_STATUS_REG_4),
233 tvp5150_read(c, TVP5150_STATUS_REG_5)); 229 tvp5150_read(sd, TVP5150_STATUS_REG_5));
234 230
235 dump_reg_range(c,"Teletext filter 1", TVP5150_TELETEXT_FIL1_INI, 231 dump_reg_range(sd, "Teletext filter 1", TVP5150_TELETEXT_FIL1_INI,
236 TVP5150_TELETEXT_FIL1_END,8); 232 TVP5150_TELETEXT_FIL1_END, 8);
237 dump_reg_range(c,"Teletext filter 2", TVP5150_TELETEXT_FIL2_INI, 233 dump_reg_range(sd, "Teletext filter 2", TVP5150_TELETEXT_FIL2_INI,
238 TVP5150_TELETEXT_FIL2_END,8); 234 TVP5150_TELETEXT_FIL2_END, 8);
239 235
240 printk("tvp5150: Teletext filter enable = 0x%02x\n", 236 printk("tvp5150: Teletext filter enable = 0x%02x\n",
241 tvp5150_read(c, TVP5150_TELETEXT_FIL_ENA)); 237 tvp5150_read(sd, TVP5150_TELETEXT_FIL_ENA));
242 printk("tvp5150: Interrupt status register A = 0x%02x\n", 238 printk("tvp5150: Interrupt status register A = 0x%02x\n",
243 tvp5150_read(c, TVP5150_INT_STATUS_REG_A)); 239 tvp5150_read(sd, TVP5150_INT_STATUS_REG_A));
244 printk("tvp5150: Interrupt enable register A = 0x%02x\n", 240 printk("tvp5150: Interrupt enable register A = 0x%02x\n",
245 tvp5150_read(c, TVP5150_INT_ENABLE_REG_A)); 241 tvp5150_read(sd, TVP5150_INT_ENABLE_REG_A));
246 printk("tvp5150: Interrupt configuration = 0x%02x\n", 242 printk("tvp5150: Interrupt configuration = 0x%02x\n",
247 tvp5150_read(c, TVP5150_INT_CONF)); 243 tvp5150_read(sd, TVP5150_INT_CONF));
248 printk("tvp5150: VDP status register = 0x%02x\n", 244 printk("tvp5150: VDP status register = 0x%02x\n",
249 tvp5150_read(c, TVP5150_VDP_STATUS_REG)); 245 tvp5150_read(sd, TVP5150_VDP_STATUS_REG));
250 printk("tvp5150: FIFO word count = 0x%02x\n", 246 printk("tvp5150: FIFO word count = 0x%02x\n",
251 tvp5150_read(c, TVP5150_FIFO_WORD_COUNT)); 247 tvp5150_read(sd, TVP5150_FIFO_WORD_COUNT));
252 printk("tvp5150: FIFO interrupt threshold = 0x%02x\n", 248 printk("tvp5150: FIFO interrupt threshold = 0x%02x\n",
253 tvp5150_read(c, TVP5150_FIFO_INT_THRESHOLD)); 249 tvp5150_read(sd, TVP5150_FIFO_INT_THRESHOLD));
254 printk("tvp5150: FIFO reset = 0x%02x\n", 250 printk("tvp5150: FIFO reset = 0x%02x\n",
255 tvp5150_read(c, TVP5150_FIFO_RESET)); 251 tvp5150_read(sd, TVP5150_FIFO_RESET));
256 printk("tvp5150: Line number interrupt = 0x%02x\n", 252 printk("tvp5150: Line number interrupt = 0x%02x\n",
257 tvp5150_read(c, TVP5150_LINE_NUMBER_INT)); 253 tvp5150_read(sd, TVP5150_LINE_NUMBER_INT));
258 printk("tvp5150: Pixel alignment register = 0x%02x%02x\n", 254 printk("tvp5150: Pixel alignment register = 0x%02x%02x\n",
259 tvp5150_read(c, TVP5150_PIX_ALIGN_REG_HIGH), 255 tvp5150_read(sd, TVP5150_PIX_ALIGN_REG_HIGH),
260 tvp5150_read(c, TVP5150_PIX_ALIGN_REG_LOW)); 256 tvp5150_read(sd, TVP5150_PIX_ALIGN_REG_LOW));
261 printk("tvp5150: FIFO output control = 0x%02x\n", 257 printk("tvp5150: FIFO output control = 0x%02x\n",
262 tvp5150_read(c, TVP5150_FIFO_OUT_CTRL)); 258 tvp5150_read(sd, TVP5150_FIFO_OUT_CTRL));
263 printk("tvp5150: Full field enable = 0x%02x\n", 259 printk("tvp5150: Full field enable = 0x%02x\n",
264 tvp5150_read(c, TVP5150_FULL_FIELD_ENA)); 260 tvp5150_read(sd, TVP5150_FULL_FIELD_ENA));
265 printk("tvp5150: Full field mode register = 0x%02x\n", 261 printk("tvp5150: Full field mode register = 0x%02x\n",
266 tvp5150_read(c, TVP5150_FULL_FIELD_MODE_REG)); 262 tvp5150_read(sd, TVP5150_FULL_FIELD_MODE_REG));
267 263
268 dump_reg_range(c,"CC data", TVP5150_CC_DATA_INI, 264 dump_reg_range(sd, "CC data", TVP5150_CC_DATA_INI,
269 TVP5150_CC_DATA_END,8); 265 TVP5150_CC_DATA_END, 8);
270 266
271 dump_reg_range(c,"WSS data", TVP5150_WSS_DATA_INI, 267 dump_reg_range(sd, "WSS data", TVP5150_WSS_DATA_INI,
272 TVP5150_WSS_DATA_END,8); 268 TVP5150_WSS_DATA_END, 8);
273 269
274 dump_reg_range(c,"VPS data", TVP5150_VPS_DATA_INI, 270 dump_reg_range(sd, "VPS data", TVP5150_VPS_DATA_INI,
275 TVP5150_VPS_DATA_END,8); 271 TVP5150_VPS_DATA_END, 8);
276 272
277 dump_reg_range(c,"VITC data", TVP5150_VITC_DATA_INI, 273 dump_reg_range(sd, "VITC data", TVP5150_VITC_DATA_INI,
278 TVP5150_VITC_DATA_END,10); 274 TVP5150_VITC_DATA_END, 10);
279 275
280 dump_reg_range(c,"Line mode", TVP5150_LINE_MODE_INI, 276 dump_reg_range(sd, "Line mode", TVP5150_LINE_MODE_INI,
281 TVP5150_LINE_MODE_END,8); 277 TVP5150_LINE_MODE_END, 8);
278 return 0;
282} 279}
283 280
284/**************************************************************************** 281/****************************************************************************
285 Basic functions 282 Basic functions
286 ****************************************************************************/ 283 ****************************************************************************/
287 284
288static inline void tvp5150_selmux(struct i2c_client *c) 285static inline void tvp5150_selmux(struct v4l2_subdev *sd)
289{ 286{
290 int opmode=0; 287 int opmode=0;
291 struct tvp5150 *decoder = i2c_get_clientdata(c); 288 struct tvp5150 *decoder = to_tvp5150(sd);
292 int input = 0; 289 int input = 0;
293 unsigned char val; 290 unsigned char val;
294 291
@@ -309,23 +306,23 @@ static inline void tvp5150_selmux(struct i2c_client *c)
309 break; 306 break;
310 } 307 }
311 308
312 tvp5150_dbg( 1, "Selecting video route: route input=%i, output=%i " 309 v4l2_dbg(1, debug, sd, "Selecting video route: route input=%i, output=%i "
313 "=> tvp5150 input=%i, opmode=%i\n", 310 "=> tvp5150 input=%i, opmode=%i\n",
314 decoder->route.input,decoder->route.output, 311 decoder->route.input,decoder->route.output,
315 input, opmode ); 312 input, opmode );
316 313
317 tvp5150_write(c, TVP5150_OP_MODE_CTL, opmode); 314 tvp5150_write(sd, TVP5150_OP_MODE_CTL, opmode);
318 tvp5150_write(c, TVP5150_VD_IN_SRC_SEL_1, input); 315 tvp5150_write(sd, TVP5150_VD_IN_SRC_SEL_1, input);
319 316
320 /* Svideo should enable YCrCb output and disable GPCL output 317 /* Svideo should enable YCrCb output and disable GPCL output
321 * For Composite and TV, it should be the reverse 318 * For Composite and TV, it should be the reverse
322 */ 319 */
323 val = tvp5150_read(c, TVP5150_MISC_CTL); 320 val = tvp5150_read(sd, TVP5150_MISC_CTL);
324 if (decoder->route.input == TVP5150_SVIDEO) 321 if (decoder->route.input == TVP5150_SVIDEO)
325 val = (val & ~0x40) | 0x10; 322 val = (val & ~0x40) | 0x10;
326 else 323 else
327 val = (val & ~0x10) | 0x40; 324 val = (val & ~0x10) | 0x40;
328 tvp5150_write(c, TVP5150_MISC_CTL, val); 325 tvp5150_write(sd, TVP5150_MISC_CTL, val);
329}; 326};
330 327
331struct i2c_reg_value { 328struct i2c_reg_value {
@@ -593,35 +590,35 @@ static struct i2c_vbi_ram_value vbi_ram_default[] =
593 { (u16)-1 } 590 { (u16)-1 }
594}; 591};
595 592
596static int tvp5150_write_inittab(struct i2c_client *c, 593static int tvp5150_write_inittab(struct v4l2_subdev *sd,
597 const struct i2c_reg_value *regs) 594 const struct i2c_reg_value *regs)
598{ 595{
599 while (regs->reg != 0xff) { 596 while (regs->reg != 0xff) {
600 tvp5150_write(c, regs->reg, regs->value); 597 tvp5150_write(sd, regs->reg, regs->value);
601 regs++; 598 regs++;
602 } 599 }
603 return 0; 600 return 0;
604} 601}
605 602
606static int tvp5150_vdp_init(struct i2c_client *c, 603static int tvp5150_vdp_init(struct v4l2_subdev *sd,
607 const struct i2c_vbi_ram_value *regs) 604 const struct i2c_vbi_ram_value *regs)
608{ 605{
609 unsigned int i; 606 unsigned int i;
610 607
611 /* Disable Full Field */ 608 /* Disable Full Field */
612 tvp5150_write(c, TVP5150_FULL_FIELD_ENA, 0); 609 tvp5150_write(sd, TVP5150_FULL_FIELD_ENA, 0);
613 610
614 /* Before programming, Line mode should be at 0xff */ 611 /* Before programming, Line mode should be at 0xff */
615 for (i=TVP5150_LINE_MODE_INI; i<=TVP5150_LINE_MODE_END; i++) 612 for (i = TVP5150_LINE_MODE_INI; i <= TVP5150_LINE_MODE_END; i++)
616 tvp5150_write(c, i, 0xff); 613 tvp5150_write(sd, i, 0xff);
617 614
618 /* Load Ram Table */ 615 /* Load Ram Table */
619 while (regs->reg != (u16)-1 ) { 616 while (regs->reg != (u16)-1) {
620 tvp5150_write(c, TVP5150_CONF_RAM_ADDR_HIGH,regs->reg>>8); 617 tvp5150_write(sd, TVP5150_CONF_RAM_ADDR_HIGH, regs->reg >> 8);
621 tvp5150_write(c, TVP5150_CONF_RAM_ADDR_LOW,regs->reg); 618 tvp5150_write(sd, TVP5150_CONF_RAM_ADDR_LOW, regs->reg);
622 619
623 for (i=0;i<16;i++) 620 for (i = 0; i < 16; i++)
624 tvp5150_write(c, TVP5150_VDP_CONF_RAM_DATA,regs->values[i]); 621 tvp5150_write(sd, TVP5150_VDP_CONF_RAM_DATA, regs->values[i]);
625 622
626 regs++; 623 regs++;
627 } 624 }
@@ -629,11 +626,13 @@ static int tvp5150_vdp_init(struct i2c_client *c,
629} 626}
630 627
631/* Fills VBI capabilities based on i2c_vbi_ram_value struct */ 628/* Fills VBI capabilities based on i2c_vbi_ram_value struct */
632static void tvp5150_vbi_get_cap(const struct i2c_vbi_ram_value *regs, 629static int tvp5150_g_sliced_vbi_cap(struct v4l2_subdev *sd,
633 struct v4l2_sliced_vbi_cap *cap) 630 struct v4l2_sliced_vbi_cap *cap)
634{ 631{
632 const struct i2c_vbi_ram_value *regs = vbi_ram_default;
635 int line; 633 int line;
636 634
635 v4l2_dbg(1, debug, sd, "VIDIOC_G_SLICED_VBI_CAP\n");
637 memset(cap, 0, sizeof *cap); 636 memset(cap, 0, sizeof *cap);
638 637
639 while (regs->reg != (u16)-1 ) { 638 while (regs->reg != (u16)-1 ) {
@@ -644,6 +643,7 @@ static void tvp5150_vbi_get_cap(const struct i2c_vbi_ram_value *regs,
644 643
645 regs++; 644 regs++;
646 } 645 }
646 return 0;
647} 647}
648 648
649/* Set vbi processing 649/* Set vbi processing
@@ -659,18 +659,18 @@ static void tvp5150_vbi_get_cap(const struct i2c_vbi_ram_value *regs,
659 * LSB = field1 659 * LSB = field1
660 * MSB = field2 660 * MSB = field2
661 */ 661 */
662static int tvp5150_set_vbi(struct i2c_client *c, 662static int tvp5150_set_vbi(struct v4l2_subdev *sd,
663 const struct i2c_vbi_ram_value *regs, 663 const struct i2c_vbi_ram_value *regs,
664 unsigned int type,u8 flags, int line, 664 unsigned int type,u8 flags, int line,
665 const int fields) 665 const int fields)
666{ 666{
667 struct tvp5150 *decoder = i2c_get_clientdata(c); 667 struct tvp5150 *decoder = to_tvp5150(sd);
668 v4l2_std_id std=decoder->norm; 668 v4l2_std_id std = decoder->norm;
669 u8 reg; 669 u8 reg;
670 int pos=0; 670 int pos=0;
671 671
672 if (std == V4L2_STD_ALL) { 672 if (std == V4L2_STD_ALL) {
673 tvp5150_err("VBI can't be configured without knowing number of lines\n"); 673 v4l2_err(sd, "VBI can't be configured without knowing number of lines\n");
674 return 0; 674 return 0;
675 } else if (std & V4L2_STD_625_50) { 675 } else if (std & V4L2_STD_625_50) {
676 /* Don't follow NTSC Line number convension */ 676 /* Don't follow NTSC Line number convension */
@@ -698,163 +698,186 @@ static int tvp5150_set_vbi(struct i2c_client *c,
698 reg=((line-6)<<1)+TVP5150_LINE_MODE_INI; 698 reg=((line-6)<<1)+TVP5150_LINE_MODE_INI;
699 699
700 if (fields&1) { 700 if (fields&1) {
701 tvp5150_write(c, reg, type); 701 tvp5150_write(sd, reg, type);
702 } 702 }
703 703
704 if (fields&2) { 704 if (fields&2) {
705 tvp5150_write(c, reg+1, type); 705 tvp5150_write(sd, reg+1, type);
706 } 706 }
707 707
708 return type; 708 return type;
709} 709}
710 710
711static int tvp5150_get_vbi(struct i2c_client *c, 711static int tvp5150_get_vbi(struct v4l2_subdev *sd,
712 const struct i2c_vbi_ram_value *regs, int line) 712 const struct i2c_vbi_ram_value *regs, int line)
713{ 713{
714 struct tvp5150 *decoder = i2c_get_clientdata(c); 714 struct tvp5150 *decoder = to_tvp5150(sd);
715 v4l2_std_id std=decoder->norm; 715 v4l2_std_id std = decoder->norm;
716 u8 reg; 716 u8 reg;
717 int pos, type=0; 717 int pos, type = 0;
718 718
719 if (std == V4L2_STD_ALL) { 719 if (std == V4L2_STD_ALL) {
720 tvp5150_err("VBI can't be configured without knowing number of lines\n"); 720 v4l2_err(sd, "VBI can't be configured without knowing number of lines\n");
721 return 0; 721 return 0;
722 } else if (std & V4L2_STD_625_50) { 722 } else if (std & V4L2_STD_625_50) {
723 /* Don't follow NTSC Line number convension */ 723 /* Don't follow NTSC Line number convension */
724 line += 3; 724 line += 3;
725 } 725 }
726 726
727 if (line<6||line>27) 727 if (line < 6 || line > 27)
728 return 0; 728 return 0;
729 729
730 reg=((line-6)<<1)+TVP5150_LINE_MODE_INI; 730 reg = ((line - 6) << 1) + TVP5150_LINE_MODE_INI;
731 731
732 pos=tvp5150_read(c, reg)&0x0f; 732 pos = tvp5150_read(sd, reg) & 0x0f;
733 if (pos<0x0f) 733 if (pos < 0x0f)
734 type=regs[pos].type.vbi_type; 734 type = regs[pos].type.vbi_type;
735 735
736 pos=tvp5150_read(c, reg+1)&0x0f; 736 pos = tvp5150_read(sd, reg + 1) & 0x0f;
737 if (pos<0x0f) 737 if (pos < 0x0f)
738 type|=regs[pos].type.vbi_type; 738 type |= regs[pos].type.vbi_type;
739 739
740 return type; 740 return type;
741} 741}
742static int tvp5150_set_std(struct i2c_client *c, v4l2_std_id std) 742
743static int tvp5150_set_std(struct v4l2_subdev *sd, v4l2_std_id std)
743{ 744{
744 struct tvp5150 *decoder = i2c_get_clientdata(c); 745 struct tvp5150 *decoder = to_tvp5150(sd);
745 int fmt=0; 746 int fmt = 0;
746 747
747 decoder->norm=std; 748 decoder->norm = std;
748 749
749 /* First tests should be against specific std */ 750 /* First tests should be against specific std */
750 751
751 if (std == V4L2_STD_ALL) { 752 if (std == V4L2_STD_ALL) {
752 fmt=0; /* Autodetect mode */ 753 fmt = 0; /* Autodetect mode */
753 } else if (std & V4L2_STD_NTSC_443) { 754 } else if (std & V4L2_STD_NTSC_443) {
754 fmt=0xa; 755 fmt = 0xa;
755 } else if (std & V4L2_STD_PAL_M) { 756 } else if (std & V4L2_STD_PAL_M) {
756 fmt=0x6; 757 fmt = 0x6;
757 } else if (std & (V4L2_STD_PAL_N| V4L2_STD_PAL_Nc)) { 758 } else if (std & (V4L2_STD_PAL_N | V4L2_STD_PAL_Nc)) {
758 fmt=0x8; 759 fmt = 0x8;
759 } else { 760 } else {
760 /* Then, test against generic ones */ 761 /* Then, test against generic ones */
761 if (std & V4L2_STD_NTSC) { 762 if (std & V4L2_STD_NTSC)
762 fmt=0x2; 763 fmt = 0x2;
763 } else if (std & V4L2_STD_PAL) { 764 else if (std & V4L2_STD_PAL)
764 fmt=0x4; 765 fmt = 0x4;
765 } else if (std & V4L2_STD_SECAM) { 766 else if (std & V4L2_STD_SECAM)
766 fmt=0xc; 767 fmt = 0xc;
767 }
768 } 768 }
769 769
770 tvp5150_dbg(1,"Set video std register to %d.\n",fmt); 770 v4l2_dbg(1, debug, sd, "Set video std register to %d.\n", fmt);
771 tvp5150_write(c, TVP5150_VIDEO_STD, fmt); 771 tvp5150_write(sd, TVP5150_VIDEO_STD, fmt);
772
773 return 0; 772 return 0;
774} 773}
775 774
776static inline void tvp5150_reset(struct i2c_client *c) 775static int tvp5150_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
776{
777 struct tvp5150 *decoder = to_tvp5150(sd);
778
779 if (decoder->norm == std)
780 return 0;
781
782 return tvp5150_set_std(sd, std);
783}
784
785static int tvp5150_reset(struct v4l2_subdev *sd, u32 val)
777{ 786{
787 struct tvp5150 *decoder = to_tvp5150(sd);
778 u8 msb_id, lsb_id, msb_rom, lsb_rom; 788 u8 msb_id, lsb_id, msb_rom, lsb_rom;
779 struct tvp5150 *decoder = i2c_get_clientdata(c);
780 789
781 msb_id=tvp5150_read(c,TVP5150_MSB_DEV_ID); 790 msb_id = tvp5150_read(sd, TVP5150_MSB_DEV_ID);
782 lsb_id=tvp5150_read(c,TVP5150_LSB_DEV_ID); 791 lsb_id = tvp5150_read(sd, TVP5150_LSB_DEV_ID);
783 msb_rom=tvp5150_read(c,TVP5150_ROM_MAJOR_VER); 792 msb_rom = tvp5150_read(sd, TVP5150_ROM_MAJOR_VER);
784 lsb_rom=tvp5150_read(c,TVP5150_ROM_MINOR_VER); 793 lsb_rom = tvp5150_read(sd, TVP5150_ROM_MINOR_VER);
785 794
786 if ((msb_rom==4)&&(lsb_rom==0)) { /* Is TVP5150AM1 */ 795 if (msb_rom == 4 && lsb_rom == 0) { /* Is TVP5150AM1 */
787 tvp5150_info("tvp%02x%02xam1 detected.\n",msb_id, lsb_id); 796 v4l2_info(sd, "tvp%02x%02xam1 detected.\n", msb_id, lsb_id);
788 797
789 /* ITU-T BT.656.4 timing */ 798 /* ITU-T BT.656.4 timing */
790 tvp5150_write(c,TVP5150_REV_SELECT,0); 799 tvp5150_write(sd, TVP5150_REV_SELECT, 0);
791 } else { 800 } else {
792 if ((msb_rom==3)||(lsb_rom==0x21)) { /* Is TVP5150A */ 801 if (msb_rom == 3 || lsb_rom == 0x21) { /* Is TVP5150A */
793 tvp5150_info("tvp%02x%02xa detected.\n",msb_id, lsb_id); 802 v4l2_info(sd, "tvp%02x%02xa detected.\n", msb_id, lsb_id);
794 } else { 803 } else {
795 tvp5150_info("*** unknown tvp%02x%02x chip detected.\n",msb_id,lsb_id); 804 v4l2_info(sd, "*** unknown tvp%02x%02x chip detected.\n",
796 tvp5150_info("*** Rom ver is %d.%d\n",msb_rom,lsb_rom); 805 msb_id, lsb_id);
806 v4l2_info(sd, "*** Rom ver is %d.%d\n", msb_rom, lsb_rom);
797 } 807 }
798 } 808 }
799 809
800 /* Initializes TVP5150 to its default values */ 810 /* Initializes TVP5150 to its default values */
801 tvp5150_write_inittab(c, tvp5150_init_default); 811 tvp5150_write_inittab(sd, tvp5150_init_default);
802 812
803 /* Initializes VDP registers */ 813 /* Initializes VDP registers */
804 tvp5150_vdp_init(c, vbi_ram_default); 814 tvp5150_vdp_init(sd, vbi_ram_default);
805 815
806 /* Selects decoder input */ 816 /* Selects decoder input */
807 tvp5150_selmux(c); 817 tvp5150_selmux(sd);
808 818
809 /* Initializes TVP5150 to stream enabled values */ 819 /* Initializes TVP5150 to stream enabled values */
810 tvp5150_write_inittab(c, tvp5150_init_enable); 820 tvp5150_write_inittab(sd, tvp5150_init_enable);
811 821
812 /* Initialize image preferences */ 822 /* Initialize image preferences */
813 tvp5150_write(c, TVP5150_BRIGHT_CTL, decoder->bright); 823 tvp5150_write(sd, TVP5150_BRIGHT_CTL, decoder->bright);
814 tvp5150_write(c, TVP5150_CONTRAST_CTL, decoder->contrast); 824 tvp5150_write(sd, TVP5150_CONTRAST_CTL, decoder->contrast);
815 tvp5150_write(c, TVP5150_SATURATION_CTL, decoder->contrast); 825 tvp5150_write(sd, TVP5150_SATURATION_CTL, decoder->contrast);
816 tvp5150_write(c, TVP5150_HUE_CTL, decoder->hue); 826 tvp5150_write(sd, TVP5150_HUE_CTL, decoder->hue);
817 827
818 tvp5150_set_std(c, decoder->norm); 828 tvp5150_set_std(sd, decoder->norm);
829 return 0;
819}; 830};
820 831
821static int tvp5150_get_ctrl(struct i2c_client *c, struct v4l2_control *ctrl) 832static int tvp5150_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
822{ 833{
823/* struct tvp5150 *decoder = i2c_get_clientdata(c); */ 834 v4l2_dbg(1, debug, sd, "VIDIOC_G_CTRL called\n");
824 835
825 switch (ctrl->id) { 836 switch (ctrl->id) {
826 case V4L2_CID_BRIGHTNESS: 837 case V4L2_CID_BRIGHTNESS:
827 ctrl->value = tvp5150_read(c, TVP5150_BRIGHT_CTL); 838 ctrl->value = tvp5150_read(sd, TVP5150_BRIGHT_CTL);
828 return 0; 839 return 0;
829 case V4L2_CID_CONTRAST: 840 case V4L2_CID_CONTRAST:
830 ctrl->value = tvp5150_read(c, TVP5150_CONTRAST_CTL); 841 ctrl->value = tvp5150_read(sd, TVP5150_CONTRAST_CTL);
831 return 0; 842 return 0;
832 case V4L2_CID_SATURATION: 843 case V4L2_CID_SATURATION:
833 ctrl->value = tvp5150_read(c, TVP5150_SATURATION_CTL); 844 ctrl->value = tvp5150_read(sd, TVP5150_SATURATION_CTL);
834 return 0; 845 return 0;
835 case V4L2_CID_HUE: 846 case V4L2_CID_HUE:
836 ctrl->value = tvp5150_read(c, TVP5150_HUE_CTL); 847 ctrl->value = tvp5150_read(sd, TVP5150_HUE_CTL);
837 return 0; 848 return 0;
838 } 849 }
839 return -EINVAL; 850 return -EINVAL;
840} 851}
841 852
842static int tvp5150_set_ctrl(struct i2c_client *c, struct v4l2_control *ctrl) 853static int tvp5150_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
843{ 854{
844/* struct tvp5150 *decoder = i2c_get_clientdata(c); */ 855 u8 i, n;
856 n = ARRAY_SIZE(tvp5150_qctrl);
857
858 for (i = 0; i < n; i++) {
859 if (ctrl->id != tvp5150_qctrl[i].id)
860 continue;
861 if (ctrl->value < tvp5150_qctrl[i].minimum ||
862 ctrl->value > tvp5150_qctrl[i].maximum)
863 return -ERANGE;
864 v4l2_dbg(1, debug, sd, "VIDIOC_S_CTRL: id=%d, value=%d\n",
865 ctrl->id, ctrl->value);
866 break;
867 }
845 868
846 switch (ctrl->id) { 869 switch (ctrl->id) {
847 case V4L2_CID_BRIGHTNESS: 870 case V4L2_CID_BRIGHTNESS:
848 tvp5150_write(c, TVP5150_BRIGHT_CTL, ctrl->value); 871 tvp5150_write(sd, TVP5150_BRIGHT_CTL, ctrl->value);
849 return 0; 872 return 0;
850 case V4L2_CID_CONTRAST: 873 case V4L2_CID_CONTRAST:
851 tvp5150_write(c, TVP5150_CONTRAST_CTL, ctrl->value); 874 tvp5150_write(sd, TVP5150_CONTRAST_CTL, ctrl->value);
852 return 0; 875 return 0;
853 case V4L2_CID_SATURATION: 876 case V4L2_CID_SATURATION:
854 tvp5150_write(c, TVP5150_SATURATION_CTL, ctrl->value); 877 tvp5150_write(sd, TVP5150_SATURATION_CTL, ctrl->value);
855 return 0; 878 return 0;
856 case V4L2_CID_HUE: 879 case V4L2_CID_HUE:
857 tvp5150_write(c, TVP5150_HUE_CTL, ctrl->value); 880 tvp5150_write(sd, TVP5150_HUE_CTL, ctrl->value);
858 return 0; 881 return 0;
859 } 882 }
860 return -EINVAL; 883 return -EINVAL;
@@ -863,227 +886,210 @@ static int tvp5150_set_ctrl(struct i2c_client *c, struct v4l2_control *ctrl)
863/**************************************************************************** 886/****************************************************************************
864 I2C Command 887 I2C Command
865 ****************************************************************************/ 888 ****************************************************************************/
866static int tvp5150_command(struct i2c_client *c,
867 unsigned int cmd, void *arg)
868{
869 struct tvp5150 *decoder = i2c_get_clientdata(c);
870 889
871 switch (cmd) { 890static int tvp5150_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
891{
892 struct tvp5150 *decoder = to_tvp5150(sd);
872 893
873 case 0: 894 decoder->route = *route;
874 case VIDIOC_INT_RESET: 895 tvp5150_selmux(sd);
875 tvp5150_reset(c); 896 return 0;
876 break; 897}
877 case VIDIOC_INT_G_VIDEO_ROUTING:
878 {
879 struct v4l2_routing *route = arg;
880 898
881 *route = decoder->route; 899static int tvp5150_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
882 break; 900{
901 struct v4l2_sliced_vbi_format *svbi;
902 int i;
903
904 /* raw vbi */
905 if (fmt->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
906 /* this is for capturing 36 raw vbi lines
907 if there's a way to cut off the beginning 2 vbi lines
908 with the tvp5150 then the vbi line count could be lowered
909 to 17 lines/field again, although I couldn't find a register
910 which could do that cropping */
911 if (fmt->fmt.vbi.sample_format == V4L2_PIX_FMT_GREY)
912 tvp5150_write(sd, TVP5150_LUMA_PROC_CTL_1, 0x70);
913 if (fmt->fmt.vbi.count[0] == 18 && fmt->fmt.vbi.count[1] == 18) {
914 tvp5150_write(sd, TVP5150_VERT_BLANKING_START, 0x00);
915 tvp5150_write(sd, TVP5150_VERT_BLANKING_STOP, 0x01);
916 }
917 return 0;
883 } 918 }
884 case VIDIOC_INT_S_VIDEO_ROUTING: 919 if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE)
885 { 920 return -EINVAL;
886 struct v4l2_routing *route = arg; 921 svbi = &fmt->fmt.sliced;
922 if (svbi->service_set != 0) {
923 for (i = 0; i <= 23; i++) {
924 svbi->service_lines[1][i] = 0;
925 svbi->service_lines[0][i] =
926 tvp5150_set_vbi(sd, vbi_ram_default,
927 svbi->service_lines[0][i], 0xf0, i, 3);
928 }
929 /* Enables FIFO */
930 tvp5150_write(sd, TVP5150_FIFO_OUT_CTRL, 1);
931 } else {
932 /* Disables FIFO*/
933 tvp5150_write(sd, TVP5150_FIFO_OUT_CTRL, 0);
887 934
888 decoder->route = *route; 935 /* Disable Full Field */
889 tvp5150_selmux(c); 936 tvp5150_write(sd, TVP5150_FULL_FIELD_ENA, 0);
890 break; 937
938 /* Disable Line modes */
939 for (i = TVP5150_LINE_MODE_INI; i <= TVP5150_LINE_MODE_END; i++)
940 tvp5150_write(sd, i, 0xff);
891 } 941 }
892 case VIDIOC_S_STD: 942 return 0;
893 if (decoder->norm == *(v4l2_std_id *)arg) 943}
894 break;
895 return tvp5150_set_std(c, *(v4l2_std_id *)arg);
896 case VIDIOC_G_STD:
897 *(v4l2_std_id *)arg = decoder->norm;
898 break;
899 944
900 case VIDIOC_G_SLICED_VBI_CAP: 945static int tvp5150_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
901 { 946{
902 struct v4l2_sliced_vbi_cap *cap = arg; 947 struct v4l2_sliced_vbi_format *svbi;
903 tvp5150_dbg(1, "VIDIOC_G_SLICED_VBI_CAP\n"); 948 int i, mask = 0;
904 949
905 tvp5150_vbi_get_cap(vbi_ram_default, cap); 950 if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE)
906 break; 951 return -EINVAL;
952 svbi = &fmt->fmt.sliced;
953 memset(svbi, 0, sizeof(*svbi));
954
955 for (i = 0; i <= 23; i++) {
956 svbi->service_lines[0][i] =
957 tvp5150_get_vbi(sd, vbi_ram_default, i);
958 mask |= svbi->service_lines[0][i];
907 } 959 }
908 case VIDIOC_S_FMT: 960 svbi->service_set = mask;
909 { 961 return 0;
910 struct v4l2_format *fmt; 962}
911 struct v4l2_sliced_vbi_format *svbi;
912 int i;
913
914 fmt = arg;
915 if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE)
916 return -EINVAL;
917 svbi = &fmt->fmt.sliced;
918 if (svbi->service_set != 0) {
919 for (i = 0; i <= 23; i++) {
920 svbi->service_lines[1][i] = 0;
921
922 svbi->service_lines[0][i]=tvp5150_set_vbi(c,
923 vbi_ram_default,
924 svbi->service_lines[0][i],0xf0,i,3);
925 }
926 /* Enables FIFO */
927 tvp5150_write(c, TVP5150_FIFO_OUT_CTRL,1);
928 } else {
929 /* Disables FIFO*/
930 tvp5150_write(c, TVP5150_FIFO_OUT_CTRL,0);
931 963
932 /* Disable Full Field */
933 tvp5150_write(c, TVP5150_FULL_FIELD_ENA, 0);
934 964
935 /* Disable Line modes */ 965static int tvp5150_g_chip_ident(struct v4l2_subdev *sd,
936 for (i=TVP5150_LINE_MODE_INI; i<=TVP5150_LINE_MODE_END; i++) 966 struct v4l2_chip_ident *chip)
937 tvp5150_write(c, i, 0xff); 967{
938 } 968 int rev;
939 break; 969 struct i2c_client *client = v4l2_get_subdevdata(sd);
940 }
941 case VIDIOC_G_FMT:
942 {
943 struct v4l2_format *fmt;
944 struct v4l2_sliced_vbi_format *svbi;
945 970
946 int i, mask=0; 971 rev = tvp5150_read(sd, TVP5150_ROM_MAJOR_VER) << 8 |
972 tvp5150_read(sd, TVP5150_ROM_MINOR_VER);
947 973
948 fmt = arg; 974 return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_TVP5150,
949 if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) 975 rev);
950 return -EINVAL; 976}
951 svbi = &fmt->fmt.sliced;
952 memset(svbi, 0, sizeof(*svbi));
953 977
954 for (i = 0; i <= 23; i++) {
955 svbi->service_lines[0][i]=tvp5150_get_vbi(c,
956 vbi_ram_default,i);
957 mask|=svbi->service_lines[0][i];
958 }
959 svbi->service_set=mask;
960 break;
961 }
962 978
963#ifdef CONFIG_VIDEO_ADV_DEBUG 979#ifdef CONFIG_VIDEO_ADV_DEBUG
964 case VIDIOC_DBG_G_REGISTER: 980static int tvp5150_g_register(struct v4l2_subdev *sd, struct v4l2_register *reg)
965 case VIDIOC_DBG_S_REGISTER: 981{
966 { 982 struct i2c_client *client = v4l2_get_subdevdata(sd);
967 struct v4l2_register *reg = arg;
968
969 if (!v4l2_chip_match_i2c_client(c, reg->match_type, reg->match_chip))
970 return -EINVAL;
971 if (!capable(CAP_SYS_ADMIN))
972 return -EPERM;
973 if (cmd == VIDIOC_DBG_G_REGISTER)
974 reg->val = tvp5150_read(c, reg->reg & 0xff);
975 else
976 tvp5150_write(c, reg->reg & 0xff, reg->val & 0xff);
977 break;
978 }
979#endif
980 983
981 case VIDIOC_LOG_STATUS: 984 if (!v4l2_chip_match_i2c_client(client,
982 dump_reg(c); 985 reg->match_type, reg->match_chip))
983 break; 986 return -EINVAL;
987 if (!capable(CAP_SYS_ADMIN))
988 return -EPERM;
989 reg->val = tvp5150_read(sd, reg->reg & 0xff);
990 return 0;
991}
984 992
985 case VIDIOC_G_TUNER: 993static int tvp5150_s_register(struct v4l2_subdev *sd, struct v4l2_register *reg)
986 { 994{
987 struct v4l2_tuner *vt = arg; 995 struct i2c_client *client = v4l2_get_subdevdata(sd);
988 int status = tvp5150_read(c, 0x88);
989 996
990 vt->signal = ((status & 0x04) && (status & 0x02)) ? 0xffff : 0x0; 997 if (!v4l2_chip_match_i2c_client(client,
991 break; 998 reg->match_type, reg->match_chip))
992 } 999 return -EINVAL;
993 case VIDIOC_QUERYCTRL: 1000 if (!capable(CAP_SYS_ADMIN))
994 { 1001 return -EPERM;
995 struct v4l2_queryctrl *qc = arg; 1002 tvp5150_write(sd, reg->reg & 0xff, reg->val & 0xff);
996 int i; 1003 return 0;
1004}
1005#endif
997 1006
998 tvp5150_dbg(1, "VIDIOC_QUERYCTRL called\n"); 1007static int tvp5150_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
1008{
1009 int status = tvp5150_read(sd, 0x88);
999 1010
1000 for (i = 0; i < ARRAY_SIZE(tvp5150_qctrl); i++) 1011 vt->signal = ((status & 0x04) && (status & 0x02)) ? 0xffff : 0x0;
1001 if (qc->id && qc->id == tvp5150_qctrl[i].id) { 1012 return 0;
1002 memcpy(qc, &(tvp5150_qctrl[i]), 1013}
1003 sizeof(*qc));
1004 return 0;
1005 }
1006 1014
1007 return -EINVAL; 1015static int tvp5150_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
1008 } 1016{
1009 case VIDIOC_G_CTRL: 1017 int i;
1010 {
1011 struct v4l2_control *ctrl = arg;
1012 tvp5150_dbg(1, "VIDIOC_G_CTRL called\n");
1013 1018
1014 return tvp5150_get_ctrl(c, ctrl); 1019 v4l2_dbg(1, debug, sd, "VIDIOC_QUERYCTRL called\n");
1015 } 1020
1016 case VIDIOC_S_CTRL: 1021 for (i = 0; i < ARRAY_SIZE(tvp5150_qctrl); i++)
1017 { 1022 if (qc->id && qc->id == tvp5150_qctrl[i].id) {
1018 struct v4l2_control *ctrl = arg; 1023 memcpy(qc, &(tvp5150_qctrl[i]),
1019 u8 i, n; 1024 sizeof(*qc));
1020 n = ARRAY_SIZE(tvp5150_qctrl); 1025 return 0;
1021 for (i = 0; i < n; i++)
1022 if (ctrl->id == tvp5150_qctrl[i].id) {
1023 if (ctrl->value <
1024 tvp5150_qctrl[i].minimum
1025 || ctrl->value >
1026 tvp5150_qctrl[i].maximum)
1027 return -ERANGE;
1028 tvp5150_dbg(1,
1029 "VIDIOC_S_CTRL: id=%d, value=%d\n",
1030 ctrl->id, ctrl->value);
1031 return tvp5150_set_ctrl(c, ctrl);
1032 }
1033 return -EINVAL;
1034 } 1026 }
1035 1027
1036 default: 1028 return -EINVAL;
1037 return -EINVAL; 1029}
1038 }
1039 1030
1040 return 0; 1031static int tvp5150_command(struct i2c_client *client, unsigned cmd, void *arg)
1032{
1033 return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
1041} 1034}
1042 1035
1036/* ----------------------------------------------------------------------- */
1037
1038static const struct v4l2_subdev_core_ops tvp5150_core_ops = {
1039 .log_status = tvp5150_log_status,
1040 .g_ctrl = tvp5150_g_ctrl,
1041 .s_ctrl = tvp5150_s_ctrl,
1042 .queryctrl = tvp5150_queryctrl,
1043 .reset = tvp5150_reset,
1044 .g_chip_ident = tvp5150_g_chip_ident,
1045#ifdef CONFIG_VIDEO_ADV_DEBUG
1046 .g_register = tvp5150_g_register,
1047 .s_register = tvp5150_s_register,
1048#endif
1049};
1050
1051static const struct v4l2_subdev_tuner_ops tvp5150_tuner_ops = {
1052 .s_std = tvp5150_s_std,
1053 .g_tuner = tvp5150_g_tuner,
1054};
1055
1056static const struct v4l2_subdev_video_ops tvp5150_video_ops = {
1057 .s_routing = tvp5150_s_routing,
1058 .g_fmt = tvp5150_g_fmt,
1059 .s_fmt = tvp5150_s_fmt,
1060 .g_sliced_vbi_cap = tvp5150_g_sliced_vbi_cap,
1061};
1062
1063static const struct v4l2_subdev_ops tvp5150_ops = {
1064 .core = &tvp5150_core_ops,
1065 .tuner = &tvp5150_tuner_ops,
1066 .video = &tvp5150_video_ops,
1067};
1068
1069
1043/**************************************************************************** 1070/****************************************************************************
1044 I2C Client & Driver 1071 I2C Client & Driver
1045 ****************************************************************************/ 1072 ****************************************************************************/
1046static struct i2c_driver driver;
1047
1048static struct i2c_client client_template = {
1049 .name = "(unset)",
1050 .driver = &driver,
1051};
1052 1073
1053static int tvp5150_detect_client(struct i2c_adapter *adapter, 1074static int tvp5150_probe(struct i2c_client *c,
1054 int address, int kind) 1075 const struct i2c_device_id *id)
1055{ 1076{
1056 struct i2c_client *c;
1057 struct tvp5150 *core; 1077 struct tvp5150 *core;
1058 int rv; 1078 struct v4l2_subdev *sd;
1059
1060 if (debug)
1061 printk( KERN_INFO
1062 "tvp5150.c: detecting tvp5150 client on address 0x%x\n",
1063 address << 1);
1064
1065 client_template.adapter = adapter;
1066 client_template.addr = address;
1067 1079
1068 /* Check if the adapter supports the needed features */ 1080 /* Check if the adapter supports the needed features */
1069 if (!i2c_check_functionality 1081 if (!i2c_check_functionality(c->adapter,
1070 (adapter,
1071 I2C_FUNC_SMBUS_READ_BYTE | I2C_FUNC_SMBUS_WRITE_BYTE_DATA)) 1082 I2C_FUNC_SMBUS_READ_BYTE | I2C_FUNC_SMBUS_WRITE_BYTE_DATA))
1072 return 0; 1083 return -EIO;
1073
1074 c = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
1075 if (!c)
1076 return -ENOMEM;
1077 memcpy(c, &client_template, sizeof(struct i2c_client));
1078 1084
1079 core = kzalloc(sizeof(struct tvp5150), GFP_KERNEL); 1085 core = kzalloc(sizeof(struct tvp5150), GFP_KERNEL);
1080 if (!core) { 1086 if (!core) {
1081 kfree(c);
1082 return -ENOMEM; 1087 return -ENOMEM;
1083 } 1088 }
1084 i2c_set_clientdata(c, core); 1089 sd = &core->sd;
1085 1090 v4l2_i2c_subdev_init(sd, c, &tvp5150_ops);
1086 rv = i2c_attach_client(c); 1091 v4l_info(c, "chip found @ 0x%02x (%s)\n",
1092 c->addr << 1, c->adapter->name);
1087 1093
1088 core->norm = V4L2_STD_ALL; /* Default is autodetect */ 1094 core->norm = V4L2_STD_ALL; /* Default is autodetect */
1089 core->route.input = TVP5150_COMPOSITE1; 1095 core->route.input = TVP5150_COMPOSITE1;
@@ -1093,69 +1099,38 @@ static int tvp5150_detect_client(struct i2c_adapter *adapter,
1093 core->hue = 0; 1099 core->hue = 0;
1094 core->sat = 128; 1100 core->sat = 128;
1095 1101
1096 if (rv) {
1097 kfree(c);
1098 kfree(core);
1099 return rv;
1100 }
1101
1102 if (debug > 1) 1102 if (debug > 1)
1103 dump_reg(c); 1103 tvp5150_log_status(sd);
1104 return 0; 1104 return 0;
1105} 1105}
1106 1106
1107static int tvp5150_attach_adapter(struct i2c_adapter *adapter) 1107static int tvp5150_remove(struct i2c_client *c)
1108{ 1108{
1109 if (debug) 1109 struct v4l2_subdev *sd = i2c_get_clientdata(c);
1110 printk( KERN_INFO
1111 "tvp5150.c: starting probe for adapter %s (0x%x)\n",
1112 adapter->name, adapter->id);
1113 return i2c_probe(adapter, &addr_data, &tvp5150_detect_client);
1114}
1115
1116static int tvp5150_detach_client(struct i2c_client *c)
1117{
1118 struct tvp5150 *decoder = i2c_get_clientdata(c);
1119 int err;
1120 1110
1121 tvp5150_dbg(1, 1111 v4l2_dbg(1, debug, sd,
1122 "tvp5150.c: removing tvp5150 adapter on address 0x%x\n", 1112 "tvp5150.c: removing tvp5150 adapter on address 0x%x\n",
1123 c->addr << 1); 1113 c->addr << 1);
1124 1114
1125 err = i2c_detach_client(c); 1115 v4l2_device_unregister_subdev(sd);
1126 if (err) { 1116 kfree(to_tvp5150(sd));
1127 return err;
1128 }
1129
1130 kfree(decoder);
1131 kfree(c);
1132
1133 return 0; 1117 return 0;
1134} 1118}
1135 1119
1136/* ----------------------------------------------------------------------- */ 1120/* ----------------------------------------------------------------------- */
1137 1121
1138static struct i2c_driver driver = { 1122static const struct i2c_device_id tvp5150_id[] = {
1139 .driver = { 1123 { "tvp5150", 0 },
1140 .name = "tvp5150", 1124 { }
1141 }, 1125};
1142 .id = I2C_DRIVERID_TVP5150, 1126MODULE_DEVICE_TABLE(i2c, tvp5150_id);
1143
1144 .attach_adapter = tvp5150_attach_adapter,
1145 .detach_client = tvp5150_detach_client,
1146 1127
1128static struct v4l2_i2c_driver_data v4l2_i2c_data = {
1129 .name = "tvp5150",
1130 .driverid = I2C_DRIVERID_TVP5150,
1147 .command = tvp5150_command, 1131 .command = tvp5150_command,
1132 .probe = tvp5150_probe,
1133 .remove = tvp5150_remove,
1134 .legacy_class = I2C_CLASS_TV_ANALOG | I2C_CLASS_TV_DIGITAL,
1135 .id_table = tvp5150_id,
1148}; 1136};
1149
1150static int __init tvp5150_init(void)
1151{
1152 return i2c_add_driver(&driver);
1153}
1154
1155static void __exit tvp5150_exit(void)
1156{
1157 i2c_del_driver(&driver);
1158}
1159
1160module_init(tvp5150_init);
1161module_exit(tvp5150_exit);
diff --git a/drivers/media/video/tw9910.c b/drivers/media/video/tw9910.c
new file mode 100644
index 000000000000..d5cdc4be1a35
--- /dev/null
+++ b/drivers/media/video/tw9910.c
@@ -0,0 +1,951 @@
1/*
2 * tw9910 Video Driver
3 *
4 * Copyright (C) 2008 Renesas Solutions Corp.
5 * Kuninori Morimoto <morimoto.kuninori@renesas.com>
6 *
7 * Based on ov772x driver,
8 *
9 * Copyright (C) 2008 Kuninori Morimoto <morimoto.kuninori@renesas.com>
10 * Copyright 2006-7 Jonathan Corbet <corbet@lwn.net>
11 * Copyright (C) 2008 Magnus Damm
12 * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de>
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 version 2 as
16 * published by the Free Software Foundation.
17 */
18
19#include <linux/init.h>
20#include <linux/module.h>
21#include <linux/i2c.h>
22#include <linux/slab.h>
23#include <linux/kernel.h>
24#include <linux/delay.h>
25#include <linux/videodev2.h>
26#include <media/v4l2-chip-ident.h>
27#include <media/v4l2-common.h>
28#include <media/soc_camera.h>
29#include <media/tw9910.h>
30
31#define GET_ID(val) ((val & 0xF8) >> 3)
32#define GET_ReV(val) (val & 0x07)
33
34/*
35 * register offset
36 */
37#define ID 0x00 /* Product ID Code Register */
38#define STATUS1 0x01 /* Chip Status Register I */
39#define INFORM 0x02 /* Input Format */
40#define OPFORM 0x03 /* Output Format Control Register */
41#define DLYCTR 0x04 /* Hysteresis and HSYNC Delay Control */
42#define OUTCTR1 0x05 /* Output Control I */
43#define ACNTL1 0x06 /* Analog Control Register 1 */
44#define CROP_HI 0x07 /* Cropping Register, High */
45#define VDELAY_LO 0x08 /* Vertical Delay Register, Low */
46#define VACTIVE_LO 0x09 /* Vertical Active Register, Low */
47#define HDELAY_LO 0x0A /* Horizontal Delay Register, Low */
48#define HACTIVE_LO 0x0B /* Horizontal Active Register, Low */
49#define CNTRL1 0x0C /* Control Register I */
50#define VSCALE_LO 0x0D /* Vertical Scaling Register, Low */
51#define SCALE_HI 0x0E /* Scaling Register, High */
52#define HSCALE_LO 0x0F /* Horizontal Scaling Register, Low */
53#define BRIGHT 0x10 /* BRIGHTNESS Control Register */
54#define CONTRAST 0x11 /* CONTRAST Control Register */
55#define SHARPNESS 0x12 /* SHARPNESS Control Register I */
56#define SAT_U 0x13 /* Chroma (U) Gain Register */
57#define SAT_V 0x14 /* Chroma (V) Gain Register */
58#define HUE 0x15 /* Hue Control Register */
59#define CORING1 0x17
60#define CORING2 0x18 /* Coring and IF compensation */
61#define VBICNTL 0x19 /* VBI Control Register */
62#define ACNTL2 0x1A /* Analog Control 2 */
63#define OUTCTR2 0x1B /* Output Control 2 */
64#define SDT 0x1C /* Standard Selection */
65#define SDTR 0x1D /* Standard Recognition */
66#define TEST 0x1F /* Test Control Register */
67#define CLMPG 0x20 /* Clamping Gain */
68#define IAGC 0x21 /* Individual AGC Gain */
69#define AGCGAIN 0x22 /* AGC Gain */
70#define PEAKWT 0x23 /* White Peak Threshold */
71#define CLMPL 0x24 /* Clamp level */
72#define SYNCT 0x25 /* Sync Amplitude */
73#define MISSCNT 0x26 /* Sync Miss Count Register */
74#define PCLAMP 0x27 /* Clamp Position Register */
75#define VCNTL1 0x28 /* Vertical Control I */
76#define VCNTL2 0x29 /* Vertical Control II */
77#define CKILL 0x2A /* Color Killer Level Control */
78#define COMB 0x2B /* Comb Filter Control */
79#define LDLY 0x2C /* Luma Delay and H Filter Control */
80#define MISC1 0x2D /* Miscellaneous Control I */
81#define LOOP 0x2E /* LOOP Control Register */
82#define MISC2 0x2F /* Miscellaneous Control II */
83#define MVSN 0x30 /* Macrovision Detection */
84#define STATUS2 0x31 /* Chip STATUS II */
85#define HFREF 0x32 /* H monitor */
86#define CLMD 0x33 /* CLAMP MODE */
87#define IDCNTL 0x34 /* ID Detection Control */
88#define CLCNTL1 0x35 /* Clamp Control I */
89#define ANAPLLCTL 0x4C
90#define VBIMIN 0x4D
91#define HSLOWCTL 0x4E
92#define WSS3 0x4F
93#define FILLDATA 0x50
94#define SDID 0x51
95#define DID 0x52
96#define WSS1 0x53
97#define WSS2 0x54
98#define VVBI 0x55
99#define LCTL6 0x56
100#define LCTL7 0x57
101#define LCTL8 0x58
102#define LCTL9 0x59
103#define LCTL10 0x5A
104#define LCTL11 0x5B
105#define LCTL12 0x5C
106#define LCTL13 0x5D
107#define LCTL14 0x5E
108#define LCTL15 0x5F
109#define LCTL16 0x60
110#define LCTL17 0x61
111#define LCTL18 0x62
112#define LCTL19 0x63
113#define LCTL20 0x64
114#define LCTL21 0x65
115#define LCTL22 0x66
116#define LCTL23 0x67
117#define LCTL24 0x68
118#define LCTL25 0x69
119#define LCTL26 0x6A
120#define HSGEGIN 0x6B
121#define HSEND 0x6C
122#define OVSDLY 0x6D
123#define OVSEND 0x6E
124#define VBIDELAY 0x6F
125
126/*
127 * register detail
128 */
129
130/* INFORM */
131#define FC27_ON 0x40 /* 1 : Input crystal clock frequency is 27MHz */
132#define FC27_FF 0x00 /* 0 : Square pixel mode. */
133 /* Must use 24.54MHz for 60Hz field rate */
134 /* source or 29.5MHz for 50Hz field rate */
135#define IFSEL_S 0x10 /* 01 : S-video decoding */
136#define IFSEL_C 0x00 /* 00 : Composite video decoding */
137 /* Y input video selection */
138#define YSEL_M0 0x00 /* 00 : Mux0 selected */
139#define YSEL_M1 0x04 /* 01 : Mux1 selected */
140#define YSEL_M2 0x08 /* 10 : Mux2 selected */
141#define YSEL_M3 0x10 /* 11 : Mux3 selected */
142
143/* OPFORM */
144#define MODE 0x80 /* 0 : CCIR601 compatible YCrCb 4:2:2 format */
145 /* 1 : ITU-R-656 compatible data sequence format */
146#define LEN 0x40 /* 0 : 8-bit YCrCb 4:2:2 output format */
147 /* 1 : 16-bit YCrCb 4:2:2 output format.*/
148#define LLCMODE 0x20 /* 1 : LLC output mode. */
149 /* 0 : free-run output mode */
150#define AINC 0x10 /* Serial interface auto-indexing control */
151 /* 0 : auto-increment */
152 /* 1 : non-auto */
153#define VSCTL 0x08 /* 1 : Vertical out ctrl by DVALID */
154 /* 0 : Vertical out ctrl by HACTIVE and DVALID */
155#define OEN 0x04 /* Output Enable together with TRI_SEL. */
156
157/* OUTCTR1 */
158#define VSP_LO 0x00 /* 0 : VS pin output polarity is active low */
159#define VSP_HI 0x80 /* 1 : VS pin output polarity is active high. */
160 /* VS pin output control */
161#define VSSL_VSYNC 0x00 /* 0 : VSYNC */
162#define VSSL_VACT 0x10 /* 1 : VACT */
163#define VSSL_FIELD 0x20 /* 2 : FIELD */
164#define VSSL_VVALID 0x30 /* 3 : VVALID */
165#define VSSL_ZERO 0x70 /* 7 : 0 */
166#define HSP_LOW 0x00 /* 0 : HS pin output polarity is active low */
167#define HSP_HI 0x08 /* 1 : HS pin output polarity is active high.*/
168 /* HS pin output control */
169#define HSSL_HACT 0x00 /* 0 : HACT */
170#define HSSL_HSYNC 0x01 /* 1 : HSYNC */
171#define HSSL_DVALID 0x02 /* 2 : DVALID */
172#define HSSL_HLOCK 0x03 /* 3 : HLOCK */
173#define HSSL_ASYNCW 0x04 /* 4 : ASYNCW */
174#define HSSL_ZERO 0x07 /* 7 : 0 */
175
176/* ACNTL1 */
177#define SRESET 0x80 /* resets the device to its default state
178 * but all register content remain unchanged.
179 * This bit is self-resetting.
180 */
181
182/* VBICNTL */
183/* RTSEL : control the real time signal
184* output from the MPOUT pin
185*/
186#define RTSEL_MASK 0x07
187#define RTSEL_VLOSS 0x00 /* 0000 = Video loss */
188#define RTSEL_HLOCK 0x01 /* 0001 = H-lock */
189#define RTSEL_SLOCK 0x02 /* 0010 = S-lock */
190#define RTSEL_VLOCK 0x03 /* 0011 = V-lock */
191#define RTSEL_MONO 0x04 /* 0100 = MONO */
192#define RTSEL_DET50 0x05 /* 0101 = DET50 */
193#define RTSEL_FIELD 0x06 /* 0110 = FIELD */
194#define RTSEL_RTCO 0x07 /* 0111 = RTCO ( Real Time Control ) */
195
196/*
197 * structure
198 */
199
200struct regval_list {
201 unsigned char reg_num;
202 unsigned char value;
203};
204
205struct tw9910_scale_ctrl {
206 char *name;
207 unsigned short width;
208 unsigned short height;
209 u16 hscale;
210 u16 vscale;
211};
212
213struct tw9910_cropping_ctrl {
214 u16 vdelay;
215 u16 vactive;
216 u16 hdelay;
217 u16 hactive;
218};
219
220struct tw9910_hsync_ctrl {
221 u16 start;
222 u16 end;
223};
224
225struct tw9910_priv {
226 struct tw9910_video_info *info;
227 struct i2c_client *client;
228 struct soc_camera_device icd;
229 const struct tw9910_scale_ctrl *scale;
230};
231
232/*
233 * register settings
234 */
235
236#define ENDMARKER { 0xff, 0xff }
237
238static const struct regval_list tw9910_default_regs[] =
239{
240 { OPFORM, 0x00 },
241 { OUTCTR1, VSP_LO | VSSL_VVALID | HSP_HI | HSSL_HSYNC },
242 ENDMARKER,
243};
244
245static const struct soc_camera_data_format tw9910_color_fmt[] = {
246 {
247 .name = "VYUY",
248 .fourcc = V4L2_PIX_FMT_VYUY,
249 .depth = 16,
250 .colorspace = V4L2_COLORSPACE_SMPTE170M,
251 }
252};
253
254static const struct tw9910_scale_ctrl tw9910_ntsc_scales[] = {
255 {
256 .name = "NTSC SQ",
257 .width = 640,
258 .height = 480,
259 .hscale = 0x0100,
260 .vscale = 0x0100,
261 },
262 {
263 .name = "NTSC CCIR601",
264 .width = 720,
265 .height = 480,
266 .hscale = 0x0100,
267 .vscale = 0x0100,
268 },
269 {
270 .name = "NTSC SQ (CIF)",
271 .width = 320,
272 .height = 240,
273 .hscale = 0x0200,
274 .vscale = 0x0200,
275 },
276 {
277 .name = "NTSC CCIR601 (CIF)",
278 .width = 360,
279 .height = 240,
280 .hscale = 0x0200,
281 .vscale = 0x0200,
282 },
283 {
284 .name = "NTSC SQ (QCIF)",
285 .width = 160,
286 .height = 120,
287 .hscale = 0x0400,
288 .vscale = 0x0400,
289 },
290 {
291 .name = "NTSC CCIR601 (QCIF)",
292 .width = 180,
293 .height = 120,
294 .hscale = 0x0400,
295 .vscale = 0x0400,
296 },
297};
298
299static const struct tw9910_scale_ctrl tw9910_pal_scales[] = {
300 {
301 .name = "PAL SQ",
302 .width = 768,
303 .height = 576,
304 .hscale = 0x0100,
305 .vscale = 0x0100,
306 },
307 {
308 .name = "PAL CCIR601",
309 .width = 720,
310 .height = 576,
311 .hscale = 0x0100,
312 .vscale = 0x0100,
313 },
314 {
315 .name = "PAL SQ (CIF)",
316 .width = 384,
317 .height = 288,
318 .hscale = 0x0200,
319 .vscale = 0x0200,
320 },
321 {
322 .name = "PAL CCIR601 (CIF)",
323 .width = 360,
324 .height = 288,
325 .hscale = 0x0200,
326 .vscale = 0x0200,
327 },
328 {
329 .name = "PAL SQ (QCIF)",
330 .width = 192,
331 .height = 144,
332 .hscale = 0x0400,
333 .vscale = 0x0400,
334 },
335 {
336 .name = "PAL CCIR601 (QCIF)",
337 .width = 180,
338 .height = 144,
339 .hscale = 0x0400,
340 .vscale = 0x0400,
341 },
342};
343
344static const struct tw9910_cropping_ctrl tw9910_cropping_ctrl = {
345 .vdelay = 0x0012,
346 .vactive = 0x00F0,
347 .hdelay = 0x0010,
348 .hactive = 0x02D0,
349};
350
351static const struct tw9910_hsync_ctrl tw9910_hsync_ctrl = {
352 .start = 0x0260,
353 .end = 0x0300,
354};
355
356/*
357 * general function
358 */
359static int tw9910_set_scale(struct i2c_client *client,
360 const struct tw9910_scale_ctrl *scale)
361{
362 int ret;
363
364 ret = i2c_smbus_write_byte_data(client, SCALE_HI,
365 (scale->vscale & 0x0F00) >> 4 |
366 (scale->hscale & 0x0F00) >> 8);
367 if (ret < 0)
368 return ret;
369
370 ret = i2c_smbus_write_byte_data(client, HSCALE_LO,
371 scale->hscale & 0x00FF);
372 if (ret < 0)
373 return ret;
374
375 ret = i2c_smbus_write_byte_data(client, VSCALE_LO,
376 scale->vscale & 0x00FF);
377
378 return ret;
379}
380
381static int tw9910_set_cropping(struct i2c_client *client,
382 const struct tw9910_cropping_ctrl *cropping)
383{
384 int ret;
385
386 ret = i2c_smbus_write_byte_data(client, CROP_HI,
387 (cropping->vdelay & 0x0300) >> 2 |
388 (cropping->vactive & 0x0300) >> 4 |
389 (cropping->hdelay & 0x0300) >> 6 |
390 (cropping->hactive & 0x0300) >> 8);
391 if (ret < 0)
392 return ret;
393
394 ret = i2c_smbus_write_byte_data(client, VDELAY_LO,
395 cropping->vdelay & 0x00FF);
396 if (ret < 0)
397 return ret;
398
399 ret = i2c_smbus_write_byte_data(client, VACTIVE_LO,
400 cropping->vactive & 0x00FF);
401 if (ret < 0)
402 return ret;
403
404 ret = i2c_smbus_write_byte_data(client, HDELAY_LO,
405 cropping->hdelay & 0x00FF);
406 if (ret < 0)
407 return ret;
408
409 ret = i2c_smbus_write_byte_data(client, HACTIVE_LO,
410 cropping->hactive & 0x00FF);
411
412 return ret;
413}
414
415static int tw9910_set_hsync(struct i2c_client *client,
416 const struct tw9910_hsync_ctrl *hsync)
417{
418 int ret;
419
420 /* bit 10 - 3 */
421 ret = i2c_smbus_write_byte_data(client, HSGEGIN,
422 (hsync->start & 0x07F8) >> 3);
423 if (ret < 0)
424 return ret;
425
426 /* bit 10 - 3 */
427 ret = i2c_smbus_write_byte_data(client, HSEND,
428 (hsync->end & 0x07F8) >> 3);
429 if (ret < 0)
430 return ret;
431
432 /* bit 2 - 0 */
433 ret = i2c_smbus_read_byte_data(client, HSLOWCTL);
434 if (ret < 0)
435 return ret;
436
437 ret = i2c_smbus_write_byte_data(client, HSLOWCTL,
438 (ret & 0x88) |
439 (hsync->start & 0x0007) << 4 |
440 (hsync->end & 0x0007));
441
442 return ret;
443}
444
445static int tw9910_write_array(struct i2c_client *client,
446 const struct regval_list *vals)
447{
448 while (vals->reg_num != 0xff) {
449 int ret = i2c_smbus_write_byte_data(client,
450 vals->reg_num,
451 vals->value);
452 if (ret < 0)
453 return ret;
454 vals++;
455 }
456 return 0;
457}
458
459static int tw9910_mask_set(struct i2c_client *client, u8 command,
460 u8 mask, u8 set)
461{
462 s32 val = i2c_smbus_read_byte_data(client, command);
463
464 val &= ~mask;
465 val |= set;
466
467 return i2c_smbus_write_byte_data(client, command, val);
468}
469
470static void tw9910_reset(struct i2c_client *client)
471{
472 i2c_smbus_write_byte_data(client, ACNTL1, SRESET);
473 msleep(1);
474}
475
476static const struct tw9910_scale_ctrl*
477tw9910_select_norm(struct soc_camera_device *icd, u32 width, u32 height)
478{
479 const struct tw9910_scale_ctrl *scale;
480 const struct tw9910_scale_ctrl *ret = NULL;
481 v4l2_std_id norm = icd->vdev->current_norm;
482 __u32 diff = 0xffffffff, tmp;
483 int size, i;
484
485 if (norm & V4L2_STD_NTSC) {
486 scale = tw9910_ntsc_scales;
487 size = ARRAY_SIZE(tw9910_ntsc_scales);
488 } else if (norm & V4L2_STD_PAL) {
489 scale = tw9910_pal_scales;
490 size = ARRAY_SIZE(tw9910_pal_scales);
491 } else {
492 return NULL;
493 }
494
495 for (i = 0; i < size; i++) {
496 tmp = abs(width - scale[i].width) +
497 abs(height - scale[i].height);
498 if (tmp < diff) {
499 diff = tmp;
500 ret = scale + i;
501 }
502 }
503
504 return ret;
505}
506
507/*
508 * soc_camera_ops function
509 */
510static int tw9910_init(struct soc_camera_device *icd)
511{
512 struct tw9910_priv *priv = container_of(icd, struct tw9910_priv, icd);
513 int ret = 0;
514
515 if (priv->info->link.power) {
516 ret = priv->info->link.power(&priv->client->dev, 1);
517 if (ret < 0)
518 return ret;
519 }
520
521 if (priv->info->link.reset)
522 ret = priv->info->link.reset(&priv->client->dev);
523
524 return ret;
525}
526
527static int tw9910_release(struct soc_camera_device *icd)
528{
529 struct tw9910_priv *priv = container_of(icd, struct tw9910_priv, icd);
530 int ret = 0;
531
532 if (priv->info->link.power)
533 ret = priv->info->link.power(&priv->client->dev, 0);
534
535 return ret;
536}
537
538static int tw9910_start_capture(struct soc_camera_device *icd)
539{
540 struct tw9910_priv *priv = container_of(icd, struct tw9910_priv, icd);
541
542 if (!priv->scale) {
543 dev_err(&icd->dev, "norm select error\n");
544 return -EPERM;
545 }
546
547 dev_dbg(&icd->dev, "%s %dx%d\n",
548 priv->scale->name,
549 priv->scale->width,
550 priv->scale->height);
551
552 return 0;
553}
554
555static int tw9910_stop_capture(struct soc_camera_device *icd)
556{
557 return 0;
558}
559
560static int tw9910_set_bus_param(struct soc_camera_device *icd,
561 unsigned long flags)
562{
563 return 0;
564}
565
566static unsigned long tw9910_query_bus_param(struct soc_camera_device *icd)
567{
568 struct tw9910_priv *priv = container_of(icd, struct tw9910_priv, icd);
569 struct soc_camera_link *icl = priv->client->dev.platform_data;
570 unsigned long flags = SOCAM_PCLK_SAMPLE_RISING | SOCAM_MASTER |
571 SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_HSYNC_ACTIVE_HIGH |
572 SOCAM_DATA_ACTIVE_HIGH | priv->info->buswidth;
573
574 return soc_camera_apply_sensor_flags(icl, flags);
575}
576
577static int tw9910_get_chip_id(struct soc_camera_device *icd,
578 struct v4l2_chip_ident *id)
579{
580 id->ident = V4L2_IDENT_TW9910;
581 id->revision = 0;
582
583 return 0;
584}
585
586static int tw9910_set_std(struct soc_camera_device *icd,
587 v4l2_std_id *a)
588{
589 int ret = -EINVAL;
590
591 if (*a & (V4L2_STD_NTSC | V4L2_STD_PAL))
592 ret = 0;
593
594 return ret;
595}
596
597static int tw9910_enum_input(struct soc_camera_device *icd,
598 struct v4l2_input *inp)
599{
600 inp->type = V4L2_INPUT_TYPE_TUNER;
601 inp->std = V4L2_STD_UNKNOWN;
602 strcpy(inp->name, "Video");
603
604 return 0;
605}
606
607#ifdef CONFIG_VIDEO_ADV_DEBUG
608static int tw9910_get_register(struct soc_camera_device *icd,
609 struct v4l2_register *reg)
610{
611 struct tw9910_priv *priv = container_of(icd, struct tw9910_priv, icd);
612 int ret;
613
614 if (reg->reg > 0xff)
615 return -EINVAL;
616
617 ret = i2c_smbus_read_byte_data(priv->client, reg->reg);
618 if (ret < 0)
619 return ret;
620
621 /* ret = int
622 * reg->val = __u64
623 */
624 reg->val = (__u64)ret;
625
626 return 0;
627}
628
629static int tw9910_set_register(struct soc_camera_device *icd,
630 struct v4l2_register *reg)
631{
632 struct tw9910_priv *priv = container_of(icd, struct tw9910_priv, icd);
633
634 if (reg->reg > 0xff ||
635 reg->val > 0xff)
636 return -EINVAL;
637
638 return i2c_smbus_write_byte_data(priv->client, reg->reg, reg->val);
639}
640#endif
641
642static int tw9910_set_fmt(struct soc_camera_device *icd, __u32 pixfmt,
643 struct v4l2_rect *rect)
644{
645 struct tw9910_priv *priv = container_of(icd, struct tw9910_priv, icd);
646 int ret = -EINVAL;
647 u8 val;
648
649 /*
650 * select suitable norm
651 */
652 priv->scale = tw9910_select_norm(icd, rect->width, rect->height);
653 if (!priv->scale)
654 goto tw9910_set_fmt_error;
655
656 /*
657 * reset hardware
658 */
659 tw9910_reset(priv->client);
660 ret = tw9910_write_array(priv->client, tw9910_default_regs);
661 if (ret < 0)
662 goto tw9910_set_fmt_error;
663
664 /*
665 * set bus width
666 */
667 val = 0x00;
668 if (SOCAM_DATAWIDTH_16 == priv->info->buswidth)
669 val = LEN;
670
671 ret = tw9910_mask_set(priv->client, OPFORM, LEN, val);
672 if (ret < 0)
673 goto tw9910_set_fmt_error;
674
675 /*
676 * select MPOUT behavior
677 */
678 switch (priv->info->mpout) {
679 case TW9910_MPO_VLOSS:
680 val = RTSEL_VLOSS; break;
681 case TW9910_MPO_HLOCK:
682 val = RTSEL_HLOCK; break;
683 case TW9910_MPO_SLOCK:
684 val = RTSEL_SLOCK; break;
685 case TW9910_MPO_VLOCK:
686 val = RTSEL_VLOCK; break;
687 case TW9910_MPO_MONO:
688 val = RTSEL_MONO; break;
689 case TW9910_MPO_DET50:
690 val = RTSEL_DET50; break;
691 case TW9910_MPO_FIELD:
692 val = RTSEL_FIELD; break;
693 case TW9910_MPO_RTCO:
694 val = RTSEL_RTCO; break;
695 default:
696 val = 0;
697 }
698
699 ret = tw9910_mask_set(priv->client, VBICNTL, RTSEL_MASK, val);
700 if (ret < 0)
701 goto tw9910_set_fmt_error;
702
703 /*
704 * set scale
705 */
706 ret = tw9910_set_scale(priv->client, priv->scale);
707 if (ret < 0)
708 goto tw9910_set_fmt_error;
709
710 /*
711 * set cropping
712 */
713 ret = tw9910_set_cropping(priv->client, &tw9910_cropping_ctrl);
714 if (ret < 0)
715 goto tw9910_set_fmt_error;
716
717 /*
718 * set hsync
719 */
720 ret = tw9910_set_hsync(priv->client, &tw9910_hsync_ctrl);
721 if (ret < 0)
722 goto tw9910_set_fmt_error;
723
724 return ret;
725
726tw9910_set_fmt_error:
727
728 tw9910_reset(priv->client);
729 priv->scale = NULL;
730
731 return ret;
732}
733
734static int tw9910_try_fmt(struct soc_camera_device *icd,
735 struct v4l2_format *f)
736{
737 struct v4l2_pix_format *pix = &f->fmt.pix;
738 const struct tw9910_scale_ctrl *scale;
739
740 if (V4L2_FIELD_ANY == pix->field) {
741 pix->field = V4L2_FIELD_INTERLACED;
742 } else if (V4L2_FIELD_INTERLACED != pix->field) {
743 dev_err(&icd->dev, "Field type invalid.\n");
744 return -EINVAL;
745 }
746
747 /*
748 * select suitable norm
749 */
750 scale = tw9910_select_norm(icd, pix->width, pix->height);
751 if (!scale)
752 return -EINVAL;
753
754 pix->width = scale->width;
755 pix->height = scale->height;
756
757 return 0;
758}
759
760static int tw9910_video_probe(struct soc_camera_device *icd)
761{
762 struct tw9910_priv *priv = container_of(icd, struct tw9910_priv, icd);
763 s32 val;
764 int ret;
765
766 /*
767 * We must have a parent by now. And it cannot be a wrong one.
768 * So this entire test is completely redundant.
769 */
770 if (!icd->dev.parent ||
771 to_soc_camera_host(icd->dev.parent)->nr != icd->iface)
772 return -ENODEV;
773
774 /*
775 * tw9910 only use 8 or 16 bit bus width
776 */
777 if (SOCAM_DATAWIDTH_16 != priv->info->buswidth &&
778 SOCAM_DATAWIDTH_8 != priv->info->buswidth) {
779 dev_err(&icd->dev, "bus width error\n");
780 return -ENODEV;
781 }
782
783 icd->formats = tw9910_color_fmt;
784 icd->num_formats = ARRAY_SIZE(tw9910_color_fmt);
785
786 /*
787 * check and show Product ID
788 */
789 val = i2c_smbus_read_byte_data(priv->client, ID);
790 if (0x0B != GET_ID(val) ||
791 0x00 != GET_ReV(val)) {
792 dev_err(&icd->dev,
793 "Product ID error %x:%x\n", GET_ID(val), GET_ReV(val));
794 return -ENODEV;
795 }
796
797 dev_info(&icd->dev,
798 "tw9910 Product ID %0x:%0x\n", GET_ID(val), GET_ReV(val));
799
800 ret = soc_camera_video_start(icd);
801 if (ret < 0)
802 return ret;
803
804 icd->vdev->tvnorms = V4L2_STD_NTSC | V4L2_STD_PAL;
805 icd->vdev->current_norm = V4L2_STD_NTSC;
806
807 return ret;
808}
809
810static void tw9910_video_remove(struct soc_camera_device *icd)
811{
812 soc_camera_video_stop(icd);
813}
814
815static struct soc_camera_ops tw9910_ops = {
816 .owner = THIS_MODULE,
817 .probe = tw9910_video_probe,
818 .remove = tw9910_video_remove,
819 .init = tw9910_init,
820 .release = tw9910_release,
821 .start_capture = tw9910_start_capture,
822 .stop_capture = tw9910_stop_capture,
823 .set_fmt = tw9910_set_fmt,
824 .try_fmt = tw9910_try_fmt,
825 .set_bus_param = tw9910_set_bus_param,
826 .query_bus_param = tw9910_query_bus_param,
827 .get_chip_id = tw9910_get_chip_id,
828 .set_std = tw9910_set_std,
829 .enum_input = tw9910_enum_input,
830#ifdef CONFIG_VIDEO_ADV_DEBUG
831 .get_register = tw9910_get_register,
832 .set_register = tw9910_set_register,
833#endif
834};
835
836/*
837 * i2c_driver function
838 */
839
840static int tw9910_probe(struct i2c_client *client,
841 const struct i2c_device_id *did)
842
843{
844 struct tw9910_priv *priv;
845 struct tw9910_video_info *info;
846 struct soc_camera_device *icd;
847 const struct tw9910_scale_ctrl *scale;
848 int i, ret;
849
850 info = client->dev.platform_data;
851 if (!info)
852 return -EINVAL;
853
854 if (!i2c_check_functionality(to_i2c_adapter(client->dev.parent),
855 I2C_FUNC_SMBUS_BYTE_DATA)) {
856 dev_err(&client->dev,
857 "I2C-Adapter doesn't support "
858 "I2C_FUNC_SMBUS_BYTE_DATA\n");
859 return -EIO;
860 }
861
862 priv = kzalloc(sizeof(*priv), GFP_KERNEL);
863 if (!priv)
864 return -ENOMEM;
865
866 priv->info = info;
867 priv->client = client;
868 i2c_set_clientdata(client, priv);
869
870 icd = &priv->icd;
871 icd->ops = &tw9910_ops;
872 icd->control = &client->dev;
873 icd->iface = info->link.bus_id;
874
875 /*
876 * set width and height
877 */
878 icd->width_max = tw9910_ntsc_scales[0].width; /* set default */
879 icd->width_min = tw9910_ntsc_scales[0].width;
880 icd->height_max = tw9910_ntsc_scales[0].height;
881 icd->height_min = tw9910_ntsc_scales[0].height;
882
883 scale = tw9910_ntsc_scales;
884 for (i = 0; i < ARRAY_SIZE(tw9910_ntsc_scales); i++) {
885 icd->width_max = max(scale[i].width, icd->width_max);
886 icd->width_min = min(scale[i].width, icd->width_min);
887 icd->height_max = max(scale[i].height, icd->height_max);
888 icd->height_min = min(scale[i].height, icd->height_min);
889 }
890 scale = tw9910_pal_scales;
891 for (i = 0; i < ARRAY_SIZE(tw9910_pal_scales); i++) {
892 icd->width_max = max(scale[i].width, icd->width_max);
893 icd->width_min = min(scale[i].width, icd->width_min);
894 icd->height_max = max(scale[i].height, icd->height_max);
895 icd->height_min = min(scale[i].height, icd->height_min);
896 }
897
898 ret = soc_camera_device_register(icd);
899
900 if (ret) {
901 i2c_set_clientdata(client, NULL);
902 kfree(priv);
903 }
904
905 return ret;
906}
907
908static int tw9910_remove(struct i2c_client *client)
909{
910 struct tw9910_priv *priv = i2c_get_clientdata(client);
911
912 soc_camera_device_unregister(&priv->icd);
913 i2c_set_clientdata(client, NULL);
914 kfree(priv);
915 return 0;
916}
917
918static const struct i2c_device_id tw9910_id[] = {
919 { "tw9910", 0 },
920 { }
921};
922MODULE_DEVICE_TABLE(i2c, tw9910_id);
923
924static struct i2c_driver tw9910_i2c_driver = {
925 .driver = {
926 .name = "tw9910",
927 },
928 .probe = tw9910_probe,
929 .remove = tw9910_remove,
930 .id_table = tw9910_id,
931};
932
933/*
934 * module function
935 */
936static int __init tw9910_module_init(void)
937{
938 return i2c_add_driver(&tw9910_i2c_driver);
939}
940
941static void __exit tw9910_module_exit(void)
942{
943 i2c_del_driver(&tw9910_i2c_driver);
944}
945
946module_init(tw9910_module_init);
947module_exit(tw9910_module_exit);
948
949MODULE_DESCRIPTION("SoC Camera driver for tw9910");
950MODULE_AUTHOR("Kuninori Morimoto");
951MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/upd64031a.c b/drivers/media/video/upd64031a.c
index b4628874933b..7a609a3a6dbe 100644
--- a/drivers/media/video/upd64031a.c
+++ b/drivers/media/video/upd64031a.c
@@ -26,7 +26,7 @@
26#include <linux/kernel.h> 26#include <linux/kernel.h>
27#include <linux/i2c.h> 27#include <linux/i2c.h>
28#include <linux/videodev2.h> 28#include <linux/videodev2.h>
29#include <media/v4l2-common.h> 29#include <media/v4l2-device.h>
30#include <media/v4l2-chip-ident.h> 30#include <media/v4l2-chip-ident.h>
31#include <media/v4l2-i2c-drv.h> 31#include <media/v4l2-i2c-drv.h>
32#include <media/upd64031a.h> 32#include <media/upd64031a.h>
@@ -62,6 +62,7 @@ enum {
62}; 62};
63 63
64struct upd64031a_state { 64struct upd64031a_state {
65 struct v4l2_subdev sd;
65 u8 regs[TOT_REGS]; 66 u8 regs[TOT_REGS];
66 u8 gr_mode; 67 u8 gr_mode;
67 u8 direct_3dycs_connect; 68 u8 direct_3dycs_connect;
@@ -69,6 +70,11 @@ struct upd64031a_state {
69 u8 ext_vert_sync; 70 u8 ext_vert_sync;
70}; 71};
71 72
73static inline struct upd64031a_state *to_state(struct v4l2_subdev *sd)
74{
75 return container_of(sd, struct upd64031a_state, sd);
76}
77
72static u8 upd64031a_init[] = { 78static u8 upd64031a_init[] = {
73 0x00, 0xb8, 0x48, 0xd2, 0xe6, 79 0x00, 0xb8, 0x48, 0xd2, 0xe6,
74 0x03, 0x10, 0x0b, 0xaf, 0x7f, 80 0x03, 0x10, 0x0b, 0xaf, 0x7f,
@@ -78,8 +84,9 @@ static u8 upd64031a_init[] = {
78 84
79/* ------------------------------------------------------------------------ */ 85/* ------------------------------------------------------------------------ */
80 86
81static u8 upd64031a_read(struct i2c_client *client, u8 reg) 87static u8 upd64031a_read(struct v4l2_subdev *sd, u8 reg)
82{ 88{
89 struct i2c_client *client = v4l2_get_subdevdata(sd);
83 u8 buf[2]; 90 u8 buf[2];
84 91
85 if (reg >= sizeof(buf)) 92 if (reg >= sizeof(buf))
@@ -90,106 +97,127 @@ static u8 upd64031a_read(struct i2c_client *client, u8 reg)
90 97
91/* ------------------------------------------------------------------------ */ 98/* ------------------------------------------------------------------------ */
92 99
93static void upd64031a_write(struct i2c_client *client, u8 reg, u8 val) 100static void upd64031a_write(struct v4l2_subdev *sd, u8 reg, u8 val)
94{ 101{
102 struct i2c_client *client = v4l2_get_subdevdata(sd);
95 u8 buf[2]; 103 u8 buf[2];
96 104
97 buf[0] = reg; 105 buf[0] = reg;
98 buf[1] = val; 106 buf[1] = val;
99 v4l_dbg(1, debug, client, "write reg: %02X val: %02X\n", reg, val); 107 v4l2_dbg(1, debug, sd, "write reg: %02X val: %02X\n", reg, val);
100 if (i2c_master_send(client, buf, 2) != 2) 108 if (i2c_master_send(client, buf, 2) != 2)
101 v4l_err(client, "I/O error write 0x%02x/0x%02x\n", reg, val); 109 v4l2_err(sd, "I/O error write 0x%02x/0x%02x\n", reg, val);
102} 110}
103 111
104/* ------------------------------------------------------------------------ */ 112/* ------------------------------------------------------------------------ */
105 113
106/* The input changed due to new input or channel changed */ 114/* The input changed due to new input or channel changed */
107static void upd64031a_change(struct i2c_client *client) 115static int upd64031a_s_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *freq)
108{ 116{
109 struct upd64031a_state *state = i2c_get_clientdata(client); 117 struct upd64031a_state *state = to_state(sd);
110 u8 reg = state->regs[R00]; 118 u8 reg = state->regs[R00];
111 119
112 v4l_dbg(1, debug, client, "changed input or channel\n"); 120 v4l2_dbg(1, debug, sd, "changed input or channel\n");
113 upd64031a_write(client, R00, reg | 0x10); 121 upd64031a_write(sd, R00, reg | 0x10);
114 upd64031a_write(client, R00, reg & ~0x10); 122 upd64031a_write(sd, R00, reg & ~0x10);
123 return 0;
115} 124}
116 125
117/* ------------------------------------------------------------------------ */ 126/* ------------------------------------------------------------------------ */
118 127
128static int upd64031a_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
129{
130 struct upd64031a_state *state = to_state(sd);
131 u8 r00, r05, r08;
132
133 state->gr_mode = (route->input & 3) << 6;
134 state->direct_3dycs_connect = (route->input & 0xc) << 4;
135 state->ext_comp_sync =
136 (route->input & UPD64031A_COMPOSITE_EXTERNAL) << 1;
137 state->ext_vert_sync =
138 (route->input & UPD64031A_VERTICAL_EXTERNAL) << 2;
139 r00 = (state->regs[R00] & ~GR_MODE_MASK) | state->gr_mode;
140 r05 = (state->regs[R00] & ~SYNC_CIRCUIT_MASK) |
141 state->ext_comp_sync | state->ext_vert_sync;
142 r08 = (state->regs[R08] & ~DIRECT_3DYCS_CONNECT_MASK) |
143 state->direct_3dycs_connect;
144 upd64031a_write(sd, R00, r00);
145 upd64031a_write(sd, R05, r05);
146 upd64031a_write(sd, R08, r08);
147 return upd64031a_s_frequency(sd, NULL);
148}
149
150static int upd64031a_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_chip_ident *chip)
151{
152 struct i2c_client *client = v4l2_get_subdevdata(sd);
153
154 return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_UPD64031A, 0);
155}
156
157static int upd64031a_log_status(struct v4l2_subdev *sd)
158{
159 v4l2_info(sd, "Status: SA00=0x%02x SA01=0x%02x\n",
160 upd64031a_read(sd, 0), upd64031a_read(sd, 1));
161 return 0;
162}
163
164#ifdef CONFIG_VIDEO_ADV_DEBUG
165static int upd64031a_g_register(struct v4l2_subdev *sd, struct v4l2_register *reg)
166{
167 struct i2c_client *client = v4l2_get_subdevdata(sd);
168
169 if (!v4l2_chip_match_i2c_client(client,
170 reg->match_type, reg->match_chip))
171 return -EINVAL;
172 if (!capable(CAP_SYS_ADMIN))
173 return -EPERM;
174 reg->val = upd64031a_read(sd, reg->reg & 0xff);
175 return 0;
176}
177
178static int upd64031a_s_register(struct v4l2_subdev *sd, struct v4l2_register *reg)
179{
180 struct i2c_client *client = v4l2_get_subdevdata(sd);
181
182 if (!v4l2_chip_match_i2c_client(client,
183 reg->match_type, reg->match_chip))
184 return -EINVAL;
185 if (!capable(CAP_SYS_ADMIN))
186 return -EPERM;
187 upd64031a_write(sd, reg->reg & 0xff, reg->val & 0xff);
188 return 0;
189}
190#endif
191
119static int upd64031a_command(struct i2c_client *client, unsigned cmd, void *arg) 192static int upd64031a_command(struct i2c_client *client, unsigned cmd, void *arg)
120{ 193{
121 struct upd64031a_state *state = i2c_get_clientdata(client); 194 return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
122 struct v4l2_routing *route = arg; 195}
123 196
124 switch (cmd) { 197/* ----------------------------------------------------------------------- */
125 case VIDIOC_S_FREQUENCY:
126 upd64031a_change(client);
127 break;
128
129 case VIDIOC_INT_G_VIDEO_ROUTING:
130 route->input = (state->gr_mode >> 6) |
131 (state->direct_3dycs_connect >> 4) |
132 (state->ext_comp_sync >> 1) |
133 (state->ext_vert_sync >> 2);
134 route->output = 0;
135 break;
136
137 case VIDIOC_INT_S_VIDEO_ROUTING:
138 {
139 u8 r00, r05, r08;
140
141 state->gr_mode = (route->input & 3) << 6;
142 state->direct_3dycs_connect = (route->input & 0xc) << 4;
143 state->ext_comp_sync =
144 (route->input & UPD64031A_COMPOSITE_EXTERNAL) << 1;
145 state->ext_vert_sync =
146 (route->input & UPD64031A_VERTICAL_EXTERNAL) << 2;
147 r00 = (state->regs[R00] & ~GR_MODE_MASK) | state->gr_mode;
148 r05 = (state->regs[R00] & ~SYNC_CIRCUIT_MASK) |
149 state->ext_comp_sync | state->ext_vert_sync;
150 r08 = (state->regs[R08] & ~DIRECT_3DYCS_CONNECT_MASK) |
151 state->direct_3dycs_connect;
152 upd64031a_write(client, R00, r00);
153 upd64031a_write(client, R05, r05);
154 upd64031a_write(client, R08, r08);
155 upd64031a_change(client);
156 break;
157 }
158
159 case VIDIOC_LOG_STATUS:
160 v4l_info(client, "Status: SA00=0x%02x SA01=0x%02x\n",
161 upd64031a_read(client, 0), upd64031a_read(client, 1));
162 break;
163 198
199static const struct v4l2_subdev_core_ops upd64031a_core_ops = {
200 .log_status = upd64031a_log_status,
201 .g_chip_ident = upd64031a_g_chip_ident,
164#ifdef CONFIG_VIDEO_ADV_DEBUG 202#ifdef CONFIG_VIDEO_ADV_DEBUG
165 case VIDIOC_DBG_G_REGISTER: 203 .g_register = upd64031a_g_register,
166 case VIDIOC_DBG_S_REGISTER: 204 .s_register = upd64031a_s_register,
167 {
168 struct v4l2_register *reg = arg;
169
170 if (!v4l2_chip_match_i2c_client(client,
171 reg->match_type, reg->match_chip))
172 return -EINVAL;
173 if (!capable(CAP_SYS_ADMIN))
174 return -EPERM;
175 if (cmd == VIDIOC_DBG_G_REGISTER) {
176 reg->val = upd64031a_read(client, reg->reg & 0xff);
177 break;
178 }
179 upd64031a_write(client, reg->reg & 0xff, reg->val & 0xff);
180 break;
181 }
182#endif 205#endif
206};
183 207
184 case VIDIOC_G_CHIP_IDENT: 208static const struct v4l2_subdev_tuner_ops upd64031a_tuner_ops = {
185 return v4l2_chip_ident_i2c_client(client, arg, 209 .s_frequency = upd64031a_s_frequency,
186 V4L2_IDENT_UPD64031A, 0); 210};
187 211
188 default: 212static const struct v4l2_subdev_video_ops upd64031a_video_ops = {
189 break; 213 .s_routing = upd64031a_s_routing,
190 } 214};
191 return 0; 215
192} 216static const struct v4l2_subdev_ops upd64031a_ops = {
217 .core = &upd64031a_core_ops,
218 .tuner = &upd64031a_tuner_ops,
219 .video = &upd64031a_video_ops,
220};
193 221
194/* ------------------------------------------------------------------------ */ 222/* ------------------------------------------------------------------------ */
195 223
@@ -199,6 +227,7 @@ static int upd64031a_probe(struct i2c_client *client,
199 const struct i2c_device_id *id) 227 const struct i2c_device_id *id)
200{ 228{
201 struct upd64031a_state *state; 229 struct upd64031a_state *state;
230 struct v4l2_subdev *sd;
202 int i; 231 int i;
203 232
204 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) 233 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
@@ -210,19 +239,23 @@ static int upd64031a_probe(struct i2c_client *client,
210 state = kmalloc(sizeof(struct upd64031a_state), GFP_KERNEL); 239 state = kmalloc(sizeof(struct upd64031a_state), GFP_KERNEL);
211 if (state == NULL) 240 if (state == NULL)
212 return -ENOMEM; 241 return -ENOMEM;
213 i2c_set_clientdata(client, state); 242 sd = &state->sd;
243 v4l2_i2c_subdev_init(sd, client, &upd64031a_ops);
214 memcpy(state->regs, upd64031a_init, sizeof(state->regs)); 244 memcpy(state->regs, upd64031a_init, sizeof(state->regs));
215 state->gr_mode = UPD64031A_GR_ON << 6; 245 state->gr_mode = UPD64031A_GR_ON << 6;
216 state->direct_3dycs_connect = UPD64031A_3DYCS_COMPOSITE << 4; 246 state->direct_3dycs_connect = UPD64031A_3DYCS_COMPOSITE << 4;
217 state->ext_comp_sync = state->ext_vert_sync = 0; 247 state->ext_comp_sync = state->ext_vert_sync = 0;
218 for (i = 0; i < TOT_REGS; i++) 248 for (i = 0; i < TOT_REGS; i++)
219 upd64031a_write(client, i, state->regs[i]); 249 upd64031a_write(sd, i, state->regs[i]);
220 return 0; 250 return 0;
221} 251}
222 252
223static int upd64031a_remove(struct i2c_client *client) 253static int upd64031a_remove(struct i2c_client *client)
224{ 254{
225 kfree(i2c_get_clientdata(client)); 255 struct v4l2_subdev *sd = i2c_get_clientdata(client);
256
257 v4l2_device_unregister_subdev(sd);
258 kfree(to_state(sd));
226 return 0; 259 return 0;
227} 260}
228 261
diff --git a/drivers/media/video/upd64083.c b/drivers/media/video/upd64083.c
index 9521ce004dcc..58412cb9c01a 100644
--- a/drivers/media/video/upd64083.c
+++ b/drivers/media/video/upd64083.c
@@ -26,7 +26,7 @@
26#include <linux/kernel.h> 26#include <linux/kernel.h>
27#include <linux/i2c.h> 27#include <linux/i2c.h>
28#include <linux/videodev2.h> 28#include <linux/videodev2.h>
29#include <media/v4l2-common.h> 29#include <media/v4l2-device.h>
30#include <media/v4l2-chip-ident.h> 30#include <media/v4l2-chip-ident.h>
31#include <media/v4l2-i2c-drv.h> 31#include <media/v4l2-i2c-drv.h>
32#include <media/upd64083.h> 32#include <media/upd64083.h>
@@ -51,11 +51,17 @@ enum {
51}; 51};
52 52
53struct upd64083_state { 53struct upd64083_state {
54 struct v4l2_subdev sd;
54 u8 mode; 55 u8 mode;
55 u8 ext_y_adc; 56 u8 ext_y_adc;
56 u8 regs[TOT_REGS]; 57 u8 regs[TOT_REGS];
57}; 58};
58 59
60static inline struct upd64083_state *to_state(struct v4l2_subdev *sd)
61{
62 return container_of(sd, struct upd64083_state, sd);
63}
64
59/* Initial values when used in combination with the 65/* Initial values when used in combination with the
60 NEC upd64031a ghost reduction chip. */ 66 NEC upd64031a ghost reduction chip. */
61static u8 upd64083_init[] = { 67static u8 upd64083_init[] = {
@@ -68,34 +74,24 @@ static u8 upd64083_init[] = {
68 74
69/* ------------------------------------------------------------------------ */ 75/* ------------------------------------------------------------------------ */
70 76
71static void upd64083_log_status(struct i2c_client *client) 77static void upd64083_write(struct v4l2_subdev *sd, u8 reg, u8 val)
72{
73 u8 buf[7];
74
75 i2c_master_recv(client, buf, 7);
76 v4l_info(client, "Status: SA00=%02x SA01=%02x SA02=%02x SA03=%02x "
77 "SA04=%02x SA05=%02x SA06=%02x\n",
78 buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6]);
79}
80
81/* ------------------------------------------------------------------------ */
82
83static void upd64083_write(struct i2c_client *client, u8 reg, u8 val)
84{ 78{
79 struct i2c_client *client = v4l2_get_subdevdata(sd);
85 u8 buf[2]; 80 u8 buf[2];
86 81
87 buf[0] = reg; 82 buf[0] = reg;
88 buf[1] = val; 83 buf[1] = val;
89 v4l_dbg(1, debug, client, "write reg: %02x val: %02x\n", reg, val); 84 v4l2_dbg(1, debug, sd, "write reg: %02x val: %02x\n", reg, val);
90 if (i2c_master_send(client, buf, 2) != 2) 85 if (i2c_master_send(client, buf, 2) != 2)
91 v4l_err(client, "I/O error write 0x%02x/0x%02x\n", reg, val); 86 v4l2_err(sd, "I/O error write 0x%02x/0x%02x\n", reg, val);
92} 87}
93 88
94/* ------------------------------------------------------------------------ */ 89/* ------------------------------------------------------------------------ */
95 90
96#ifdef CONFIG_VIDEO_ADV_DEBUG 91#ifdef CONFIG_VIDEO_ADV_DEBUG
97static u8 upd64083_read(struct i2c_client *client, u8 reg) 92static u8 upd64083_read(struct v4l2_subdev *sd, u8 reg)
98{ 93{
94 struct i2c_client *client = v4l2_get_subdevdata(sd);
99 u8 buf[7]; 95 u8 buf[7];
100 96
101 if (reg >= sizeof(buf)) 97 if (reg >= sizeof(buf))
@@ -107,67 +103,94 @@ static u8 upd64083_read(struct i2c_client *client, u8 reg)
107 103
108/* ------------------------------------------------------------------------ */ 104/* ------------------------------------------------------------------------ */
109 105
110static int upd64083_command(struct i2c_client *client, unsigned cmd, void *arg) 106static int upd64083_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
111{ 107{
112 struct upd64083_state *state = i2c_get_clientdata(client); 108 struct upd64083_state *state = to_state(sd);
113 struct v4l2_routing *route = arg; 109 u8 r00, r02;
114 110
115 switch (cmd) { 111 if (route->input > 7 || (route->input & 6) == 6)
116 case VIDIOC_INT_G_VIDEO_ROUTING: 112 return -EINVAL;
117 route->input = (state->mode >> 6) | (state->ext_y_adc >> 3); 113 state->mode = (route->input & 3) << 6;
118 route->output = 0; 114 state->ext_y_adc = (route->input & UPD64083_EXT_Y_ADC) << 3;
119 break; 115 r00 = (state->regs[R00] & ~(3 << 6)) | state->mode;
120 116 r02 = (state->regs[R02] & ~(1 << 5)) | state->ext_y_adc;
121 case VIDIOC_INT_S_VIDEO_ROUTING: 117 upd64083_write(sd, R00, r00);
122 { 118 upd64083_write(sd, R02, r02);
123 u8 r00, r02; 119 return 0;
124 120}
125 if (route->input > 7 || (route->input & 6) == 6)
126 return -EINVAL;
127 state->mode = (route->input & 3) << 6;
128 state->ext_y_adc = (route->input & UPD64083_EXT_Y_ADC) << 3;
129 r00 = (state->regs[R00] & ~(3 << 6)) | state->mode;
130 r02 = (state->regs[R02] & ~(1 << 5)) | state->ext_y_adc;
131 upd64083_write(client, R00, r00);
132 upd64083_write(client, R02, r02);
133 break;
134 }
135
136 case VIDIOC_LOG_STATUS:
137 upd64083_log_status(client);
138 break;
139 121
140#ifdef CONFIG_VIDEO_ADV_DEBUG 122#ifdef CONFIG_VIDEO_ADV_DEBUG
141 case VIDIOC_DBG_G_REGISTER: 123static int upd64083_g_register(struct v4l2_subdev *sd, struct v4l2_register *reg)
142 case VIDIOC_DBG_S_REGISTER: 124{
143 { 125 struct i2c_client *client = v4l2_get_subdevdata(sd);
144 struct v4l2_register *reg = arg; 126
127 if (!v4l2_chip_match_i2c_client(client,
128 reg->match_type, reg->match_chip))
129 return -EINVAL;
130 if (!capable(CAP_SYS_ADMIN))
131 return -EPERM;
132 reg->val = upd64083_read(sd, reg->reg & 0xff);
133 return 0;
134}
145 135
146 if (!v4l2_chip_match_i2c_client(client, 136static int upd64083_s_register(struct v4l2_subdev *sd, struct v4l2_register *reg)
137{
138 struct i2c_client *client = v4l2_get_subdevdata(sd);
139
140 if (!v4l2_chip_match_i2c_client(client,
147 reg->match_type, reg->match_chip)) 141 reg->match_type, reg->match_chip))
148 return -EINVAL; 142 return -EINVAL;
149 if (!capable(CAP_SYS_ADMIN)) 143 if (!capable(CAP_SYS_ADMIN))
150 return -EPERM; 144 return -EPERM;
151 if (cmd == VIDIOC_DBG_G_REGISTER) { 145 upd64083_write(sd, reg->reg & 0xff, reg->val & 0xff);
152 reg->val = upd64083_read(client, reg->reg & 0xff); 146 return 0;
153 break; 147}
154 }
155 upd64083_write(client, reg->reg & 0xff, reg->val & 0xff);
156 break;
157 }
158#endif 148#endif
159 149
160 case VIDIOC_G_CHIP_IDENT: 150static int upd64083_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_chip_ident *chip)
161 return v4l2_chip_ident_i2c_client(client, arg, 151{
162 V4L2_IDENT_UPD64083, 0); 152 struct i2c_client *client = v4l2_get_subdevdata(sd);
153
154 return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_UPD64083, 0);
155}
163 156
164 default: 157static int upd64083_log_status(struct v4l2_subdev *sd)
165 break; 158{
166 } 159 struct i2c_client *client = v4l2_get_subdevdata(sd);
160 u8 buf[7];
167 161
162 i2c_master_recv(client, buf, 7);
163 v4l2_info(sd, "Status: SA00=%02x SA01=%02x SA02=%02x SA03=%02x "
164 "SA04=%02x SA05=%02x SA06=%02x\n",
165 buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6]);
168 return 0; 166 return 0;
169} 167}
170 168
169static int upd64083_command(struct i2c_client *client, unsigned cmd, void *arg)
170{
171 return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
172}
173
174/* ----------------------------------------------------------------------- */
175
176static const struct v4l2_subdev_core_ops upd64083_core_ops = {
177 .log_status = upd64083_log_status,
178 .g_chip_ident = upd64083_g_chip_ident,
179#ifdef CONFIG_VIDEO_ADV_DEBUG
180 .g_register = upd64083_g_register,
181 .s_register = upd64083_s_register,
182#endif
183};
184
185static const struct v4l2_subdev_video_ops upd64083_video_ops = {
186 .s_routing = upd64083_s_routing,
187};
188
189static const struct v4l2_subdev_ops upd64083_ops = {
190 .core = &upd64083_core_ops,
191 .video = &upd64083_video_ops,
192};
193
171/* ------------------------------------------------------------------------ */ 194/* ------------------------------------------------------------------------ */
172 195
173/* i2c implementation */ 196/* i2c implementation */
@@ -176,6 +199,7 @@ static int upd64083_probe(struct i2c_client *client,
176 const struct i2c_device_id *id) 199 const struct i2c_device_id *id)
177{ 200{
178 struct upd64083_state *state; 201 struct upd64083_state *state;
202 struct v4l2_subdev *sd;
179 int i; 203 int i;
180 204
181 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) 205 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
@@ -187,19 +211,23 @@ static int upd64083_probe(struct i2c_client *client,
187 state = kmalloc(sizeof(struct upd64083_state), GFP_KERNEL); 211 state = kmalloc(sizeof(struct upd64083_state), GFP_KERNEL);
188 if (state == NULL) 212 if (state == NULL)
189 return -ENOMEM; 213 return -ENOMEM;
190 i2c_set_clientdata(client, state); 214 sd = &state->sd;
215 v4l2_i2c_subdev_init(sd, client, &upd64083_ops);
191 /* Initially assume that a ghost reduction chip is present */ 216 /* Initially assume that a ghost reduction chip is present */
192 state->mode = 0; /* YCS mode */ 217 state->mode = 0; /* YCS mode */
193 state->ext_y_adc = (1 << 5); 218 state->ext_y_adc = (1 << 5);
194 memcpy(state->regs, upd64083_init, TOT_REGS); 219 memcpy(state->regs, upd64083_init, TOT_REGS);
195 for (i = 0; i < TOT_REGS; i++) 220 for (i = 0; i < TOT_REGS; i++)
196 upd64083_write(client, i, state->regs[i]); 221 upd64083_write(sd, i, state->regs[i]);
197 return 0; 222 return 0;
198} 223}
199 224
200static int upd64083_remove(struct i2c_client *client) 225static int upd64083_remove(struct i2c_client *client)
201{ 226{
202 kfree(i2c_get_clientdata(client)); 227 struct v4l2_subdev *sd = i2c_get_clientdata(client);
228
229 v4l2_device_unregister_subdev(sd);
230 kfree(to_state(sd));
203 return 0; 231 return 0;
204} 232}
205 233
diff --git a/drivers/media/video/usbvideo/ibmcam.c b/drivers/media/video/usbvideo/ibmcam.c
index c710bcd1df48..f8d85ddb4804 100644
--- a/drivers/media/video/usbvideo/ibmcam.c
+++ b/drivers/media/video/usbvideo/ibmcam.c
@@ -3779,11 +3779,11 @@ static int ibmcam_probe(struct usb_interface *intf, const struct usb_device_id *
3779 err("Alternate settings have different endpoint addresses!"); 3779 err("Alternate settings have different endpoint addresses!");
3780 return -ENODEV; 3780 return -ENODEV;
3781 } 3781 }
3782 if ((endpoint->bmAttributes & 0x03) != 0x01) { 3782 if (usb_endpoint_type(endpoint) != USB_ENDPOINT_XFER_ISOC) {
3783 err("Interface %d. has non-ISO endpoint!", ifnum); 3783 err("Interface %d. has non-ISO endpoint!", ifnum);
3784 return -ENODEV; 3784 return -ENODEV;
3785 } 3785 }
3786 if ((endpoint->bEndpointAddress & 0x80) == 0) { 3786 if (usb_endpoint_dir_out(endpoint)) {
3787 err("Interface %d. has ISO OUT endpoint!", ifnum); 3787 err("Interface %d. has ISO OUT endpoint!", ifnum);
3788 return -ENODEV; 3788 return -ENODEV;
3789 } 3789 }
diff --git a/drivers/media/video/usbvideo/konicawc.c b/drivers/media/video/usbvideo/konicawc.c
index da27a5287983..90f0ce6a26bc 100644
--- a/drivers/media/video/usbvideo/konicawc.c
+++ b/drivers/media/video/usbvideo/konicawc.c
@@ -823,12 +823,12 @@ static int konicawc_probe(struct usb_interface *intf, const struct usb_device_id
823 err("Alternate settings have different endpoint addresses!"); 823 err("Alternate settings have different endpoint addresses!");
824 return -ENODEV; 824 return -ENODEV;
825 } 825 }
826 if ((endpoint->bmAttributes & 0x03) != 0x01) { 826 if (usb_endpoint_type(endpoint) != USB_ENDPOINT_XFER_ISOC) {
827 err("Interface %d. has non-ISO endpoint!", 827 err("Interface %d. has non-ISO endpoint!",
828 interface->desc.bInterfaceNumber); 828 interface->desc.bInterfaceNumber);
829 return -ENODEV; 829 return -ENODEV;
830 } 830 }
831 if ((endpoint->bEndpointAddress & 0x80) == 0) { 831 if (usb_endpoint_dir_out(endpoint)) {
832 err("Interface %d. has ISO OUT endpoint!", 832 err("Interface %d. has ISO OUT endpoint!",
833 interface->desc.bInterfaceNumber); 833 interface->desc.bInterfaceNumber);
834 return -ENODEV; 834 return -ENODEV;
diff --git a/drivers/media/video/usbvideo/quickcam_messenger.c b/drivers/media/video/usbvideo/quickcam_messenger.c
index 4459b8a7f818..fd112f0b9d35 100644
--- a/drivers/media/video/usbvideo/quickcam_messenger.c
+++ b/drivers/media/video/usbvideo/quickcam_messenger.c
@@ -447,7 +447,7 @@ static int qcm_sensor_init(struct uvd *uvd)
447 CHECK_RET(ret, qcm_stv_setw(uvd->dev, 0x15c1, 447 CHECK_RET(ret, qcm_stv_setw(uvd->dev, 0x15c1,
448 cpu_to_le16(ISOC_PACKET_SIZE))); 448 cpu_to_le16(ISOC_PACKET_SIZE)));
449 CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x15c3, 0x08)); 449 CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x15c3, 0x08));
450 CHECK_RET(ret, ret = qcm_stv_setb(uvd->dev, 0x143f, 0x01)); 450 CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x143f, 0x01));
451 451
452 CHECK_RET(ret, qcm_stv_setb(uvd->dev, STV_ISO_ENABLE, 0x00)); 452 CHECK_RET(ret, qcm_stv_setb(uvd->dev, STV_ISO_ENABLE, 0x00));
453 453
@@ -955,8 +955,7 @@ static int qcm_probe(struct usb_interface *intf,
955 for (j=0; j < interface->desc.bNumEndpoints; j++) { 955 for (j=0; j < interface->desc.bNumEndpoints; j++) {
956 endpoint = &interface->endpoint[j].desc; 956 endpoint = &interface->endpoint[j].desc;
957 957
958 if ((endpoint->bEndpointAddress & 958 if (usb_endpoint_dir_out(endpoint))
959 USB_ENDPOINT_DIR_MASK) != USB_DIR_IN)
960 continue; /* not input then not good */ 959 continue; /* not input then not good */
961 960
962 buffer_size = le16_to_cpu(endpoint->wMaxPacketSize); 961 buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);
@@ -965,9 +964,7 @@ static int qcm_probe(struct usb_interface *intf,
965 continue; /* 0 pkt size is not what we want */ 964 continue; /* 0 pkt size is not what we want */
966 } 965 }
967 966
968 if ((endpoint->bmAttributes & 967 if (usb_endpoint_xfer_isoc(endpoint)) {
969 USB_ENDPOINT_XFERTYPE_MASK) ==
970 USB_ENDPOINT_XFER_ISOC) {
971 video_ep = endpoint->bEndpointAddress; 968 video_ep = endpoint->bEndpointAddress;
972 /* break out of the search */ 969 /* break out of the search */
973 goto good_videoep; 970 goto good_videoep;
diff --git a/drivers/media/video/usbvideo/ultracam.c b/drivers/media/video/usbvideo/ultracam.c
index 9714baab7833..839a08240c25 100644
--- a/drivers/media/video/usbvideo/ultracam.c
+++ b/drivers/media/video/usbvideo/ultracam.c
@@ -556,12 +556,12 @@ static int ultracam_probe(struct usb_interface *intf, const struct usb_device_id
556 err("Alternate settings have different endpoint addresses!"); 556 err("Alternate settings have different endpoint addresses!");
557 return -ENODEV; 557 return -ENODEV;
558 } 558 }
559 if ((endpoint->bmAttributes & 0x03) != 0x01) { 559 if (usb_endpoint_type(endpoint) != USB_ENDPOINT_XFER_ISOC) {
560 err("Interface %d. has non-ISO endpoint!", 560 err("Interface %d. has non-ISO endpoint!",
561 interface->desc.bInterfaceNumber); 561 interface->desc.bInterfaceNumber);
562 return -ENODEV; 562 return -ENODEV;
563 } 563 }
564 if ((endpoint->bEndpointAddress & 0x80) == 0) { 564 if (usb_endpoint_dir_out(endpoint)) {
565 err("Interface %d. has ISO OUT endpoint!", 565 err("Interface %d. has ISO OUT endpoint!",
566 interface->desc.bInterfaceNumber); 566 interface->desc.bInterfaceNumber);
567 return -ENODEV; 567 return -ENODEV;
diff --git a/drivers/media/video/usbvideo/usbvideo.c b/drivers/media/video/usbvideo/usbvideo.c
index 7c575bb8184f..148a1f98c70f 100644
--- a/drivers/media/video/usbvideo/usbvideo.c
+++ b/drivers/media/video/usbvideo/usbvideo.c
@@ -1123,7 +1123,7 @@ static int usbvideo_v4l_open(struct inode *inode, struct file *file)
1123 if (uvd->debug > 1) 1123 if (uvd->debug > 1)
1124 dev_info(&uvd->dev->dev, "%s($%p)\n", __func__, dev); 1124 dev_info(&uvd->dev->dev, "%s($%p)\n", __func__, dev);
1125 1125
1126 if (0 < usbvideo_ClientIncModCount(uvd)) 1126 if (usbvideo_ClientIncModCount(uvd) < 0)
1127 return -ENODEV; 1127 return -ENODEV;
1128 mutex_lock(&uvd->lock); 1128 mutex_lock(&uvd->lock);
1129 1129
@@ -1281,8 +1281,7 @@ static int usbvideo_v4l_close(struct inode *inode, struct file *file)
1281 * History: 1281 * History:
1282 * 22-Jan-2000 Corrected VIDIOCSPICT to reject unsupported settings. 1282 * 22-Jan-2000 Corrected VIDIOCSPICT to reject unsupported settings.
1283 */ 1283 */
1284static int usbvideo_v4l_do_ioctl(struct inode *inode, struct file *file, 1284static int usbvideo_v4l_do_ioctl(struct file *file, unsigned int cmd, void *arg)
1285 unsigned int cmd, void *arg)
1286{ 1285{
1287 struct uvd *uvd = file->private_data; 1286 struct uvd *uvd = file->private_data;
1288 1287
@@ -1505,7 +1504,7 @@ static int usbvideo_v4l_do_ioctl(struct inode *inode, struct file *file,
1505static int usbvideo_v4l_ioctl(struct inode *inode, struct file *file, 1504static int usbvideo_v4l_ioctl(struct inode *inode, struct file *file,
1506 unsigned int cmd, unsigned long arg) 1505 unsigned int cmd, unsigned long arg)
1507{ 1506{
1508 return video_usercopy(inode, file, cmd, arg, usbvideo_v4l_do_ioctl); 1507 return video_usercopy(file, cmd, arg, usbvideo_v4l_do_ioctl);
1509} 1508}
1510 1509
1511/* 1510/*
diff --git a/drivers/media/video/usbvideo/vicam.c b/drivers/media/video/usbvideo/vicam.c
index 8e2d58bec481..4602597ed8d1 100644
--- a/drivers/media/video/usbvideo/vicam.c
+++ b/drivers/media/video/usbvideo/vicam.c
@@ -844,8 +844,7 @@ vicam_probe( struct usb_interface *intf, const struct usb_device_id *id)
844 interface->desc.bInterfaceNumber, (unsigned) (interface->desc.bNumEndpoints)); 844 interface->desc.bInterfaceNumber, (unsigned) (interface->desc.bNumEndpoints));
845 endpoint = &interface->endpoint[0].desc; 845 endpoint = &interface->endpoint[0].desc;
846 846
847 if ((endpoint->bEndpointAddress & 0x80) && 847 if (usb_endpoint_is_bulk_in(endpoint)) {
848 ((endpoint->bmAttributes & 3) == 0x02)) {
849 /* we found a bulk in endpoint */ 848 /* we found a bulk in endpoint */
850 bulkEndpoint = endpoint->bEndpointAddress; 849 bulkEndpoint = endpoint->bEndpointAddress;
851 } else { 850 } else {
diff --git a/drivers/media/video/usbvision/usbvision-video.c b/drivers/media/video/usbvision/usbvision-video.c
index d185b57fdcd0..85661b1848fe 100644
--- a/drivers/media/video/usbvision/usbvision-video.c
+++ b/drivers/media/video/usbvision/usbvision-video.c
@@ -523,7 +523,7 @@ static int vidioc_querycap (struct file *file, void *priv,
523 strlcpy(vc->card, 523 strlcpy(vc->card,
524 usbvision_device_data[usbvision->DevModel].ModelString, 524 usbvision_device_data[usbvision->DevModel].ModelString,
525 sizeof(vc->card)); 525 sizeof(vc->card));
526 strlcpy(vc->bus_info, usbvision->dev->dev.bus_id, 526 strlcpy(vc->bus_info, dev_name(&usbvision->dev->dev),
527 sizeof(vc->bus_info)); 527 sizeof(vc->bus_info));
528 vc->version = USBVISION_DRIVER_VERSION; 528 vc->version = USBVISION_DRIVER_VERSION;
529 vc->capabilities = V4L2_CAP_VIDEO_CAPTURE | 529 vc->capabilities = V4L2_CAP_VIDEO_CAPTURE |
@@ -1278,7 +1278,7 @@ static int usbvision_vbi_close(struct inode *inode, struct file *file)
1278 return -ENODEV; 1278 return -ENODEV;
1279} 1279}
1280 1280
1281static int usbvision_do_vbi_ioctl(struct inode *inode, struct file *file, 1281static int usbvision_do_vbi_ioctl(struct file *file,
1282 unsigned int cmd, void *arg) 1282 unsigned int cmd, void *arg)
1283{ 1283{
1284 /* TODO */ 1284 /* TODO */
@@ -1288,7 +1288,7 @@ static int usbvision_do_vbi_ioctl(struct inode *inode, struct file *file,
1288static int usbvision_vbi_ioctl(struct inode *inode, struct file *file, 1288static int usbvision_vbi_ioctl(struct inode *inode, struct file *file,
1289 unsigned int cmd, unsigned long arg) 1289 unsigned int cmd, unsigned long arg)
1290{ 1290{
1291 return video_usercopy(inode, file, cmd, arg, usbvision_do_vbi_ioctl); 1291 return video_usercopy(file, cmd, arg, usbvision_do_vbi_ioctl);
1292} 1292}
1293 1293
1294 1294
@@ -1679,7 +1679,7 @@ static int __devinit usbvision_probe(struct usb_interface *intf,
1679 interface = &dev->actconfig->interface[ifnum]->altsetting[0]; 1679 interface = &dev->actconfig->interface[ifnum]->altsetting[0];
1680 } 1680 }
1681 endpoint = &interface->endpoint[1].desc; 1681 endpoint = &interface->endpoint[1].desc;
1682 if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != 1682 if (usb_endpoint_type(endpoint) !=
1683 USB_ENDPOINT_XFER_ISOC) { 1683 USB_ENDPOINT_XFER_ISOC) {
1684 err("%s: interface %d. has non-ISO endpoint!", 1684 err("%s: interface %d. has non-ISO endpoint!",
1685 __func__, ifnum); 1685 __func__, ifnum);
@@ -1687,8 +1687,7 @@ static int __devinit usbvision_probe(struct usb_interface *intf,
1687 __func__, endpoint->bmAttributes); 1687 __func__, endpoint->bmAttributes);
1688 return -ENODEV; 1688 return -ENODEV;
1689 } 1689 }
1690 if ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == 1690 if (usb_endpoint_dir_out(endpoint)) {
1691 USB_DIR_OUT) {
1692 err("%s: interface %d. has ISO OUT endpoint!", 1691 err("%s: interface %d. has ISO OUT endpoint!",
1693 __func__, ifnum); 1692 __func__, ifnum);
1694 return -ENODEV; 1693 return -ENODEV;
diff --git a/drivers/media/video/uvc/uvc_ctrl.c b/drivers/media/video/uvc/uvc_ctrl.c
index f16aafe9cf14..2208165aa6f0 100644
--- a/drivers/media/video/uvc/uvc_ctrl.c
+++ b/drivers/media/video/uvc/uvc_ctrl.c
@@ -327,6 +327,31 @@ static struct uvc_menu_info exposure_auto_controls[] = {
327 { 8, "Aperture Priority Mode" }, 327 { 8, "Aperture Priority Mode" },
328}; 328};
329 329
330static __s32 uvc_ctrl_get_zoom(struct uvc_control_mapping *mapping,
331 __u8 query, const __u8 *data)
332{
333 __s8 zoom = (__s8)data[0];
334
335 switch (query) {
336 case GET_CUR:
337 return (zoom == 0) ? 0 : (zoom > 0 ? data[2] : -data[2]);
338
339 case GET_MIN:
340 case GET_MAX:
341 case GET_RES:
342 case GET_DEF:
343 default:
344 return data[2];
345 }
346}
347
348static void uvc_ctrl_set_zoom(struct uvc_control_mapping *mapping,
349 __s32 value, __u8 *data)
350{
351 data[0] = value == 0 ? 0 : (value > 0) ? 1 : 0xff;
352 data[2] = min(abs(value), 0xff);
353}
354
330static struct uvc_control_mapping uvc_ctrl_mappings[] = { 355static struct uvc_control_mapping uvc_ctrl_mappings[] = {
331 { 356 {
332 .id = V4L2_CID_BRIGHTNESS, 357 .id = V4L2_CID_BRIGHTNESS,
@@ -532,6 +557,38 @@ static struct uvc_control_mapping uvc_ctrl_mappings[] = {
532 .v4l2_type = V4L2_CTRL_TYPE_BOOLEAN, 557 .v4l2_type = V4L2_CTRL_TYPE_BOOLEAN,
533 .data_type = UVC_CTRL_DATA_TYPE_BOOLEAN, 558 .data_type = UVC_CTRL_DATA_TYPE_BOOLEAN,
534 }, 559 },
560 {
561 .id = V4L2_CID_ZOOM_ABSOLUTE,
562 .name = "Zoom, Absolute",
563 .entity = UVC_GUID_UVC_CAMERA,
564 .selector = CT_ZOOM_ABSOLUTE_CONTROL,
565 .size = 16,
566 .offset = 0,
567 .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
568 .data_type = UVC_CTRL_DATA_TYPE_UNSIGNED,
569 },
570 {
571 .id = V4L2_CID_ZOOM_CONTINUOUS,
572 .name = "Zoom, Continuous",
573 .entity = UVC_GUID_UVC_CAMERA,
574 .selector = CT_ZOOM_RELATIVE_CONTROL,
575 .size = 0,
576 .offset = 0,
577 .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
578 .data_type = UVC_CTRL_DATA_TYPE_SIGNED,
579 .get = uvc_ctrl_get_zoom,
580 .set = uvc_ctrl_set_zoom,
581 },
582 {
583 .id = V4L2_CID_PRIVACY,
584 .name = "Privacy",
585 .entity = UVC_GUID_UVC_CAMERA,
586 .selector = CT_PRIVACY_CONTROL,
587 .size = 1,
588 .offset = 0,
589 .v4l2_type = V4L2_CTRL_TYPE_BOOLEAN,
590 .data_type = UVC_CTRL_DATA_TYPE_BOOLEAN,
591 },
535}; 592};
536 593
537/* ------------------------------------------------------------------------ 594/* ------------------------------------------------------------------------
@@ -543,18 +600,23 @@ static inline __u8 *uvc_ctrl_data(struct uvc_control *ctrl, int id)
543 return ctrl->data + id * ctrl->info->size; 600 return ctrl->data + id * ctrl->info->size;
544} 601}
545 602
546static inline int uvc_get_bit(const __u8 *data, int bit) 603static inline int uvc_test_bit(const __u8 *data, int bit)
547{ 604{
548 return (data[bit >> 3] >> (bit & 7)) & 1; 605 return (data[bit >> 3] >> (bit & 7)) & 1;
549} 606}
550 607
608static inline void uvc_clear_bit(__u8 *data, int bit)
609{
610 data[bit >> 3] &= ~(1 << (bit & 7));
611}
612
551/* Extract the bit string specified by mapping->offset and mapping->size 613/* Extract the bit string specified by mapping->offset and mapping->size
552 * from the little-endian data stored at 'data' and return the result as 614 * from the little-endian data stored at 'data' and return the result as
553 * a signed 32bit integer. Sign extension will be performed if the mapping 615 * a signed 32bit integer. Sign extension will be performed if the mapping
554 * references a signed data type. 616 * references a signed data type.
555 */ 617 */
556static __s32 uvc_get_le_value(const __u8 *data, 618static __s32 uvc_get_le_value(struct uvc_control_mapping *mapping,
557 struct uvc_control_mapping *mapping) 619 __u8 query, const __u8 *data)
558{ 620{
559 int bits = mapping->size; 621 int bits = mapping->size;
560 int offset = mapping->offset; 622 int offset = mapping->offset;
@@ -583,8 +645,8 @@ static __s32 uvc_get_le_value(const __u8 *data,
583/* Set the bit string specified by mapping->offset and mapping->size 645/* Set the bit string specified by mapping->offset and mapping->size
584 * in the little-endian data stored at 'data' to the value 'value'. 646 * in the little-endian data stored at 'data' to the value 'value'.
585 */ 647 */
586static void uvc_set_le_value(__s32 value, __u8 *data, 648static void uvc_set_le_value(struct uvc_control_mapping *mapping,
587 struct uvc_control_mapping *mapping) 649 __s32 value, __u8 *data)
588{ 650{
589 int bits = mapping->size; 651 int bits = mapping->size;
590 int offset = mapping->offset; 652 int offset = mapping->offset;
@@ -736,7 +798,7 @@ int uvc_query_v4l2_ctrl(struct uvc_video_device *video,
736 video->dev->intfnum, ctrl->info->selector, 798 video->dev->intfnum, ctrl->info->selector,
737 data, ctrl->info->size)) < 0) 799 data, ctrl->info->size)) < 0)
738 goto out; 800 goto out;
739 v4l2_ctrl->default_value = uvc_get_le_value(data, mapping); 801 v4l2_ctrl->default_value = mapping->get(mapping, GET_DEF, data);
740 } 802 }
741 803
742 switch (mapping->v4l2_type) { 804 switch (mapping->v4l2_type) {
@@ -772,21 +834,21 @@ int uvc_query_v4l2_ctrl(struct uvc_video_device *video,
772 video->dev->intfnum, ctrl->info->selector, 834 video->dev->intfnum, ctrl->info->selector,
773 data, ctrl->info->size)) < 0) 835 data, ctrl->info->size)) < 0)
774 goto out; 836 goto out;
775 v4l2_ctrl->minimum = uvc_get_le_value(data, mapping); 837 v4l2_ctrl->minimum = mapping->get(mapping, GET_MIN, data);
776 } 838 }
777 if (ctrl->info->flags & UVC_CONTROL_GET_MAX) { 839 if (ctrl->info->flags & UVC_CONTROL_GET_MAX) {
778 if ((ret = uvc_query_ctrl(video->dev, GET_MAX, ctrl->entity->id, 840 if ((ret = uvc_query_ctrl(video->dev, GET_MAX, ctrl->entity->id,
779 video->dev->intfnum, ctrl->info->selector, 841 video->dev->intfnum, ctrl->info->selector,
780 data, ctrl->info->size)) < 0) 842 data, ctrl->info->size)) < 0)
781 goto out; 843 goto out;
782 v4l2_ctrl->maximum = uvc_get_le_value(data, mapping); 844 v4l2_ctrl->maximum = mapping->get(mapping, GET_MAX, data);
783 } 845 }
784 if (ctrl->info->flags & UVC_CONTROL_GET_RES) { 846 if (ctrl->info->flags & UVC_CONTROL_GET_RES) {
785 if ((ret = uvc_query_ctrl(video->dev, GET_RES, ctrl->entity->id, 847 if ((ret = uvc_query_ctrl(video->dev, GET_RES, ctrl->entity->id,
786 video->dev->intfnum, ctrl->info->selector, 848 video->dev->intfnum, ctrl->info->selector,
787 data, ctrl->info->size)) < 0) 849 data, ctrl->info->size)) < 0)
788 goto out; 850 goto out;
789 v4l2_ctrl->step = uvc_get_le_value(data, mapping); 851 v4l2_ctrl->step = mapping->get(mapping, GET_RES, data);
790 } 852 }
791 853
792 ret = 0; 854 ret = 0;
@@ -923,8 +985,8 @@ int uvc_ctrl_get(struct uvc_video_device *video,
923 ctrl->loaded = 1; 985 ctrl->loaded = 1;
924 } 986 }
925 987
926 xctrl->value = uvc_get_le_value( 988 xctrl->value = mapping->get(mapping, GET_CUR,
927 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT), mapping); 989 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT));
928 990
929 if (mapping->v4l2_type == V4L2_CTRL_TYPE_MENU) { 991 if (mapping->v4l2_type == V4L2_CTRL_TYPE_MENU) {
930 menu = mapping->menu_info; 992 menu = mapping->menu_info;
@@ -980,8 +1042,8 @@ int uvc_ctrl_set(struct uvc_video_device *video,
980 ctrl->info->size); 1042 ctrl->info->size);
981 } 1043 }
982 1044
983 uvc_set_le_value(value, 1045 mapping->set(mapping, value,
984 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT), mapping); 1046 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT));
985 1047
986 ctrl->dirty = 1; 1048 ctrl->dirty = 1;
987 ctrl->modified = 1; 1049 ctrl->modified = 1;
@@ -1257,6 +1319,11 @@ int uvc_ctrl_add_mapping(struct uvc_control_mapping *mapping)
1257 struct uvc_control_mapping *map; 1319 struct uvc_control_mapping *map;
1258 int ret = -EINVAL; 1320 int ret = -EINVAL;
1259 1321
1322 if (mapping->get == NULL)
1323 mapping->get = uvc_get_le_value;
1324 if (mapping->set == NULL)
1325 mapping->set = uvc_set_le_value;
1326
1260 if (mapping->id & ~V4L2_CTRL_ID_MASK) { 1327 if (mapping->id & ~V4L2_CTRL_ID_MASK) {
1261 uvc_trace(UVC_TRACE_CONTROL, "Can't add mapping '%s' with " 1328 uvc_trace(UVC_TRACE_CONTROL, "Can't add mapping '%s' with "
1262 "invalid control id 0x%08x\n", mapping->name, 1329 "invalid control id 0x%08x\n", mapping->name,
@@ -1306,6 +1373,51 @@ end:
1306} 1373}
1307 1374
1308/* 1375/*
1376 * Prune an entity of its bogus controls. This currently includes processing
1377 * unit auto controls for which no corresponding manual control is available.
1378 * Such auto controls make little sense if any, and are known to crash at
1379 * least the SiGma Micro webcam.
1380 */
1381static void
1382uvc_ctrl_prune_entity(struct uvc_entity *entity)
1383{
1384 static const struct {
1385 u8 idx_manual;
1386 u8 idx_auto;
1387 } blacklist[] = {
1388 { 2, 11 }, /* Hue */
1389 { 6, 12 }, /* White Balance Temperature */
1390 { 7, 13 }, /* White Balance Component */
1391 };
1392
1393 u8 *controls;
1394 unsigned int size;
1395 unsigned int i;
1396
1397 if (UVC_ENTITY_TYPE(entity) != VC_PROCESSING_UNIT)
1398 return;
1399
1400 controls = entity->processing.bmControls;
1401 size = entity->processing.bControlSize;
1402
1403 for (i = 0; i < ARRAY_SIZE(blacklist); ++i) {
1404 if (blacklist[i].idx_auto >= 8 * size ||
1405 blacklist[i].idx_manual >= 8 * size)
1406 continue;
1407
1408 if (!uvc_test_bit(controls, blacklist[i].idx_auto) ||
1409 uvc_test_bit(controls, blacklist[i].idx_manual))
1410 continue;
1411
1412 uvc_trace(UVC_TRACE_CONTROL, "Auto control %u/%u has no "
1413 "matching manual control, removing it.\n", entity->id,
1414 blacklist[i].idx_auto);
1415
1416 uvc_clear_bit(controls, blacklist[i].idx_auto);
1417 }
1418}
1419
1420/*
1309 * Initialize device controls. 1421 * Initialize device controls.
1310 */ 1422 */
1311int uvc_ctrl_init_device(struct uvc_device *dev) 1423int uvc_ctrl_init_device(struct uvc_device *dev)
@@ -1331,6 +1443,9 @@ int uvc_ctrl_init_device(struct uvc_device *dev)
1331 bControlSize = entity->camera.bControlSize; 1443 bControlSize = entity->camera.bControlSize;
1332 } 1444 }
1333 1445
1446 if (dev->quirks & UVC_QUIRK_PRUNE_CONTROLS)
1447 uvc_ctrl_prune_entity(entity);
1448
1334 for (i = 0; i < bControlSize; ++i) 1449 for (i = 0; i < bControlSize; ++i)
1335 ncontrols += hweight8(bmControls[i]); 1450 ncontrols += hweight8(bmControls[i]);
1336 1451
@@ -1345,7 +1460,7 @@ int uvc_ctrl_init_device(struct uvc_device *dev)
1345 1460
1346 ctrl = entity->controls; 1461 ctrl = entity->controls;
1347 for (i = 0; i < bControlSize * 8; ++i) { 1462 for (i = 0; i < bControlSize * 8; ++i) {
1348 if (uvc_get_bit(bmControls, i) == 0) 1463 if (uvc_test_bit(bmControls, i) == 0)
1349 continue; 1464 continue;
1350 1465
1351 ctrl->entity = entity; 1466 ctrl->entity = entity;
diff --git a/drivers/media/video/uvc/uvc_driver.c b/drivers/media/video/uvc/uvc_driver.c
index d7ad060640bc..89d8bd10a852 100644
--- a/drivers/media/video/uvc/uvc_driver.c
+++ b/drivers/media/video/uvc/uvc_driver.c
@@ -12,8 +12,8 @@
12 */ 12 */
13 13
14/* 14/*
15 * This driver aims to support video input devices compliant with the 'USB 15 * This driver aims to support video input and ouput devices compliant with the
16 * Video Class' specification. 16 * 'USB Video Class' specification.
17 * 17 *
18 * The driver doesn't support the deprecated v4l1 interface. It implements the 18 * The driver doesn't support the deprecated v4l1 interface. It implements the
19 * mmap capture method only, and doesn't do any image format conversion in 19 * mmap capture method only, and doesn't do any image format conversion in
@@ -32,6 +32,7 @@
32#include <linux/vmalloc.h> 32#include <linux/vmalloc.h>
33#include <linux/wait.h> 33#include <linux/wait.h>
34#include <asm/atomic.h> 34#include <asm/atomic.h>
35#include <asm/unaligned.h>
35 36
36#include <media/v4l2-common.h> 37#include <media/v4l2-common.h>
37 38
@@ -43,6 +44,7 @@
43#define DRIVER_VERSION "v0.1.0" 44#define DRIVER_VERSION "v0.1.0"
44#endif 45#endif
45 46
47unsigned int uvc_no_drop_param;
46static unsigned int uvc_quirks_param; 48static unsigned int uvc_quirks_param;
47unsigned int uvc_trace_param; 49unsigned int uvc_trace_param;
48 50
@@ -288,8 +290,10 @@ static int uvc_parse_format(struct uvc_device *dev,
288 struct uvc_format_desc *fmtdesc; 290 struct uvc_format_desc *fmtdesc;
289 struct uvc_frame *frame; 291 struct uvc_frame *frame;
290 const unsigned char *start = buffer; 292 const unsigned char *start = buffer;
293 unsigned char *_buffer;
291 unsigned int interval; 294 unsigned int interval;
292 unsigned int i, n; 295 unsigned int i, n;
296 int _buflen;
293 __u8 ftype; 297 __u8 ftype;
294 298
295 format->type = buffer[2]; 299 format->type = buffer[2];
@@ -410,12 +414,20 @@ static int uvc_parse_format(struct uvc_device *dev,
410 buflen -= buffer[0]; 414 buflen -= buffer[0];
411 buffer += buffer[0]; 415 buffer += buffer[0];
412 416
417 /* Count the number of frame descriptors to test the bFrameIndex
418 * field when parsing the descriptors. We can't rely on the
419 * bNumFrameDescriptors field as some cameras don't initialize it
420 * properly.
421 */
422 for (_buflen = buflen, _buffer = buffer;
423 _buflen > 2 && _buffer[2] == ftype;
424 _buflen -= _buffer[0], _buffer += _buffer[0])
425 format->nframes++;
426
413 /* Parse the frame descriptors. Only uncompressed, MJPEG and frame 427 /* Parse the frame descriptors. Only uncompressed, MJPEG and frame
414 * based formats have frame descriptors. 428 * based formats have frame descriptors.
415 */ 429 */
416 while (buflen > 2 && buffer[2] == ftype) { 430 while (buflen > 2 && buffer[2] == ftype) {
417 frame = &format->frame[format->nframes];
418
419 if (ftype != VS_FRAME_FRAME_BASED) 431 if (ftype != VS_FRAME_FRAME_BASED)
420 n = buflen > 25 ? buffer[25] : 0; 432 n = buflen > 25 ? buffer[25] : 0;
421 else 433 else
@@ -430,22 +442,32 @@ static int uvc_parse_format(struct uvc_device *dev,
430 return -EINVAL; 442 return -EINVAL;
431 } 443 }
432 444
445 if (buffer[3] - 1 >= format->nframes) {
446 uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming"
447 "interface %d frame index %u out of range\n",
448 dev->udev->devnum, alts->desc.bInterfaceNumber,
449 buffer[3]);
450 return -EINVAL;
451 }
452
453 frame = &format->frame[buffer[3] - 1];
454
433 frame->bFrameIndex = buffer[3]; 455 frame->bFrameIndex = buffer[3];
434 frame->bmCapabilities = buffer[4]; 456 frame->bmCapabilities = buffer[4];
435 frame->wWidth = le16_to_cpup((__le16 *)&buffer[5]); 457 frame->wWidth = get_unaligned_le16(&buffer[5]);
436 frame->wHeight = le16_to_cpup((__le16 *)&buffer[7]); 458 frame->wHeight = get_unaligned_le16(&buffer[7]);
437 frame->dwMinBitRate = le32_to_cpup((__le32 *)&buffer[9]); 459 frame->dwMinBitRate = get_unaligned_le32(&buffer[9]);
438 frame->dwMaxBitRate = le32_to_cpup((__le32 *)&buffer[13]); 460 frame->dwMaxBitRate = get_unaligned_le32(&buffer[13]);
439 if (ftype != VS_FRAME_FRAME_BASED) { 461 if (ftype != VS_FRAME_FRAME_BASED) {
440 frame->dwMaxVideoFrameBufferSize = 462 frame->dwMaxVideoFrameBufferSize =
441 le32_to_cpup((__le32 *)&buffer[17]); 463 get_unaligned_le32(&buffer[17]);
442 frame->dwDefaultFrameInterval = 464 frame->dwDefaultFrameInterval =
443 le32_to_cpup((__le32 *)&buffer[21]); 465 get_unaligned_le32(&buffer[21]);
444 frame->bFrameIntervalType = buffer[25]; 466 frame->bFrameIntervalType = buffer[25];
445 } else { 467 } else {
446 frame->dwMaxVideoFrameBufferSize = 0; 468 frame->dwMaxVideoFrameBufferSize = 0;
447 frame->dwDefaultFrameInterval = 469 frame->dwDefaultFrameInterval =
448 le32_to_cpup((__le32 *)&buffer[17]); 470 get_unaligned_le32(&buffer[17]);
449 frame->bFrameIntervalType = buffer[21]; 471 frame->bFrameIntervalType = buffer[21];
450 } 472 }
451 frame->dwFrameInterval = *intervals; 473 frame->dwFrameInterval = *intervals;
@@ -468,7 +490,7 @@ static int uvc_parse_format(struct uvc_device *dev,
468 * some other divisions by zero which could happen. 490 * some other divisions by zero which could happen.
469 */ 491 */
470 for (i = 0; i < n; ++i) { 492 for (i = 0; i < n; ++i) {
471 interval = le32_to_cpup((__le32 *)&buffer[26+4*i]); 493 interval = get_unaligned_le32(&buffer[26+4*i]);
472 *(*intervals)++ = interval ? interval : 1; 494 *(*intervals)++ = interval ? interval : 1;
473 } 495 }
474 496
@@ -486,7 +508,6 @@ static int uvc_parse_format(struct uvc_device *dev,
486 10000000/frame->dwDefaultFrameInterval, 508 10000000/frame->dwDefaultFrameInterval,
487 (100000000/frame->dwDefaultFrameInterval)%10); 509 (100000000/frame->dwDefaultFrameInterval)%10);
488 510
489 format->nframes++;
490 buflen -= buffer[0]; 511 buflen -= buffer[0];
491 buffer += buffer[0]; 512 buffer += buffer[0];
492 } 513 }
@@ -588,46 +609,55 @@ static int uvc_parse_streaming(struct uvc_device *dev,
588 } 609 }
589 610
590 /* Parse the header descriptor. */ 611 /* Parse the header descriptor. */
591 if (buffer[2] == VS_OUTPUT_HEADER) { 612 switch (buffer[2]) {
613 case VS_OUTPUT_HEADER:
614 streaming->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
615 size = 9;
616 break;
617
618 case VS_INPUT_HEADER:
619 streaming->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
620 size = 13;
621 break;
622
623 default:
592 uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming interface " 624 uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming interface "
593 "%d OUTPUT HEADER descriptor is not supported.\n", 625 "%d HEADER descriptor not found.\n", dev->udev->devnum,
594 dev->udev->devnum, alts->desc.bInterfaceNumber); 626 alts->desc.bInterfaceNumber);
595 goto error; 627 goto error;
596 } else if (buffer[2] == VS_INPUT_HEADER) { 628 }
597 p = buflen >= 5 ? buffer[3] : 0;
598 n = buflen >= 12 ? buffer[12] : 0;
599 629
600 if (buflen < 13 + p*n || buffer[2] != VS_INPUT_HEADER) { 630 p = buflen >= 4 ? buffer[3] : 0;
601 uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming " 631 n = buflen >= size ? buffer[size-1] : 0;
602 "interface %d INPUT HEADER descriptor is " 632
603 "invalid.\n", dev->udev->devnum, 633 if (buflen < size + p*n) {
604 alts->desc.bInterfaceNumber); 634 uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming "
605 goto error; 635 "interface %d HEADER descriptor is invalid.\n",
606 } 636 dev->udev->devnum, alts->desc.bInterfaceNumber);
637 goto error;
638 }
607 639
608 streaming->header.bNumFormats = p; 640 streaming->header.bNumFormats = p;
609 streaming->header.bEndpointAddress = buffer[6]; 641 streaming->header.bEndpointAddress = buffer[6];
642 if (buffer[2] == VS_INPUT_HEADER) {
610 streaming->header.bmInfo = buffer[7]; 643 streaming->header.bmInfo = buffer[7];
611 streaming->header.bTerminalLink = buffer[8]; 644 streaming->header.bTerminalLink = buffer[8];
612 streaming->header.bStillCaptureMethod = buffer[9]; 645 streaming->header.bStillCaptureMethod = buffer[9];
613 streaming->header.bTriggerSupport = buffer[10]; 646 streaming->header.bTriggerSupport = buffer[10];
614 streaming->header.bTriggerUsage = buffer[11]; 647 streaming->header.bTriggerUsage = buffer[11];
615 streaming->header.bControlSize = n;
616
617 streaming->header.bmaControls = kmalloc(p*n, GFP_KERNEL);
618 if (streaming->header.bmaControls == NULL) {
619 ret = -ENOMEM;
620 goto error;
621 }
622
623 memcpy(streaming->header.bmaControls, &buffer[13], p*n);
624 } else { 648 } else {
625 uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming interface " 649 streaming->header.bTerminalLink = buffer[7];
626 "%d HEADER descriptor not found.\n", dev->udev->devnum, 650 }
627 alts->desc.bInterfaceNumber); 651 streaming->header.bControlSize = n;
652
653 streaming->header.bmaControls = kmalloc(p*n, GFP_KERNEL);
654 if (streaming->header.bmaControls == NULL) {
655 ret = -ENOMEM;
628 goto error; 656 goto error;
629 } 657 }
630 658
659 memcpy(streaming->header.bmaControls, &buffer[size], p*n);
660
631 buflen -= buffer[0]; 661 buflen -= buffer[0];
632 buffer += buffer[0]; 662 buffer += buffer[0];
633 663
@@ -813,8 +843,7 @@ static int uvc_parse_vendor_control(struct uvc_device *dev,
813 unit->type = VC_EXTENSION_UNIT; 843 unit->type = VC_EXTENSION_UNIT;
814 memcpy(unit->extension.guidExtensionCode, &buffer[4], 16); 844 memcpy(unit->extension.guidExtensionCode, &buffer[4], 16);
815 unit->extension.bNumControls = buffer[20]; 845 unit->extension.bNumControls = buffer[20];
816 unit->extension.bNrInPins = 846 unit->extension.bNrInPins = get_unaligned_le16(&buffer[21]);
817 le16_to_cpup((__le16 *)&buffer[21]);
818 unit->extension.baSourceID = (__u8 *)unit + sizeof *unit; 847 unit->extension.baSourceID = (__u8 *)unit + sizeof *unit;
819 memcpy(unit->extension.baSourceID, &buffer[22], p); 848 memcpy(unit->extension.baSourceID, &buffer[22], p);
820 unit->extension.bControlSize = buffer[22+p]; 849 unit->extension.bControlSize = buffer[22+p];
@@ -858,8 +887,8 @@ static int uvc_parse_standard_control(struct uvc_device *dev,
858 return -EINVAL; 887 return -EINVAL;
859 } 888 }
860 889
861 dev->uvc_version = le16_to_cpup((__le16 *)&buffer[3]); 890 dev->uvc_version = get_unaligned_le16(&buffer[3]);
862 dev->clock_frequency = le32_to_cpup((__le32 *)&buffer[7]); 891 dev->clock_frequency = get_unaligned_le32(&buffer[7]);
863 892
864 /* Parse all USB Video Streaming interfaces. */ 893 /* Parse all USB Video Streaming interfaces. */
865 for (i = 0; i < n; ++i) { 894 for (i = 0; i < n; ++i) {
@@ -886,7 +915,7 @@ static int uvc_parse_standard_control(struct uvc_device *dev,
886 /* Make sure the terminal type MSB is not null, otherwise it 915 /* Make sure the terminal type MSB is not null, otherwise it
887 * could be confused with a unit. 916 * could be confused with a unit.
888 */ 917 */
889 type = le16_to_cpup((__le16 *)&buffer[4]); 918 type = get_unaligned_le16(&buffer[4]);
890 if ((type & 0xff00) == 0) { 919 if ((type & 0xff00) == 0) {
891 uvc_trace(UVC_TRACE_DESCR, "device %d videocontrol " 920 uvc_trace(UVC_TRACE_DESCR, "device %d videocontrol "
892 "interface %d INPUT_TERMINAL %d has invalid " 921 "interface %d INPUT_TERMINAL %d has invalid "
@@ -928,11 +957,11 @@ static int uvc_parse_standard_control(struct uvc_device *dev,
928 term->camera.bControlSize = n; 957 term->camera.bControlSize = n;
929 term->camera.bmControls = (__u8 *)term + sizeof *term; 958 term->camera.bmControls = (__u8 *)term + sizeof *term;
930 term->camera.wObjectiveFocalLengthMin = 959 term->camera.wObjectiveFocalLengthMin =
931 le16_to_cpup((__le16 *)&buffer[8]); 960 get_unaligned_le16(&buffer[8]);
932 term->camera.wObjectiveFocalLengthMax = 961 term->camera.wObjectiveFocalLengthMax =
933 le16_to_cpup((__le16 *)&buffer[10]); 962 get_unaligned_le16(&buffer[10]);
934 term->camera.wOcularFocalLength = 963 term->camera.wOcularFocalLength =
935 le16_to_cpup((__le16 *)&buffer[12]); 964 get_unaligned_le16(&buffer[12]);
936 memcpy(term->camera.bmControls, &buffer[15], n); 965 memcpy(term->camera.bmControls, &buffer[15], n);
937 } else if (UVC_ENTITY_TYPE(term) == ITT_MEDIA_TRANSPORT_INPUT) { 966 } else if (UVC_ENTITY_TYPE(term) == ITT_MEDIA_TRANSPORT_INPUT) {
938 term->media.bControlSize = n; 967 term->media.bControlSize = n;
@@ -968,7 +997,7 @@ static int uvc_parse_standard_control(struct uvc_device *dev,
968 /* Make sure the terminal type MSB is not null, otherwise it 997 /* Make sure the terminal type MSB is not null, otherwise it
969 * could be confused with a unit. 998 * could be confused with a unit.
970 */ 999 */
971 type = le16_to_cpup((__le16 *)&buffer[4]); 1000 type = get_unaligned_le16(&buffer[4]);
972 if ((type & 0xff00) == 0) { 1001 if ((type & 0xff00) == 0) {
973 uvc_trace(UVC_TRACE_DESCR, "device %d videocontrol " 1002 uvc_trace(UVC_TRACE_DESCR, "device %d videocontrol "
974 "interface %d OUTPUT_TERMINAL %d has invalid " 1003 "interface %d OUTPUT_TERMINAL %d has invalid "
@@ -1042,7 +1071,7 @@ static int uvc_parse_standard_control(struct uvc_device *dev,
1042 unit->type = buffer[2]; 1071 unit->type = buffer[2];
1043 unit->processing.bSourceID = buffer[4]; 1072 unit->processing.bSourceID = buffer[4];
1044 unit->processing.wMaxMultiplier = 1073 unit->processing.wMaxMultiplier =
1045 le16_to_cpup((__le16 *)&buffer[5]); 1074 get_unaligned_le16(&buffer[5]);
1046 unit->processing.bControlSize = buffer[7]; 1075 unit->processing.bControlSize = buffer[7];
1047 unit->processing.bmControls = (__u8 *)unit + sizeof *unit; 1076 unit->processing.bmControls = (__u8 *)unit + sizeof *unit;
1048 memcpy(unit->processing.bmControls, &buffer[8], n); 1077 memcpy(unit->processing.bmControls, &buffer[8], n);
@@ -1077,8 +1106,7 @@ static int uvc_parse_standard_control(struct uvc_device *dev,
1077 unit->type = buffer[2]; 1106 unit->type = buffer[2];
1078 memcpy(unit->extension.guidExtensionCode, &buffer[4], 16); 1107 memcpy(unit->extension.guidExtensionCode, &buffer[4], 16);
1079 unit->extension.bNumControls = buffer[20]; 1108 unit->extension.bNumControls = buffer[20];
1080 unit->extension.bNrInPins = 1109 unit->extension.bNrInPins = get_unaligned_le16(&buffer[21]);
1081 le16_to_cpup((__le16 *)&buffer[21]);
1082 unit->extension.baSourceID = (__u8 *)unit + sizeof *unit; 1110 unit->extension.baSourceID = (__u8 *)unit + sizeof *unit;
1083 memcpy(unit->extension.baSourceID, &buffer[22], p); 1111 memcpy(unit->extension.baSourceID, &buffer[22], p);
1084 unit->extension.bControlSize = buffer[22+p]; 1112 unit->extension.bControlSize = buffer[22+p];
@@ -1128,8 +1156,13 @@ next_descriptor:
1128 buffer += buffer[0]; 1156 buffer += buffer[0];
1129 } 1157 }
1130 1158
1131 /* Check if the optional status endpoint is present. */ 1159 /* Check if the optional status endpoint is present. Built-in iSight
1132 if (alts->desc.bNumEndpoints == 1) { 1160 * webcams have an interrupt endpoint but spit proprietary data that
1161 * don't conform to the UVC status endpoint messages. Don't try to
1162 * handle the interrupt endpoint for those cameras.
1163 */
1164 if (alts->desc.bNumEndpoints == 1 &&
1165 !(dev->quirks & UVC_QUIRK_BUILTIN_ISIGHT)) {
1133 struct usb_host_endpoint *ep = &alts->endpoint[0]; 1166 struct usb_host_endpoint *ep = &alts->endpoint[0];
1134 struct usb_endpoint_descriptor *desc = &ep->desc; 1167 struct usb_endpoint_descriptor *desc = &ep->desc;
1135 1168
@@ -1234,6 +1267,26 @@ static int uvc_scan_chain_entity(struct uvc_video_device *video,
1234 list_add_tail(&entity->chain, &video->iterms); 1267 list_add_tail(&entity->chain, &video->iterms);
1235 break; 1268 break;
1236 1269
1270 case TT_STREAMING:
1271 if (uvc_trace_param & UVC_TRACE_PROBE)
1272 printk(" <- IT %d\n", entity->id);
1273
1274 if (!UVC_ENTITY_IS_ITERM(entity)) {
1275 uvc_trace(UVC_TRACE_DESCR, "Unsupported input "
1276 "terminal %u.\n", entity->id);
1277 return -1;
1278 }
1279
1280 if (video->sterm != NULL) {
1281 uvc_trace(UVC_TRACE_DESCR, "Found multiple streaming "
1282 "entities in chain.\n");
1283 return -1;
1284 }
1285
1286 list_add_tail(&entity->chain, &video->iterms);
1287 video->sterm = entity;
1288 break;
1289
1237 default: 1290 default:
1238 uvc_trace(UVC_TRACE_DESCR, "Unsupported entity type " 1291 uvc_trace(UVC_TRACE_DESCR, "Unsupported entity type "
1239 "0x%04x found in chain.\n", UVC_ENTITY_TYPE(entity)); 1292 "0x%04x found in chain.\n", UVC_ENTITY_TYPE(entity));
@@ -1344,6 +1397,10 @@ static int uvc_scan_chain(struct uvc_video_device *video)
1344 1397
1345 entity = video->oterm; 1398 entity = video->oterm;
1346 uvc_trace(UVC_TRACE_PROBE, "Scanning UVC chain: OT %d", entity->id); 1399 uvc_trace(UVC_TRACE_PROBE, "Scanning UVC chain: OT %d", entity->id);
1400
1401 if (UVC_ENTITY_TYPE(entity) == TT_STREAMING)
1402 video->sterm = entity;
1403
1347 id = entity->output.bSourceID; 1404 id = entity->output.bSourceID;
1348 while (id != 0) { 1405 while (id != 0) {
1349 prev = entity; 1406 prev = entity;
@@ -1372,8 +1429,11 @@ static int uvc_scan_chain(struct uvc_video_device *video)
1372 return id; 1429 return id;
1373 } 1430 }
1374 1431
1375 /* Initialize the video buffers queue. */ 1432 if (video->sterm == NULL) {
1376 uvc_queue_init(&video->queue); 1433 uvc_trace(UVC_TRACE_DESCR, "No streaming entity found in "
1434 "chain.\n");
1435 return -1;
1436 }
1377 1437
1378 return 0; 1438 return 0;
1379} 1439}
@@ -1384,7 +1444,8 @@ static int uvc_scan_chain(struct uvc_video_device *video)
1384 * The driver currently supports a single video device per control interface 1444 * The driver currently supports a single video device per control interface
1385 * only. The terminal and units must match the following structure: 1445 * only. The terminal and units must match the following structure:
1386 * 1446 *
1387 * ITT_CAMERA -> VC_PROCESSING_UNIT -> VC_EXTENSION_UNIT{0,n} -> TT_STREAMING 1447 * ITT_* -> VC_PROCESSING_UNIT -> VC_EXTENSION_UNIT{0,n} -> TT_STREAMING
1448 * TT_STREAMING -> VC_PROCESSING_UNIT -> VC_EXTENSION_UNIT{0,n} -> OTT_*
1388 * 1449 *
1389 * The Extension Units, if present, must have a single input pin. The 1450 * The Extension Units, if present, must have a single input pin. The
1390 * Processing Unit and Extension Units can be in any order. Additional 1451 * Processing Unit and Extension Units can be in any order. Additional
@@ -1401,7 +1462,7 @@ static int uvc_register_video(struct uvc_device *dev)
1401 list_for_each_entry(term, &dev->entities, list) { 1462 list_for_each_entry(term, &dev->entities, list) {
1402 struct uvc_streaming *streaming; 1463 struct uvc_streaming *streaming;
1403 1464
1404 if (UVC_ENTITY_TYPE(term) != TT_STREAMING) 1465 if (!UVC_ENTITY_IS_TERM(term) || !UVC_ENTITY_IS_OTERM(term))
1405 continue; 1466 continue;
1406 1467
1407 memset(&dev->video, 0, sizeof dev->video); 1468 memset(&dev->video, 0, sizeof dev->video);
@@ -1414,7 +1475,8 @@ static int uvc_register_video(struct uvc_device *dev)
1414 continue; 1475 continue;
1415 1476
1416 list_for_each_entry(streaming, &dev->streaming, list) { 1477 list_for_each_entry(streaming, &dev->streaming, list) {
1417 if (streaming->header.bTerminalLink == term->id) { 1478 if (streaming->header.bTerminalLink ==
1479 dev->video.sterm->id) {
1418 dev->video.streaming = streaming; 1480 dev->video.streaming = streaming;
1419 found = 1; 1481 found = 1;
1420 break; 1482 break;
@@ -1440,6 +1502,9 @@ static int uvc_register_video(struct uvc_device *dev)
1440 printk(" -> %d).\n", dev->video.oterm->id); 1502 printk(" -> %d).\n", dev->video.oterm->id);
1441 } 1503 }
1442 1504
1505 /* Initialize the video buffers queue. */
1506 uvc_queue_init(&dev->video.queue, dev->video.streaming->type);
1507
1443 /* Initialize the streaming interface with default streaming 1508 /* Initialize the streaming interface with default streaming
1444 * parameters. 1509 * parameters.
1445 */ 1510 */
@@ -1707,24 +1772,6 @@ static int uvc_reset_resume(struct usb_interface *intf)
1707 * though they are compliant. 1772 * though they are compliant.
1708 */ 1773 */
1709static struct usb_device_id uvc_ids[] = { 1774static struct usb_device_id uvc_ids[] = {
1710 /* ALi M5606 (Clevo M540SR) */
1711 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
1712 | USB_DEVICE_ID_MATCH_INT_INFO,
1713 .idVendor = 0x0402,
1714 .idProduct = 0x5606,
1715 .bInterfaceClass = USB_CLASS_VIDEO,
1716 .bInterfaceSubClass = 1,
1717 .bInterfaceProtocol = 0,
1718 .driver_info = UVC_QUIRK_PROBE_MINMAX },
1719 /* Creative Live! Optia */
1720 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
1721 | USB_DEVICE_ID_MATCH_INT_INFO,
1722 .idVendor = 0x041e,
1723 .idProduct = 0x4057,
1724 .bInterfaceClass = USB_CLASS_VIDEO,
1725 .bInterfaceSubClass = 1,
1726 .bInterfaceProtocol = 0,
1727 .driver_info = UVC_QUIRK_PROBE_MINMAX },
1728 /* Microsoft Lifecam NX-6000 */ 1775 /* Microsoft Lifecam NX-6000 */
1729 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE 1776 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
1730 | USB_DEVICE_ID_MATCH_INT_INFO, 1777 | USB_DEVICE_ID_MATCH_INT_INFO,
@@ -1810,15 +1857,6 @@ static struct usb_device_id uvc_ids[] = {
1810 .bInterfaceSubClass = 1, 1857 .bInterfaceSubClass = 1,
1811 .bInterfaceProtocol = 0, 1858 .bInterfaceProtocol = 0,
1812 .driver_info = UVC_QUIRK_STREAM_NO_FID }, 1859 .driver_info = UVC_QUIRK_STREAM_NO_FID },
1813 /* Silicon Motion SM371 */
1814 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
1815 | USB_DEVICE_ID_MATCH_INT_INFO,
1816 .idVendor = 0x090c,
1817 .idProduct = 0xb371,
1818 .bInterfaceClass = USB_CLASS_VIDEO,
1819 .bInterfaceSubClass = 1,
1820 .bInterfaceProtocol = 0,
1821 .driver_info = UVC_QUIRK_PROBE_MINMAX },
1822 /* MT6227 */ 1860 /* MT6227 */
1823 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE 1861 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
1824 | USB_DEVICE_ID_MATCH_INT_INFO, 1862 | USB_DEVICE_ID_MATCH_INT_INFO,
@@ -1837,6 +1875,15 @@ static struct usb_device_id uvc_ids[] = {
1837 .bInterfaceSubClass = 1, 1875 .bInterfaceSubClass = 1,
1838 .bInterfaceProtocol = 0, 1876 .bInterfaceProtocol = 0,
1839 .driver_info = UVC_QUIRK_STREAM_NO_FID }, 1877 .driver_info = UVC_QUIRK_STREAM_NO_FID },
1878 /* Syntek (Samsung Q310) */
1879 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
1880 | USB_DEVICE_ID_MATCH_INT_INFO,
1881 .idVendor = 0x174f,
1882 .idProduct = 0x5931,
1883 .bInterfaceClass = USB_CLASS_VIDEO,
1884 .bInterfaceSubClass = 1,
1885 .bInterfaceProtocol = 0,
1886 .driver_info = UVC_QUIRK_STREAM_NO_FID },
1840 /* Asus F9SG */ 1887 /* Asus F9SG */
1841 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE 1888 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
1842 | USB_DEVICE_ID_MATCH_INT_INFO, 1889 | USB_DEVICE_ID_MATCH_INT_INFO,
@@ -1855,6 +1902,15 @@ static struct usb_device_id uvc_ids[] = {
1855 .bInterfaceSubClass = 1, 1902 .bInterfaceSubClass = 1,
1856 .bInterfaceProtocol = 0, 1903 .bInterfaceProtocol = 0,
1857 .driver_info = UVC_QUIRK_STREAM_NO_FID }, 1904 .driver_info = UVC_QUIRK_STREAM_NO_FID },
1905 /* Lenovo Thinkpad SL500 */
1906 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
1907 | USB_DEVICE_ID_MATCH_INT_INFO,
1908 .idVendor = 0x17ef,
1909 .idProduct = 0x480b,
1910 .bInterfaceClass = USB_CLASS_VIDEO,
1911 .bInterfaceSubClass = 1,
1912 .bInterfaceProtocol = 0,
1913 .driver_info = UVC_QUIRK_STREAM_NO_FID },
1858 /* Ecamm Pico iMage */ 1914 /* Ecamm Pico iMage */
1859 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE 1915 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
1860 | USB_DEVICE_ID_MATCH_INT_INFO, 1916 | USB_DEVICE_ID_MATCH_INT_INFO,
@@ -1884,106 +1940,8 @@ static struct usb_device_id uvc_ids[] = {
1884 .bInterfaceSubClass = 1, 1940 .bInterfaceSubClass = 1,
1885 .bInterfaceProtocol = 0, 1941 .bInterfaceProtocol = 0,
1886 .driver_info = UVC_QUIRK_PROBE_MINMAX 1942 .driver_info = UVC_QUIRK_PROBE_MINMAX
1887 | UVC_QUIRK_IGNORE_SELECTOR_UNIT}, 1943 | UVC_QUIRK_IGNORE_SELECTOR_UNIT
1888 /* Acer OEM Webcam - Unknown vendor */ 1944 | UVC_QUIRK_PRUNE_CONTROLS },
1889 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
1890 | USB_DEVICE_ID_MATCH_INT_INFO,
1891 .idVendor = 0x5986,
1892 .idProduct = 0x0100,
1893 .bInterfaceClass = USB_CLASS_VIDEO,
1894 .bInterfaceSubClass = 1,
1895 .bInterfaceProtocol = 0,
1896 .driver_info = UVC_QUIRK_PROBE_MINMAX },
1897 /* Packard Bell OEM Webcam - Bison Electronics */
1898 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
1899 | USB_DEVICE_ID_MATCH_INT_INFO,
1900 .idVendor = 0x5986,
1901 .idProduct = 0x0101,
1902 .bInterfaceClass = USB_CLASS_VIDEO,
1903 .bInterfaceSubClass = 1,
1904 .bInterfaceProtocol = 0,
1905 .driver_info = UVC_QUIRK_PROBE_MINMAX },
1906 /* Acer Crystal Eye webcam - Bison Electronics */
1907 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
1908 | USB_DEVICE_ID_MATCH_INT_INFO,
1909 .idVendor = 0x5986,
1910 .idProduct = 0x0102,
1911 .bInterfaceClass = USB_CLASS_VIDEO,
1912 .bInterfaceSubClass = 1,
1913 .bInterfaceProtocol = 0,
1914 .driver_info = UVC_QUIRK_PROBE_MINMAX },
1915 /* Compaq Presario B1200 - Bison Electronics */
1916 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
1917 | USB_DEVICE_ID_MATCH_INT_INFO,
1918 .idVendor = 0x5986,
1919 .idProduct = 0x0104,
1920 .bInterfaceClass = USB_CLASS_VIDEO,
1921 .bInterfaceSubClass = 1,
1922 .bInterfaceProtocol = 0,
1923 .driver_info = UVC_QUIRK_PROBE_MINMAX },
1924 /* Acer Travelmate 7720 - Bison Electronics */
1925 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
1926 | USB_DEVICE_ID_MATCH_INT_INFO,
1927 .idVendor = 0x5986,
1928 .idProduct = 0x0105,
1929 .bInterfaceClass = USB_CLASS_VIDEO,
1930 .bInterfaceSubClass = 1,
1931 .bInterfaceProtocol = 0,
1932 .driver_info = UVC_QUIRK_PROBE_MINMAX },
1933 /* Medion Akoya Mini E1210 - Bison Electronics */
1934 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
1935 | USB_DEVICE_ID_MATCH_INT_INFO,
1936 .idVendor = 0x5986,
1937 .idProduct = 0x0141,
1938 .bInterfaceClass = USB_CLASS_VIDEO,
1939 .bInterfaceSubClass = 1,
1940 .bInterfaceProtocol = 0,
1941 .driver_info = UVC_QUIRK_PROBE_MINMAX },
1942 /* Acer OrbiCam - Bison Electronics */
1943 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
1944 | USB_DEVICE_ID_MATCH_INT_INFO,
1945 .idVendor = 0x5986,
1946 .idProduct = 0x0200,
1947 .bInterfaceClass = USB_CLASS_VIDEO,
1948 .bInterfaceSubClass = 1,
1949 .bInterfaceProtocol = 0,
1950 .driver_info = UVC_QUIRK_PROBE_MINMAX },
1951 /* Fujitsu Amilo SI2636 - Bison Electronics */
1952 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
1953 | USB_DEVICE_ID_MATCH_INT_INFO,
1954 .idVendor = 0x5986,
1955 .idProduct = 0x0202,
1956 .bInterfaceClass = USB_CLASS_VIDEO,
1957 .bInterfaceSubClass = 1,
1958 .bInterfaceProtocol = 0,
1959 .driver_info = UVC_QUIRK_PROBE_MINMAX },
1960 /* Advent 4211 - Bison Electronics */
1961 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
1962 | USB_DEVICE_ID_MATCH_INT_INFO,
1963 .idVendor = 0x5986,
1964 .idProduct = 0x0203,
1965 .bInterfaceClass = USB_CLASS_VIDEO,
1966 .bInterfaceSubClass = 1,
1967 .bInterfaceProtocol = 0,
1968 .driver_info = UVC_QUIRK_PROBE_MINMAX },
1969 /* Bison Electronics */
1970 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
1971 | USB_DEVICE_ID_MATCH_INT_INFO,
1972 .idVendor = 0x5986,
1973 .idProduct = 0x0300,
1974 .bInterfaceClass = USB_CLASS_VIDEO,
1975 .bInterfaceSubClass = 1,
1976 .bInterfaceProtocol = 0,
1977 .driver_info = UVC_QUIRK_PROBE_MINMAX },
1978 /* Clevo M570TU - Bison Electronics */
1979 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
1980 | USB_DEVICE_ID_MATCH_INT_INFO,
1981 .idVendor = 0x5986,
1982 .idProduct = 0x0303,
1983 .bInterfaceClass = USB_CLASS_VIDEO,
1984 .bInterfaceSubClass = 1,
1985 .bInterfaceProtocol = 0,
1986 .driver_info = UVC_QUIRK_PROBE_MINMAX },
1987 /* Generic USB Video Class */ 1945 /* Generic USB Video Class */
1988 { USB_INTERFACE_INFO(USB_CLASS_VIDEO, 1, 0) }, 1946 { USB_INTERFACE_INFO(USB_CLASS_VIDEO, 1, 0) },
1989 {} 1947 {}
@@ -2029,6 +1987,8 @@ static void __exit uvc_cleanup(void)
2029module_init(uvc_init); 1987module_init(uvc_init);
2030module_exit(uvc_cleanup); 1988module_exit(uvc_cleanup);
2031 1989
1990module_param_named(nodrop, uvc_no_drop_param, uint, S_IRUGO|S_IWUSR);
1991MODULE_PARM_DESC(nodrop, "Don't drop incomplete frames");
2032module_param_named(quirks, uvc_quirks_param, uint, S_IRUGO|S_IWUSR); 1992module_param_named(quirks, uvc_quirks_param, uint, S_IRUGO|S_IWUSR);
2033MODULE_PARM_DESC(quirks, "Forced device quirks"); 1993MODULE_PARM_DESC(quirks, "Forced device quirks");
2034module_param_named(trace, uvc_trace_param, uint, S_IRUGO|S_IWUSR); 1994module_param_named(trace, uvc_trace_param, uint, S_IRUGO|S_IWUSR);
diff --git a/drivers/media/video/uvc/uvc_queue.c b/drivers/media/video/uvc/uvc_queue.c
index 5646a6a32939..42546342e97d 100644
--- a/drivers/media/video/uvc/uvc_queue.c
+++ b/drivers/media/video/uvc/uvc_queue.c
@@ -79,12 +79,13 @@
79 * 79 *
80 */ 80 */
81 81
82void uvc_queue_init(struct uvc_video_queue *queue) 82void uvc_queue_init(struct uvc_video_queue *queue, enum v4l2_buf_type type)
83{ 83{
84 mutex_init(&queue->mutex); 84 mutex_init(&queue->mutex);
85 spin_lock_init(&queue->irqlock); 85 spin_lock_init(&queue->irqlock);
86 INIT_LIST_HEAD(&queue->mainqueue); 86 INIT_LIST_HEAD(&queue->mainqueue);
87 INIT_LIST_HEAD(&queue->irqqueue); 87 INIT_LIST_HEAD(&queue->irqqueue);
88 queue->type = type;
88} 89}
89 90
90/* 91/*
@@ -132,7 +133,7 @@ int uvc_alloc_buffers(struct uvc_video_queue *queue, unsigned int nbuffers,
132 queue->buffer[i].buf.index = i; 133 queue->buffer[i].buf.index = i;
133 queue->buffer[i].buf.m.offset = i * bufsize; 134 queue->buffer[i].buf.m.offset = i * bufsize;
134 queue->buffer[i].buf.length = buflength; 135 queue->buffer[i].buf.length = buflength;
135 queue->buffer[i].buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 136 queue->buffer[i].buf.type = queue->type;
136 queue->buffer[i].buf.sequence = 0; 137 queue->buffer[i].buf.sequence = 0;
137 queue->buffer[i].buf.field = V4L2_FIELD_NONE; 138 queue->buffer[i].buf.field = V4L2_FIELD_NONE;
138 queue->buffer[i].buf.memory = V4L2_MEMORY_MMAP; 139 queue->buffer[i].buf.memory = V4L2_MEMORY_MMAP;
@@ -226,7 +227,7 @@ int uvc_queue_buffer(struct uvc_video_queue *queue,
226 227
227 uvc_trace(UVC_TRACE_CAPTURE, "Queuing buffer %u.\n", v4l2_buf->index); 228 uvc_trace(UVC_TRACE_CAPTURE, "Queuing buffer %u.\n", v4l2_buf->index);
228 229
229 if (v4l2_buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || 230 if (v4l2_buf->type != queue->type ||
230 v4l2_buf->memory != V4L2_MEMORY_MMAP) { 231 v4l2_buf->memory != V4L2_MEMORY_MMAP) {
231 uvc_trace(UVC_TRACE_CAPTURE, "[E] Invalid buffer type (%u) " 232 uvc_trace(UVC_TRACE_CAPTURE, "[E] Invalid buffer type (%u) "
232 "and/or memory (%u).\n", v4l2_buf->type, 233 "and/or memory (%u).\n", v4l2_buf->type,
@@ -249,6 +250,13 @@ int uvc_queue_buffer(struct uvc_video_queue *queue,
249 goto done; 250 goto done;
250 } 251 }
251 252
253 if (v4l2_buf->type == V4L2_BUF_TYPE_VIDEO_OUTPUT &&
254 v4l2_buf->bytesused > buf->buf.length) {
255 uvc_trace(UVC_TRACE_CAPTURE, "[E] Bytes used out of bounds.\n");
256 ret = -EINVAL;
257 goto done;
258 }
259
252 spin_lock_irqsave(&queue->irqlock, flags); 260 spin_lock_irqsave(&queue->irqlock, flags);
253 if (queue->flags & UVC_QUEUE_DISCONNECTED) { 261 if (queue->flags & UVC_QUEUE_DISCONNECTED) {
254 spin_unlock_irqrestore(&queue->irqlock, flags); 262 spin_unlock_irqrestore(&queue->irqlock, flags);
@@ -256,7 +264,11 @@ int uvc_queue_buffer(struct uvc_video_queue *queue,
256 goto done; 264 goto done;
257 } 265 }
258 buf->state = UVC_BUF_STATE_QUEUED; 266 buf->state = UVC_BUF_STATE_QUEUED;
259 buf->buf.bytesused = 0; 267 if (v4l2_buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
268 buf->buf.bytesused = 0;
269 else
270 buf->buf.bytesused = v4l2_buf->bytesused;
271
260 list_add_tail(&buf->stream, &queue->mainqueue); 272 list_add_tail(&buf->stream, &queue->mainqueue);
261 list_add_tail(&buf->queue, &queue->irqqueue); 273 list_add_tail(&buf->queue, &queue->irqqueue);
262 spin_unlock_irqrestore(&queue->irqlock, flags); 274 spin_unlock_irqrestore(&queue->irqlock, flags);
@@ -289,7 +301,7 @@ int uvc_dequeue_buffer(struct uvc_video_queue *queue,
289 struct uvc_buffer *buf; 301 struct uvc_buffer *buf;
290 int ret = 0; 302 int ret = 0;
291 303
292 if (v4l2_buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || 304 if (v4l2_buf->type != queue->type ||
293 v4l2_buf->memory != V4L2_MEMORY_MMAP) { 305 v4l2_buf->memory != V4L2_MEMORY_MMAP) {
294 uvc_trace(UVC_TRACE_CAPTURE, "[E] Invalid buffer type (%u) " 306 uvc_trace(UVC_TRACE_CAPTURE, "[E] Invalid buffer type (%u) "
295 "and/or memory (%u).\n", v4l2_buf->type, 307 "and/or memory (%u).\n", v4l2_buf->type,
@@ -397,6 +409,7 @@ int uvc_queue_enable(struct uvc_video_queue *queue, int enable)
397 } 409 }
398 queue->sequence = 0; 410 queue->sequence = 0;
399 queue->flags |= UVC_QUEUE_STREAMING; 411 queue->flags |= UVC_QUEUE_STREAMING;
412 queue->buf_used = 0;
400 } else { 413 } else {
401 uvc_queue_cancel(queue, 0); 414 uvc_queue_cancel(queue, 0);
402 INIT_LIST_HEAD(&queue->mainqueue); 415 INIT_LIST_HEAD(&queue->mainqueue);
diff --git a/drivers/media/video/uvc/uvc_v4l2.c b/drivers/media/video/uvc/uvc_v4l2.c
index 758dfefaba8d..afcc6934559e 100644
--- a/drivers/media/video/uvc/uvc_v4l2.c
+++ b/drivers/media/video/uvc/uvc_v4l2.c
@@ -110,7 +110,7 @@ static int uvc_v4l2_try_format(struct uvc_video_device *video,
110 int ret = 0; 110 int ret = 0;
111 __u8 *fcc; 111 __u8 *fcc;
112 112
113 if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 113 if (fmt->type != video->streaming->type)
114 return -EINVAL; 114 return -EINVAL;
115 115
116 fcc = (__u8 *)&fmt->fmt.pix.pixelformat; 116 fcc = (__u8 *)&fmt->fmt.pix.pixelformat;
@@ -216,7 +216,7 @@ static int uvc_v4l2_get_format(struct uvc_video_device *video,
216 struct uvc_format *format = video->streaming->cur_format; 216 struct uvc_format *format = video->streaming->cur_format;
217 struct uvc_frame *frame = video->streaming->cur_frame; 217 struct uvc_frame *frame = video->streaming->cur_frame;
218 218
219 if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 219 if (fmt->type != video->streaming->type)
220 return -EINVAL; 220 return -EINVAL;
221 221
222 if (format == NULL || frame == NULL) 222 if (format == NULL || frame == NULL)
@@ -242,7 +242,7 @@ static int uvc_v4l2_set_format(struct uvc_video_device *video,
242 struct uvc_frame *frame; 242 struct uvc_frame *frame;
243 int ret; 243 int ret;
244 244
245 if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 245 if (fmt->type != video->streaming->type)
246 return -EINVAL; 246 return -EINVAL;
247 247
248 if (uvc_queue_streaming(&video->queue)) 248 if (uvc_queue_streaming(&video->queue))
@@ -252,9 +252,6 @@ static int uvc_v4l2_set_format(struct uvc_video_device *video,
252 if (ret < 0) 252 if (ret < 0)
253 return ret; 253 return ret;
254 254
255 if ((ret = uvc_set_video_ctrl(video, &probe, 0)) < 0)
256 return ret;
257
258 memcpy(&video->streaming->ctrl, &probe, sizeof probe); 255 memcpy(&video->streaming->ctrl, &probe, sizeof probe);
259 video->streaming->cur_format = format; 256 video->streaming->cur_format = format;
260 video->streaming->cur_frame = frame; 257 video->streaming->cur_frame = frame;
@@ -267,7 +264,7 @@ static int uvc_v4l2_get_streamparm(struct uvc_video_device *video,
267{ 264{
268 uint32_t numerator, denominator; 265 uint32_t numerator, denominator;
269 266
270 if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 267 if (parm->type != video->streaming->type)
271 return -EINVAL; 268 return -EINVAL;
272 269
273 numerator = video->streaming->ctrl.dwFrameInterval; 270 numerator = video->streaming->ctrl.dwFrameInterval;
@@ -275,13 +272,21 @@ static int uvc_v4l2_get_streamparm(struct uvc_video_device *video,
275 uvc_simplify_fraction(&numerator, &denominator, 8, 333); 272 uvc_simplify_fraction(&numerator, &denominator, 8, 333);
276 273
277 memset(parm, 0, sizeof *parm); 274 memset(parm, 0, sizeof *parm);
278 parm->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 275 parm->type = video->streaming->type;
279 parm->parm.capture.capability = V4L2_CAP_TIMEPERFRAME; 276
280 parm->parm.capture.capturemode = 0; 277 if (video->streaming->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
281 parm->parm.capture.timeperframe.numerator = numerator; 278 parm->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
282 parm->parm.capture.timeperframe.denominator = denominator; 279 parm->parm.capture.capturemode = 0;
283 parm->parm.capture.extendedmode = 0; 280 parm->parm.capture.timeperframe.numerator = numerator;
284 parm->parm.capture.readbuffers = 0; 281 parm->parm.capture.timeperframe.denominator = denominator;
282 parm->parm.capture.extendedmode = 0;
283 parm->parm.capture.readbuffers = 0;
284 } else {
285 parm->parm.output.capability = V4L2_CAP_TIMEPERFRAME;
286 parm->parm.output.outputmode = 0;
287 parm->parm.output.timeperframe.numerator = numerator;
288 parm->parm.output.timeperframe.denominator = denominator;
289 }
285 290
286 return 0; 291 return 0;
287} 292}
@@ -291,42 +296,45 @@ static int uvc_v4l2_set_streamparm(struct uvc_video_device *video,
291{ 296{
292 struct uvc_frame *frame = video->streaming->cur_frame; 297 struct uvc_frame *frame = video->streaming->cur_frame;
293 struct uvc_streaming_control probe; 298 struct uvc_streaming_control probe;
299 struct v4l2_fract timeperframe;
294 uint32_t interval; 300 uint32_t interval;
295 int ret; 301 int ret;
296 302
297 if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 303 if (parm->type != video->streaming->type)
298 return -EINVAL; 304 return -EINVAL;
299 305
300 if (uvc_queue_streaming(&video->queue)) 306 if (uvc_queue_streaming(&video->queue))
301 return -EBUSY; 307 return -EBUSY;
302 308
309 if (parm->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
310 timeperframe = parm->parm.capture.timeperframe;
311 else
312 timeperframe = parm->parm.output.timeperframe;
313
303 memcpy(&probe, &video->streaming->ctrl, sizeof probe); 314 memcpy(&probe, &video->streaming->ctrl, sizeof probe);
304 interval = uvc_fraction_to_interval( 315 interval = uvc_fraction_to_interval(timeperframe.numerator,
305 parm->parm.capture.timeperframe.numerator, 316 timeperframe.denominator);
306 parm->parm.capture.timeperframe.denominator);
307 317
308 uvc_trace(UVC_TRACE_FORMAT, "Setting frame interval to %u/%u (%u).\n", 318 uvc_trace(UVC_TRACE_FORMAT, "Setting frame interval to %u/%u (%u).\n",
309 parm->parm.capture.timeperframe.numerator, 319 timeperframe.numerator, timeperframe.denominator, interval);
310 parm->parm.capture.timeperframe.denominator,
311 interval);
312 probe.dwFrameInterval = uvc_try_frame_interval(frame, interval); 320 probe.dwFrameInterval = uvc_try_frame_interval(frame, interval);
313 321
314 /* Probe the device with the new settings. */ 322 /* Probe the device with the new settings. */
315 if ((ret = uvc_probe_video(video, &probe)) < 0) 323 if ((ret = uvc_probe_video(video, &probe)) < 0)
316 return ret; 324 return ret;
317 325
318 /* Commit the new settings. */
319 if ((ret = uvc_set_video_ctrl(video, &probe, 0)) < 0)
320 return ret;
321
322 memcpy(&video->streaming->ctrl, &probe, sizeof probe); 326 memcpy(&video->streaming->ctrl, &probe, sizeof probe);
323 327
324 /* Return the actual frame period. */ 328 /* Return the actual frame period. */
325 parm->parm.capture.timeperframe.numerator = probe.dwFrameInterval; 329 timeperframe.numerator = probe.dwFrameInterval;
326 parm->parm.capture.timeperframe.denominator = 10000000; 330 timeperframe.denominator = 10000000;
327 uvc_simplify_fraction(&parm->parm.capture.timeperframe.numerator, 331 uvc_simplify_fraction(&timeperframe.numerator,
328 &parm->parm.capture.timeperframe.denominator, 332 &timeperframe.denominator, 8, 333);
329 8, 333); 333
334 if (parm->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
335 parm->parm.capture.timeperframe = timeperframe;
336 else
337 parm->parm.output.timeperframe = timeperframe;
330 338
331 return 0; 339 return 0;
332} 340}
@@ -464,17 +472,13 @@ static int uvc_v4l2_release(struct inode *inode, struct file *file)
464 return 0; 472 return 0;
465} 473}
466 474
467static int __uvc_v4l2_do_ioctl(struct file *file, 475static int uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
468 unsigned int cmd, void *arg)
469{ 476{
470 struct video_device *vdev = video_devdata(file); 477 struct video_device *vdev = video_devdata(file);
471 struct uvc_video_device *video = video_get_drvdata(vdev); 478 struct uvc_video_device *video = video_get_drvdata(vdev);
472 struct uvc_fh *handle = (struct uvc_fh *)file->private_data; 479 struct uvc_fh *handle = (struct uvc_fh *)file->private_data;
473 int ret = 0; 480 int ret = 0;
474 481
475 if (uvc_trace_param & UVC_TRACE_IOCTL)
476 v4l_printk_ioctl(cmd);
477
478 switch (cmd) { 482 switch (cmd) {
479 /* Query capabilities */ 483 /* Query capabilities */
480 case VIDIOC_QUERYCAP: 484 case VIDIOC_QUERYCAP:
@@ -487,8 +491,12 @@ static int __uvc_v4l2_do_ioctl(struct file *file,
487 strncpy(cap->bus_info, video->dev->udev->bus->bus_name, 491 strncpy(cap->bus_info, video->dev->udev->bus->bus_name,
488 sizeof cap->bus_info); 492 sizeof cap->bus_info);
489 cap->version = DRIVER_VERSION_NUMBER; 493 cap->version = DRIVER_VERSION_NUMBER;
490 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE 494 if (video->streaming->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
491 | V4L2_CAP_STREAMING; 495 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE
496 | V4L2_CAP_STREAMING;
497 else
498 cap->capabilities = V4L2_CAP_VIDEO_OUTPUT
499 | V4L2_CAP_STREAMING;
492 break; 500 break;
493 } 501 }
494 502
@@ -666,7 +674,7 @@ static int __uvc_v4l2_do_ioctl(struct file *file,
666 struct v4l2_fmtdesc *fmt = arg; 674 struct v4l2_fmtdesc *fmt = arg;
667 struct uvc_format *format; 675 struct uvc_format *format;
668 676
669 if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || 677 if (fmt->type != video->streaming->type ||
670 fmt->index >= video->streaming->nformats) 678 fmt->index >= video->streaming->nformats)
671 return -EINVAL; 679 return -EINVAL;
672 680
@@ -805,7 +813,7 @@ static int __uvc_v4l2_do_ioctl(struct file *file,
805 struct v4l2_cropcap *ccap = arg; 813 struct v4l2_cropcap *ccap = arg;
806 struct uvc_frame *frame = video->streaming->cur_frame; 814 struct uvc_frame *frame = video->streaming->cur_frame;
807 815
808 if (ccap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 816 if (ccap->type != video->streaming->type)
809 return -EINVAL; 817 return -EINVAL;
810 818
811 ccap->bounds.left = 0; 819 ccap->bounds.left = 0;
@@ -831,7 +839,7 @@ static int __uvc_v4l2_do_ioctl(struct file *file,
831 unsigned int bufsize = 839 unsigned int bufsize =
832 video->streaming->ctrl.dwMaxVideoFrameSize; 840 video->streaming->ctrl.dwMaxVideoFrameSize;
833 841
834 if (rb->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || 842 if (rb->type != video->streaming->type ||
835 rb->memory != V4L2_MEMORY_MMAP) 843 rb->memory != V4L2_MEMORY_MMAP)
836 return -EINVAL; 844 return -EINVAL;
837 845
@@ -851,7 +859,7 @@ static int __uvc_v4l2_do_ioctl(struct file *file,
851 { 859 {
852 struct v4l2_buffer *buf = arg; 860 struct v4l2_buffer *buf = arg;
853 861
854 if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 862 if (buf->type != video->streaming->type)
855 return -EINVAL; 863 return -EINVAL;
856 864
857 if (!uvc_has_privileges(handle)) 865 if (!uvc_has_privileges(handle))
@@ -877,7 +885,7 @@ static int __uvc_v4l2_do_ioctl(struct file *file,
877 { 885 {
878 int *type = arg; 886 int *type = arg;
879 887
880 if (*type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 888 if (*type != video->streaming->type)
881 return -EINVAL; 889 return -EINVAL;
882 890
883 if (!uvc_has_privileges(handle)) 891 if (!uvc_has_privileges(handle))
@@ -892,7 +900,7 @@ static int __uvc_v4l2_do_ioctl(struct file *file,
892 { 900 {
893 int *type = arg; 901 int *type = arg;
894 902
895 if (*type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 903 if (*type != video->streaming->type)
896 return -EINVAL; 904 return -EINVAL;
897 905
898 if (!uvc_has_privileges(handle)) 906 if (!uvc_has_privileges(handle))
@@ -925,7 +933,7 @@ static int __uvc_v4l2_do_ioctl(struct file *file,
925 if (!capable(CAP_SYS_ADMIN)) 933 if (!capable(CAP_SYS_ADMIN))
926 return -EPERM; 934 return -EPERM;
927 935
928 info = kmalloc(sizeof *info, GFP_KERNEL); 936 info = kzalloc(sizeof *info, GFP_KERNEL);
929 if (info == NULL) 937 if (info == NULL)
930 return -ENOMEM; 938 return -ENOMEM;
931 939
@@ -952,7 +960,7 @@ static int __uvc_v4l2_do_ioctl(struct file *file,
952 if (!capable(CAP_SYS_ADMIN)) 960 if (!capable(CAP_SYS_ADMIN))
953 return -EPERM; 961 return -EPERM;
954 962
955 map = kmalloc(sizeof *map, GFP_KERNEL); 963 map = kzalloc(sizeof *map, GFP_KERNEL);
956 if (map == NULL) 964 if (map == NULL)
957 return -ENOMEM; 965 return -ENOMEM;
958 966
@@ -979,7 +987,7 @@ static int __uvc_v4l2_do_ioctl(struct file *file,
979 987
980 default: 988 default:
981 if ((ret = v4l_compat_translate_ioctl(file, cmd, arg, 989 if ((ret = v4l_compat_translate_ioctl(file, cmd, arg,
982 __uvc_v4l2_do_ioctl)) == -ENOIOCTLCMD) 990 uvc_v4l2_do_ioctl)) == -ENOIOCTLCMD)
983 uvc_trace(UVC_TRACE_IOCTL, "Unknown ioctl 0x%08x\n", 991 uvc_trace(UVC_TRACE_IOCTL, "Unknown ioctl 0x%08x\n",
984 cmd); 992 cmd);
985 return ret; 993 return ret;
@@ -988,17 +996,16 @@ static int __uvc_v4l2_do_ioctl(struct file *file,
988 return ret; 996 return ret;
989} 997}
990 998
991static int uvc_v4l2_do_ioctl(struct inode *inode, struct file *file,
992 unsigned int cmd, void *arg)
993{
994 return __uvc_v4l2_do_ioctl(file, cmd, arg);
995}
996
997static int uvc_v4l2_ioctl(struct inode *inode, struct file *file, 999static int uvc_v4l2_ioctl(struct inode *inode, struct file *file,
998 unsigned int cmd, unsigned long arg) 1000 unsigned int cmd, unsigned long arg)
999{ 1001{
1000 uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_ioctl\n"); 1002 if (uvc_trace_param & UVC_TRACE_IOCTL) {
1001 return video_usercopy(inode, file, cmd, arg, uvc_v4l2_do_ioctl); 1003 uvc_printk(KERN_DEBUG, "uvc_v4l2_ioctl(");
1004 v4l_printk_ioctl(cmd);
1005 printk(")\n");
1006 }
1007
1008 return video_usercopy(file, cmd, arg, uvc_v4l2_do_ioctl);
1002} 1009}
1003 1010
1004static ssize_t uvc_v4l2_read(struct file *file, char __user *data, 1011static ssize_t uvc_v4l2_read(struct file *file, char __user *data,
diff --git a/drivers/media/video/uvc/uvc_video.c b/drivers/media/video/uvc/uvc_video.c
index b7bb23820d80..e7c31995527f 100644
--- a/drivers/media/video/uvc/uvc_video.c
+++ b/drivers/media/video/uvc/uvc_video.c
@@ -36,15 +36,22 @@ static int __uvc_query_ctrl(struct uvc_device *dev, __u8 query, __u8 unit,
36{ 36{
37 __u8 type = USB_TYPE_CLASS | USB_RECIP_INTERFACE; 37 __u8 type = USB_TYPE_CLASS | USB_RECIP_INTERFACE;
38 unsigned int pipe; 38 unsigned int pipe;
39 int ret;
40 39
41 pipe = (query & 0x80) ? usb_rcvctrlpipe(dev->udev, 0) 40 pipe = (query & 0x80) ? usb_rcvctrlpipe(dev->udev, 0)
42 : usb_sndctrlpipe(dev->udev, 0); 41 : usb_sndctrlpipe(dev->udev, 0);
43 type |= (query & 0x80) ? USB_DIR_IN : USB_DIR_OUT; 42 type |= (query & 0x80) ? USB_DIR_IN : USB_DIR_OUT;
44 43
45 ret = usb_control_msg(dev->udev, pipe, query, type, cs << 8, 44 return usb_control_msg(dev->udev, pipe, query, type, cs << 8,
46 unit << 8 | intfnum, data, size, timeout); 45 unit << 8 | intfnum, data, size, timeout);
46}
47
48int uvc_query_ctrl(struct uvc_device *dev, __u8 query, __u8 unit,
49 __u8 intfnum, __u8 cs, void *data, __u16 size)
50{
51 int ret;
47 52
53 ret = __uvc_query_ctrl(dev, query, unit, intfnum, cs, data, size,
54 UVC_CTRL_CONTROL_TIMEOUT);
48 if (ret != size) { 55 if (ret != size) {
49 uvc_printk(KERN_ERR, "Failed to query (%u) UVC control %u " 56 uvc_printk(KERN_ERR, "Failed to query (%u) UVC control %u "
50 "(unit %u) : %d (exp. %u).\n", query, cs, unit, ret, 57 "(unit %u) : %d (exp. %u).\n", query, cs, unit, ret,
@@ -55,13 +62,6 @@ static int __uvc_query_ctrl(struct uvc_device *dev, __u8 query, __u8 unit,
55 return 0; 62 return 0;
56} 63}
57 64
58int uvc_query_ctrl(struct uvc_device *dev, __u8 query, __u8 unit,
59 __u8 intfnum, __u8 cs, void *data, __u16 size)
60{
61 return __uvc_query_ctrl(dev, query, unit, intfnum, cs, data, size,
62 UVC_CTRL_CONTROL_TIMEOUT);
63}
64
65static void uvc_fixup_buffer_size(struct uvc_video_device *video, 65static void uvc_fixup_buffer_size(struct uvc_video_device *video,
66 struct uvc_streaming_control *ctrl) 66 struct uvc_streaming_control *ctrl)
67{ 67{
@@ -102,8 +102,36 @@ static int uvc_get_video_ctrl(struct uvc_video_device *video,
102 ret = __uvc_query_ctrl(video->dev, query, 0, video->streaming->intfnum, 102 ret = __uvc_query_ctrl(video->dev, query, 0, video->streaming->intfnum,
103 probe ? VS_PROBE_CONTROL : VS_COMMIT_CONTROL, data, size, 103 probe ? VS_PROBE_CONTROL : VS_COMMIT_CONTROL, data, size,
104 UVC_CTRL_STREAMING_TIMEOUT); 104 UVC_CTRL_STREAMING_TIMEOUT);
105 if (ret < 0) 105
106 if ((query == GET_MIN || query == GET_MAX) && ret == 2) {
107 /* Some cameras, mostly based on Bison Electronics chipsets,
108 * answer a GET_MIN or GET_MAX request with the wCompQuality
109 * field only.
110 */
111 uvc_warn_once(video->dev, UVC_WARN_MINMAX, "UVC non "
112 "compliance - GET_MIN/MAX(PROBE) incorrectly "
113 "supported. Enabling workaround.\n");
114 memset(ctrl, 0, sizeof ctrl);
115 ctrl->wCompQuality = le16_to_cpup((__le16 *)data);
116 ret = 0;
117 goto out;
118 } else if (query == GET_DEF && probe == 1) {
119 /* Many cameras don't support the GET_DEF request on their
120 * video probe control. Warn once and return, the caller will
121 * fall back to GET_CUR.
122 */
123 uvc_warn_once(video->dev, UVC_WARN_PROBE_DEF, "UVC non "
124 "compliance - GET_DEF(PROBE) not supported. "
125 "Enabling workaround.\n");
126 ret = -EIO;
127 goto out;
128 } else if (ret != size) {
129 uvc_printk(KERN_ERR, "Failed to query (%u) UVC %s control : "
130 "%d (exp. %u).\n", query, probe ? "probe" : "commit",
131 ret, size);
132 ret = -EIO;
106 goto out; 133 goto out;
134 }
107 135
108 ctrl->bmHint = le16_to_cpup((__le16 *)&data[0]); 136 ctrl->bmHint = le16_to_cpup((__le16 *)&data[0]);
109 ctrl->bFormatIndex = data[2]; 137 ctrl->bFormatIndex = data[2];
@@ -114,14 +142,11 @@ static int uvc_get_video_ctrl(struct uvc_video_device *video,
114 ctrl->wCompQuality = le16_to_cpup((__le16 *)&data[12]); 142 ctrl->wCompQuality = le16_to_cpup((__le16 *)&data[12]);
115 ctrl->wCompWindowSize = le16_to_cpup((__le16 *)&data[14]); 143 ctrl->wCompWindowSize = le16_to_cpup((__le16 *)&data[14]);
116 ctrl->wDelay = le16_to_cpup((__le16 *)&data[16]); 144 ctrl->wDelay = le16_to_cpup((__le16 *)&data[16]);
117 ctrl->dwMaxVideoFrameSize = 145 ctrl->dwMaxVideoFrameSize = get_unaligned_le32(&data[18]);
118 le32_to_cpu(get_unaligned((__le32 *)&data[18])); 146 ctrl->dwMaxPayloadTransferSize = get_unaligned_le32(&data[22]);
119 ctrl->dwMaxPayloadTransferSize =
120 le32_to_cpu(get_unaligned((__le32 *)&data[22]));
121 147
122 if (size == 34) { 148 if (size == 34) {
123 ctrl->dwClockFrequency = 149 ctrl->dwClockFrequency = get_unaligned_le32(&data[26]);
124 le32_to_cpu(get_unaligned((__le32 *)&data[26]));
125 ctrl->bmFramingInfo = data[30]; 150 ctrl->bmFramingInfo = data[30];
126 ctrl->bPreferedVersion = data[31]; 151 ctrl->bPreferedVersion = data[31];
127 ctrl->bMinVersion = data[32]; 152 ctrl->bMinVersion = data[32];
@@ -138,13 +163,14 @@ static int uvc_get_video_ctrl(struct uvc_video_device *video,
138 * Try to get the value from the format and frame descriptor. 163 * Try to get the value from the format and frame descriptor.
139 */ 164 */
140 uvc_fixup_buffer_size(video, ctrl); 165 uvc_fixup_buffer_size(video, ctrl);
166 ret = 0;
141 167
142out: 168out:
143 kfree(data); 169 kfree(data);
144 return ret; 170 return ret;
145} 171}
146 172
147int uvc_set_video_ctrl(struct uvc_video_device *video, 173static int uvc_set_video_ctrl(struct uvc_video_device *video,
148 struct uvc_streaming_control *ctrl, int probe) 174 struct uvc_streaming_control *ctrl, int probe)
149{ 175{
150 __u8 *data; 176 __u8 *data;
@@ -168,14 +194,11 @@ int uvc_set_video_ctrl(struct uvc_video_device *video,
168 /* Note: Some of the fields below are not required for IN devices (see 194 /* Note: Some of the fields below are not required for IN devices (see
169 * UVC spec, 4.3.1.1), but we still copy them in case support for OUT 195 * UVC spec, 4.3.1.1), but we still copy them in case support for OUT
170 * devices is added in the future. */ 196 * devices is added in the future. */
171 put_unaligned(cpu_to_le32(ctrl->dwMaxVideoFrameSize), 197 put_unaligned_le32(ctrl->dwMaxVideoFrameSize, &data[18]);
172 (__le32 *)&data[18]); 198 put_unaligned_le32(ctrl->dwMaxPayloadTransferSize, &data[22]);
173 put_unaligned(cpu_to_le32(ctrl->dwMaxPayloadTransferSize),
174 (__le32 *)&data[22]);
175 199
176 if (size == 34) { 200 if (size == 34) {
177 put_unaligned(cpu_to_le32(ctrl->dwClockFrequency), 201 put_unaligned_le32(ctrl->dwClockFrequency, &data[26]);
178 (__le32 *)&data[26]);
179 data[30] = ctrl->bmFramingInfo; 202 data[30] = ctrl->bmFramingInfo;
180 data[31] = ctrl->bPreferedVersion; 203 data[31] = ctrl->bPreferedVersion;
181 data[32] = ctrl->bMinVersion; 204 data[32] = ctrl->bMinVersion;
@@ -186,6 +209,12 @@ int uvc_set_video_ctrl(struct uvc_video_device *video,
186 video->streaming->intfnum, 209 video->streaming->intfnum,
187 probe ? VS_PROBE_CONTROL : VS_COMMIT_CONTROL, data, size, 210 probe ? VS_PROBE_CONTROL : VS_COMMIT_CONTROL, data, size,
188 UVC_CTRL_STREAMING_TIMEOUT); 211 UVC_CTRL_STREAMING_TIMEOUT);
212 if (ret != size) {
213 uvc_printk(KERN_ERR, "Failed to set UVC %s control : "
214 "%d (exp. %u).\n", probe ? "probe" : "commit",
215 ret, size);
216 ret = -EIO;
217 }
189 218
190 kfree(data); 219 kfree(data);
191 return ret; 220 return ret;
@@ -252,6 +281,12 @@ done:
252 return ret; 281 return ret;
253} 282}
254 283
284int uvc_commit_video(struct uvc_video_device *video,
285 struct uvc_streaming_control *probe)
286{
287 return uvc_set_video_ctrl(video, probe, 0);
288}
289
255/* ------------------------------------------------------------------------ 290/* ------------------------------------------------------------------------
256 * Video codecs 291 * Video codecs
257 */ 292 */
@@ -333,7 +368,7 @@ static int uvc_video_decode_start(struct uvc_video_device *video,
333 368
334 /* Synchronize to the input stream by waiting for the FID bit to be 369 /* Synchronize to the input stream by waiting for the FID bit to be
335 * toggled when the the buffer state is not UVC_BUF_STATE_ACTIVE. 370 * toggled when the the buffer state is not UVC_BUF_STATE_ACTIVE.
336 * queue->last_fid is initialized to -1, so the first isochronous 371 * video->last_fid is initialized to -1, so the first isochronous
337 * frame will always be in sync. 372 * frame will always be in sync.
338 * 373 *
339 * If the device doesn't toggle the FID bit, invert video->last_fid 374 * If the device doesn't toggle the FID bit, invert video->last_fid
@@ -360,7 +395,7 @@ static int uvc_video_decode_start(struct uvc_video_device *video,
360 * last payload can be lost anyway). We thus must check if the FID has 395 * last payload can be lost anyway). We thus must check if the FID has
361 * been toggled. 396 * been toggled.
362 * 397 *
363 * queue->last_fid is initialized to -1, so the first isochronous 398 * video->last_fid is initialized to -1, so the first isochronous
364 * frame will never trigger an end of frame detection. 399 * frame will never trigger an end of frame detection.
365 * 400 *
366 * Empty buffers (bytesused == 0) don't trigger end of frame detection 401 * Empty buffers (bytesused == 0) don't trigger end of frame detection
@@ -418,6 +453,34 @@ static void uvc_video_decode_end(struct uvc_video_device *video,
418 } 453 }
419} 454}
420 455
456static int uvc_video_encode_header(struct uvc_video_device *video,
457 struct uvc_buffer *buf, __u8 *data, int len)
458{
459 data[0] = 2; /* Header length */
460 data[1] = UVC_STREAM_EOH | UVC_STREAM_EOF
461 | (video->last_fid & UVC_STREAM_FID);
462 return 2;
463}
464
465static int uvc_video_encode_data(struct uvc_video_device *video,
466 struct uvc_buffer *buf, __u8 *data, int len)
467{
468 struct uvc_video_queue *queue = &video->queue;
469 unsigned int nbytes;
470 void *mem;
471
472 /* Copy video data to the URB buffer. */
473 mem = queue->mem + buf->buf.m.offset + queue->buf_used;
474 nbytes = min((unsigned int)len, buf->buf.bytesused - queue->buf_used);
475 nbytes = min(video->bulk.max_payload_size - video->bulk.payload_size,
476 nbytes);
477 memcpy(data, mem, nbytes);
478
479 queue->buf_used += nbytes;
480
481 return nbytes;
482}
483
421/* ------------------------------------------------------------------------ 484/* ------------------------------------------------------------------------
422 * URB handling 485 * URB handling
423 */ 486 */
@@ -477,7 +540,7 @@ static void uvc_video_decode_bulk(struct urb *urb,
477 /* If the URB is the first of its payload, decode and save the 540 /* If the URB is the first of its payload, decode and save the
478 * header. 541 * header.
479 */ 542 */
480 if (video->bulk.header_size == 0) { 543 if (video->bulk.header_size == 0 && !video->bulk.skip_payload) {
481 do { 544 do {
482 ret = uvc_video_decode_start(video, buf, mem, len); 545 ret = uvc_video_decode_start(video, buf, mem, len);
483 if (ret == -EAGAIN) 546 if (ret == -EAGAIN)
@@ -487,14 +550,13 @@ static void uvc_video_decode_bulk(struct urb *urb,
487 /* If an error occured skip the rest of the payload. */ 550 /* If an error occured skip the rest of the payload. */
488 if (ret < 0 || buf == NULL) { 551 if (ret < 0 || buf == NULL) {
489 video->bulk.skip_payload = 1; 552 video->bulk.skip_payload = 1;
490 return; 553 } else {
491 } 554 memcpy(video->bulk.header, mem, ret);
555 video->bulk.header_size = ret;
492 556
493 video->bulk.header_size = ret; 557 mem += ret;
494 memcpy(video->bulk.header, mem, video->bulk.header_size); 558 len -= ret;
495 559 }
496 mem += ret;
497 len -= ret;
498 } 560 }
499 561
500 /* The buffer queue might have been cancelled while a bulk transfer 562 /* The buffer queue might have been cancelled while a bulk transfer
@@ -525,6 +587,48 @@ static void uvc_video_decode_bulk(struct urb *urb,
525 } 587 }
526} 588}
527 589
590static void uvc_video_encode_bulk(struct urb *urb,
591 struct uvc_video_device *video, struct uvc_buffer *buf)
592{
593 u8 *mem = urb->transfer_buffer;
594 int len = video->urb_size, ret;
595
596 if (buf == NULL) {
597 urb->transfer_buffer_length = 0;
598 return;
599 }
600
601 /* If the URB is the first of its payload, add the header. */
602 if (video->bulk.header_size == 0) {
603 ret = uvc_video_encode_header(video, buf, mem, len);
604 video->bulk.header_size = ret;
605 video->bulk.payload_size += ret;
606 mem += ret;
607 len -= ret;
608 }
609
610 /* Process video data. */
611 ret = uvc_video_encode_data(video, buf, mem, len);
612
613 video->bulk.payload_size += ret;
614 len -= ret;
615
616 if (buf->buf.bytesused == video->queue.buf_used ||
617 video->bulk.payload_size == video->bulk.max_payload_size) {
618 if (buf->buf.bytesused == video->queue.buf_used) {
619 video->queue.buf_used = 0;
620 buf->state = UVC_BUF_STATE_DONE;
621 uvc_queue_next_buffer(&video->queue, buf);
622 video->last_fid ^= UVC_STREAM_FID;
623 }
624
625 video->bulk.header_size = 0;
626 video->bulk.payload_size = 0;
627 }
628
629 urb->transfer_buffer_length = video->urb_size - len;
630}
631
528static void uvc_video_complete(struct urb *urb) 632static void uvc_video_complete(struct urb *urb)
529{ 633{
530 struct uvc_video_device *video = urb->context; 634 struct uvc_video_device *video = urb->context;
@@ -722,7 +826,15 @@ static int uvc_init_video_bulk(struct uvc_video_device *video,
722 if (uvc_alloc_urb_buffers(video, size) < 0) 826 if (uvc_alloc_urb_buffers(video, size) < 0)
723 return -ENOMEM; 827 return -ENOMEM;
724 828
725 pipe = usb_rcvbulkpipe(video->dev->udev, ep->desc.bEndpointAddress); 829 if (usb_endpoint_dir_in(&ep->desc))
830 pipe = usb_rcvbulkpipe(video->dev->udev,
831 ep->desc.bEndpointAddress);
832 else
833 pipe = usb_sndbulkpipe(video->dev->udev,
834 ep->desc.bEndpointAddress);
835
836 if (video->streaming->type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
837 size = 0;
726 838
727 for (i = 0; i < UVC_URBS; ++i) { 839 for (i = 0; i < UVC_URBS; ++i) {
728 urb = usb_alloc_urb(0, gfp_flags); 840 urb = usb_alloc_urb(0, gfp_flags);
@@ -854,7 +966,7 @@ int uvc_video_resume(struct uvc_video_device *video)
854 966
855 video->frozen = 0; 967 video->frozen = 0;
856 968
857 if ((ret = uvc_set_video_ctrl(video, &video->streaming->ctrl, 0)) < 0) { 969 if ((ret = uvc_commit_video(video, &video->streaming->ctrl)) < 0) {
858 uvc_queue_enable(&video->queue, 0); 970 uvc_queue_enable(&video->queue, 0);
859 return ret; 971 return ret;
860 } 972 }
@@ -935,23 +1047,30 @@ int uvc_video_init(struct uvc_video_device *video)
935 break; 1047 break;
936 } 1048 }
937 1049
938 /* Commit the default settings. */
939 probe->bFormatIndex = format->index; 1050 probe->bFormatIndex = format->index;
940 probe->bFrameIndex = frame->bFrameIndex; 1051 probe->bFrameIndex = frame->bFrameIndex;
941 if ((ret = uvc_set_video_ctrl(video, probe, 0)) < 0)
942 return ret;
943 1052
944 video->streaming->cur_format = format; 1053 video->streaming->cur_format = format;
945 video->streaming->cur_frame = frame; 1054 video->streaming->cur_frame = frame;
946 atomic_set(&video->active, 0); 1055 atomic_set(&video->active, 0);
947 1056
948 /* Select the video decoding function */ 1057 /* Select the video decoding function */
949 if (video->dev->quirks & UVC_QUIRK_BUILTIN_ISIGHT) 1058 if (video->streaming->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
950 video->decode = uvc_video_decode_isight; 1059 if (video->dev->quirks & UVC_QUIRK_BUILTIN_ISIGHT)
951 else if (video->streaming->intf->num_altsetting > 1) 1060 video->decode = uvc_video_decode_isight;
952 video->decode = uvc_video_decode_isoc; 1061 else if (video->streaming->intf->num_altsetting > 1)
953 else 1062 video->decode = uvc_video_decode_isoc;
954 video->decode = uvc_video_decode_bulk; 1063 else
1064 video->decode = uvc_video_decode_bulk;
1065 } else {
1066 if (video->streaming->intf->num_altsetting == 1)
1067 video->decode = uvc_video_encode_bulk;
1068 else {
1069 uvc_printk(KERN_INFO, "Isochronous endpoints are not "
1070 "supported for video output devices.\n");
1071 return -EINVAL;
1072 }
1073 }
955 1074
956 return 0; 1075 return 0;
957} 1076}
@@ -971,7 +1090,8 @@ int uvc_video_enable(struct uvc_video_device *video, int enable)
971 return 0; 1090 return 0;
972 } 1091 }
973 1092
974 if (video->streaming->cur_format->flags & UVC_FMT_FLAG_COMPRESSED) 1093 if ((video->streaming->cur_format->flags & UVC_FMT_FLAG_COMPRESSED) ||
1094 uvc_no_drop_param)
975 video->queue.flags &= ~UVC_QUEUE_DROP_INCOMPLETE; 1095 video->queue.flags &= ~UVC_QUEUE_DROP_INCOMPLETE;
976 else 1096 else
977 video->queue.flags |= UVC_QUEUE_DROP_INCOMPLETE; 1097 video->queue.flags |= UVC_QUEUE_DROP_INCOMPLETE;
@@ -979,6 +1099,10 @@ int uvc_video_enable(struct uvc_video_device *video, int enable)
979 if ((ret = uvc_queue_enable(&video->queue, 1)) < 0) 1099 if ((ret = uvc_queue_enable(&video->queue, 1)) < 0)
980 return ret; 1100 return ret;
981 1101
1102 /* Commit the streaming parameters. */
1103 if ((ret = uvc_commit_video(video, &video->streaming->ctrl)) < 0)
1104 return ret;
1105
982 return uvc_init_video(video, GFP_KERNEL); 1106 return uvc_init_video(video, GFP_KERNEL);
983} 1107}
984 1108
diff --git a/drivers/media/video/uvc/uvcvideo.h b/drivers/media/video/uvc/uvcvideo.h
index 9a6bc1aafb16..896b791ece15 100644
--- a/drivers/media/video/uvc/uvcvideo.h
+++ b/drivers/media/video/uvc/uvcvideo.h
@@ -4,7 +4,6 @@
4#include <linux/kernel.h> 4#include <linux/kernel.h>
5#include <linux/videodev2.h> 5#include <linux/videodev2.h>
6 6
7
8/* 7/*
9 * Dynamic controls 8 * Dynamic controls
10 */ 9 */
@@ -316,6 +315,7 @@ struct uvc_xu_control {
316#define UVC_QUIRK_BUILTIN_ISIGHT 0x00000008 315#define UVC_QUIRK_BUILTIN_ISIGHT 0x00000008
317#define UVC_QUIRK_STREAM_NO_FID 0x00000010 316#define UVC_QUIRK_STREAM_NO_FID 0x00000010
318#define UVC_QUIRK_IGNORE_SELECTOR_UNIT 0x00000020 317#define UVC_QUIRK_IGNORE_SELECTOR_UNIT 0x00000020
318#define UVC_QUIRK_PRUNE_CONTROLS 0x00000040
319 319
320/* Format flags */ 320/* Format flags */
321#define UVC_FMT_FLAG_COMPRESSED 0x00000001 321#define UVC_FMT_FLAG_COMPRESSED 0x00000001
@@ -383,6 +383,11 @@ struct uvc_control_mapping {
383 383
384 struct uvc_menu_info *menu_info; 384 struct uvc_menu_info *menu_info;
385 __u32 menu_count; 385 __u32 menu_count;
386
387 __s32 (*get) (struct uvc_control_mapping *mapping, __u8 query,
388 const __u8 *data);
389 void (*set) (struct uvc_control_mapping *mapping, __s32 value,
390 __u8 *data);
386}; 391};
387 392
388struct uvc_control { 393struct uvc_control {
@@ -523,6 +528,7 @@ struct uvc_streaming {
523 __u16 maxpsize; 528 __u16 maxpsize;
524 529
525 struct uvc_streaming_header header; 530 struct uvc_streaming_header header;
531 enum v4l2_buf_type type;
526 532
527 unsigned int nformats; 533 unsigned int nformats;
528 struct uvc_format *format; 534 struct uvc_format *format;
@@ -558,12 +564,15 @@ struct uvc_buffer {
558#define UVC_QUEUE_DROP_INCOMPLETE (1 << 2) 564#define UVC_QUEUE_DROP_INCOMPLETE (1 << 2)
559 565
560struct uvc_video_queue { 566struct uvc_video_queue {
567 enum v4l2_buf_type type;
568
561 void *mem; 569 void *mem;
562 unsigned int flags; 570 unsigned int flags;
563 __u32 sequence; 571 __u32 sequence;
564 572
565 unsigned int count; 573 unsigned int count;
566 unsigned int buf_size; 574 unsigned int buf_size;
575 unsigned int buf_used;
567 struct uvc_buffer buffer[UVC_MAX_VIDEO_BUFFERS]; 576 struct uvc_buffer buffer[UVC_MAX_VIDEO_BUFFERS];
568 struct mutex mutex; /* protects buffers and mainqueue */ 577 struct mutex mutex; /* protects buffers and mainqueue */
569 spinlock_t irqlock; /* protects irqqueue */ 578 spinlock_t irqlock; /* protects irqqueue */
@@ -578,8 +587,9 @@ struct uvc_video_device {
578 atomic_t active; 587 atomic_t active;
579 unsigned int frozen : 1; 588 unsigned int frozen : 1;
580 589
581 struct list_head iterms; 590 struct list_head iterms; /* Input terminals */
582 struct uvc_entity *oterm; 591 struct uvc_entity *oterm; /* Output terminal */
592 struct uvc_entity *sterm; /* USB streaming terminal */
583 struct uvc_entity *processing; 593 struct uvc_entity *processing;
584 struct uvc_entity *selector; 594 struct uvc_entity *selector;
585 struct list_head extensions; 595 struct list_head extensions;
@@ -617,6 +627,7 @@ enum uvc_device_state {
617struct uvc_device { 627struct uvc_device {
618 struct usb_device *udev; 628 struct usb_device *udev;
619 struct usb_interface *intf; 629 struct usb_interface *intf;
630 unsigned long warnings;
620 __u32 quirks; 631 __u32 quirks;
621 int intfnum; 632 int intfnum;
622 char name[32]; 633 char name[32];
@@ -679,6 +690,10 @@ struct uvc_driver {
679#define UVC_TRACE_SUSPEND (1 << 8) 690#define UVC_TRACE_SUSPEND (1 << 8)
680#define UVC_TRACE_STATUS (1 << 9) 691#define UVC_TRACE_STATUS (1 << 9)
681 692
693#define UVC_WARN_MINMAX 0
694#define UVC_WARN_PROBE_DEF 1
695
696extern unsigned int uvc_no_drop_param;
682extern unsigned int uvc_trace_param; 697extern unsigned int uvc_trace_param;
683 698
684#define uvc_trace(flag, msg...) \ 699#define uvc_trace(flag, msg...) \
@@ -687,6 +702,12 @@ extern unsigned int uvc_trace_param;
687 printk(KERN_DEBUG "uvcvideo: " msg); \ 702 printk(KERN_DEBUG "uvcvideo: " msg); \
688 } while (0) 703 } while (0)
689 704
705#define uvc_warn_once(dev, warn, msg...) \
706 do { \
707 if (!test_and_set_bit(warn, &dev->warnings)) \
708 printk(KERN_INFO "uvcvideo: " msg); \
709 } while (0)
710
690#define uvc_printk(level, msg...) \ 711#define uvc_printk(level, msg...) \
691 printk(level "uvcvideo: " msg) 712 printk(level "uvcvideo: " msg)
692 713
@@ -709,7 +730,8 @@ extern struct uvc_driver uvc_driver;
709extern void uvc_delete(struct kref *kref); 730extern void uvc_delete(struct kref *kref);
710 731
711/* Video buffers queue management. */ 732/* Video buffers queue management. */
712extern void uvc_queue_init(struct uvc_video_queue *queue); 733extern void uvc_queue_init(struct uvc_video_queue *queue,
734 enum v4l2_buf_type type);
713extern int uvc_alloc_buffers(struct uvc_video_queue *queue, 735extern int uvc_alloc_buffers(struct uvc_video_queue *queue,
714 unsigned int nbuffers, unsigned int buflength); 736 unsigned int nbuffers, unsigned int buflength);
715extern int uvc_free_buffers(struct uvc_video_queue *queue); 737extern int uvc_free_buffers(struct uvc_video_queue *queue);
@@ -740,10 +762,10 @@ extern int uvc_video_resume(struct uvc_video_device *video);
740extern int uvc_video_enable(struct uvc_video_device *video, int enable); 762extern int uvc_video_enable(struct uvc_video_device *video, int enable);
741extern int uvc_probe_video(struct uvc_video_device *video, 763extern int uvc_probe_video(struct uvc_video_device *video,
742 struct uvc_streaming_control *probe); 764 struct uvc_streaming_control *probe);
765extern int uvc_commit_video(struct uvc_video_device *video,
766 struct uvc_streaming_control *ctrl);
743extern int uvc_query_ctrl(struct uvc_device *dev, __u8 query, __u8 unit, 767extern int uvc_query_ctrl(struct uvc_device *dev, __u8 query, __u8 unit,
744 __u8 intfnum, __u8 cs, void *data, __u16 size); 768 __u8 intfnum, __u8 cs, void *data, __u16 size);
745extern int uvc_set_video_ctrl(struct uvc_video_device *video,
746 struct uvc_streaming_control *ctrl, int probe);
747 769
748/* Status */ 770/* Status */
749extern int uvc_status_init(struct uvc_device *dev); 771extern int uvc_status_init(struct uvc_device *dev);
diff --git a/drivers/media/video/v4l2-common.c b/drivers/media/video/v4l2-common.c
index 846763d7349e..c676b0b0f708 100644
--- a/drivers/media/video/v4l2-common.c
+++ b/drivers/media/video/v4l2-common.c
@@ -28,7 +28,7 @@
28 * as published by the Free Software Foundation; either version 28 * as published by the Free Software Foundation; either version
29 * 2 of the License, or (at your option) any later version. 29 * 2 of the License, or (at your option) any later version.
30 * 30 *
31 * Author: Alan Cox, <alan@redhat.com> 31 * Author: Alan Cox, <alan@lxorguk.ukuu.org.uk>
32 * 32 *
33 * Fixes: 33 * Fixes:
34 */ 34 */
@@ -58,6 +58,7 @@
58#include <asm/div64.h> 58#include <asm/div64.h>
59#define __OLD_VIDIOC_ /* To allow fixing old calls*/ 59#define __OLD_VIDIOC_ /* To allow fixing old calls*/
60#include <media/v4l2-common.h> 60#include <media/v4l2-common.h>
61#include <media/v4l2-device.h>
61#include <media/v4l2-chip-ident.h> 62#include <media/v4l2-chip-ident.h>
62 63
63#include <linux/videodev2.h> 64#include <linux/videodev2.h>
@@ -320,6 +321,19 @@ const char **v4l2_ctrl_get_menu(u32 id)
320 "Private packet, IVTV format", 321 "Private packet, IVTV format",
321 NULL 322 NULL
322 }; 323 };
324 static const char *camera_power_line_frequency[] = {
325 "Disabled",
326 "50 Hz",
327 "60 Hz",
328 NULL
329 };
330 static const char *camera_exposure_auto[] = {
331 "Auto Mode",
332 "Manual Mode",
333 "Shutter Priority Mode",
334 "Aperture Priority Mode",
335 NULL
336 };
323 337
324 switch (id) { 338 switch (id) {
325 case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ: 339 case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
@@ -352,6 +366,10 @@ const char **v4l2_ctrl_get_menu(u32 id)
352 return mpeg_stream_type; 366 return mpeg_stream_type;
353 case V4L2_CID_MPEG_STREAM_VBI_FMT: 367 case V4L2_CID_MPEG_STREAM_VBI_FMT:
354 return mpeg_stream_vbi_fmt; 368 return mpeg_stream_vbi_fmt;
369 case V4L2_CID_POWER_LINE_FREQUENCY:
370 return camera_power_line_frequency;
371 case V4L2_CID_EXPOSURE_AUTO:
372 return camera_exposure_auto;
355 default: 373 default:
356 return NULL; 374 return NULL;
357 } 375 }
@@ -363,17 +381,37 @@ const char *v4l2_ctrl_get_name(u32 id)
363{ 381{
364 switch (id) { 382 switch (id) {
365 /* USER controls */ 383 /* USER controls */
366 case V4L2_CID_USER_CLASS: return "User Controls"; 384 case V4L2_CID_USER_CLASS: return "User Controls";
367 case V4L2_CID_AUDIO_VOLUME: return "Volume"; 385 case V4L2_CID_AUDIO_VOLUME: return "Volume";
368 case V4L2_CID_AUDIO_MUTE: return "Mute"; 386 case V4L2_CID_AUDIO_MUTE: return "Mute";
369 case V4L2_CID_AUDIO_BALANCE: return "Balance"; 387 case V4L2_CID_AUDIO_BALANCE: return "Balance";
370 case V4L2_CID_AUDIO_BASS: return "Bass"; 388 case V4L2_CID_AUDIO_BASS: return "Bass";
371 case V4L2_CID_AUDIO_TREBLE: return "Treble"; 389 case V4L2_CID_AUDIO_TREBLE: return "Treble";
372 case V4L2_CID_AUDIO_LOUDNESS: return "Loudness"; 390 case V4L2_CID_AUDIO_LOUDNESS: return "Loudness";
373 case V4L2_CID_BRIGHTNESS: return "Brightness"; 391 case V4L2_CID_BRIGHTNESS: return "Brightness";
374 case V4L2_CID_CONTRAST: return "Contrast"; 392 case V4L2_CID_CONTRAST: return "Contrast";
375 case V4L2_CID_SATURATION: return "Saturation"; 393 case V4L2_CID_SATURATION: return "Saturation";
376 case V4L2_CID_HUE: return "Hue"; 394 case V4L2_CID_HUE: return "Hue";
395 case V4L2_CID_BLACK_LEVEL: return "Black Level";
396 case V4L2_CID_AUTO_WHITE_BALANCE: return "White Balance, Automatic";
397 case V4L2_CID_DO_WHITE_BALANCE: return "Do White Balance";
398 case V4L2_CID_RED_BALANCE: return "Red Balance";
399 case V4L2_CID_BLUE_BALANCE: return "Blue Balance";
400 case V4L2_CID_GAMMA: return "Gamma";
401 case V4L2_CID_EXPOSURE: return "Exposure";
402 case V4L2_CID_AUTOGAIN: return "Gain, Automatic";
403 case V4L2_CID_GAIN: return "Gain";
404 case V4L2_CID_HFLIP: return "Horizontal Flip";
405 case V4L2_CID_VFLIP: return "Vertical Flip";
406 case V4L2_CID_HCENTER: return "Horizontal Center";
407 case V4L2_CID_VCENTER: return "Vertical Center";
408 case V4L2_CID_POWER_LINE_FREQUENCY: return "Power Line Frequency";
409 case V4L2_CID_HUE_AUTO: return "Hue, Automatic";
410 case V4L2_CID_WHITE_BALANCE_TEMPERATURE: return "White Balance Temperature";
411 case V4L2_CID_SHARPNESS: return "Sharpness";
412 case V4L2_CID_BACKLIGHT_COMPENSATION: return "Backlight Compensation";
413 case V4L2_CID_CHROMA_AGC: return "Chroma AGC";
414 case V4L2_CID_COLOR_KILLER: return "Color Killer";
377 415
378 /* MPEG controls */ 416 /* MPEG controls */
379 case V4L2_CID_MPEG_CLASS: return "MPEG Encoder Controls"; 417 case V4L2_CID_MPEG_CLASS: return "MPEG Encoder Controls";
@@ -410,6 +448,25 @@ const char *v4l2_ctrl_get_name(u32 id)
410 case V4L2_CID_MPEG_STREAM_PES_ID_VIDEO: return "Stream PES Video ID"; 448 case V4L2_CID_MPEG_STREAM_PES_ID_VIDEO: return "Stream PES Video ID";
411 case V4L2_CID_MPEG_STREAM_VBI_FMT: return "Stream VBI Format"; 449 case V4L2_CID_MPEG_STREAM_VBI_FMT: return "Stream VBI Format";
412 450
451 /* CAMERA controls */
452 case V4L2_CID_CAMERA_CLASS: return "Camera Controls";
453 case V4L2_CID_EXPOSURE_AUTO: return "Auto Exposure";
454 case V4L2_CID_EXPOSURE_ABSOLUTE: return "Exposure Time, Absolute";
455 case V4L2_CID_EXPOSURE_AUTO_PRIORITY: return "Exposure, Dynamic Framerate";
456 case V4L2_CID_PAN_RELATIVE: return "Pan, Relative";
457 case V4L2_CID_TILT_RELATIVE: return "Tilt, Relative";
458 case V4L2_CID_PAN_RESET: return "Pan, Reset";
459 case V4L2_CID_TILT_RESET: return "Tilt, Reset";
460 case V4L2_CID_PAN_ABSOLUTE: return "Pan, Absolute";
461 case V4L2_CID_TILT_ABSOLUTE: return "Tilt, Absolute";
462 case V4L2_CID_FOCUS_ABSOLUTE: return "Focus, Absolute";
463 case V4L2_CID_FOCUS_RELATIVE: return "Focus, Relative";
464 case V4L2_CID_FOCUS_AUTO: return "Focus, Automatic";
465 case V4L2_CID_ZOOM_ABSOLUTE: return "Zoom, Absolute";
466 case V4L2_CID_ZOOM_RELATIVE: return "Zoom, Relative";
467 case V4L2_CID_ZOOM_CONTINUOUS: return "Zoom, Continuous";
468 case V4L2_CID_PRIVACY: return "Privacy";
469
413 default: 470 default:
414 return NULL; 471 return NULL;
415 } 472 }
@@ -428,14 +485,22 @@ int v4l2_ctrl_query_fill(struct v4l2_queryctrl *qctrl, s32 min, s32 max, s32 ste
428 switch (qctrl->id) { 485 switch (qctrl->id) {
429 case V4L2_CID_AUDIO_MUTE: 486 case V4L2_CID_AUDIO_MUTE:
430 case V4L2_CID_AUDIO_LOUDNESS: 487 case V4L2_CID_AUDIO_LOUDNESS:
488 case V4L2_CID_AUTO_WHITE_BALANCE:
489 case V4L2_CID_AUTOGAIN:
490 case V4L2_CID_HFLIP:
491 case V4L2_CID_VFLIP:
492 case V4L2_CID_HUE_AUTO:
431 case V4L2_CID_MPEG_AUDIO_MUTE: 493 case V4L2_CID_MPEG_AUDIO_MUTE:
432 case V4L2_CID_MPEG_VIDEO_MUTE: 494 case V4L2_CID_MPEG_VIDEO_MUTE:
433 case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE: 495 case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE:
434 case V4L2_CID_MPEG_VIDEO_PULLDOWN: 496 case V4L2_CID_MPEG_VIDEO_PULLDOWN:
497 case V4L2_CID_EXPOSURE_AUTO_PRIORITY:
498 case V4L2_CID_PRIVACY:
435 qctrl->type = V4L2_CTRL_TYPE_BOOLEAN; 499 qctrl->type = V4L2_CTRL_TYPE_BOOLEAN;
436 min = 0; 500 min = 0;
437 max = step = 1; 501 max = step = 1;
438 break; 502 break;
503 case V4L2_CID_POWER_LINE_FREQUENCY:
439 case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ: 504 case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
440 case V4L2_CID_MPEG_AUDIO_ENCODING: 505 case V4L2_CID_MPEG_AUDIO_ENCODING:
441 case V4L2_CID_MPEG_AUDIO_L1_BITRATE: 506 case V4L2_CID_MPEG_AUDIO_L1_BITRATE:
@@ -451,10 +516,12 @@ int v4l2_ctrl_query_fill(struct v4l2_queryctrl *qctrl, s32 min, s32 max, s32 ste
451 case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: 516 case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
452 case V4L2_CID_MPEG_STREAM_TYPE: 517 case V4L2_CID_MPEG_STREAM_TYPE:
453 case V4L2_CID_MPEG_STREAM_VBI_FMT: 518 case V4L2_CID_MPEG_STREAM_VBI_FMT:
519 case V4L2_CID_EXPOSURE_AUTO:
454 qctrl->type = V4L2_CTRL_TYPE_MENU; 520 qctrl->type = V4L2_CTRL_TYPE_MENU;
455 step = 1; 521 step = 1;
456 break; 522 break;
457 case V4L2_CID_USER_CLASS: 523 case V4L2_CID_USER_CLASS:
524 case V4L2_CID_CAMERA_CLASS:
458 case V4L2_CID_MPEG_CLASS: 525 case V4L2_CID_MPEG_CLASS:
459 qctrl->type = V4L2_CTRL_TYPE_CTRL_CLASS; 526 qctrl->type = V4L2_CTRL_TYPE_CTRL_CLASS;
460 qctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY; 527 qctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
@@ -801,4 +868,116 @@ int v4l2_i2c_attach(struct i2c_adapter *adapter, int address, struct i2c_driver
801 return err != -ENOMEM ? 0 : err; 868 return err != -ENOMEM ? 0 : err;
802} 869}
803EXPORT_SYMBOL(v4l2_i2c_attach); 870EXPORT_SYMBOL(v4l2_i2c_attach);
871
872void v4l2_i2c_subdev_init(struct v4l2_subdev *sd, struct i2c_client *client,
873 const struct v4l2_subdev_ops *ops)
874{
875 v4l2_subdev_init(sd, ops);
876 /* the owner is the same as the i2c_client's driver owner */
877 sd->owner = client->driver->driver.owner;
878 /* i2c_client and v4l2_subdev point to one another */
879 v4l2_set_subdevdata(sd, client);
880 i2c_set_clientdata(client, sd);
881 /* initialize name */
882 snprintf(sd->name, sizeof(sd->name), "%s %d-%04x",
883 client->driver->driver.name, i2c_adapter_id(client->adapter),
884 client->addr);
885}
886EXPORT_SYMBOL_GPL(v4l2_i2c_subdev_init);
887
888
889
890/* Load an i2c sub-device. It assumes that i2c_get_adapdata(adapter)
891 returns the v4l2_device and that i2c_get_clientdata(client)
892 returns the v4l2_subdev. */
893struct v4l2_subdev *v4l2_i2c_new_subdev(struct i2c_adapter *adapter,
894 const char *module_name, const char *client_type, u8 addr)
895{
896 struct v4l2_device *dev = i2c_get_adapdata(adapter);
897 struct v4l2_subdev *sd = NULL;
898 struct i2c_client *client;
899 struct i2c_board_info info;
900
901 BUG_ON(!dev);
902#ifdef MODULE
903 if (module_name)
904 request_module(module_name);
905#endif
906 /* Setup the i2c board info with the device type and
907 the device address. */
908 memset(&info, 0, sizeof(info));
909 strlcpy(info.type, client_type, sizeof(info.type));
910 info.addr = addr;
911
912 /* Create the i2c client */
913 client = i2c_new_device(adapter, &info);
914 /* Note: it is possible in the future that
915 c->driver is NULL if the driver is still being loaded.
916 We need better support from the kernel so that we
917 can easily wait for the load to finish. */
918 if (client == NULL || client->driver == NULL)
919 return NULL;
920
921 /* Lock the module so we can safely get the v4l2_subdev pointer */
922 if (!try_module_get(client->driver->driver.owner))
923 return NULL;
924 sd = i2c_get_clientdata(client);
925
926 /* Register with the v4l2_device which increases the module's
927 use count as well. */
928 if (v4l2_device_register_subdev(dev, sd))
929 sd = NULL;
930 /* Decrease the module use count to match the first try_module_get. */
931 module_put(client->driver->driver.owner);
932 return sd;
933
934}
935EXPORT_SYMBOL_GPL(v4l2_i2c_new_subdev);
936
937/* Probe and load an i2c sub-device. It assumes that i2c_get_adapdata(adapter)
938 returns the v4l2_device and that i2c_get_clientdata(client)
939 returns the v4l2_subdev. */
940struct v4l2_subdev *v4l2_i2c_new_probed_subdev(struct i2c_adapter *adapter,
941 const char *module_name, const char *client_type,
942 const unsigned short *addrs)
943{
944 struct v4l2_device *dev = i2c_get_adapdata(adapter);
945 struct v4l2_subdev *sd = NULL;
946 struct i2c_client *client = NULL;
947 struct i2c_board_info info;
948
949 BUG_ON(!dev);
950#ifdef MODULE
951 if (module_name)
952 request_module(module_name);
953#endif
954 /* Setup the i2c board info with the device type and
955 the device address. */
956 memset(&info, 0, sizeof(info));
957 strlcpy(info.type, client_type, sizeof(info.type));
958
959 /* Probe and create the i2c client */
960 client = i2c_new_probed_device(adapter, &info, addrs);
961 /* Note: it is possible in the future that
962 c->driver is NULL if the driver is still being loaded.
963 We need better support from the kernel so that we
964 can easily wait for the load to finish. */
965 if (client == NULL || client->driver == NULL)
966 return NULL;
967
968 /* Lock the module so we can safely get the v4l2_subdev pointer */
969 if (!try_module_get(client->driver->driver.owner))
970 return NULL;
971 sd = i2c_get_clientdata(client);
972
973 /* Register with the v4l2_device which increases the module's
974 use count as well. */
975 if (v4l2_device_register_subdev(dev, sd))
976 sd = NULL;
977 /* Decrease the module use count to match the first try_module_get. */
978 module_put(client->driver->driver.owner);
979 return sd;
980}
981EXPORT_SYMBOL_GPL(v4l2_i2c_new_probed_subdev);
982
804#endif 983#endif
diff --git a/drivers/media/video/compat_ioctl32.c b/drivers/media/video/v4l2-compat-ioctl32.c
index 0ea85a05e5c0..d0e1bd3ace6a 100644
--- a/drivers/media/video/compat_ioctl32.c
+++ b/drivers/media/video/v4l2-compat-ioctl32.c
@@ -7,12 +7,14 @@
7 * Copyright (C) 2001,2002 Andi Kleen, SuSE Labs 7 * Copyright (C) 2001,2002 Andi Kleen, SuSE Labs
8 * Copyright (C) 2003 Pavel Machek (pavel@suse.cz) 8 * Copyright (C) 2003 Pavel Machek (pavel@suse.cz)
9 * Copyright (C) 2005 Philippe De Muyter (phdm@macqel.be) 9 * Copyright (C) 2005 Philippe De Muyter (phdm@macqel.be)
10 * Copyright (C) 2008 Hans Verkuil <hverkuil@xs4all.nl>
10 * 11 *
11 * These routines maintain argument size conversion between 32bit and 64bit 12 * These routines maintain argument size conversion between 32bit and 64bit
12 * ioctls. 13 * ioctls.
13 */ 14 */
14 15
15#include <linux/compat.h> 16#include <linux/compat.h>
17#define __OLD_VIDIOC_ /* To allow fixing old calls*/
16#include <linux/videodev.h> 18#include <linux/videodev.h>
17#include <linux/videodev2.h> 19#include <linux/videodev2.h>
18#include <linux/module.h> 20#include <linux/module.h>
@@ -32,7 +34,7 @@ struct video_tuner32 {
32 34
33static int get_video_tuner32(struct video_tuner *kp, struct video_tuner32 __user *up) 35static int get_video_tuner32(struct video_tuner *kp, struct video_tuner32 __user *up)
34{ 36{
35 if(!access_ok(VERIFY_READ, up, sizeof(struct video_tuner32)) || 37 if (!access_ok(VERIFY_READ, up, sizeof(struct video_tuner32)) ||
36 get_user(kp->tuner, &up->tuner) || 38 get_user(kp->tuner, &up->tuner) ||
37 copy_from_user(kp->name, up->name, 32) || 39 copy_from_user(kp->name, up->name, 32) ||
38 get_user(kp->rangelow, &up->rangelow) || 40 get_user(kp->rangelow, &up->rangelow) ||
@@ -46,7 +48,7 @@ static int get_video_tuner32(struct video_tuner *kp, struct video_tuner32 __user
46 48
47static int put_video_tuner32(struct video_tuner *kp, struct video_tuner32 __user *up) 49static int put_video_tuner32(struct video_tuner *kp, struct video_tuner32 __user *up)
48{ 50{
49 if(!access_ok(VERIFY_WRITE, up, sizeof(struct video_tuner32)) || 51 if (!access_ok(VERIFY_WRITE, up, sizeof(struct video_tuner32)) ||
50 put_user(kp->tuner, &up->tuner) || 52 put_user(kp->tuner, &up->tuner) ||
51 copy_to_user(up->name, kp->name, 32) || 53 copy_to_user(up->name, kp->name, 32) ||
52 put_user(kp->rangelow, &up->rangelow) || 54 put_user(kp->rangelow, &up->rangelow) ||
@@ -58,7 +60,6 @@ static int put_video_tuner32(struct video_tuner *kp, struct video_tuner32 __user
58 return 0; 60 return 0;
59} 61}
60 62
61
62struct video_buffer32 { 63struct video_buffer32 {
63 compat_caddr_t base; 64 compat_caddr_t base;
64 compat_int_t height, width, depth, bytesperline; 65 compat_int_t height, width, depth, bytesperline;
@@ -88,7 +89,7 @@ static int put_video_buffer32(struct video_buffer *kp, struct video_buffer32 __u
88{ 89{
89 u32 tmp = (u32)((unsigned long)kp->base); 90 u32 tmp = (u32)((unsigned long)kp->base);
90 91
91 if(!access_ok(VERIFY_WRITE, up, sizeof(struct video_buffer32)) || 92 if (!access_ok(VERIFY_WRITE, up, sizeof(struct video_buffer32)) ||
92 put_user(tmp, &up->base) || 93 put_user(tmp, &up->base) ||
93 put_user(kp->height, &up->height) || 94 put_user(kp->height, &up->height) ||
94 put_user(kp->width, &up->width) || 95 put_user(kp->width, &up->width) ||
@@ -99,7 +100,7 @@ static int put_video_buffer32(struct video_buffer *kp, struct video_buffer32 __u
99} 100}
100 101
101struct video_clip32 { 102struct video_clip32 {
102 s32 x, y, width, height; /* Its really s32 in videodev.h */ 103 s32 x, y, width, height; /* It's really s32 in videodev.h */
103 compat_caddr_t next; 104 compat_caddr_t next;
104}; 105};
105 106
@@ -108,29 +109,76 @@ struct video_window32 {
108 compat_caddr_t clips; 109 compat_caddr_t clips;
109 compat_int_t clipcount; 110 compat_int_t clipcount;
110}; 111};
111#endif
112 112
113static int native_ioctl(struct file *file, unsigned int cmd, unsigned long arg) 113static int get_video_window32(struct video_window *kp, struct video_window32 __user *up)
114{ 114{
115 int ret = -ENOIOCTLCMD; 115 struct video_clip __user *uclips;
116 struct video_clip __user *kclips;
117 compat_caddr_t p;
118 int nclips;
116 119
117 if (file->f_op->unlocked_ioctl) 120 if (!access_ok(VERIFY_READ, up, sizeof(struct video_window32)))
118 ret = file->f_op->unlocked_ioctl(file, cmd, arg); 121 return -EFAULT;
119 else if (file->f_op->ioctl) { 122
120 lock_kernel(); 123 if (get_user(nclips, &up->clipcount))
121 ret = file->f_op->ioctl(file->f_path.dentry->d_inode, file, cmd, arg); 124 return -EFAULT;
122 unlock_kernel(); 125
126 if (!access_ok(VERIFY_READ, up, sizeof(struct video_window32)) ||
127 get_user(kp->x, &up->x) ||
128 get_user(kp->y, &up->y) ||
129 get_user(kp->width, &up->width) ||
130 get_user(kp->height, &up->height) ||
131 get_user(kp->chromakey, &up->chromakey) ||
132 get_user(kp->flags, &up->flags) ||
133 get_user(kp->clipcount, &up->clipcount))
134 return -EFAULT;
135
136 nclips = kp->clipcount;
137 kp->clips = NULL;
138
139 if (nclips == 0)
140 return 0;
141 if (get_user(p, &up->clips))
142 return -EFAULT;
143 uclips = compat_ptr(p);
144
145 /* If nclips < 0, then it is a clipping bitmap of size
146 VIDEO_CLIPMAP_SIZE */
147 if (nclips < 0) {
148 if (!access_ok(VERIFY_READ, uclips, VIDEO_CLIPMAP_SIZE))
149 return -EFAULT;
150 kp->clips = compat_alloc_user_space(VIDEO_CLIPMAP_SIZE);
151 if (copy_in_user(kp->clips, uclips, VIDEO_CLIPMAP_SIZE))
152 return -EFAULT;
153 return 0;
123 } 154 }
124 155
125 return ret; 156 /* Otherwise it is an array of video_clip structs. */
126} 157 if (!access_ok(VERIFY_READ, uclips, nclips * sizeof(struct video_clip)))
158 return -EFAULT;
127 159
160 kp->clips = compat_alloc_user_space(nclips * sizeof(struct video_clip));
161 kclips = kp->clips;
162 while (nclips--) {
163 int err;
164
165 err = copy_in_user(&kclips->x, &uclips->x, sizeof(kclips->x));
166 err |= copy_in_user(&kclips->y, &uclips->y, sizeof(kclips->y));
167 err |= copy_in_user(&kclips->width, &uclips->width, sizeof(kclips->width));
168 err |= copy_in_user(&kclips->height, &uclips->height, sizeof(kclips->height));
169 kclips->next = NULL;
170 if (err)
171 return -EFAULT;
172 kclips++;
173 uclips++;
174 }
175 return 0;
176}
128 177
129#ifdef CONFIG_VIDEO_V4L1_COMPAT
130/* You get back everything except the clips... */ 178/* You get back everything except the clips... */
131static int put_video_window32(struct video_window *kp, struct video_window32 __user *up) 179static int put_video_window32(struct video_window *kp, struct video_window32 __user *up)
132{ 180{
133 if(!access_ok(VERIFY_WRITE, up, sizeof(struct video_window32)) || 181 if (!access_ok(VERIFY_WRITE, up, sizeof(struct video_window32)) ||
134 put_user(kp->x, &up->x) || 182 put_user(kp->x, &up->x) ||
135 put_user(kp->y, &up->y) || 183 put_user(kp->y, &up->y) ||
136 put_user(kp->width, &up->width) || 184 put_user(kp->width, &up->width) ||
@@ -141,16 +189,61 @@ static int put_video_window32(struct video_window *kp, struct video_window32 __u
141 return -EFAULT; 189 return -EFAULT;
142 return 0; 190 return 0;
143} 191}
192
193struct video_code32 {
194 char loadwhat[16]; /* name or tag of file being passed */
195 compat_int_t datasize;
196 unsigned char *data;
197};
198
199static int get_microcode32(struct video_code *kp, struct video_code32 __user *up)
200{
201 if (!access_ok(VERIFY_READ, up, sizeof(struct video_code32)) ||
202 copy_from_user(kp->loadwhat, up->loadwhat, sizeof(up->loadwhat)) ||
203 get_user(kp->datasize, &up->datasize) ||
204 copy_from_user(kp->data, up->data, up->datasize))
205 return -EFAULT;
206 return 0;
207}
208
209#define VIDIOCGTUNER32 _IOWR('v', 4, struct video_tuner32)
210#define VIDIOCSTUNER32 _IOW('v', 5, struct video_tuner32)
211#define VIDIOCGWIN32 _IOR('v', 9, struct video_window32)
212#define VIDIOCSWIN32 _IOW('v', 10, struct video_window32)
213#define VIDIOCGFBUF32 _IOR('v', 11, struct video_buffer32)
214#define VIDIOCSFBUF32 _IOW('v', 12, struct video_buffer32)
215#define VIDIOCGFREQ32 _IOR('v', 14, u32)
216#define VIDIOCSFREQ32 _IOW('v', 15, u32)
217#define VIDIOCSMICROCODE32 _IOW('v', 27, struct video_code32)
218
219#define VIDIOCCAPTURE32 _IOW('v', 8, s32)
220#define VIDIOCSYNC32 _IOW('v', 18, s32)
221#define VIDIOCSWRITEMODE32 _IOW('v', 25, s32)
222
144#endif 223#endif
145 224
146struct v4l2_clip32 225static int native_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
147{ 226{
227 int ret = -ENOIOCTLCMD;
228
229 if (file->f_op->unlocked_ioctl)
230 ret = file->f_op->unlocked_ioctl(file, cmd, arg);
231 else if (file->f_op->ioctl) {
232 lock_kernel();
233 ret = file->f_op->ioctl(file->f_path.dentry->d_inode, file, cmd, arg);
234 unlock_kernel();
235 }
236
237 return ret;
238}
239
240
241struct v4l2_clip32 {
148 struct v4l2_rect c; 242 struct v4l2_rect c;
149 compat_caddr_t next; 243 compat_caddr_t next;
150}; 244};
151 245
152struct v4l2_window32 246struct v4l2_window32 {
153{
154 struct v4l2_rect w; 247 struct v4l2_rect w;
155 enum v4l2_field field; 248 enum v4l2_field field;
156 __u32 chromakey; 249 __u32 chromakey;
@@ -231,15 +324,28 @@ static inline int put_v4l2_vbi_format(struct v4l2_vbi_format *kp, struct v4l2_vb
231 return 0; 324 return 0;
232} 325}
233 326
234struct v4l2_format32 327static inline int get_v4l2_sliced_vbi_format(struct v4l2_sliced_vbi_format *kp, struct v4l2_sliced_vbi_format __user *up)
328{
329 if (copy_from_user(kp, up, sizeof(struct v4l2_sliced_vbi_format)))
330 return -EFAULT;
331 return 0;
332}
333
334static inline int put_v4l2_sliced_vbi_format(struct v4l2_sliced_vbi_format *kp, struct v4l2_sliced_vbi_format __user *up)
235{ 335{
336 if (copy_to_user(up, kp, sizeof(struct v4l2_sliced_vbi_format)))
337 return -EFAULT;
338 return 0;
339}
340
341struct v4l2_format32 {
236 enum v4l2_buf_type type; 342 enum v4l2_buf_type type;
237 union 343 union {
238 { 344 struct v4l2_pix_format pix;
239 struct v4l2_pix_format pix; // V4L2_BUF_TYPE_VIDEO_CAPTURE 345 struct v4l2_window32 win;
240 struct v4l2_window32 win; // V4L2_BUF_TYPE_VIDEO_OVERLAY 346 struct v4l2_vbi_format vbi;
241 struct v4l2_vbi_format vbi; // V4L2_BUF_TYPE_VBI_CAPTURE 347 struct v4l2_sliced_vbi_format sliced;
242 __u8 raw_data[200]; // user-defined 348 __u8 raw_data[200]; /* user-defined */
243 } fmt; 349 } fmt;
244}; 350};
245 351
@@ -250,52 +356,62 @@ static int get_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user
250 return -EFAULT; 356 return -EFAULT;
251 switch (kp->type) { 357 switch (kp->type) {
252 case V4L2_BUF_TYPE_VIDEO_CAPTURE: 358 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
359 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
253 return get_v4l2_pix_format(&kp->fmt.pix, &up->fmt.pix); 360 return get_v4l2_pix_format(&kp->fmt.pix, &up->fmt.pix);
254 case V4L2_BUF_TYPE_VIDEO_OVERLAY: 361 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
362 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
255 return get_v4l2_window32(&kp->fmt.win, &up->fmt.win); 363 return get_v4l2_window32(&kp->fmt.win, &up->fmt.win);
256 case V4L2_BUF_TYPE_VBI_CAPTURE: 364 case V4L2_BUF_TYPE_VBI_CAPTURE:
365 case V4L2_BUF_TYPE_VBI_OUTPUT:
257 return get_v4l2_vbi_format(&kp->fmt.vbi, &up->fmt.vbi); 366 return get_v4l2_vbi_format(&kp->fmt.vbi, &up->fmt.vbi);
367 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
368 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
369 return get_v4l2_sliced_vbi_format(&kp->fmt.sliced, &up->fmt.sliced);
370 case V4L2_BUF_TYPE_PRIVATE:
371 if (copy_from_user(kp, up, sizeof(kp->fmt.raw_data)))
372 return -EFAULT;
373 return 0;
374 case 0:
375 return -EINVAL;
258 default: 376 default:
259 printk("compat_ioctl : unexpected VIDIOC_FMT type %d\n", 377 printk(KERN_INFO "compat_ioctl32: unexpected VIDIOC_FMT type %d\n",
260 kp->type); 378 kp->type);
261 return -ENXIO; 379 return -EINVAL;
262 } 380 }
263} 381}
264 382
265static int put_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up) 383static int put_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
266{ 384{
267 if(!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_format32)) || 385 if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_format32)) ||
268 put_user(kp->type, &up->type)) 386 put_user(kp->type, &up->type))
269 return -EFAULT; 387 return -EFAULT;
270 switch (kp->type) { 388 switch (kp->type) {
271 case V4L2_BUF_TYPE_VIDEO_CAPTURE: 389 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
390 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
272 return put_v4l2_pix_format(&kp->fmt.pix, &up->fmt.pix); 391 return put_v4l2_pix_format(&kp->fmt.pix, &up->fmt.pix);
273 case V4L2_BUF_TYPE_VIDEO_OVERLAY: 392 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
393 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
274 return put_v4l2_window32(&kp->fmt.win, &up->fmt.win); 394 return put_v4l2_window32(&kp->fmt.win, &up->fmt.win);
275 case V4L2_BUF_TYPE_VBI_CAPTURE: 395 case V4L2_BUF_TYPE_VBI_CAPTURE:
396 case V4L2_BUF_TYPE_VBI_OUTPUT:
276 return put_v4l2_vbi_format(&kp->fmt.vbi, &up->fmt.vbi); 397 return put_v4l2_vbi_format(&kp->fmt.vbi, &up->fmt.vbi);
398 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
399 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
400 return put_v4l2_sliced_vbi_format(&kp->fmt.sliced, &up->fmt.sliced);
401 case V4L2_BUF_TYPE_PRIVATE:
402 if (copy_to_user(up, kp, sizeof(up->fmt.raw_data)))
403 return -EFAULT;
404 return 0;
405 case 0:
406 return -EINVAL;
277 default: 407 default:
278 return -ENXIO; 408 printk(KERN_INFO "compat_ioctl32: unexpected VIDIOC_FMT type %d\n",
409 kp->type);
410 return -EINVAL;
279 } 411 }
280} 412}
281 413
282static inline int get_v4l2_standard(struct v4l2_standard *kp, struct v4l2_standard __user *up) 414struct v4l2_standard32 {
283{
284 if (copy_from_user(kp, up, sizeof(struct v4l2_standard)))
285 return -EFAULT;
286 return 0;
287
288}
289
290static inline int put_v4l2_standard(struct v4l2_standard *kp, struct v4l2_standard __user *up)
291{
292 if (copy_to_user(up, kp, sizeof(struct v4l2_standard)))
293 return -EFAULT;
294 return 0;
295}
296
297struct v4l2_standard32
298{
299 __u32 index; 415 __u32 index;
300 __u32 id[2]; /* __u64 would get the alignment wrong */ 416 __u32 id[2]; /* __u64 would get the alignment wrong */
301 __u8 name[24]; 417 __u8 name[24];
@@ -315,7 +431,7 @@ static int get_v4l2_standard32(struct v4l2_standard *kp, struct v4l2_standard32
315 431
316static int put_v4l2_standard32(struct v4l2_standard *kp, struct v4l2_standard32 __user *up) 432static int put_v4l2_standard32(struct v4l2_standard *kp, struct v4l2_standard32 __user *up)
317{ 433{
318 if(!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_standard32)) || 434 if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_standard32)) ||
319 put_user(kp->index, &up->index) || 435 put_user(kp->index, &up->index) ||
320 copy_to_user(up->id, &kp->id, sizeof(__u64)) || 436 copy_to_user(up->id, &kp->id, sizeof(__u64)) ||
321 copy_to_user(up->name, kp->name, 24) || 437 copy_to_user(up->name, kp->name, 24) ||
@@ -326,23 +442,7 @@ static int put_v4l2_standard32(struct v4l2_standard *kp, struct v4l2_standard32
326 return 0; 442 return 0;
327} 443}
328 444
329static inline int get_v4l2_tuner(struct v4l2_tuner *kp, struct v4l2_tuner __user *up) 445struct v4l2_buffer32 {
330{
331 if (copy_from_user(kp, up, sizeof(struct v4l2_tuner)))
332 return -EFAULT;
333 return 0;
334
335}
336
337static inline int put_v4l2_tuner(struct v4l2_tuner *kp, struct v4l2_tuner __user *up)
338{
339 if (copy_to_user(up, kp, sizeof(struct v4l2_tuner)))
340 return -EFAULT;
341 return 0;
342}
343
344struct v4l2_buffer32
345{
346 __u32 index; 446 __u32 index;
347 enum v4l2_buf_type type; 447 enum v4l2_buf_type type;
348 __u32 bytesused; 448 __u32 bytesused;
@@ -373,7 +473,7 @@ static int get_v4l2_buffer32(struct v4l2_buffer *kp, struct v4l2_buffer32 __user
373 get_user(kp->memory, &up->memory) || 473 get_user(kp->memory, &up->memory) ||
374 get_user(kp->input, &up->input)) 474 get_user(kp->input, &up->input))
375 return -EFAULT; 475 return -EFAULT;
376 switch(kp->memory) { 476 switch (kp->memory) {
377 case V4L2_MEMORY_MMAP: 477 case V4L2_MEMORY_MMAP:
378 break; 478 break;
379 case V4L2_MEMORY_USERPTR: 479 case V4L2_MEMORY_USERPTR:
@@ -388,7 +488,7 @@ static int get_v4l2_buffer32(struct v4l2_buffer *kp, struct v4l2_buffer32 __user
388 } 488 }
389 break; 489 break;
390 case V4L2_MEMORY_OVERLAY: 490 case V4L2_MEMORY_OVERLAY:
391 if(get_user(kp->m.offset, &up->m.offset)) 491 if (get_user(kp->m.offset, &up->m.offset))
392 return -EFAULT; 492 return -EFAULT;
393 break; 493 break;
394 } 494 }
@@ -404,7 +504,7 @@ static int put_v4l2_buffer32(struct v4l2_buffer *kp, struct v4l2_buffer32 __user
404 put_user(kp->memory, &up->memory) || 504 put_user(kp->memory, &up->memory) ||
405 put_user(kp->input, &up->input)) 505 put_user(kp->input, &up->input))
406 return -EFAULT; 506 return -EFAULT;
407 switch(kp->memory) { 507 switch (kp->memory) {
408 case V4L2_MEMORY_MMAP: 508 case V4L2_MEMORY_MMAP:
409 if (put_user(kp->length, &up->length) || 509 if (put_user(kp->length, &up->length) ||
410 put_user(kp->m.offset, &up->m.offset)) 510 put_user(kp->m.offset, &up->m.offset))
@@ -431,8 +531,7 @@ static int put_v4l2_buffer32(struct v4l2_buffer *kp, struct v4l2_buffer32 __user
431 return 0; 531 return 0;
432} 532}
433 533
434struct v4l2_framebuffer32 534struct v4l2_framebuffer32 {
435{
436 __u32 capability; 535 __u32 capability;
437 __u32 flags; 536 __u32 flags;
438 compat_caddr_t base; 537 compat_caddr_t base;
@@ -457,7 +556,7 @@ static int put_v4l2_framebuffer32(struct v4l2_framebuffer *kp, struct v4l2_frame
457{ 556{
458 u32 tmp = (u32)((unsigned long)kp->base); 557 u32 tmp = (u32)((unsigned long)kp->base);
459 558
460 if(!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_framebuffer32)) || 559 if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_framebuffer32)) ||
461 put_user(tmp, &up->base) || 560 put_user(tmp, &up->base) ||
462 put_user(kp->capability, &up->capability) || 561 put_user(kp->capability, &up->capability) ||
463 put_user(kp->flags, &up->flags)) 562 put_user(kp->flags, &up->flags))
@@ -466,150 +565,145 @@ static int put_v4l2_framebuffer32(struct v4l2_framebuffer *kp, struct v4l2_frame
466 return 0; 565 return 0;
467} 566}
468 567
469static inline int get_v4l2_input32(struct v4l2_input *kp, struct v4l2_input __user *up) 568struct v4l2_input32 {
569 __u32 index; /* Which input */
570 __u8 name[32]; /* Label */
571 __u32 type; /* Type of input */
572 __u32 audioset; /* Associated audios (bitfield) */
573 __u32 tuner; /* Associated tuner */
574 v4l2_std_id std;
575 __u32 status;
576 __u32 reserved[4];
577} __attribute__ ((packed));
578
579/* The 64-bit v4l2_input struct has extra padding at the end of the struct.
580 Otherwise it is identical to the 32-bit version. */
581static inline int get_v4l2_input32(struct v4l2_input *kp, struct v4l2_input32 __user *up)
470{ 582{
471 if (copy_from_user(kp, up, sizeof(struct v4l2_input) - 4)) 583 if (copy_from_user(kp, up, sizeof(struct v4l2_input32)))
472 return -EFAULT; 584 return -EFAULT;
473 return 0; 585 return 0;
474} 586}
475 587
476static inline int put_v4l2_input32(struct v4l2_input *kp, struct v4l2_input __user *up) 588static inline int put_v4l2_input32(struct v4l2_input *kp, struct v4l2_input32 __user *up)
477{ 589{
478 if (copy_to_user(up, kp, sizeof(struct v4l2_input) - 4)) 590 if (copy_to_user(up, kp, sizeof(struct v4l2_input32)))
479 return -EFAULT; 591 return -EFAULT;
480 return 0; 592 return 0;
481} 593}
482 594
483static inline int get_v4l2_input(struct v4l2_input *kp, struct v4l2_input __user *up) 595struct v4l2_ext_controls32 {
484{ 596 __u32 ctrl_class;
485 if (copy_from_user(kp, up, sizeof(struct v4l2_input))) 597 __u32 count;
486 return -EFAULT; 598 __u32 error_idx;
487 return 0; 599 __u32 reserved[2];
488} 600 compat_caddr_t controls; /* actually struct v4l2_ext_control32 * */
489
490static inline int put_v4l2_input(struct v4l2_input *kp, struct v4l2_input __user *up)
491{
492 if (copy_to_user(up, kp, sizeof(struct v4l2_input)))
493 return -EFAULT;
494 return 0;
495}
496
497#ifdef CONFIG_VIDEO_V4L1_COMPAT
498struct video_code32
499{
500 char loadwhat[16]; /* name or tag of file being passed */
501 compat_int_t datasize;
502 unsigned char *data;
503}; 601};
504 602
505static inline int microcode32(struct video_code *kp, struct video_code32 __user *up) 603static int get_v4l2_ext_controls32(struct v4l2_ext_controls *kp, struct v4l2_ext_controls32 __user *up)
506{ 604{
507 if(!access_ok(VERIFY_READ, up, sizeof(struct video_code32)) || 605 struct v4l2_ext_control __user *ucontrols;
508 copy_from_user(kp->loadwhat, up->loadwhat, sizeof (up->loadwhat)) || 606 struct v4l2_ext_control __user *kcontrols;
509 get_user(kp->datasize, &up->datasize) || 607 int n;
510 copy_from_user(kp->data, up->data, up->datasize)) 608 compat_caddr_t p;
609
610 if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_ext_controls32)) ||
611 get_user(kp->ctrl_class, &up->ctrl_class) ||
612 get_user(kp->count, &up->count) ||
613 get_user(kp->error_idx, &up->error_idx) ||
614 copy_from_user(kp->reserved, up->reserved, sizeof(kp->reserved)))
511 return -EFAULT; 615 return -EFAULT;
616 n = kp->count;
617 if (n == 0) {
618 kp->controls = NULL;
619 return 0;
620 }
621 if (get_user(p, &up->controls))
622 return -EFAULT;
623 ucontrols = compat_ptr(p);
624 if (!access_ok(VERIFY_READ, ucontrols, n * sizeof(struct v4l2_ext_control)))
625 return -EFAULT;
626 kcontrols = compat_alloc_user_space(n * sizeof(struct v4l2_ext_control));
627 kp->controls = kcontrols;
628 while (--n >= 0) {
629 if (copy_in_user(&kcontrols->id, &ucontrols->id, sizeof(__u32)))
630 return -EFAULT;
631 if (copy_in_user(&kcontrols->reserved2, &ucontrols->reserved2, sizeof(ucontrols->reserved2)))
632 return -EFAULT;
633 /* Note: if the void * part of the union ever becomes relevant
634 then we need to know the type of the control in order to do
635 the right thing here. Luckily, that is not yet an issue. */
636 if (copy_in_user(&kcontrols->value, &ucontrols->value, sizeof(ucontrols->value)))
637 return -EFAULT;
638 ucontrols++;
639 kcontrols++;
640 }
512 return 0; 641 return 0;
513} 642}
514 643
515#define VIDIOCGTUNER32 _IOWR('v',4, struct video_tuner32) 644static int put_v4l2_ext_controls32(struct v4l2_ext_controls *kp, struct v4l2_ext_controls32 __user *up)
516#define VIDIOCSTUNER32 _IOW('v',5, struct video_tuner32)
517#define VIDIOCGWIN32 _IOR('v',9, struct video_window32)
518#define VIDIOCSWIN32 _IOW('v',10, struct video_window32)
519#define VIDIOCGFBUF32 _IOR('v',11, struct video_buffer32)
520#define VIDIOCSFBUF32 _IOW('v',12, struct video_buffer32)
521#define VIDIOCGFREQ32 _IOR('v',14, u32)
522#define VIDIOCSFREQ32 _IOW('v',15, u32)
523#define VIDIOCSMICROCODE32 _IOW('v',27, struct video_code32)
524
525#endif
526
527/* VIDIOC_ENUMINPUT32 is VIDIOC_ENUMINPUT minus 4 bytes of padding alignement */
528#define VIDIOC_ENUMINPUT32 VIDIOC_ENUMINPUT - _IOC(0, 0, 0, 4)
529#define VIDIOC_G_FMT32 _IOWR ('V', 4, struct v4l2_format32)
530#define VIDIOC_S_FMT32 _IOWR ('V', 5, struct v4l2_format32)
531#define VIDIOC_QUERYBUF32 _IOWR ('V', 9, struct v4l2_buffer32)
532#define VIDIOC_G_FBUF32 _IOR ('V', 10, struct v4l2_framebuffer32)
533#define VIDIOC_S_FBUF32 _IOW ('V', 11, struct v4l2_framebuffer32)
534/* VIDIOC_OVERLAY is now _IOW, but was _IOWR */
535#define VIDIOC_OVERLAY32 _IOWR ('V', 14, compat_int_t)
536#define VIDIOC_QBUF32 _IOWR ('V', 15, struct v4l2_buffer32)
537#define VIDIOC_DQBUF32 _IOWR ('V', 17, struct v4l2_buffer32)
538#define VIDIOC_STREAMON32 _IOW ('V', 18, compat_int_t)
539#define VIDIOC_STREAMOFF32 _IOW ('V', 19, compat_int_t)
540#define VIDIOC_ENUMSTD32 _IOWR ('V', 25, struct v4l2_standard32)
541/* VIDIOC_S_CTRL is now _IOWR, but was _IOW */
542#define VIDIOC_S_CTRL32 _IOW ('V', 28, struct v4l2_control)
543#define VIDIOC_G_INPUT32 _IOR ('V', 38, compat_int_t)
544#define VIDIOC_S_INPUT32 _IOWR ('V', 39, compat_int_t)
545#define VIDIOC_TRY_FMT32 _IOWR ('V', 64, struct v4l2_format32)
546
547#ifdef CONFIG_VIDEO_V4L1_COMPAT
548enum {
549 MaxClips = (~0U-sizeof(struct video_window))/sizeof(struct video_clip)
550};
551
552static int do_set_window(struct file *file, unsigned int cmd, unsigned long arg)
553{ 645{
554 struct video_window32 __user *up = compat_ptr(arg); 646 struct v4l2_ext_control __user *ucontrols;
555 struct video_window __user *vw; 647 struct v4l2_ext_control __user *kcontrols = kp->controls;
556 struct video_clip __user *p; 648 int n = kp->count;
557 int nclips; 649 compat_caddr_t p;
558 u32 n; 650
559 651 if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_ext_controls32)) ||
560 if (!access_ok(VERIFY_READ, up, sizeof(struct video_window32))) 652 put_user(kp->ctrl_class, &up->ctrl_class) ||
561 return -EFAULT; 653 put_user(kp->count, &up->count) ||
654 put_user(kp->error_idx, &up->error_idx) ||
655 copy_to_user(up->reserved, kp->reserved, sizeof(up->reserved)))
656 return -EFAULT;
657 if (!kp->count)
658 return 0;
562 659
563 if (get_user(nclips, &up->clipcount)) 660 if (get_user(p, &up->controls))
564 return -EFAULT; 661 return -EFAULT;
565 662 ucontrols = compat_ptr(p);
566 /* Peculiar interface... */ 663 if (!access_ok(VERIFY_WRITE, ucontrols, n * sizeof(struct v4l2_ext_control)))
567 if (nclips < 0)
568 nclips = VIDEO_CLIPMAP_SIZE;
569
570 if (nclips > MaxClips)
571 return -ENOMEM;
572
573 vw = compat_alloc_user_space(sizeof(struct video_window) +
574 nclips * sizeof(struct video_clip));
575
576 p = nclips ? (struct video_clip __user *)(vw + 1) : NULL;
577
578 if (get_user(n, &up->x) || put_user(n, &vw->x) ||
579 get_user(n, &up->y) || put_user(n, &vw->y) ||
580 get_user(n, &up->width) || put_user(n, &vw->width) ||
581 get_user(n, &up->height) || put_user(n, &vw->height) ||
582 get_user(n, &up->chromakey) || put_user(n, &vw->chromakey) ||
583 get_user(n, &up->flags) || put_user(n, &vw->flags) ||
584 get_user(n, &up->clipcount) || put_user(n, &vw->clipcount) ||
585 get_user(n, &up->clips) || put_user(p, &vw->clips))
586 return -EFAULT; 664 return -EFAULT;
587 665
588 if (nclips) { 666 while (--n >= 0) {
589 struct video_clip32 __user *u = compat_ptr(n); 667 if (copy_in_user(&ucontrols->id, &kcontrols->id, sizeof(__u32)))
590 int i; 668 return -EFAULT;
591 if (!u) 669 if (copy_in_user(&ucontrols->reserved2, &kcontrols->reserved2,
592 return -EINVAL; 670 sizeof(ucontrols->reserved2)))
593 for (i = 0; i < nclips; i++, u++, p++) { 671 return -EFAULT;
594 s32 v; 672 /* Note: if the void * part of the union ever becomes relevant
595 if (!access_ok(VERIFY_READ, u, sizeof(struct video_clip32)) || 673 then we need to know the type of the control in order to do
596 !access_ok(VERIFY_WRITE, p, sizeof(struct video_clip32)) || 674 the right thing here. Luckily, that is not yet an issue. */
597 get_user(v, &u->x) || 675 if (copy_in_user(&ucontrols->value, &kcontrols->value, sizeof(ucontrols->value)))
598 put_user(v, &p->x) || 676 return -EFAULT;
599 get_user(v, &u->y) || 677 ucontrols++;
600 put_user(v, &p->y) || 678 kcontrols++;
601 get_user(v, &u->width) ||
602 put_user(v, &p->width) ||
603 get_user(v, &u->height) ||
604 put_user(v, &p->height) ||
605 put_user(NULL, &p->next))
606 return -EFAULT;
607 }
608 } 679 }
609 680 return 0;
610 return native_ioctl(file, VIDIOCSWIN, (unsigned long)vw);
611} 681}
682
683#define VIDIOC_G_FMT32 _IOWR('V', 4, struct v4l2_format32)
684#define VIDIOC_S_FMT32 _IOWR('V', 5, struct v4l2_format32)
685#define VIDIOC_QUERYBUF32 _IOWR('V', 9, struct v4l2_buffer32)
686#define VIDIOC_G_FBUF32 _IOR ('V', 10, struct v4l2_framebuffer32)
687#define VIDIOC_S_FBUF32 _IOW ('V', 11, struct v4l2_framebuffer32)
688#define VIDIOC_QBUF32 _IOWR('V', 15, struct v4l2_buffer32)
689#define VIDIOC_DQBUF32 _IOWR('V', 17, struct v4l2_buffer32)
690#define VIDIOC_ENUMSTD32 _IOWR('V', 25, struct v4l2_standard32)
691#define VIDIOC_ENUMINPUT32 _IOWR('V', 26, struct v4l2_input32)
692#define VIDIOC_TRY_FMT32 _IOWR('V', 64, struct v4l2_format32)
693#define VIDIOC_G_EXT_CTRLS32 _IOWR('V', 71, struct v4l2_ext_controls32)
694#define VIDIOC_S_EXT_CTRLS32 _IOWR('V', 72, struct v4l2_ext_controls32)
695#define VIDIOC_TRY_EXT_CTRLS32 _IOWR('V', 73, struct v4l2_ext_controls32)
696
697#define VIDIOC_OVERLAY32 _IOW ('V', 14, s32)
698#ifdef __OLD_VIDIOC_
699#define VIDIOC_OVERLAY32_OLD _IOWR('V', 14, s32)
612#endif 700#endif
701#define VIDIOC_STREAMON32 _IOW ('V', 18, s32)
702#define VIDIOC_STREAMOFF32 _IOW ('V', 19, s32)
703#define VIDIOC_G_INPUT32 _IOR ('V', 38, s32)
704#define VIDIOC_S_INPUT32 _IOWR('V', 39, s32)
705#define VIDIOC_G_OUTPUT32 _IOR ('V', 46, s32)
706#define VIDIOC_S_OUTPUT32 _IOWR('V', 47, s32)
613 707
614static int do_video_ioctl(struct file *file, unsigned int cmd, unsigned long arg) 708static int do_video_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
615{ 709{
@@ -624,53 +718,60 @@ static int do_video_ioctl(struct file *file, unsigned int cmd, unsigned long arg
624 struct v4l2_format v2f; 718 struct v4l2_format v2f;
625 struct v4l2_buffer v2b; 719 struct v4l2_buffer v2b;
626 struct v4l2_framebuffer v2fb; 720 struct v4l2_framebuffer v2fb;
627 struct v4l2_standard v2s;
628 struct v4l2_input v2i; 721 struct v4l2_input v2i;
629 struct v4l2_tuner v2t; 722 struct v4l2_standard v2s;
723 struct v4l2_ext_controls v2ecs;
630 unsigned long vx; 724 unsigned long vx;
725 int vi;
631 } karg; 726 } karg;
632 void __user *up = compat_ptr(arg); 727 void __user *up = compat_ptr(arg);
633 int compatible_arg = 1; 728 int compatible_arg = 1;
634 int err = 0; 729 int err = 0;
635 int realcmd = cmd;
636 730
637 /* First, convert the command. */ 731 /* First, convert the command. */
638 switch(cmd) { 732 switch (cmd) {
639#ifdef CONFIG_VIDEO_V4L1_COMPAT 733#ifdef CONFIG_VIDEO_V4L1_COMPAT
640 case VIDIOCGTUNER32: realcmd = cmd = VIDIOCGTUNER; break; 734 case VIDIOCGTUNER32: cmd = VIDIOCGTUNER; break;
641 case VIDIOCSTUNER32: realcmd = cmd = VIDIOCSTUNER; break; 735 case VIDIOCSTUNER32: cmd = VIDIOCSTUNER; break;
642 case VIDIOCGWIN32: realcmd = cmd = VIDIOCGWIN; break; 736 case VIDIOCGWIN32: cmd = VIDIOCGWIN; break;
643 case VIDIOCGFBUF32: realcmd = cmd = VIDIOCGFBUF; break; 737 case VIDIOCSWIN32: cmd = VIDIOCSWIN; break;
644 case VIDIOCSFBUF32: realcmd = cmd = VIDIOCSFBUF; break; 738 case VIDIOCGFBUF32: cmd = VIDIOCGFBUF; break;
645 case VIDIOCGFREQ32: realcmd = cmd = VIDIOCGFREQ; break; 739 case VIDIOCSFBUF32: cmd = VIDIOCSFBUF; break;
646 case VIDIOCSFREQ32: realcmd = cmd = VIDIOCSFREQ; break; 740 case VIDIOCGFREQ32: cmd = VIDIOCGFREQ; break;
647 case VIDIOCSMICROCODE32: realcmd = cmd = VIDIOCSMICROCODE; break; 741 case VIDIOCSFREQ32: cmd = VIDIOCSFREQ; break;
742 case VIDIOCSMICROCODE32: cmd = VIDIOCSMICROCODE; break;
648#endif 743#endif
649 case VIDIOC_G_FMT32: realcmd = cmd = VIDIOC_G_FMT; break; 744 case VIDIOC_G_FMT32: cmd = VIDIOC_G_FMT; break;
650 case VIDIOC_S_FMT32: realcmd = cmd = VIDIOC_S_FMT; break; 745 case VIDIOC_S_FMT32: cmd = VIDIOC_S_FMT; break;
651 case VIDIOC_QUERYBUF32: realcmd = cmd = VIDIOC_QUERYBUF; break; 746 case VIDIOC_QUERYBUF32: cmd = VIDIOC_QUERYBUF; break;
652 case VIDIOC_QBUF32: realcmd = cmd = VIDIOC_QBUF; break; 747 case VIDIOC_G_FBUF32: cmd = VIDIOC_G_FBUF; break;
653 case VIDIOC_DQBUF32: realcmd = cmd = VIDIOC_DQBUF; break; 748 case VIDIOC_S_FBUF32: cmd = VIDIOC_S_FBUF; break;
654 case VIDIOC_STREAMON32: realcmd = cmd = VIDIOC_STREAMON; break; 749 case VIDIOC_QBUF32: cmd = VIDIOC_QBUF; break;
655 case VIDIOC_STREAMOFF32: realcmd = cmd = VIDIOC_STREAMOFF; break; 750 case VIDIOC_DQBUF32: cmd = VIDIOC_DQBUF; break;
656 case VIDIOC_G_FBUF32: realcmd = cmd = VIDIOC_G_FBUF; break; 751 case VIDIOC_ENUMSTD32: cmd = VIDIOC_ENUMSTD; break;
657 case VIDIOC_S_FBUF32: realcmd = cmd = VIDIOC_S_FBUF; break; 752 case VIDIOC_ENUMINPUT32: cmd = VIDIOC_ENUMINPUT; break;
658 case VIDIOC_OVERLAY32: realcmd = cmd = VIDIOC_OVERLAY; break; 753 case VIDIOC_TRY_FMT32: cmd = VIDIOC_TRY_FMT; break;
659 case VIDIOC_ENUMSTD32: realcmd = VIDIOC_ENUMSTD; break; 754 case VIDIOC_G_EXT_CTRLS32: cmd = VIDIOC_G_EXT_CTRLS; break;
660 case VIDIOC_ENUMINPUT32: realcmd = VIDIOC_ENUMINPUT; break; 755 case VIDIOC_S_EXT_CTRLS32: cmd = VIDIOC_S_EXT_CTRLS; break;
661 case VIDIOC_S_CTRL32: realcmd = cmd = VIDIOC_S_CTRL; break; 756 case VIDIOC_TRY_EXT_CTRLS32: cmd = VIDIOC_TRY_EXT_CTRLS; break;
662 case VIDIOC_G_INPUT32: realcmd = cmd = VIDIOC_G_INPUT; break; 757 case VIDIOC_OVERLAY32: cmd = VIDIOC_OVERLAY; break;
663 case VIDIOC_S_INPUT32: realcmd = cmd = VIDIOC_S_INPUT; break; 758#ifdef __OLD_VIDIOC_
664 case VIDIOC_TRY_FMT32: realcmd = cmd = VIDIOC_TRY_FMT; break; 759 case VIDIOC_OVERLAY32_OLD: cmd = VIDIOC_OVERLAY; break;
665 }; 760#endif
666 761 case VIDIOC_STREAMON32: cmd = VIDIOC_STREAMON; break;
667 switch(cmd) { 762 case VIDIOC_STREAMOFF32: cmd = VIDIOC_STREAMOFF; break;
763 case VIDIOC_G_INPUT32: cmd = VIDIOC_G_INPUT; break;
764 case VIDIOC_S_INPUT32: cmd = VIDIOC_S_INPUT; break;
765 case VIDIOC_G_OUTPUT32: cmd = VIDIOC_G_OUTPUT; break;
766 case VIDIOC_S_OUTPUT32: cmd = VIDIOC_S_OUTPUT; break;
767 }
768
769 switch (cmd) {
668#ifdef CONFIG_VIDEO_V4L1_COMPAT 770#ifdef CONFIG_VIDEO_V4L1_COMPAT
669 case VIDIOCSTUNER: 771 case VIDIOCSTUNER:
670 case VIDIOCGTUNER: 772 case VIDIOCGTUNER:
671 err = get_video_tuner32(&karg.vt, up); 773 err = get_video_tuner32(&karg.vt, up);
672 compatible_arg = 0; 774 compatible_arg = 0;
673
674 break; 775 break;
675 776
676 case VIDIOCSFBUF: 777 case VIDIOCSFBUF:
@@ -678,19 +779,42 @@ static int do_video_ioctl(struct file *file, unsigned int cmd, unsigned long arg
678 compatible_arg = 0; 779 compatible_arg = 0;
679 break; 780 break;
680 781
782 case VIDIOCSWIN:
783 err = get_video_window32(&karg.vw, up);
784 compatible_arg = 0;
785 break;
786
787 case VIDIOCGWIN:
788 case VIDIOCGFBUF:
789 case VIDIOCGFREQ:
790 compatible_arg = 0;
791 break;
792
793 case VIDIOCSMICROCODE:
794 err = get_microcode32(&karg.vc, up);
795 compatible_arg = 0;
796 break;
681 797
682 case VIDIOCSFREQ: 798 case VIDIOCSFREQ:
799 err = get_user(karg.vx, (u32 __user *)up);
800 compatible_arg = 0;
801 break;
802
803 case VIDIOCCAPTURE:
804 case VIDIOCSYNC:
805 case VIDIOCSWRITEMODE:
683#endif 806#endif
684 case VIDIOC_S_INPUT:
685 case VIDIOC_OVERLAY: 807 case VIDIOC_OVERLAY:
686 case VIDIOC_STREAMON: 808 case VIDIOC_STREAMON:
687 case VIDIOC_STREAMOFF: 809 case VIDIOC_STREAMOFF:
688 err = get_user(karg.vx, (u32 __user *)up); 810 case VIDIOC_S_INPUT:
689 compatible_arg = 1; 811 case VIDIOC_S_OUTPUT:
812 err = get_user(karg.vi, (s32 __user *)up);
813 compatible_arg = 0;
690 break; 814 break;
691 815
692 case VIDIOC_S_FBUF: 816 case VIDIOC_G_INPUT:
693 err = get_v4l2_framebuffer32(&karg.v2fb, up); 817 case VIDIOC_G_OUTPUT:
694 compatible_arg = 0; 818 compatible_arg = 0;
695 break; 819 break;
696 820
@@ -708,122 +832,108 @@ static int do_video_ioctl(struct file *file, unsigned int cmd, unsigned long arg
708 compatible_arg = 0; 832 compatible_arg = 0;
709 break; 833 break;
710 834
711 case VIDIOC_ENUMSTD: 835 case VIDIOC_S_FBUF:
712 err = get_v4l2_standard(&karg.v2s, up); 836 err = get_v4l2_framebuffer32(&karg.v2fb, up);
713 compatible_arg = 0; 837 compatible_arg = 0;
714 break; 838 break;
715 839
716 case VIDIOC_ENUMSTD32: 840 case VIDIOC_G_FBUF:
717 err = get_v4l2_standard32(&karg.v2s, up);
718 compatible_arg = 0; 841 compatible_arg = 0;
719 break; 842 break;
720 843
721 case VIDIOC_ENUMINPUT: 844 case VIDIOC_ENUMSTD:
722 err = get_v4l2_input(&karg.v2i, up); 845 err = get_v4l2_standard32(&karg.v2s, up);
723 compatible_arg = 0; 846 compatible_arg = 0;
724 break; 847 break;
725 848
726 case VIDIOC_ENUMINPUT32: 849 case VIDIOC_ENUMINPUT:
727 err = get_v4l2_input32(&karg.v2i, up); 850 err = get_v4l2_input32(&karg.v2i, up);
728 compatible_arg = 0; 851 compatible_arg = 0;
729 break; 852 break;
730 853
731 case VIDIOC_G_TUNER: 854 case VIDIOC_G_EXT_CTRLS:
732 case VIDIOC_S_TUNER: 855 case VIDIOC_S_EXT_CTRLS:
733 err = get_v4l2_tuner(&karg.v2t, up); 856 case VIDIOC_TRY_EXT_CTRLS:
857 err = get_v4l2_ext_controls32(&karg.v2ecs, up);
734 compatible_arg = 0; 858 compatible_arg = 0;
735 break; 859 break;
860 }
861 if (err)
862 return err;
736 863
737#ifdef CONFIG_VIDEO_V4L1_COMPAT 864 if (compatible_arg)
738 case VIDIOCGWIN: 865 err = native_ioctl(file, cmd, (unsigned long)up);
739 case VIDIOCGFBUF:
740 case VIDIOCGFREQ:
741#endif
742 case VIDIOC_G_FBUF:
743 case VIDIOC_G_INPUT:
744 compatible_arg = 0;
745 break;
746#ifdef CONFIG_VIDEO_V4L1_COMPAT
747 case VIDIOCSMICROCODE:
748 err = microcode32(&karg.vc, up);
749 compatible_arg = 0;
750 break;
751#endif
752 };
753 if(err)
754 goto out;
755
756 if(compatible_arg)
757 err = native_ioctl(file, realcmd, (unsigned long)up);
758 else { 866 else {
759 mm_segment_t old_fs = get_fs(); 867 mm_segment_t old_fs = get_fs();
760 868
761 set_fs(KERNEL_DS); 869 set_fs(KERNEL_DS);
762 err = native_ioctl(file, realcmd, (unsigned long) &karg); 870 err = native_ioctl(file, cmd, (unsigned long)&karg);
763 set_fs(old_fs); 871 set_fs(old_fs);
764 } 872 }
765 if(err == 0) { 873
766 switch(cmd) { 874 /* Special case: even after an error we need to put the
875 results back for these ioctls since the error_idx will
876 contain information on which control failed. */
877 switch (cmd) {
878 case VIDIOC_G_EXT_CTRLS:
879 case VIDIOC_S_EXT_CTRLS:
880 case VIDIOC_TRY_EXT_CTRLS:
881 if (put_v4l2_ext_controls32(&karg.v2ecs, up))
882 err = -EFAULT;
883 break;
884 }
885 if (err)
886 return err;
887
888 switch (cmd) {
767#ifdef CONFIG_VIDEO_V4L1_COMPAT 889#ifdef CONFIG_VIDEO_V4L1_COMPAT
768 case VIDIOCGTUNER: 890 case VIDIOCGTUNER:
769 err = put_video_tuner32(&karg.vt, up); 891 err = put_video_tuner32(&karg.vt, up);
770 break; 892 break;
771 893
772 case VIDIOCGWIN: 894 case VIDIOCGWIN:
773 err = put_video_window32(&karg.vw, up); 895 err = put_video_window32(&karg.vw, up);
774 break; 896 break;
775 897
776 case VIDIOCGFBUF: 898 case VIDIOCGFBUF:
777 err = put_video_buffer32(&karg.vb, up); 899 err = put_video_buffer32(&karg.vb, up);
778 break; 900 break;
779 901
902 case VIDIOCGFREQ:
903 err = put_user(((u32)karg.vx), (u32 __user *)up);
904 break;
780#endif 905#endif
781 case VIDIOC_G_FBUF: 906 case VIDIOC_S_INPUT:
782 err = put_v4l2_framebuffer32(&karg.v2fb, up); 907 case VIDIOC_S_OUTPUT:
783 break; 908 case VIDIOC_G_INPUT:
784 909 case VIDIOC_G_OUTPUT:
785 case VIDIOC_G_FMT: 910 err = put_user(((s32)karg.vi), (s32 __user *)up);
786 case VIDIOC_S_FMT: 911 break;
787 case VIDIOC_TRY_FMT:
788 err = put_v4l2_format32(&karg.v2f, up);
789 break;
790
791 case VIDIOC_QUERYBUF:
792 case VIDIOC_QBUF:
793 case VIDIOC_DQBUF:
794 err = put_v4l2_buffer32(&karg.v2b, up);
795 break;
796
797 case VIDIOC_ENUMSTD:
798 err = put_v4l2_standard(&karg.v2s, up);
799 break;
800
801 case VIDIOC_ENUMSTD32:
802 err = put_v4l2_standard32(&karg.v2s, up);
803 break;
804
805 case VIDIOC_G_TUNER:
806 case VIDIOC_S_TUNER:
807 err = put_v4l2_tuner(&karg.v2t, up);
808 break;
809
810 case VIDIOC_ENUMINPUT:
811 err = put_v4l2_input(&karg.v2i, up);
812 break;
813
814 case VIDIOC_ENUMINPUT32:
815 err = put_v4l2_input32(&karg.v2i, up);
816 break;
817 912
818#ifdef CONFIG_VIDEO_V4L1_COMPAT 913 case VIDIOC_G_FBUF:
819 case VIDIOCGFREQ: 914 err = put_v4l2_framebuffer32(&karg.v2fb, up);
820#endif 915 break;
821 case VIDIOC_G_INPUT: 916
822 err = put_user(((u32)karg.vx), (u32 __user *)up); 917 case VIDIOC_G_FMT:
823 break; 918 case VIDIOC_S_FMT:
824 }; 919 case VIDIOC_TRY_FMT:
920 err = put_v4l2_format32(&karg.v2f, up);
921 break;
922
923 case VIDIOC_QUERYBUF:
924 case VIDIOC_QBUF:
925 case VIDIOC_DQBUF:
926 err = put_v4l2_buffer32(&karg.v2b, up);
927 break;
928
929 case VIDIOC_ENUMSTD:
930 err = put_v4l2_standard32(&karg.v2s, up);
931 break;
932
933 case VIDIOC_ENUMINPUT:
934 err = put_v4l2_input32(&karg.v2i, up);
935 break;
825 } 936 }
826out:
827 return err; 937 return err;
828} 938}
829 939
@@ -836,26 +946,48 @@ long v4l_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg)
836 946
837 switch (cmd) { 947 switch (cmd) {
838#ifdef CONFIG_VIDEO_V4L1_COMPAT 948#ifdef CONFIG_VIDEO_V4L1_COMPAT
839 case VIDIOCSWIN32: 949 case VIDIOCGCAP:
840 ret = do_set_window(file, cmd, arg); 950 case VIDIOCGCHAN:
841 break; 951 case VIDIOCSCHAN:
842 case VIDIOCGTUNER32: 952 case VIDIOCGTUNER32:
843 case VIDIOCSTUNER32: 953 case VIDIOCSTUNER32:
954 case VIDIOCGPICT:
955 case VIDIOCSPICT:
956 case VIDIOCCAPTURE32:
844 case VIDIOCGWIN32: 957 case VIDIOCGWIN32:
958 case VIDIOCSWIN32:
845 case VIDIOCGFBUF32: 959 case VIDIOCGFBUF32:
846 case VIDIOCSFBUF32: 960 case VIDIOCSFBUF32:
961 case VIDIOCKEY:
847 case VIDIOCGFREQ32: 962 case VIDIOCGFREQ32:
848 case VIDIOCSFREQ32: 963 case VIDIOCSFREQ32:
849 case VIDIOCGAUDIO: 964 case VIDIOCGAUDIO:
850 case VIDIOCSAUDIO: 965 case VIDIOCSAUDIO:
966 case VIDIOCSYNC32:
967 case VIDIOCMCAPTURE:
968 case VIDIOCGMBUF:
969 case VIDIOCGUNIT:
970 case VIDIOCGCAPTURE:
971 case VIDIOCSCAPTURE:
972 case VIDIOCSPLAYMODE:
973 case VIDIOCSWRITEMODE32:
974 case VIDIOCGPLAYINFO:
975 case VIDIOCSMICROCODE32:
851 case VIDIOCGVBIFMT: 976 case VIDIOCGVBIFMT:
852 case VIDIOCSVBIFMT: 977 case VIDIOCSVBIFMT:
853#endif 978#endif
979#ifdef __OLD_VIDIOC_
980 case VIDIOC_OVERLAY32_OLD:
981 case VIDIOC_S_PARM_OLD:
982 case VIDIOC_S_CTRL_OLD:
983 case VIDIOC_G_AUDIO_OLD:
984 case VIDIOC_G_AUDOUT_OLD:
985 case VIDIOC_CROPCAP_OLD:
986#endif
854 case VIDIOC_QUERYCAP: 987 case VIDIOC_QUERYCAP:
988 case VIDIOC_RESERVED:
855 case VIDIOC_ENUM_FMT: 989 case VIDIOC_ENUM_FMT:
856 case VIDIOC_G_FMT32: 990 case VIDIOC_G_FMT32:
857 case VIDIOC_CROPCAP:
858 case VIDIOC_S_CROP:
859 case VIDIOC_S_FMT32: 991 case VIDIOC_S_FMT32:
860 case VIDIOC_REQBUFS: 992 case VIDIOC_REQBUFS:
861 case VIDIOC_QUERYBUF32: 993 case VIDIOC_QUERYBUF32:
@@ -870,43 +1002,56 @@ long v4l_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg)
870 case VIDIOC_S_PARM: 1002 case VIDIOC_S_PARM:
871 case VIDIOC_G_STD: 1003 case VIDIOC_G_STD:
872 case VIDIOC_S_STD: 1004 case VIDIOC_S_STD:
873 case VIDIOC_G_TUNER:
874 case VIDIOC_S_TUNER:
875 case VIDIOC_ENUMSTD:
876 case VIDIOC_ENUMSTD32: 1005 case VIDIOC_ENUMSTD32:
877 case VIDIOC_ENUMINPUT:
878 case VIDIOC_ENUMINPUT32: 1006 case VIDIOC_ENUMINPUT32:
879 case VIDIOC_G_CTRL: 1007 case VIDIOC_G_CTRL:
880 case VIDIOC_S_CTRL: 1008 case VIDIOC_S_CTRL:
881 case VIDIOC_S_CTRL32: 1009 case VIDIOC_G_TUNER:
882 case VIDIOC_S_FREQUENCY: 1010 case VIDIOC_S_TUNER:
883 case VIDIOC_G_FREQUENCY: 1011 case VIDIOC_G_AUDIO:
1012 case VIDIOC_S_AUDIO:
884 case VIDIOC_QUERYCTRL: 1013 case VIDIOC_QUERYCTRL:
1014 case VIDIOC_QUERYMENU:
885 case VIDIOC_G_INPUT32: 1015 case VIDIOC_G_INPUT32:
886 case VIDIOC_S_INPUT32: 1016 case VIDIOC_S_INPUT32:
1017 case VIDIOC_G_OUTPUT32:
1018 case VIDIOC_S_OUTPUT32:
1019 case VIDIOC_ENUMOUTPUT:
1020 case VIDIOC_G_AUDOUT:
1021 case VIDIOC_S_AUDOUT:
1022 case VIDIOC_G_MODULATOR:
1023 case VIDIOC_S_MODULATOR:
1024 case VIDIOC_S_FREQUENCY:
1025 case VIDIOC_G_FREQUENCY:
1026 case VIDIOC_CROPCAP:
1027 case VIDIOC_G_CROP:
1028 case VIDIOC_S_CROP:
1029 case VIDIOC_G_JPEGCOMP:
1030 case VIDIOC_S_JPEGCOMP:
1031 case VIDIOC_QUERYSTD:
887 case VIDIOC_TRY_FMT32: 1032 case VIDIOC_TRY_FMT32:
888 case VIDIOC_S_HW_FREQ_SEEK: 1033 case VIDIOC_ENUMAUDIO:
1034 case VIDIOC_ENUMAUDOUT:
1035 case VIDIOC_G_PRIORITY:
1036 case VIDIOC_S_PRIORITY:
1037 case VIDIOC_G_SLICED_VBI_CAP:
1038 case VIDIOC_LOG_STATUS:
1039 case VIDIOC_G_EXT_CTRLS32:
1040 case VIDIOC_S_EXT_CTRLS32:
1041 case VIDIOC_TRY_EXT_CTRLS32:
889 case VIDIOC_ENUM_FRAMESIZES: 1042 case VIDIOC_ENUM_FRAMESIZES:
890 case VIDIOC_ENUM_FRAMEINTERVALS: 1043 case VIDIOC_ENUM_FRAMEINTERVALS:
1044 case VIDIOC_G_ENC_INDEX:
1045 case VIDIOC_ENCODER_CMD:
1046 case VIDIOC_TRY_ENCODER_CMD:
1047 case VIDIOC_DBG_S_REGISTER:
1048 case VIDIOC_DBG_G_REGISTER:
1049 case VIDIOC_G_CHIP_IDENT:
1050 case VIDIOC_S_HW_FREQ_SEEK:
891 ret = do_video_ioctl(file, cmd, arg); 1051 ret = do_video_ioctl(file, cmd, arg);
892 break; 1052 break;
893 1053
894#ifdef CONFIG_VIDEO_V4L1_COMPAT 1054#ifdef CONFIG_VIDEO_V4L1_COMPAT
895 /* Little v, the video4linux ioctls (conflict?) */
896 case VIDIOCGCAP:
897 case VIDIOCGCHAN:
898 case VIDIOCSCHAN:
899 case VIDIOCGPICT:
900 case VIDIOCSPICT:
901 case VIDIOCCAPTURE:
902 case VIDIOCKEY:
903 case VIDIOCSYNC:
904 case VIDIOCMCAPTURE:
905 case VIDIOCGMBUF:
906 case VIDIOCGUNIT:
907 case VIDIOCGCAPTURE:
908 case VIDIOCSCAPTURE:
909
910 /* BTTV specific... */ 1055 /* BTTV specific... */
911 case _IOW('v', BASE_VIDIOCPRIVATE+0, char [256]): 1056 case _IOW('v', BASE_VIDIOCPRIVATE+0, char [256]):
912 case _IOR('v', BASE_VIDIOCPRIVATE+1, char [256]): 1057 case _IOR('v', BASE_VIDIOCPRIVATE+1, char [256]):
@@ -921,6 +1066,8 @@ long v4l_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg)
921#endif 1066#endif
922 default: 1067 default:
923 v4l_print_ioctl("compat_ioctl32", cmd); 1068 v4l_print_ioctl("compat_ioctl32", cmd);
1069 printk(KERN_CONT "\n");
1070 break;
924 } 1071 }
925 return ret; 1072 return ret;
926} 1073}
diff --git a/drivers/media/video/v4l2-dev.c b/drivers/media/video/v4l2-dev.c
index ccd6566a515e..7ad6711ee327 100644
--- a/drivers/media/video/v4l2-dev.c
+++ b/drivers/media/video/v4l2-dev.c
@@ -9,7 +9,7 @@
9 * as published by the Free Software Foundation; either version 9 * as published by the Free Software Foundation; either version
10 * 2 of the License, or (at your option) any later version. 10 * 2 of the License, or (at your option) any later version.
11 * 11 *
12 * Authors: Alan Cox, <alan@redhat.com> (version 1) 12 * Authors: Alan Cox, <alan@lxorguk.ukuu.org.uk> (version 1)
13 * Mauro Carvalho Chehab <mchehab@infradead.org> (version 2) 13 * Mauro Carvalho Chehab <mchehab@infradead.org> (version 2)
14 * 14 *
15 * Fixes: 20000516 Claudio Matsuoka <claudio@conectiva.com> 15 * Fixes: 20000516 Claudio Matsuoka <claudio@conectiva.com>
@@ -30,6 +30,7 @@
30#include <asm/system.h> 30#include <asm/system.h>
31 31
32#include <media/v4l2-common.h> 32#include <media/v4l2-common.h>
33#include <media/v4l2-device.h>
33 34
34#define VIDEO_NUM_DEVICES 256 35#define VIDEO_NUM_DEVICES 256
35#define VIDEO_NAME "video4linux" 36#define VIDEO_NAME "video4linux"
@@ -41,17 +42,17 @@
41static ssize_t show_index(struct device *cd, 42static ssize_t show_index(struct device *cd,
42 struct device_attribute *attr, char *buf) 43 struct device_attribute *attr, char *buf)
43{ 44{
44 struct video_device *vfd = container_of(cd, struct video_device, dev); 45 struct video_device *vdev = to_video_device(cd);
45 46
46 return sprintf(buf, "%i\n", vfd->index); 47 return sprintf(buf, "%i\n", vdev->index);
47} 48}
48 49
49static ssize_t show_name(struct device *cd, 50static ssize_t show_name(struct device *cd,
50 struct device_attribute *attr, char *buf) 51 struct device_attribute *attr, char *buf)
51{ 52{
52 struct video_device *vfd = container_of(cd, struct video_device, dev); 53 struct video_device *vdev = to_video_device(cd);
53 54
54 return sprintf(buf, "%.*s\n", (int)sizeof(vfd->name), vfd->name); 55 return sprintf(buf, "%.*s\n", (int)sizeof(vdev->name), vdev->name);
55} 56}
56 57
57static struct device_attribute video_device_attrs[] = { 58static struct device_attribute video_device_attrs[] = {
@@ -73,64 +74,64 @@ struct video_device *video_device_alloc(void)
73} 74}
74EXPORT_SYMBOL(video_device_alloc); 75EXPORT_SYMBOL(video_device_alloc);
75 76
76void video_device_release(struct video_device *vfd) 77void video_device_release(struct video_device *vdev)
77{ 78{
78 kfree(vfd); 79 kfree(vdev);
79} 80}
80EXPORT_SYMBOL(video_device_release); 81EXPORT_SYMBOL(video_device_release);
81 82
82void video_device_release_empty(struct video_device *vfd) 83void video_device_release_empty(struct video_device *vdev)
83{ 84{
84 /* Do nothing */ 85 /* Do nothing */
85 /* Only valid when the video_device struct is a static. */ 86 /* Only valid when the video_device struct is a static. */
86} 87}
87EXPORT_SYMBOL(video_device_release_empty); 88EXPORT_SYMBOL(video_device_release_empty);
88 89
89/* Called when the last user of the character device is gone. */ 90static inline void video_get(struct video_device *vdev)
90static void v4l2_chardev_release(struct kobject *kobj)
91{ 91{
92 struct video_device *vfd = container_of(kobj, struct video_device, cdev.kobj); 92 get_device(&vdev->dev);
93}
94
95static inline void video_put(struct video_device *vdev)
96{
97 put_device(&vdev->dev);
98}
99
100/* Called when the last user of the video device exits. */
101static void v4l2_device_release(struct device *cd)
102{
103 struct video_device *vdev = to_video_device(cd);
93 104
94 mutex_lock(&videodev_lock); 105 mutex_lock(&videodev_lock);
95 if (video_device[vfd->minor] != vfd) { 106 if (video_device[vdev->minor] != vdev) {
96 mutex_unlock(&videodev_lock); 107 mutex_unlock(&videodev_lock);
97 BUG(); 108 /* should not happen */
109 WARN_ON(1);
98 return; 110 return;
99 } 111 }
100 112
101 /* Free up this device for reuse */ 113 /* Free up this device for reuse */
102 video_device[vfd->minor] = NULL; 114 video_device[vdev->minor] = NULL;
103 clear_bit(vfd->num, video_nums[vfd->vfl_type]);
104 mutex_unlock(&videodev_lock);
105 115
106 /* Release the character device */ 116 /* Delete the cdev on this minor as well */
107 vfd->cdev_release(kobj); 117 cdev_del(vdev->cdev);
108 /* Release video_device and perform other 118 /* Just in case some driver tries to access this from
109 cleanups as needed. */ 119 the release() callback. */
110 if (vfd->release) 120 vdev->cdev = NULL;
111 vfd->release(vfd);
112}
113 121
114/* The new kobj_type for the character device */ 122 /* Mark minor as free */
115static struct kobj_type v4l2_ktype_cdev_default = { 123 clear_bit(vdev->num, video_nums[vdev->vfl_type]);
116 .release = v4l2_chardev_release,
117};
118 124
119static void video_release(struct device *cd) 125 mutex_unlock(&videodev_lock);
120{
121 struct video_device *vfd = container_of(cd, struct video_device, dev);
122 126
123 /* It's now safe to delete the char device. 127 /* Release video_device and perform other
124 This will either trigger the v4l2_chardev_release immediately (if 128 cleanups as needed. */
125 the refcount goes to 0) or later when the last user of the 129 vdev->release(vdev);
126 character device closes it. */
127 cdev_del(&vfd->cdev);
128} 130}
129 131
130static struct class video_class = { 132static struct class video_class = {
131 .name = VIDEO_NAME, 133 .name = VIDEO_NAME,
132 .dev_attrs = video_device_attrs, 134 .dev_attrs = video_device_attrs,
133 .dev_release = video_release,
134}; 135};
135 136
136struct video_device *video_devdata(struct file *file) 137struct video_device *video_devdata(struct file *file)
@@ -139,13 +140,163 @@ struct video_device *video_devdata(struct file *file)
139} 140}
140EXPORT_SYMBOL(video_devdata); 141EXPORT_SYMBOL(video_devdata);
141 142
143static ssize_t v4l2_read(struct file *filp, char __user *buf,
144 size_t sz, loff_t *off)
145{
146 struct video_device *vdev = video_devdata(filp);
147
148 if (!vdev->fops->read)
149 return -EINVAL;
150 if (video_is_unregistered(vdev))
151 return -EIO;
152 return vdev->fops->read(filp, buf, sz, off);
153}
154
155static ssize_t v4l2_write(struct file *filp, const char __user *buf,
156 size_t sz, loff_t *off)
157{
158 struct video_device *vdev = video_devdata(filp);
159
160 if (!vdev->fops->write)
161 return -EINVAL;
162 if (video_is_unregistered(vdev))
163 return -EIO;
164 return vdev->fops->write(filp, buf, sz, off);
165}
166
167static unsigned int v4l2_poll(struct file *filp, struct poll_table_struct *poll)
168{
169 struct video_device *vdev = video_devdata(filp);
170
171 if (!vdev->fops->poll || video_is_unregistered(vdev))
172 return DEFAULT_POLLMASK;
173 return vdev->fops->poll(filp, poll);
174}
175
176static int v4l2_ioctl(struct inode *inode, struct file *filp,
177 unsigned int cmd, unsigned long arg)
178{
179 struct video_device *vdev = video_devdata(filp);
180
181 if (!vdev->fops->ioctl)
182 return -ENOTTY;
183 /* Allow ioctl to continue even if the device was unregistered.
184 Things like dequeueing buffers might still be useful. */
185 return vdev->fops->ioctl(inode, filp, cmd, arg);
186}
187
188static long v4l2_unlocked_ioctl(struct file *filp,
189 unsigned int cmd, unsigned long arg)
190{
191 struct video_device *vdev = video_devdata(filp);
192
193 if (!vdev->fops->unlocked_ioctl)
194 return -ENOTTY;
195 /* Allow ioctl to continue even if the device was unregistered.
196 Things like dequeueing buffers might still be useful. */
197 return vdev->fops->unlocked_ioctl(filp, cmd, arg);
198}
199
200#ifdef CONFIG_COMPAT
201static long v4l2_compat_ioctl(struct file *filp,
202 unsigned int cmd, unsigned long arg)
203{
204 struct video_device *vdev = video_devdata(filp);
205
206 if (!vdev->fops->compat_ioctl)
207 return -ENOIOCTLCMD;
208 /* Allow ioctl to continue even if the device was unregistered.
209 Things like dequeueing buffers might still be useful. */
210 return vdev->fops->compat_ioctl(filp, cmd, arg);
211}
212#endif
213
214static int v4l2_mmap(struct file *filp, struct vm_area_struct *vm)
215{
216 struct video_device *vdev = video_devdata(filp);
217
218 if (!vdev->fops->mmap ||
219 video_is_unregistered(vdev))
220 return -ENODEV;
221 return vdev->fops->mmap(filp, vm);
222}
223
224/* Override for the open function */
225static int v4l2_open(struct inode *inode, struct file *filp)
226{
227 struct video_device *vdev;
228 int ret;
229
230 /* Check if the video device is available */
231 mutex_lock(&videodev_lock);
232 vdev = video_devdata(filp);
233 /* return ENODEV if the video device has been removed
234 already or if it is not registered anymore. */
235 if (vdev == NULL || video_is_unregistered(vdev)) {
236 mutex_unlock(&videodev_lock);
237 return -ENODEV;
238 }
239 /* and increase the device refcount */
240 video_get(vdev);
241 mutex_unlock(&videodev_lock);
242 ret = vdev->fops->open(inode, filp);
243 /* decrease the refcount in case of an error */
244 if (ret)
245 video_put(vdev);
246 return ret;
247}
248
249/* Override for the release function */
250static int v4l2_release(struct inode *inode, struct file *filp)
251{
252 struct video_device *vdev = video_devdata(filp);
253 int ret = vdev->fops->release(inode, filp);
254
255 /* decrease the refcount unconditionally since the release()
256 return value is ignored. */
257 video_put(vdev);
258 return ret;
259}
260
261static const struct file_operations v4l2_unlocked_fops = {
262 .owner = THIS_MODULE,
263 .read = v4l2_read,
264 .write = v4l2_write,
265 .open = v4l2_open,
266 .mmap = v4l2_mmap,
267 .unlocked_ioctl = v4l2_unlocked_ioctl,
268#ifdef CONFIG_COMPAT
269 .compat_ioctl = v4l2_compat_ioctl,
270#endif
271 .release = v4l2_release,
272 .poll = v4l2_poll,
273 .llseek = no_llseek,
274};
275
276static const struct file_operations v4l2_fops = {
277 .owner = THIS_MODULE,
278 .read = v4l2_read,
279 .write = v4l2_write,
280 .open = v4l2_open,
281 .mmap = v4l2_mmap,
282 .ioctl = v4l2_ioctl,
283#ifdef CONFIG_COMPAT
284 .compat_ioctl = v4l2_compat_ioctl,
285#endif
286 .release = v4l2_release,
287 .poll = v4l2_poll,
288 .llseek = no_llseek,
289};
290
142/** 291/**
143 * get_index - assign stream number based on parent device 292 * get_index - assign stream number based on parent device
144 * @vdev: video_device to assign index number to, vdev->dev should be assigned 293 * @vdev: video_device to assign index number to, vdev->parent should be assigned
145 * @num: -1 if auto assign, requested number otherwise 294 * @num: -1 if auto assign, requested number otherwise
146 * 295 *
296 * Note that when this is called the new device has not yet been registered
297 * in the video_device array.
147 * 298 *
148 * returns -ENFILE if num is already in use, a free index number if 299 * Returns -ENFILE if num is already in use, a free index number if
149 * successful. 300 * successful.
150 */ 301 */
151static int get_index(struct video_device *vdev, int num) 302static int get_index(struct video_device *vdev, int num)
@@ -162,9 +313,12 @@ static int get_index(struct video_device *vdev, int num)
162 return -EINVAL; 313 return -EINVAL;
163 } 314 }
164 315
316 /* Some drivers do not set the parent. In that case always return 0. */
317 if (vdev->parent == NULL)
318 return 0;
319
165 for (i = 0; i < VIDEO_NUM_DEVICES; i++) { 320 for (i = 0; i < VIDEO_NUM_DEVICES; i++) {
166 if (video_device[i] != NULL && 321 if (video_device[i] != NULL &&
167 video_device[i] != vdev &&
168 video_device[i]->parent == vdev->parent) { 322 video_device[i]->parent == vdev->parent) {
169 used |= 1 << video_device[i]->index; 323 used |= 1 << video_device[i]->index;
170 } 324 }
@@ -180,17 +334,15 @@ static int get_index(struct video_device *vdev, int num)
180 return i > max_index ? -ENFILE : i; 334 return i > max_index ? -ENFILE : i;
181} 335}
182 336
183static const struct file_operations video_fops; 337int video_register_device(struct video_device *vdev, int type, int nr)
184
185int video_register_device(struct video_device *vfd, int type, int nr)
186{ 338{
187 return video_register_device_index(vfd, type, nr, -1); 339 return video_register_device_index(vdev, type, nr, -1);
188} 340}
189EXPORT_SYMBOL(video_register_device); 341EXPORT_SYMBOL(video_register_device);
190 342
191/** 343/**
192 * video_register_device_index - register video4linux devices 344 * video_register_device_index - register video4linux devices
193 * @vfd: video device structure we want to register 345 * @vdev: video device structure we want to register
194 * @type: type of device to register 346 * @type: type of device to register
195 * @nr: which device number (0 == /dev/video0, 1 == /dev/video1, ... 347 * @nr: which device number (0 == /dev/video0, 1 == /dev/video1, ...
196 * -1 == first free) 348 * -1 == first free)
@@ -214,8 +366,7 @@ EXPORT_SYMBOL(video_register_device);
214 * 366 *
215 * %VFL_TYPE_RADIO - A radio card 367 * %VFL_TYPE_RADIO - A radio card
216 */ 368 */
217 369int video_register_device_index(struct video_device *vdev, int type, int nr,
218int video_register_device_index(struct video_device *vfd, int type, int nr,
219 int index) 370 int index)
220{ 371{
221 int i = 0; 372 int i = 0;
@@ -223,14 +374,19 @@ int video_register_device_index(struct video_device *vfd, int type, int nr,
223 int minor_offset = 0; 374 int minor_offset = 0;
224 int minor_cnt = VIDEO_NUM_DEVICES; 375 int minor_cnt = VIDEO_NUM_DEVICES;
225 const char *name_base; 376 const char *name_base;
226 void *priv = video_get_drvdata(vfd); 377 void *priv = video_get_drvdata(vdev);
227 378
228 /* the release callback MUST be present */ 379 /* A minor value of -1 marks this video device as never
229 BUG_ON(!vfd->release); 380 having been registered */
381 if (vdev)
382 vdev->minor = -1;
230 383
231 if (vfd == NULL) 384 /* the release callback MUST be present */
385 WARN_ON(!vdev || !vdev->release);
386 if (!vdev || !vdev->release)
232 return -EINVAL; 387 return -EINVAL;
233 388
389 /* Part 1: check device type */
234 switch (type) { 390 switch (type) {
235 case VFL_TYPE_GRABBER: 391 case VFL_TYPE_GRABBER:
236 name_base = "video"; 392 name_base = "video";
@@ -250,8 +406,12 @@ int video_register_device_index(struct video_device *vfd, int type, int nr,
250 return -EINVAL; 406 return -EINVAL;
251 } 407 }
252 408
253 vfd->vfl_type = type; 409 vdev->vfl_type = type;
410 vdev->cdev = NULL;
411 if (vdev->v4l2_dev)
412 vdev->parent = vdev->v4l2_dev->dev;
254 413
414 /* Part 2: find a free minor, kernel number and device index. */
255#ifdef CONFIG_VIDEO_FIXED_MINOR_RANGES 415#ifdef CONFIG_VIDEO_FIXED_MINOR_RANGES
256 /* Keep the ranges for the first four types for historical 416 /* Keep the ranges for the first four types for historical
257 * reasons. 417 * reasons.
@@ -282,10 +442,7 @@ int video_register_device_index(struct video_device *vfd, int type, int nr,
282 } 442 }
283#endif 443#endif
284 444
285 /* Initialize the character device */ 445 /* Pick a minor number */
286 cdev_init(&vfd->cdev, vfd->fops);
287 vfd->cdev.owner = vfd->fops->owner;
288 /* pick a minor number */
289 mutex_lock(&videodev_lock); 446 mutex_lock(&videodev_lock);
290 nr = find_next_zero_bit(video_nums[type], minor_cnt, nr == -1 ? 0 : nr); 447 nr = find_next_zero_bit(video_nums[type], minor_cnt, nr == -1 ? 0 : nr);
291 if (nr == minor_cnt) 448 if (nr == minor_cnt)
@@ -309,72 +466,92 @@ int video_register_device_index(struct video_device *vfd, int type, int nr,
309 return -ENFILE; 466 return -ENFILE;
310 } 467 }
311#endif 468#endif
312 vfd->minor = i + minor_offset; 469 vdev->minor = i + minor_offset;
313 vfd->num = nr; 470 vdev->num = nr;
314 set_bit(nr, video_nums[type]); 471 set_bit(nr, video_nums[type]);
315 BUG_ON(video_device[vfd->minor]); 472 /* Should not happen since we thought this minor was free */
316 video_device[vfd->minor] = vfd; 473 WARN_ON(video_device[vdev->minor] != NULL);
317 474 ret = vdev->index = get_index(vdev, index);
318 ret = get_index(vfd, index);
319 vfd->index = ret;
320
321 mutex_unlock(&videodev_lock); 475 mutex_unlock(&videodev_lock);
322 476
323 if (ret < 0) { 477 if (ret < 0) {
324 printk(KERN_ERR "%s: get_index failed\n", __func__); 478 printk(KERN_ERR "%s: get_index failed\n", __func__);
325 goto fail_minor; 479 goto cleanup;
326 } 480 }
327 481
328 ret = cdev_add(&vfd->cdev, MKDEV(VIDEO_MAJOR, vfd->minor), 1); 482 /* Part 3: Initialize the character device */
483 vdev->cdev = cdev_alloc();
484 if (vdev->cdev == NULL) {
485 ret = -ENOMEM;
486 goto cleanup;
487 }
488 if (vdev->fops->unlocked_ioctl)
489 vdev->cdev->ops = &v4l2_unlocked_fops;
490 else
491 vdev->cdev->ops = &v4l2_fops;
492 vdev->cdev->owner = vdev->fops->owner;
493 ret = cdev_add(vdev->cdev, MKDEV(VIDEO_MAJOR, vdev->minor), 1);
329 if (ret < 0) { 494 if (ret < 0) {
330 printk(KERN_ERR "%s: cdev_add failed\n", __func__); 495 printk(KERN_ERR "%s: cdev_add failed\n", __func__);
331 goto fail_minor; 496 kfree(vdev->cdev);
497 vdev->cdev = NULL;
498 goto cleanup;
332 } 499 }
333 /* sysfs class */ 500
334 memset(&vfd->dev, 0, sizeof(vfd->dev)); 501 /* Part 4: register the device with sysfs */
502 memset(&vdev->dev, 0, sizeof(vdev->dev));
335 /* The memset above cleared the device's drvdata, so 503 /* The memset above cleared the device's drvdata, so
336 put back the copy we made earlier. */ 504 put back the copy we made earlier. */
337 video_set_drvdata(vfd, priv); 505 video_set_drvdata(vdev, priv);
338 vfd->dev.class = &video_class; 506 vdev->dev.class = &video_class;
339 vfd->dev.devt = MKDEV(VIDEO_MAJOR, vfd->minor); 507 vdev->dev.devt = MKDEV(VIDEO_MAJOR, vdev->minor);
340 if (vfd->parent) 508 if (vdev->parent)
341 vfd->dev.parent = vfd->parent; 509 vdev->dev.parent = vdev->parent;
342 sprintf(vfd->dev.bus_id, "%s%d", name_base, nr); 510 dev_set_name(&vdev->dev, "%s%d", name_base, nr);
343 ret = device_register(&vfd->dev); 511 ret = device_register(&vdev->dev);
344 if (ret < 0) { 512 if (ret < 0) {
345 printk(KERN_ERR "%s: device_register failed\n", __func__); 513 printk(KERN_ERR "%s: device_register failed\n", __func__);
346 goto del_cdev; 514 goto cleanup;
347 } 515 }
348 /* Remember the cdev's release function */ 516 /* Register the release callback that will be called when the last
349 vfd->cdev_release = vfd->cdev.kobj.ktype->release; 517 reference to the device goes away. */
350 /* Install our own */ 518 vdev->dev.release = v4l2_device_release;
351 vfd->cdev.kobj.ktype = &v4l2_ktype_cdev_default;
352 return 0;
353 519
354del_cdev: 520 /* Part 5: Activate this minor. The char device can now be used. */
355 cdev_del(&vfd->cdev); 521 mutex_lock(&videodev_lock);
522 video_device[vdev->minor] = vdev;
523 mutex_unlock(&videodev_lock);
524 return 0;
356 525
357fail_minor: 526cleanup:
358 mutex_lock(&videodev_lock); 527 mutex_lock(&videodev_lock);
359 video_device[vfd->minor] = NULL; 528 if (vdev->cdev)
360 clear_bit(vfd->num, video_nums[type]); 529 cdev_del(vdev->cdev);
530 clear_bit(vdev->num, video_nums[type]);
361 mutex_unlock(&videodev_lock); 531 mutex_unlock(&videodev_lock);
362 vfd->minor = -1; 532 /* Mark this video device as never having been registered. */
533 vdev->minor = -1;
363 return ret; 534 return ret;
364} 535}
365EXPORT_SYMBOL(video_register_device_index); 536EXPORT_SYMBOL(video_register_device_index);
366 537
367/** 538/**
368 * video_unregister_device - unregister a video4linux device 539 * video_unregister_device - unregister a video4linux device
369 * @vfd: the device to unregister 540 * @vdev: the device to unregister
370 * 541 *
371 * This unregisters the passed device and deassigns the minor 542 * This unregisters the passed device. Future open calls will
372 * number. Future open calls will be met with errors. 543 * be met with errors.
373 */ 544 */
374 545void video_unregister_device(struct video_device *vdev)
375void video_unregister_device(struct video_device *vfd)
376{ 546{
377 device_unregister(&vfd->dev); 547 /* Check if vdev was ever registered at all */
548 if (!vdev || vdev->minor < 0)
549 return;
550
551 mutex_lock(&videodev_lock);
552 set_bit(V4L2_FL_UNREGISTERED, &vdev->flags);
553 mutex_unlock(&videodev_lock);
554 device_unregister(&vdev->dev);
378} 555}
379EXPORT_SYMBOL(video_unregister_device); 556EXPORT_SYMBOL(video_unregister_device);
380 557
diff --git a/drivers/media/video/v4l2-device.c b/drivers/media/video/v4l2-device.c
new file mode 100644
index 000000000000..9eefde031597
--- /dev/null
+++ b/drivers/media/video/v4l2-device.c
@@ -0,0 +1,86 @@
1/*
2 V4L2 device support.
3
4 Copyright (C) 2008 Hans Verkuil <hverkuil@xs4all.nl>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#include <linux/types.h>
22#include <linux/ioctl.h>
23#include <linux/i2c.h>
24#include <linux/videodev2.h>
25#include <media/v4l2-device.h>
26
27int v4l2_device_register(struct device *dev, struct v4l2_device *v4l2_dev)
28{
29 if (dev == NULL || v4l2_dev == NULL)
30 return -EINVAL;
31 /* Warn if we apparently re-register a device */
32 WARN_ON(dev_get_drvdata(dev));
33 INIT_LIST_HEAD(&v4l2_dev->subdevs);
34 spin_lock_init(&v4l2_dev->lock);
35 v4l2_dev->dev = dev;
36 snprintf(v4l2_dev->name, sizeof(v4l2_dev->name), "%s %s",
37 dev->driver->name, dev->bus_id);
38 dev_set_drvdata(dev, v4l2_dev);
39 return 0;
40}
41EXPORT_SYMBOL_GPL(v4l2_device_register);
42
43void v4l2_device_unregister(struct v4l2_device *v4l2_dev)
44{
45 struct v4l2_subdev *sd, *next;
46
47 if (v4l2_dev == NULL || v4l2_dev->dev == NULL)
48 return;
49 dev_set_drvdata(v4l2_dev->dev, NULL);
50 /* unregister subdevs */
51 list_for_each_entry_safe(sd, next, &v4l2_dev->subdevs, list)
52 v4l2_device_unregister_subdev(sd);
53
54 v4l2_dev->dev = NULL;
55}
56EXPORT_SYMBOL_GPL(v4l2_device_unregister);
57
58int v4l2_device_register_subdev(struct v4l2_device *dev, struct v4l2_subdev *sd)
59{
60 /* Check for valid input */
61 if (dev == NULL || sd == NULL || !sd->name[0])
62 return -EINVAL;
63 /* Warn if we apparently re-register a subdev */
64 WARN_ON(sd->dev);
65 if (!try_module_get(sd->owner))
66 return -ENODEV;
67 sd->dev = dev;
68 spin_lock(&dev->lock);
69 list_add_tail(&sd->list, &dev->subdevs);
70 spin_unlock(&dev->lock);
71 return 0;
72}
73EXPORT_SYMBOL_GPL(v4l2_device_register_subdev);
74
75void v4l2_device_unregister_subdev(struct v4l2_subdev *sd)
76{
77 /* return if it isn't registered */
78 if (sd == NULL || sd->dev == NULL)
79 return;
80 spin_lock(&sd->dev->lock);
81 list_del(&sd->list);
82 spin_unlock(&sd->dev->lock);
83 sd->dev = NULL;
84 module_put(sd->owner);
85}
86EXPORT_SYMBOL_GPL(v4l2_device_unregister_subdev);
diff --git a/drivers/media/video/v4l2-ioctl.c b/drivers/media/video/v4l2-ioctl.c
index 710e1a40c422..b063381f4b3b 100644
--- a/drivers/media/video/v4l2-ioctl.c
+++ b/drivers/media/video/v4l2-ioctl.c
@@ -8,7 +8,7 @@
8 * as published by the Free Software Foundation; either version 8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version. 9 * 2 of the License, or (at your option) any later version.
10 * 10 *
11 * Authors: Alan Cox, <alan@redhat.com> (version 1) 11 * Authors: Alan Cox, <alan@lxorguk.ukuu.org.uk> (version 1)
12 * Mauro Carvalho Chehab <mchehab@infradead.org> (version 2) 12 * Mauro Carvalho Chehab <mchehab@infradead.org> (version 2)
13 */ 13 */
14 14
@@ -393,10 +393,8 @@ video_fix_command(unsigned int cmd)
393 * Obsolete usercopy function - Should be removed soon 393 * Obsolete usercopy function - Should be removed soon
394 */ 394 */
395int 395int
396video_usercopy(struct inode *inode, struct file *file, 396video_usercopy(struct file *file, unsigned int cmd, unsigned long arg,
397 unsigned int cmd, unsigned long arg, 397 v4l2_kioctl func)
398 int (*func)(struct inode *inode, struct file *file,
399 unsigned int cmd, void *arg))
400{ 398{
401 char sbuf[128]; 399 char sbuf[128];
402 void *mbuf = NULL; 400 void *mbuf = NULL;
@@ -458,7 +456,7 @@ video_usercopy(struct inode *inode, struct file *file,
458 } 456 }
459 457
460 /* call driver */ 458 /* call driver */
461 err = func(inode, file, cmd, parg); 459 err = func(file, cmd, parg);
462 if (err == -ENOIOCTLCMD) 460 if (err == -ENOIOCTLCMD)
463 err = -EINVAL; 461 err = -EINVAL;
464 if (is_ext_ctrl) { 462 if (is_ext_ctrl) {
@@ -1481,9 +1479,15 @@ static int __video_do_ioctl(struct file *file,
1481 case VIDIOC_G_CROP: 1479 case VIDIOC_G_CROP:
1482 { 1480 {
1483 struct v4l2_crop *p = arg; 1481 struct v4l2_crop *p = arg;
1482 __u32 type;
1484 1483
1485 if (!ops->vidioc_g_crop) 1484 if (!ops->vidioc_g_crop)
1486 break; 1485 break;
1486
1487 type = p->type;
1488 memset(p, 0, sizeof(*p));
1489 p->type = type;
1490
1487 dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names)); 1491 dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names));
1488 ret = ops->vidioc_g_crop(file, fh, p); 1492 ret = ops->vidioc_g_crop(file, fh, p);
1489 if (!ret) 1493 if (!ret)
@@ -1504,10 +1508,16 @@ static int __video_do_ioctl(struct file *file,
1504 case VIDIOC_CROPCAP: 1508 case VIDIOC_CROPCAP:
1505 { 1509 {
1506 struct v4l2_cropcap *p = arg; 1510 struct v4l2_cropcap *p = arg;
1511 __u32 type;
1507 1512
1508 /*FIXME: Should also show v4l2_fract pixelaspect */ 1513 /*FIXME: Should also show v4l2_fract pixelaspect */
1509 if (!ops->vidioc_cropcap) 1514 if (!ops->vidioc_cropcap)
1510 break; 1515 break;
1516
1517 type = p->type;
1518 memset(p, 0, sizeof(*p));
1519 p->type = type;
1520
1511 dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names)); 1521 dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names));
1512 ret = ops->vidioc_cropcap(file, fh, p); 1522 ret = ops->vidioc_cropcap(file, fh, p);
1513 if (!ret) { 1523 if (!ret) {
@@ -1522,6 +1532,9 @@ static int __video_do_ioctl(struct file *file,
1522 1532
1523 if (!ops->vidioc_g_jpegcomp) 1533 if (!ops->vidioc_g_jpegcomp)
1524 break; 1534 break;
1535
1536 memset(p, 0, sizeof(*p));
1537
1525 ret = ops->vidioc_g_jpegcomp(file, fh, p); 1538 ret = ops->vidioc_g_jpegcomp(file, fh, p);
1526 if (!ret) 1539 if (!ret)
1527 dbgarg(cmd, "quality=%d, APPn=%d, " 1540 dbgarg(cmd, "quality=%d, APPn=%d, "
@@ -1749,6 +1762,77 @@ static int __video_do_ioctl(struct file *file,
1749 ret = ops->vidioc_s_hw_freq_seek(file, fh, p); 1762 ret = ops->vidioc_s_hw_freq_seek(file, fh, p);
1750 break; 1763 break;
1751 } 1764 }
1765 case VIDIOC_ENUM_FRAMESIZES:
1766 {
1767 struct v4l2_frmsizeenum *p = arg;
1768
1769 if (!ops->vidioc_enum_framesizes)
1770 break;
1771
1772 memset(p, 0, sizeof(*p));
1773
1774 ret = ops->vidioc_enum_framesizes(file, fh, p);
1775 dbgarg(cmd,
1776 "index=%d, pixelformat=%d, type=%d ",
1777 p->index, p->pixel_format, p->type);
1778 switch (p->type) {
1779 case V4L2_FRMSIZE_TYPE_DISCRETE:
1780 dbgarg2("width = %d, height=%d\n",
1781 p->discrete.width, p->discrete.height);
1782 break;
1783 case V4L2_FRMSIZE_TYPE_STEPWISE:
1784 dbgarg2("min %dx%d, max %dx%d, step %dx%d\n",
1785 p->stepwise.min_width, p->stepwise.min_height,
1786 p->stepwise.step_width, p->stepwise.step_height,
1787 p->stepwise.max_width, p->stepwise.max_height);
1788 break;
1789 case V4L2_FRMSIZE_TYPE_CONTINUOUS:
1790 dbgarg2("continuous\n");
1791 break;
1792 default:
1793 dbgarg2("- Unknown type!\n");
1794 }
1795
1796 break;
1797 }
1798 case VIDIOC_ENUM_FRAMEINTERVALS:
1799 {
1800 struct v4l2_frmivalenum *p = arg;
1801
1802 if (!ops->vidioc_enum_frameintervals)
1803 break;
1804
1805 memset(p, 0, sizeof(*p));
1806
1807 ret = ops->vidioc_enum_frameintervals(file, fh, p);
1808 dbgarg(cmd,
1809 "index=%d, pixelformat=%d, width=%d, height=%d, type=%d ",
1810 p->index, p->pixel_format,
1811 p->width, p->height, p->type);
1812 switch (p->type) {
1813 case V4L2_FRMIVAL_TYPE_DISCRETE:
1814 dbgarg2("fps=%d/%d\n",
1815 p->discrete.numerator,
1816 p->discrete.denominator);
1817 break;
1818 case V4L2_FRMIVAL_TYPE_STEPWISE:
1819 dbgarg2("min=%d/%d, max=%d/%d, step=%d/%d\n",
1820 p->stepwise.min.numerator,
1821 p->stepwise.min.denominator,
1822 p->stepwise.max.numerator,
1823 p->stepwise.max.denominator,
1824 p->stepwise.step.numerator,
1825 p->stepwise.step.denominator);
1826 break;
1827 case V4L2_FRMIVAL_TYPE_CONTINUOUS:
1828 dbgarg2("continuous\n");
1829 break;
1830 default:
1831 dbgarg2("- Unknown type!\n");
1832 }
1833 break;
1834 }
1835
1752 default: 1836 default:
1753 { 1837 {
1754 if (!ops->vidioc_default) 1838 if (!ops->vidioc_default)
@@ -1768,7 +1852,7 @@ static int __video_do_ioctl(struct file *file,
1768 return ret; 1852 return ret;
1769} 1853}
1770 1854
1771int __video_ioctl2(struct file *file, 1855long __video_ioctl2(struct file *file,
1772 unsigned int cmd, unsigned long arg) 1856 unsigned int cmd, unsigned long arg)
1773{ 1857{
1774 char sbuf[128]; 1858 char sbuf[128];
diff --git a/drivers/media/video/v4l2-subdev.c b/drivers/media/video/v4l2-subdev.c
new file mode 100644
index 000000000000..e3612f29d0df
--- /dev/null
+++ b/drivers/media/video/v4l2-subdev.c
@@ -0,0 +1,110 @@
1/*
2 V4L2 sub-device support.
3
4 Copyright (C) 2008 Hans Verkuil <hverkuil@xs4all.nl>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#include <linux/types.h>
22#include <linux/ioctl.h>
23#include <linux/i2c.h>
24#include <linux/videodev2.h>
25#include <media/v4l2-subdev.h>
26
27int v4l2_subdev_command(struct v4l2_subdev *sd, unsigned cmd, void *arg)
28{
29 switch (cmd) {
30 case VIDIOC_QUERYCTRL:
31 return v4l2_subdev_call(sd, core, querymenu, arg);
32 case VIDIOC_G_CTRL:
33 return v4l2_subdev_call(sd, core, g_ctrl, arg);
34 case VIDIOC_S_CTRL:
35 return v4l2_subdev_call(sd, core, s_ctrl, arg);
36 case VIDIOC_QUERYMENU:
37 return v4l2_subdev_call(sd, core, queryctrl, arg);
38 case VIDIOC_LOG_STATUS:
39 return v4l2_subdev_call(sd, core, log_status);
40 case VIDIOC_G_CHIP_IDENT:
41 return v4l2_subdev_call(sd, core, g_chip_ident, arg);
42 case VIDIOC_INT_S_STANDBY:
43 return v4l2_subdev_call(sd, core, s_standby, arg ? (*(u32 *)arg) : 0);
44 case VIDIOC_INT_RESET:
45 return v4l2_subdev_call(sd, core, reset, arg ? (*(u32 *)arg) : 0);
46 case VIDIOC_INT_S_GPIO:
47 return v4l2_subdev_call(sd, core, s_gpio, arg ? (*(u32 *)arg) : 0);
48 case VIDIOC_INT_INIT:
49 return v4l2_subdev_call(sd, core, init, arg ? (*(u32 *)arg) : 0);
50#ifdef CONFIG_VIDEO_ADV_DEBUG
51 case VIDIOC_DBG_G_REGISTER:
52 return v4l2_subdev_call(sd, core, g_register, arg);
53 case VIDIOC_DBG_S_REGISTER:
54 return v4l2_subdev_call(sd, core, s_register, arg);
55#endif
56
57 case VIDIOC_INT_S_TUNER_MODE:
58 return v4l2_subdev_call(sd, tuner, s_mode, *(enum v4l2_tuner_type *)arg);
59 case AUDC_SET_RADIO:
60 return v4l2_subdev_call(sd, tuner, s_radio);
61 case VIDIOC_S_TUNER:
62 return v4l2_subdev_call(sd, tuner, s_tuner, arg);
63 case VIDIOC_G_TUNER:
64 return v4l2_subdev_call(sd, tuner, g_tuner, arg);
65 case VIDIOC_S_STD:
66 return v4l2_subdev_call(sd, tuner, s_std, *(v4l2_std_id *)arg);
67 case VIDIOC_S_FREQUENCY:
68 return v4l2_subdev_call(sd, tuner, s_frequency, arg);
69 case VIDIOC_G_FREQUENCY:
70 return v4l2_subdev_call(sd, tuner, g_frequency, arg);
71 case TUNER_SET_TYPE_ADDR:
72 return v4l2_subdev_call(sd, tuner, s_type_addr, arg);
73 case TUNER_SET_CONFIG:
74 return v4l2_subdev_call(sd, tuner, s_config, arg);
75
76 case VIDIOC_INT_AUDIO_CLOCK_FREQ:
77 return v4l2_subdev_call(sd, audio, s_clock_freq, *(u32 *)arg);
78 case VIDIOC_INT_S_AUDIO_ROUTING:
79 return v4l2_subdev_call(sd, audio, s_routing, arg);
80 case VIDIOC_INT_I2S_CLOCK_FREQ:
81 return v4l2_subdev_call(sd, audio, s_i2s_clock_freq, *(u32 *)arg);
82
83 case VIDIOC_INT_S_VIDEO_ROUTING:
84 return v4l2_subdev_call(sd, video, s_routing, arg);
85 case VIDIOC_INT_S_CRYSTAL_FREQ:
86 return v4l2_subdev_call(sd, video, s_crystal_freq, arg);
87 case VIDIOC_INT_DECODE_VBI_LINE:
88 return v4l2_subdev_call(sd, video, decode_vbi_line, arg);
89 case VIDIOC_INT_S_VBI_DATA:
90 return v4l2_subdev_call(sd, video, s_vbi_data, arg);
91 case VIDIOC_INT_G_VBI_DATA:
92 return v4l2_subdev_call(sd, video, g_vbi_data, arg);
93 case VIDIOC_G_SLICED_VBI_CAP:
94 return v4l2_subdev_call(sd, video, g_sliced_vbi_cap, arg);
95 case VIDIOC_S_FMT:
96 return v4l2_subdev_call(sd, video, s_fmt, arg);
97 case VIDIOC_G_FMT:
98 return v4l2_subdev_call(sd, video, g_fmt, arg);
99 case VIDIOC_INT_S_STD_OUTPUT:
100 return v4l2_subdev_call(sd, video, s_std_output, *(v4l2_std_id *)arg);
101 case VIDIOC_STREAMON:
102 return v4l2_subdev_call(sd, video, s_stream, 1);
103 case VIDIOC_STREAMOFF:
104 return v4l2_subdev_call(sd, video, s_stream, 0);
105
106 default:
107 return v4l2_subdev_call(sd, core, ioctl, cmd, arg);
108 }
109}
110EXPORT_SYMBOL_GPL(v4l2_subdev_command);
diff --git a/drivers/media/video/vino.c b/drivers/media/video/vino.c
index 1efc5f3462c6..a72a361daade 100644
--- a/drivers/media/video/vino.c
+++ b/drivers/media/video/vino.c
@@ -4237,8 +4237,7 @@ error:
4237 return ret; 4237 return ret;
4238} 4238}
4239 4239
4240static int vino_do_ioctl(struct inode *inode, struct file *file, 4240static int vino_do_ioctl(struct file *file, unsigned int cmd, void *arg)
4241 unsigned int cmd, void *arg)
4242{ 4241{
4243 struct vino_channel_settings *vcs = video_drvdata(file); 4242 struct vino_channel_settings *vcs = video_drvdata(file);
4244 4243
@@ -4353,7 +4352,7 @@ static int vino_ioctl(struct inode *inode, struct file *file,
4353 if (mutex_lock_interruptible(&vcs->mutex)) 4352 if (mutex_lock_interruptible(&vcs->mutex))
4354 return -EINTR; 4353 return -EINTR;
4355 4354
4356 ret = video_usercopy(inode, file, cmd, arg, vino_do_ioctl); 4355 ret = video_usercopy(file, cmd, arg, vino_do_ioctl);
4357 4356
4358 mutex_unlock(&vcs->mutex); 4357 mutex_unlock(&vcs->mutex);
4359 4358
diff --git a/drivers/media/video/vp27smpx.c b/drivers/media/video/vp27smpx.c
index 577956c5410b..f72b859486ad 100644
--- a/drivers/media/video/vp27smpx.c
+++ b/drivers/media/video/vp27smpx.c
@@ -28,7 +28,7 @@
28#include <linux/i2c.h> 28#include <linux/i2c.h>
29#include <linux/i2c-id.h> 29#include <linux/i2c-id.h>
30#include <linux/videodev2.h> 30#include <linux/videodev2.h>
31#include <media/v4l2-common.h> 31#include <media/v4l2-device.h>
32#include <media/v4l2-chip-ident.h> 32#include <media/v4l2-chip-ident.h>
33#include <media/v4l2-i2c-drv.h> 33#include <media/v4l2-i2c-drv.h>
34 34
@@ -40,13 +40,20 @@ MODULE_LICENSE("GPL");
40/* ----------------------------------------------------------------------- */ 40/* ----------------------------------------------------------------------- */
41 41
42struct vp27smpx_state { 42struct vp27smpx_state {
43 struct v4l2_subdev sd;
43 int radio; 44 int radio;
44 u32 audmode; 45 u32 audmode;
45}; 46};
46 47
47static void vp27smpx_set_audmode(struct i2c_client *client, u32 audmode) 48static inline struct vp27smpx_state *to_state(struct v4l2_subdev *sd)
48{ 49{
49 struct vp27smpx_state *state = i2c_get_clientdata(client); 50 return container_of(sd, struct vp27smpx_state, sd);
51}
52
53static void vp27smpx_set_audmode(struct v4l2_subdev *sd, u32 audmode)
54{
55 struct vp27smpx_state *state = to_state(sd);
56 struct i2c_client *client = v4l2_get_subdevdata(sd);
50 u8 data[3] = { 0x00, 0x00, 0x04 }; 57 u8 data[3] = { 0x00, 0x00, 0x04 };
51 58
52 switch (audmode) { 59 switch (audmode) {
@@ -63,55 +70,89 @@ static void vp27smpx_set_audmode(struct i2c_client *client, u32 audmode)
63 } 70 }
64 71
65 if (i2c_master_send(client, data, sizeof(data)) != sizeof(data)) 72 if (i2c_master_send(client, data, sizeof(data)) != sizeof(data))
66 v4l_err(client, "%s: I/O error setting audmode\n", 73 v4l2_err(sd, "I/O error setting audmode\n");
67 client->name);
68 else 74 else
69 state->audmode = audmode; 75 state->audmode = audmode;
70} 76}
71 77
72static int vp27smpx_command(struct i2c_client *client, unsigned cmd, void *arg) 78static int vp27smpx_s_radio(struct v4l2_subdev *sd)
73{ 79{
74 struct vp27smpx_state *state = i2c_get_clientdata(client); 80 struct vp27smpx_state *state = to_state(sd);
75 struct v4l2_tuner *vt = arg;
76 81
77 switch (cmd) { 82 state->radio = 1;
78 case AUDC_SET_RADIO: 83 return 0;
79 state->radio = 1; 84}
80 break;
81 85
82 case VIDIOC_S_STD: 86static int vp27smpx_s_std(struct v4l2_subdev *sd, v4l2_std_id norm)
83 state->radio = 0; 87{
84 break; 88 struct vp27smpx_state *state = to_state(sd);
85 89
86 case VIDIOC_S_TUNER: 90 state->radio = 0;
87 if (!state->radio) 91 return 0;
88 vp27smpx_set_audmode(client, vt->audmode); 92}
89 break;
90 93
91 case VIDIOC_G_TUNER: 94static int vp27smpx_s_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
92 if (state->radio) 95{
93 break; 96 struct vp27smpx_state *state = to_state(sd);
94 vt->audmode = state->audmode;
95 vt->capability = V4L2_TUNER_CAP_STEREO |
96 V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2;
97 vt->rxsubchans = V4L2_TUNER_SUB_MONO;
98 break;
99 97
100 case VIDIOC_G_CHIP_IDENT: 98 if (!state->radio)
101 return v4l2_chip_ident_i2c_client(client, arg, 99 vp27smpx_set_audmode(sd, vt->audmode);
102 V4L2_IDENT_VP27SMPX, 0); 100 return 0;
101}
103 102
104 case VIDIOC_LOG_STATUS: 103static int vp27smpx_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
105 v4l_info(client, "Audio Mode: %u%s\n", state->audmode, 104{
106 state->radio ? " (Radio)" : ""); 105 struct vp27smpx_state *state = to_state(sd);
107 break; 106
107 if (state->radio)
108 return 0;
109 vt->audmode = state->audmode;
110 vt->capability = V4L2_TUNER_CAP_STEREO |
111 V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2;
112 vt->rxsubchans = V4L2_TUNER_SUB_MONO;
113 return 0;
114}
108 115
109 default: 116static int vp27smpx_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_chip_ident *chip)
110 return -EINVAL; 117{
111 } 118 struct i2c_client *client = v4l2_get_subdevdata(sd);
119
120 return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_VP27SMPX, 0);
121}
122
123static int vp27smpx_log_status(struct v4l2_subdev *sd)
124{
125 struct vp27smpx_state *state = to_state(sd);
126
127 v4l2_info(sd, "Audio Mode: %u%s\n", state->audmode,
128 state->radio ? " (Radio)" : "");
112 return 0; 129 return 0;
113} 130}
114 131
132static int vp27smpx_command(struct i2c_client *client, unsigned cmd, void *arg)
133{
134 return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
135}
136
137/* ----------------------------------------------------------------------- */
138
139static const struct v4l2_subdev_core_ops vp27smpx_core_ops = {
140 .log_status = vp27smpx_log_status,
141 .g_chip_ident = vp27smpx_g_chip_ident,
142};
143
144static const struct v4l2_subdev_tuner_ops vp27smpx_tuner_ops = {
145 .s_radio = vp27smpx_s_radio,
146 .s_std = vp27smpx_s_std,
147 .s_tuner = vp27smpx_s_tuner,
148 .g_tuner = vp27smpx_g_tuner,
149};
150
151static const struct v4l2_subdev_ops vp27smpx_ops = {
152 .core = &vp27smpx_core_ops,
153 .tuner = &vp27smpx_tuner_ops,
154};
155
115/* ----------------------------------------------------------------------- */ 156/* ----------------------------------------------------------------------- */
116 157
117/* i2c implementation */ 158/* i2c implementation */
@@ -125,6 +166,7 @@ static int vp27smpx_probe(struct i2c_client *client,
125 const struct i2c_device_id *id) 166 const struct i2c_device_id *id)
126{ 167{
127 struct vp27smpx_state *state; 168 struct vp27smpx_state *state;
169 struct v4l2_subdev *sd;
128 170
129 /* Check if the adapter supports the needed features */ 171 /* Check if the adapter supports the needed features */
130 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) 172 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
@@ -136,17 +178,21 @@ static int vp27smpx_probe(struct i2c_client *client,
136 state = kzalloc(sizeof(struct vp27smpx_state), GFP_KERNEL); 178 state = kzalloc(sizeof(struct vp27smpx_state), GFP_KERNEL);
137 if (state == NULL) 179 if (state == NULL)
138 return -ENOMEM; 180 return -ENOMEM;
181 sd = &state->sd;
182 v4l2_i2c_subdev_init(sd, client, &vp27smpx_ops);
139 state->audmode = V4L2_TUNER_MODE_STEREO; 183 state->audmode = V4L2_TUNER_MODE_STEREO;
140 i2c_set_clientdata(client, state);
141 184
142 /* initialize vp27smpx */ 185 /* initialize vp27smpx */
143 vp27smpx_set_audmode(client, state->audmode); 186 vp27smpx_set_audmode(sd, state->audmode);
144 return 0; 187 return 0;
145} 188}
146 189
147static int vp27smpx_remove(struct i2c_client *client) 190static int vp27smpx_remove(struct i2c_client *client)
148{ 191{
149 kfree(i2c_get_clientdata(client)); 192 struct v4l2_subdev *sd = i2c_get_clientdata(client);
193
194 v4l2_device_unregister_subdev(sd);
195 kfree(to_state(sd));
150 return 0; 196 return 0;
151} 197}
152 198
diff --git a/drivers/media/video/w9966.c b/drivers/media/video/w9966.c
index b2dbe48a92bb..56c570c267ea 100644
--- a/drivers/media/video/w9966.c
+++ b/drivers/media/video/w9966.c
@@ -727,8 +727,7 @@ static int w9966_wReg_i2c(struct w9966_dev* cam, int reg, int data)
727 * Video4linux interfacing 727 * Video4linux interfacing
728 */ 728 */
729 729
730static int w9966_v4l_do_ioctl(struct inode *inode, struct file *file, 730static int w9966_v4l_do_ioctl(struct file *file, unsigned int cmd, void *arg)
731 unsigned int cmd, void *arg)
732{ 731{
733 struct w9966_dev *cam = video_drvdata(file); 732 struct w9966_dev *cam = video_drvdata(file);
734 733
@@ -881,7 +880,7 @@ static int w9966_v4l_do_ioctl(struct inode *inode, struct file *file,
881static int w9966_v4l_ioctl(struct inode *inode, struct file *file, 880static int w9966_v4l_ioctl(struct inode *inode, struct file *file,
882 unsigned int cmd, unsigned long arg) 881 unsigned int cmd, unsigned long arg)
883{ 882{
884 return video_usercopy(inode, file, cmd, arg, w9966_v4l_do_ioctl); 883 return video_usercopy(file, cmd, arg, w9966_v4l_do_ioctl);
885} 884}
886 885
887// Capture data 886// Capture data
diff --git a/drivers/media/video/wm8739.c b/drivers/media/video/wm8739.c
index 54ac3fe26ec2..12a31e7a5f6d 100644
--- a/drivers/media/video/wm8739.c
+++ b/drivers/media/video/wm8739.c
@@ -28,7 +28,7 @@
28#include <linux/i2c.h> 28#include <linux/i2c.h>
29#include <linux/i2c-id.h> 29#include <linux/i2c-id.h>
30#include <linux/videodev2.h> 30#include <linux/videodev2.h>
31#include <media/v4l2-common.h> 31#include <media/v4l2-device.h>
32#include <media/v4l2-chip-ident.h> 32#include <media/v4l2-chip-ident.h>
33#include <media/v4l2-i2c-drv.h> 33#include <media/v4l2-i2c-drv.h>
34 34
@@ -52,6 +52,7 @@ enum {
52}; 52};
53 53
54struct wm8739_state { 54struct wm8739_state {
55 struct v4l2_subdev sd;
55 u32 clock_freq; 56 u32 clock_freq;
56 u8 muted; 57 u8 muted;
57 u16 volume; 58 u16 volume;
@@ -60,43 +61,49 @@ struct wm8739_state {
60 u8 vol_r; /* +12dB to -34.5dB 1.5dB step (5bit) def:0dB */ 61 u8 vol_r; /* +12dB to -34.5dB 1.5dB step (5bit) def:0dB */
61}; 62};
62 63
64static inline struct wm8739_state *to_state(struct v4l2_subdev *sd)
65{
66 return container_of(sd, struct wm8739_state, sd);
67}
68
63/* ------------------------------------------------------------------------ */ 69/* ------------------------------------------------------------------------ */
64 70
65static int wm8739_write(struct i2c_client *client, int reg, u16 val) 71static int wm8739_write(struct v4l2_subdev *sd, int reg, u16 val)
66{ 72{
73 struct i2c_client *client = v4l2_get_subdevdata(sd);
67 int i; 74 int i;
68 75
69 if (reg < 0 || reg >= TOT_REGS) { 76 if (reg < 0 || reg >= TOT_REGS) {
70 v4l_err(client, "Invalid register R%d\n", reg); 77 v4l2_err(sd, "Invalid register R%d\n", reg);
71 return -1; 78 return -1;
72 } 79 }
73 80
74 v4l_dbg(1, debug, client, "write: %02x %02x\n", reg, val); 81 v4l2_dbg(1, debug, sd, "write: %02x %02x\n", reg, val);
75 82
76 for (i = 0; i < 3; i++) 83 for (i = 0; i < 3; i++)
77 if (i2c_smbus_write_byte_data(client, 84 if (i2c_smbus_write_byte_data(client,
78 (reg << 1) | (val >> 8), val & 0xff) == 0) 85 (reg << 1) | (val >> 8), val & 0xff) == 0)
79 return 0; 86 return 0;
80 v4l_err(client, "I2C: cannot write %03x to register R%d\n", val, reg); 87 v4l2_err(sd, "I2C: cannot write %03x to register R%d\n", val, reg);
81 return -1; 88 return -1;
82} 89}
83 90
84/* write regs to set audio volume etc */ 91/* write regs to set audio volume etc */
85static void wm8739_set_audio(struct i2c_client *client) 92static void wm8739_set_audio(struct v4l2_subdev *sd)
86{ 93{
87 struct wm8739_state *state = i2c_get_clientdata(client); 94 struct wm8739_state *state = to_state(sd);
88 u16 mute = state->muted ? 0x80 : 0; 95 u16 mute = state->muted ? 0x80 : 0;
89 96
90 /* Volume setting: bits 0-4, 0x1f = 12 dB, 0x00 = -34.5 dB 97 /* Volume setting: bits 0-4, 0x1f = 12 dB, 0x00 = -34.5 dB
91 * Default setting: 0x17 = 0 dB 98 * Default setting: 0x17 = 0 dB
92 */ 99 */
93 wm8739_write(client, R0, (state->vol_l & 0x1f) | mute); 100 wm8739_write(sd, R0, (state->vol_l & 0x1f) | mute);
94 wm8739_write(client, R1, (state->vol_r & 0x1f) | mute); 101 wm8739_write(sd, R1, (state->vol_r & 0x1f) | mute);
95} 102}
96 103
97static int wm8739_get_ctrl(struct i2c_client *client, struct v4l2_control *ctrl) 104static int wm8739_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
98{ 105{
99 struct wm8739_state *state = i2c_get_clientdata(client); 106 struct wm8739_state *state = to_state(sd);
100 107
101 switch (ctrl->id) { 108 switch (ctrl->id) {
102 case V4L2_CID_AUDIO_MUTE: 109 case V4L2_CID_AUDIO_MUTE:
@@ -117,9 +124,9 @@ static int wm8739_get_ctrl(struct i2c_client *client, struct v4l2_control *ctrl)
117 return 0; 124 return 0;
118} 125}
119 126
120static int wm8739_set_ctrl(struct i2c_client *client, struct v4l2_control *ctrl) 127static int wm8739_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
121{ 128{
122 struct wm8739_state *state = i2c_get_clientdata(client); 129 struct wm8739_state *state = to_state(sd);
123 unsigned int work_l, work_r; 130 unsigned int work_l, work_r;
124 131
125 switch (ctrl->id) { 132 switch (ctrl->id) {
@@ -147,7 +154,7 @@ static int wm8739_set_ctrl(struct i2c_client *client, struct v4l2_control *ctrl)
147 state->vol_r = (long)work_r * 31 / 65535; 154 state->vol_r = (long)work_r * 31 / 65535;
148 155
149 /* set audio volume etc. */ 156 /* set audio volume etc. */
150 wm8739_set_audio(client); 157 wm8739_set_audio(sd);
151 return 0; 158 return 0;
152} 159}
153 160
@@ -186,77 +193,89 @@ static struct v4l2_queryctrl wm8739_qctrl[] = {
186 193
187/* ------------------------------------------------------------------------ */ 194/* ------------------------------------------------------------------------ */
188 195
189static int wm8739_command(struct i2c_client *client, unsigned cmd, void *arg) 196static int wm8739_s_clock_freq(struct v4l2_subdev *sd, u32 audiofreq)
190{ 197{
191 struct wm8739_state *state = i2c_get_clientdata(client); 198 struct wm8739_state *state = to_state(sd);
192 199
193 switch (cmd) { 200 state->clock_freq = audiofreq;
194 case VIDIOC_INT_AUDIO_CLOCK_FREQ: 201 /* de-activate */
195 { 202 wm8739_write(sd, R9, 0x000);
196 u32 audiofreq = *(u32 *)arg; 203 switch (audiofreq) {
197 204 case 44100:
198 state->clock_freq = audiofreq; 205 /* 256fps, fs=44.1k */
199 /* de-activate */ 206 wm8739_write(sd, R8, 0x020);
200 wm8739_write(client, R9, 0x000); 207 break;
201 switch (audiofreq) { 208 case 48000:
202 case 44100: 209 /* 256fps, fs=48k */
203 /* 256fps, fs=44.1k */ 210 wm8739_write(sd, R8, 0x000);
204 wm8739_write(client, R8, 0x020); 211 break;
205 break; 212 case 32000:
206 case 48000: 213 /* 256fps, fs=32k */
207 /* 256fps, fs=48k */ 214 wm8739_write(sd, R8, 0x018);
208 wm8739_write(client, R8, 0x000); 215 break;
209 break; 216 default:
210 case 32000:
211 /* 256fps, fs=32k */
212 wm8739_write(client, R8, 0x018);
213 break;
214 default:
215 break;
216 }
217 /* activate */
218 wm8739_write(client, R9, 0x001);
219 break; 217 break;
220 } 218 }
219 /* activate */
220 wm8739_write(sd, R9, 0x001);
221 return 0;
222}
221 223
222 case VIDIOC_G_CTRL: 224static int wm8739_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
223 return wm8739_get_ctrl(client, arg); 225{
224 226 int i;
225 case VIDIOC_S_CTRL:
226 return wm8739_set_ctrl(client, arg);
227 227
228 case VIDIOC_QUERYCTRL: 228 for (i = 0; i < ARRAY_SIZE(wm8739_qctrl); i++)
229 { 229 if (qc->id && qc->id == wm8739_qctrl[i].id) {
230 struct v4l2_queryctrl *qc = arg; 230 memcpy(qc, &wm8739_qctrl[i], sizeof(*qc));
231 int i; 231 return 0;
232 232 }
233 for (i = 0; i < ARRAY_SIZE(wm8739_qctrl); i++) 233 return -EINVAL;
234 if (qc->id && qc->id == wm8739_qctrl[i].id) { 234}
235 memcpy(qc, &wm8739_qctrl[i], sizeof(*qc));
236 return 0;
237 }
238 return -EINVAL;
239 }
240 235
241 case VIDIOC_G_CHIP_IDENT: 236static int wm8739_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_chip_ident *chip)
242 return v4l2_chip_ident_i2c_client(client, 237{
243 arg, V4L2_IDENT_WM8739, 0); 238 struct i2c_client *client = v4l2_get_subdevdata(sd);
244 239
245 case VIDIOC_LOG_STATUS: 240 return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_WM8739, 0);
246 v4l_info(client, "Frequency: %u Hz\n", state->clock_freq); 241}
247 v4l_info(client, "Volume L: %02x%s\n", state->vol_l & 0x1f,
248 state->muted ? " (muted)" : "");
249 v4l_info(client, "Volume R: %02x%s\n", state->vol_r & 0x1f,
250 state->muted ? " (muted)" : "");
251 break;
252 242
253 default: 243static int wm8739_log_status(struct v4l2_subdev *sd)
254 return -EINVAL; 244{
255 } 245 struct wm8739_state *state = to_state(sd);
256 246
247 v4l2_info(sd, "Frequency: %u Hz\n", state->clock_freq);
248 v4l2_info(sd, "Volume L: %02x%s\n", state->vol_l & 0x1f,
249 state->muted ? " (muted)" : "");
250 v4l2_info(sd, "Volume R: %02x%s\n", state->vol_r & 0x1f,
251 state->muted ? " (muted)" : "");
257 return 0; 252 return 0;
258} 253}
259 254
255static int wm8739_command(struct i2c_client *client, unsigned cmd, void *arg)
256{
257 return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
258}
259
260/* ----------------------------------------------------------------------- */
261
262static const struct v4l2_subdev_core_ops wm8739_core_ops = {
263 .log_status = wm8739_log_status,
264 .g_chip_ident = wm8739_g_chip_ident,
265 .queryctrl = wm8739_queryctrl,
266 .g_ctrl = wm8739_g_ctrl,
267 .s_ctrl = wm8739_s_ctrl,
268};
269
270static const struct v4l2_subdev_audio_ops wm8739_audio_ops = {
271 .s_clock_freq = wm8739_s_clock_freq,
272};
273
274static const struct v4l2_subdev_ops wm8739_ops = {
275 .core = &wm8739_core_ops,
276 .audio = &wm8739_audio_ops,
277};
278
260/* ------------------------------------------------------------------------ */ 279/* ------------------------------------------------------------------------ */
261 280
262/* i2c implementation */ 281/* i2c implementation */
@@ -265,6 +284,7 @@ static int wm8739_probe(struct i2c_client *client,
265 const struct i2c_device_id *id) 284 const struct i2c_device_id *id)
266{ 285{
267 struct wm8739_state *state; 286 struct wm8739_state *state;
287 struct v4l2_subdev *sd;
268 288
269 /* Check if the adapter supports the needed features */ 289 /* Check if the adapter supports the needed features */
270 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) 290 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
@@ -276,6 +296,8 @@ static int wm8739_probe(struct i2c_client *client,
276 state = kmalloc(sizeof(struct wm8739_state), GFP_KERNEL); 296 state = kmalloc(sizeof(struct wm8739_state), GFP_KERNEL);
277 if (state == NULL) 297 if (state == NULL)
278 return -ENOMEM; 298 return -ENOMEM;
299 sd = &state->sd;
300 v4l2_i2c_subdev_init(sd, client, &wm8739_ops);
279 state->vol_l = 0x17; /* 0dB */ 301 state->vol_l = 0x17; /* 0dB */
280 state->vol_r = 0x17; /* 0dB */ 302 state->vol_r = 0x17; /* 0dB */
281 state->muted = 0; 303 state->muted = 0;
@@ -283,31 +305,33 @@ static int wm8739_probe(struct i2c_client *client,
283 /* normalize (12dB(31) to -34.5dB(0) [0dB(23)] -> 65535 to 0) */ 305 /* normalize (12dB(31) to -34.5dB(0) [0dB(23)] -> 65535 to 0) */
284 state->volume = ((long)state->vol_l + 1) * 65535 / 31; 306 state->volume = ((long)state->vol_l + 1) * 65535 / 31;
285 state->clock_freq = 48000; 307 state->clock_freq = 48000;
286 i2c_set_clientdata(client, state);
287 308
288 /* Initialize wm8739 */ 309 /* Initialize wm8739 */
289 310
290 /* reset */ 311 /* reset */
291 wm8739_write(client, R15, 0x00); 312 wm8739_write(sd, R15, 0x00);
292 /* filter setting, high path, offet clear */ 313 /* filter setting, high path, offet clear */
293 wm8739_write(client, R5, 0x000); 314 wm8739_write(sd, R5, 0x000);
294 /* ADC, OSC, Power Off mode Disable */ 315 /* ADC, OSC, Power Off mode Disable */
295 wm8739_write(client, R6, 0x000); 316 wm8739_write(sd, R6, 0x000);
296 /* Digital Audio interface format: 317 /* Digital Audio interface format:
297 Enable Master mode, 24 bit, MSB first/left justified */ 318 Enable Master mode, 24 bit, MSB first/left justified */
298 wm8739_write(client, R7, 0x049); 319 wm8739_write(sd, R7, 0x049);
299 /* sampling control: normal, 256fs, 48KHz sampling rate */ 320 /* sampling control: normal, 256fs, 48KHz sampling rate */
300 wm8739_write(client, R8, 0x000); 321 wm8739_write(sd, R8, 0x000);
301 /* activate */ 322 /* activate */
302 wm8739_write(client, R9, 0x001); 323 wm8739_write(sd, R9, 0x001);
303 /* set volume/mute */ 324 /* set volume/mute */
304 wm8739_set_audio(client); 325 wm8739_set_audio(sd);
305 return 0; 326 return 0;
306} 327}
307 328
308static int wm8739_remove(struct i2c_client *client) 329static int wm8739_remove(struct i2c_client *client)
309{ 330{
310 kfree(i2c_get_clientdata(client)); 331 struct v4l2_subdev *sd = i2c_get_clientdata(client);
332
333 v4l2_device_unregister_subdev(sd);
334 kfree(to_state(sd));
311 return 0; 335 return 0;
312} 336}
313 337
diff --git a/drivers/media/video/wm8775.c b/drivers/media/video/wm8775.c
index 48df661d4fc3..d0220b0ec0bc 100644
--- a/drivers/media/video/wm8775.c
+++ b/drivers/media/video/wm8775.c
@@ -32,7 +32,7 @@
32#include <linux/i2c.h> 32#include <linux/i2c.h>
33#include <linux/i2c-id.h> 33#include <linux/i2c-id.h>
34#include <linux/videodev2.h> 34#include <linux/videodev2.h>
35#include <media/v4l2-common.h> 35#include <media/v4l2-device.h>
36#include <media/v4l2-chip-ident.h> 36#include <media/v4l2-chip-ident.h>
37#include <media/v4l2-i2c-drv-legacy.h> 37#include <media/v4l2-i2c-drv-legacy.h>
38 38
@@ -54,16 +54,23 @@ enum {
54}; 54};
55 55
56struct wm8775_state { 56struct wm8775_state {
57 struct v4l2_subdev sd;
57 u8 input; /* Last selected input (0-0xf) */ 58 u8 input; /* Last selected input (0-0xf) */
58 u8 muted; 59 u8 muted;
59}; 60};
60 61
61static int wm8775_write(struct i2c_client *client, int reg, u16 val) 62static inline struct wm8775_state *to_state(struct v4l2_subdev *sd)
62{ 63{
64 return container_of(sd, struct wm8775_state, sd);
65}
66
67static int wm8775_write(struct v4l2_subdev *sd, int reg, u16 val)
68{
69 struct i2c_client *client = v4l2_get_subdevdata(sd);
63 int i; 70 int i;
64 71
65 if (reg < 0 || reg >= TOT_REGS) { 72 if (reg < 0 || reg >= TOT_REGS) {
66 v4l_err(client, "Invalid register R%d\n", reg); 73 v4l2_err(sd, "Invalid register R%d\n", reg);
67 return -1; 74 return -1;
68 } 75 }
69 76
@@ -71,84 +78,117 @@ static int wm8775_write(struct i2c_client *client, int reg, u16 val)
71 if (i2c_smbus_write_byte_data(client, 78 if (i2c_smbus_write_byte_data(client,
72 (reg << 1) | (val >> 8), val & 0xff) == 0) 79 (reg << 1) | (val >> 8), val & 0xff) == 0)
73 return 0; 80 return 0;
74 v4l_err(client, "I2C: cannot write %03x to register R%d\n", val, reg); 81 v4l2_err(sd, "I2C: cannot write %03x to register R%d\n", val, reg);
75 return -1; 82 return -1;
76} 83}
77 84
78static int wm8775_command(struct i2c_client *client, unsigned cmd, void *arg) 85static int wm8775_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
79{ 86{
80 struct wm8775_state *state = i2c_get_clientdata(client); 87 struct wm8775_state *state = to_state(sd);
81 struct v4l2_routing *route = arg; 88
82 struct v4l2_control *ctrl = arg; 89 /* There are 4 inputs and one output. Zero or more inputs
83 90 are multiplexed together to the output. Hence there are
84 switch (cmd) { 91 16 combinations.
85 case VIDIOC_INT_G_AUDIO_ROUTING: 92 If only one input is active (the normal case) then the
86 route->input = state->input; 93 input values 1, 2, 4 or 8 should be used. */
87 route->output = 0; 94 if (route->input > 15) {
88 break; 95 v4l2_err(sd, "Invalid input %d.\n", route->input);
89
90 case VIDIOC_INT_S_AUDIO_ROUTING:
91 /* There are 4 inputs and one output. Zero or more inputs
92 are multiplexed together to the output. Hence there are
93 16 combinations.
94 If only one input is active (the normal case) then the
95 input values 1, 2, 4 or 8 should be used. */
96 if (route->input > 15) {
97 v4l_err(client, "Invalid input %d.\n", route->input);
98 return -EINVAL;
99 }
100 state->input = route->input;
101 if (state->muted)
102 break;
103 wm8775_write(client, R21, 0x0c0);
104 wm8775_write(client, R14, 0x1d4);
105 wm8775_write(client, R15, 0x1d4);
106 wm8775_write(client, R21, 0x100 + state->input);
107 break;
108
109 case VIDIOC_G_CTRL:
110 if (ctrl->id != V4L2_CID_AUDIO_MUTE)
111 return -EINVAL;
112 ctrl->value = state->muted;
113 break;
114
115 case VIDIOC_S_CTRL:
116 if (ctrl->id != V4L2_CID_AUDIO_MUTE)
117 return -EINVAL;
118 state->muted = ctrl->value;
119 wm8775_write(client, R21, 0x0c0);
120 wm8775_write(client, R14, 0x1d4);
121 wm8775_write(client, R15, 0x1d4);
122 if (!state->muted)
123 wm8775_write(client, R21, 0x100 + state->input);
124 break;
125
126 case VIDIOC_G_CHIP_IDENT:
127 return v4l2_chip_ident_i2c_client(client,
128 arg, V4L2_IDENT_WM8775, 0);
129
130 case VIDIOC_LOG_STATUS:
131 v4l_info(client, "Input: %d%s\n", state->input,
132 state->muted ? " (muted)" : "");
133 break;
134
135 case VIDIOC_S_FREQUENCY:
136 /* If I remove this, then it can happen that I have no
137 sound the first time I tune from static to a valid channel.
138 It's difficult to reproduce and is almost certainly related
139 to the zero cross detect circuit. */
140 wm8775_write(client, R21, 0x0c0);
141 wm8775_write(client, R14, 0x1d4);
142 wm8775_write(client, R15, 0x1d4);
143 wm8775_write(client, R21, 0x100 + state->input);
144 break;
145
146 default:
147 return -EINVAL; 96 return -EINVAL;
148 } 97 }
98 state->input = route->input;
99 if (state->muted)
100 return 0;
101 wm8775_write(sd, R21, 0x0c0);
102 wm8775_write(sd, R14, 0x1d4);
103 wm8775_write(sd, R15, 0x1d4);
104 wm8775_write(sd, R21, 0x100 + state->input);
105 return 0;
106}
107
108static int wm8775_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
109{
110 struct wm8775_state *state = to_state(sd);
111
112 if (ctrl->id != V4L2_CID_AUDIO_MUTE)
113 return -EINVAL;
114 ctrl->value = state->muted;
115 return 0;
116}
117
118static int wm8775_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
119{
120 struct wm8775_state *state = to_state(sd);
121
122 if (ctrl->id != V4L2_CID_AUDIO_MUTE)
123 return -EINVAL;
124 state->muted = ctrl->value;
125 wm8775_write(sd, R21, 0x0c0);
126 wm8775_write(sd, R14, 0x1d4);
127 wm8775_write(sd, R15, 0x1d4);
128 if (!state->muted)
129 wm8775_write(sd, R21, 0x100 + state->input);
130 return 0;
131}
132
133static int wm8775_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_chip_ident *chip)
134{
135 struct i2c_client *client = v4l2_get_subdevdata(sd);
136
137 return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_WM8775, 0);
138}
139
140static int wm8775_log_status(struct v4l2_subdev *sd)
141{
142 struct wm8775_state *state = to_state(sd);
143
144 v4l2_info(sd, "Input: %d%s\n", state->input,
145 state->muted ? " (muted)" : "");
149 return 0; 146 return 0;
150} 147}
151 148
149static int wm8775_s_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *freq)
150{
151 struct wm8775_state *state = to_state(sd);
152
153 /* If I remove this, then it can happen that I have no
154 sound the first time I tune from static to a valid channel.
155 It's difficult to reproduce and is almost certainly related
156 to the zero cross detect circuit. */
157 wm8775_write(sd, R21, 0x0c0);
158 wm8775_write(sd, R14, 0x1d4);
159 wm8775_write(sd, R15, 0x1d4);
160 wm8775_write(sd, R21, 0x100 + state->input);
161 return 0;
162}
163
164static int wm8775_command(struct i2c_client *client, unsigned cmd, void *arg)
165{
166 return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
167}
168
169/* ----------------------------------------------------------------------- */
170
171static const struct v4l2_subdev_core_ops wm8775_core_ops = {
172 .log_status = wm8775_log_status,
173 .g_chip_ident = wm8775_g_chip_ident,
174 .g_ctrl = wm8775_g_ctrl,
175 .s_ctrl = wm8775_s_ctrl,
176};
177
178static const struct v4l2_subdev_tuner_ops wm8775_tuner_ops = {
179 .s_frequency = wm8775_s_frequency,
180};
181
182static const struct v4l2_subdev_audio_ops wm8775_audio_ops = {
183 .s_routing = wm8775_s_routing,
184};
185
186static const struct v4l2_subdev_ops wm8775_ops = {
187 .core = &wm8775_core_ops,
188 .tuner = &wm8775_tuner_ops,
189 .audio = &wm8775_audio_ops,
190};
191
152/* ----------------------------------------------------------------------- */ 192/* ----------------------------------------------------------------------- */
153 193
154/* i2c implementation */ 194/* i2c implementation */
@@ -162,56 +202,61 @@ static int wm8775_probe(struct i2c_client *client,
162 const struct i2c_device_id *id) 202 const struct i2c_device_id *id)
163{ 203{
164 struct wm8775_state *state; 204 struct wm8775_state *state;
205 struct v4l2_subdev *sd;
165 206
166 /* Check if the adapter supports the needed features */ 207 /* Check if the adapter supports the needed features */
167 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) 208 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
168 return -EIO; 209 return -EIO;
169 210
170 v4l_info(client, "chip found @ 0x%x (%s)\n", 211 v4l_info(client, "chip found @ 0x%02x (%s)\n",
171 client->addr << 1, client->adapter->name); 212 client->addr << 1, client->adapter->name);
172 213
173 state = kmalloc(sizeof(struct wm8775_state), GFP_KERNEL); 214 state = kmalloc(sizeof(struct wm8775_state), GFP_KERNEL);
174 if (state == NULL) 215 if (state == NULL)
175 return -ENOMEM; 216 return -ENOMEM;
217 sd = &state->sd;
218 v4l2_i2c_subdev_init(sd, client, &wm8775_ops);
176 state->input = 2; 219 state->input = 2;
177 state->muted = 0; 220 state->muted = 0;
178 i2c_set_clientdata(client, state);
179 221
180 /* Initialize wm8775 */ 222 /* Initialize wm8775 */
181 223
182 /* RESET */ 224 /* RESET */
183 wm8775_write(client, R23, 0x000); 225 wm8775_write(sd, R23, 0x000);
184 /* Disable zero cross detect timeout */ 226 /* Disable zero cross detect timeout */
185 wm8775_write(client, R7, 0x000); 227 wm8775_write(sd, R7, 0x000);
186 /* Left justified, 24-bit mode */ 228 /* Left justified, 24-bit mode */
187 wm8775_write(client, R11, 0x021); 229 wm8775_write(sd, R11, 0x021);
188 /* Master mode, clock ratio 256fs */ 230 /* Master mode, clock ratio 256fs */
189 wm8775_write(client, R12, 0x102); 231 wm8775_write(sd, R12, 0x102);
190 /* Powered up */ 232 /* Powered up */
191 wm8775_write(client, R13, 0x000); 233 wm8775_write(sd, R13, 0x000);
192 /* ADC gain +2.5dB, enable zero cross */ 234 /* ADC gain +2.5dB, enable zero cross */
193 wm8775_write(client, R14, 0x1d4); 235 wm8775_write(sd, R14, 0x1d4);
194 /* ADC gain +2.5dB, enable zero cross */ 236 /* ADC gain +2.5dB, enable zero cross */
195 wm8775_write(client, R15, 0x1d4); 237 wm8775_write(sd, R15, 0x1d4);
196 /* ALC Stereo, ALC target level -1dB FS max gain +8dB */ 238 /* ALC Stereo, ALC target level -1dB FS max gain +8dB */
197 wm8775_write(client, R16, 0x1bf); 239 wm8775_write(sd, R16, 0x1bf);
198 /* Enable gain control, use zero cross detection, 240 /* Enable gain control, use zero cross detection,
199 ALC hold time 42.6 ms */ 241 ALC hold time 42.6 ms */
200 wm8775_write(client, R17, 0x185); 242 wm8775_write(sd, R17, 0x185);
201 /* ALC gain ramp up delay 34 s, ALC gain ramp down delay 33 ms */ 243 /* ALC gain ramp up delay 34 s, ALC gain ramp down delay 33 ms */
202 wm8775_write(client, R18, 0x0a2); 244 wm8775_write(sd, R18, 0x0a2);
203 /* Enable noise gate, threshold -72dBfs */ 245 /* Enable noise gate, threshold -72dBfs */
204 wm8775_write(client, R19, 0x005); 246 wm8775_write(sd, R19, 0x005);
205 /* Transient window 4ms, lower PGA gain limit -1dB */ 247 /* Transient window 4ms, lower PGA gain limit -1dB */
206 wm8775_write(client, R20, 0x07a); 248 wm8775_write(sd, R20, 0x07a);
207 /* LRBOTH = 1, use input 2. */ 249 /* LRBOTH = 1, use input 2. */
208 wm8775_write(client, R21, 0x102); 250 wm8775_write(sd, R21, 0x102);
209 return 0; 251 return 0;
210} 252}
211 253
212static int wm8775_remove(struct i2c_client *client) 254static int wm8775_remove(struct i2c_client *client)
213{ 255{
214 kfree(i2c_get_clientdata(client)); 256 struct v4l2_subdev *sd = i2c_get_clientdata(client);
257
258 v4l2_device_unregister_subdev(sd);
259 kfree(to_state(sd));
215 return 0; 260 return 0;
216} 261}
217 262
diff --git a/drivers/media/video/zc0301/zc0301_core.c b/drivers/media/video/zc0301/zc0301_core.c
index 9fc581707638..9d00e6056491 100644
--- a/drivers/media/video/zc0301/zc0301_core.c
+++ b/drivers/media/video/zc0301/zc0301_core.c
@@ -1020,7 +1020,7 @@ zc0301_vidioc_querycap(struct zc0301_device* cam, void __user * arg)
1020 1020
1021 strlcpy(cap.card, cam->v4ldev->name, sizeof(cap.card)); 1021 strlcpy(cap.card, cam->v4ldev->name, sizeof(cap.card));
1022 if (usb_make_path(cam->usbdev, cap.bus_info, sizeof(cap.bus_info)) < 0) 1022 if (usb_make_path(cam->usbdev, cap.bus_info, sizeof(cap.bus_info)) < 0)
1023 strlcpy(cap.bus_info, cam->usbdev->dev.bus_id, 1023 strlcpy(cap.bus_info, dev_name(&cam->usbdev->dev),
1024 sizeof(cap.bus_info)); 1024 sizeof(cap.bus_info));
1025 1025
1026 if (copy_to_user(arg, &cap, sizeof(cap))) 1026 if (copy_to_user(arg, &cap, sizeof(cap)))
diff --git a/drivers/media/video/zoran/zoran_card.c b/drivers/media/video/zoran/zoran_card.c
index fa5f2f8f518a..05f39195372e 100644
--- a/drivers/media/video/zoran/zoran_card.c
+++ b/drivers/media/video/zoran/zoran_card.c
@@ -153,12 +153,6 @@ MODULE_DESCRIPTION("Zoran-36057/36067 JPEG codec driver");
153MODULE_AUTHOR("Serguei Miridonov"); 153MODULE_AUTHOR("Serguei Miridonov");
154MODULE_LICENSE("GPL"); 154MODULE_LICENSE("GPL");
155 155
156static struct pci_device_id zr36067_pci_tbl[] = {
157 {PCI_VENDOR_ID_ZORAN, PCI_DEVICE_ID_ZORAN_36057,
158 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
159 {0}
160};
161MODULE_DEVICE_TABLE(pci, zr36067_pci_tbl);
162 156
163int zoran_num; /* number of Buzs in use */ 157int zoran_num; /* number of Buzs in use */
164struct zoran *zoran[BUZ_MAX]; 158struct zoran *zoran[BUZ_MAX];
diff --git a/drivers/media/video/zoran/zoran_driver.c b/drivers/media/video/zoran/zoran_driver.c
index db11ab9e60da..00b97d97aeaa 100644
--- a/drivers/media/video/zoran/zoran_driver.c
+++ b/drivers/media/video/zoran/zoran_driver.c
@@ -1940,11 +1940,7 @@ zoran_set_input (struct zoran *zr,
1940 * ioctl routine 1940 * ioctl routine
1941 */ 1941 */
1942 1942
1943static int 1943static int zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg)
1944zoran_do_ioctl (struct inode *inode,
1945 struct file *file,
1946 unsigned int cmd,
1947 void *arg)
1948{ 1944{
1949 struct zoran_fh *fh = file->private_data; 1945 struct zoran_fh *fh = file->private_data;
1950 struct zoran *zr = fh->zr; 1946 struct zoran *zr = fh->zr;
@@ -4201,7 +4197,7 @@ zoran_ioctl (struct inode *inode,
4201 unsigned int cmd, 4197 unsigned int cmd,
4202 unsigned long arg) 4198 unsigned long arg)
4203{ 4199{
4204 return video_usercopy(inode, file, cmd, arg, zoran_do_ioctl); 4200 return video_usercopy(file, cmd, arg, zoran_do_ioctl);
4205} 4201}
4206 4202
4207static unsigned int 4203static unsigned int
diff --git a/firmware/Makefile b/firmware/Makefile
index 4993a4b3d8ab..6968388818be 100644
--- a/firmware/Makefile
+++ b/firmware/Makefile
@@ -150,27 +150,15 @@ $(patsubst %,$(obj)/%.gen.o, $(fw-external-y)): $(obj)/%.gen.o: $(fwdir)/%
150$(obj)/%: $(obj)/%.ihex | $(objtree)/$(obj)/$$(dir %) 150$(obj)/%: $(obj)/%.ihex | $(objtree)/$(obj)/$$(dir %)
151 $(call cmd,ihex) 151 $(call cmd,ihex)
152 152
153# Don't depend on ihex2fw if we're installing and it already exists.
154# Putting it after | in the dependencies doesn't seem sufficient when
155# we're installing after a cross-compile, because ihex2fw has dependencies
156# on stuff like /usr/lib/gcc/ppc64-redhat-linux/4.3.0/include/stddef.h and
157# thus wants to be rebuilt. Which it can't be, if the prebuilt kernel tree
158# is exported read-only for someone to run 'make install'.
159ifeq ($(INSTALL):$(wildcard $(obj)/ihex2fw),install:$(obj)/ihex2fw)
160ihex2fw_dep :=
161else
162ihex2fw_dep := $(obj)/ihex2fw
163endif
164
165# .HEX is also Intel HEX, but where the offset and length in each record 153# .HEX is also Intel HEX, but where the offset and length in each record
166# is actually meaningful, because the firmware has to be loaded in a certain 154# is actually meaningful, because the firmware has to be loaded in a certain
167# order rather than as a single binary blob. Thus, we convert them into our 155# order rather than as a single binary blob. Thus, we convert them into our
168# more compact binary representation of ihex records (<linux/ihex.h>) 156# more compact binary representation of ihex records (<linux/ihex.h>)
169$(obj)/%.fw: $(obj)/%.HEX $(ihex2fw_dep) | $(objtree)/$(obj)/$$(dir %) 157$(obj)/%.fw: $(obj)/%.HEX $(obj)/ihex2fw | $(objtree)/$(obj)/$$(dir %)
170 $(call cmd,ihex2fw) 158 $(call cmd,ihex2fw)
171 159
172# .H16 is our own modified form of Intel HEX, with 16-bit length for records. 160# .H16 is our own modified form of Intel HEX, with 16-bit length for records.
173$(obj)/%.fw: $(obj)/%.H16 $(ihex2fw_dep) | $(objtree)/$(obj)/$$(dir %) 161$(obj)/%.fw: $(obj)/%.H16 $(obj)/ihex2fw | $(objtree)/$(obj)/$$(dir %)
174 $(call cmd,h16tofw) 162 $(call cmd,h16tofw)
175 163
176$(firmware-dirs): 164$(firmware-dirs):
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
index 4669d7e72e75..1f126e30766c 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -293,6 +293,7 @@ struct v4l2_pix_format {
293#define V4L2_PIX_FMT_YVU420 v4l2_fourcc('Y', 'V', '1', '2') /* 12 YVU 4:2:0 */ 293#define V4L2_PIX_FMT_YVU420 v4l2_fourcc('Y', 'V', '1', '2') /* 12 YVU 4:2:0 */
294#define V4L2_PIX_FMT_YUYV v4l2_fourcc('Y', 'U', 'Y', 'V') /* 16 YUV 4:2:2 */ 294#define V4L2_PIX_FMT_YUYV v4l2_fourcc('Y', 'U', 'Y', 'V') /* 16 YUV 4:2:2 */
295#define V4L2_PIX_FMT_UYVY v4l2_fourcc('U', 'Y', 'V', 'Y') /* 16 YUV 4:2:2 */ 295#define V4L2_PIX_FMT_UYVY v4l2_fourcc('U', 'Y', 'V', 'Y') /* 16 YUV 4:2:2 */
296#define V4L2_PIX_FMT_VYUY v4l2_fourcc('V', 'Y', 'U', 'Y') /* 16 YUV 4:2:2 */
296#define V4L2_PIX_FMT_YUV422P v4l2_fourcc('4', '2', '2', 'P') /* 16 YVU422 planar */ 297#define V4L2_PIX_FMT_YUV422P v4l2_fourcc('4', '2', '2', 'P') /* 16 YVU422 planar */
297#define V4L2_PIX_FMT_YUV411P v4l2_fourcc('4', '1', '1', 'P') /* 16 YVU411 planar */ 298#define V4L2_PIX_FMT_YUV411P v4l2_fourcc('4', '1', '1', 'P') /* 16 YVU411 planar */
298#define V4L2_PIX_FMT_Y41P v4l2_fourcc('Y', '4', '1', 'P') /* 12 YUV 4:1:1 */ 299#define V4L2_PIX_FMT_Y41P v4l2_fourcc('Y', '4', '1', 'P') /* 12 YUV 4:1:1 */
@@ -304,6 +305,8 @@ struct v4l2_pix_format {
304/* two planes -- one Y, one Cr + Cb interleaved */ 305/* two planes -- one Y, one Cr + Cb interleaved */
305#define V4L2_PIX_FMT_NV12 v4l2_fourcc('N', 'V', '1', '2') /* 12 Y/CbCr 4:2:0 */ 306#define V4L2_PIX_FMT_NV12 v4l2_fourcc('N', 'V', '1', '2') /* 12 Y/CbCr 4:2:0 */
306#define V4L2_PIX_FMT_NV21 v4l2_fourcc('N', 'V', '2', '1') /* 12 Y/CrCb 4:2:0 */ 307#define V4L2_PIX_FMT_NV21 v4l2_fourcc('N', 'V', '2', '1') /* 12 Y/CrCb 4:2:0 */
308#define V4L2_PIX_FMT_NV16 v4l2_fourcc('N', 'V', '1', '6') /* 16 Y/CbCr 4:2:2 */
309#define V4L2_PIX_FMT_NV61 v4l2_fourcc('N', 'V', '6', '1') /* 16 Y/CrCb 4:2:2 */
307 310
308/* The following formats are not defined in the V4L2 specification */ 311/* The following formats are not defined in the V4L2 specification */
309#define V4L2_PIX_FMT_YUV410 v4l2_fourcc('Y', 'U', 'V', '9') /* 9 YUV 4:1:0 */ 312#define V4L2_PIX_FMT_YUV410 v4l2_fourcc('Y', 'U', 'V', '9') /* 9 YUV 4:1:0 */
@@ -1050,7 +1053,7 @@ enum v4l2_mpeg_video_bitrate_mode {
1050#define V4L2_CID_MPEG_VIDEO_MUTE (V4L2_CID_MPEG_BASE+210) 1053#define V4L2_CID_MPEG_VIDEO_MUTE (V4L2_CID_MPEG_BASE+210)
1051#define V4L2_CID_MPEG_VIDEO_MUTE_YUV (V4L2_CID_MPEG_BASE+211) 1054#define V4L2_CID_MPEG_VIDEO_MUTE_YUV (V4L2_CID_MPEG_BASE+211)
1052 1055
1053/* MPEG-class control IDs specific to the CX2584x driver as defined by V4L2 */ 1056/* MPEG-class control IDs specific to the CX2341x driver as defined by V4L2 */
1054#define V4L2_CID_MPEG_CX2341X_BASE (V4L2_CTRL_CLASS_MPEG | 0x1000) 1057#define V4L2_CID_MPEG_CX2341X_BASE (V4L2_CTRL_CLASS_MPEG | 0x1000)
1055#define V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE (V4L2_CID_MPEG_CX2341X_BASE+0) 1058#define V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE (V4L2_CID_MPEG_CX2341X_BASE+0)
1056enum v4l2_mpeg_cx2341x_video_spatial_filter_mode { 1059enum v4l2_mpeg_cx2341x_video_spatial_filter_mode {
@@ -1117,6 +1120,12 @@ enum v4l2_exposure_auto_type {
1117#define V4L2_CID_FOCUS_RELATIVE (V4L2_CID_CAMERA_CLASS_BASE+11) 1120#define V4L2_CID_FOCUS_RELATIVE (V4L2_CID_CAMERA_CLASS_BASE+11)
1118#define V4L2_CID_FOCUS_AUTO (V4L2_CID_CAMERA_CLASS_BASE+12) 1121#define V4L2_CID_FOCUS_AUTO (V4L2_CID_CAMERA_CLASS_BASE+12)
1119 1122
1123#define V4L2_CID_ZOOM_ABSOLUTE (V4L2_CID_CAMERA_CLASS_BASE+13)
1124#define V4L2_CID_ZOOM_RELATIVE (V4L2_CID_CAMERA_CLASS_BASE+14)
1125#define V4L2_CID_ZOOM_CONTINUOUS (V4L2_CID_CAMERA_CLASS_BASE+15)
1126
1127#define V4L2_CID_PRIVACY (V4L2_CID_CAMERA_CLASS_BASE+16)
1128
1120/* 1129/*
1121 * T U N I N G 1130 * T U N I N G
1122 */ 1131 */
@@ -1369,6 +1378,7 @@ struct v4l2_streamparm {
1369#define V4L2_CHIP_MATCH_HOST 0 /* Match against chip ID on host (0 for the host) */ 1378#define V4L2_CHIP_MATCH_HOST 0 /* Match against chip ID on host (0 for the host) */
1370#define V4L2_CHIP_MATCH_I2C_DRIVER 1 /* Match against I2C driver ID */ 1379#define V4L2_CHIP_MATCH_I2C_DRIVER 1 /* Match against I2C driver ID */
1371#define V4L2_CHIP_MATCH_I2C_ADDR 2 /* Match against I2C 7-bit address */ 1380#define V4L2_CHIP_MATCH_I2C_ADDR 2 /* Match against I2C 7-bit address */
1381#define V4L2_CHIP_MATCH_AC97 3 /* Match against anciliary AC97 chip */
1372 1382
1373struct v4l2_register { 1383struct v4l2_register {
1374 __u32 match_type; /* Match type */ 1384 __u32 match_type; /* Match type */
@@ -1458,6 +1468,8 @@ struct v4l2_chip_ident {
1458#define VIDIOC_G_CHIP_IDENT _IOWR('V', 81, struct v4l2_chip_ident) 1468#define VIDIOC_G_CHIP_IDENT _IOWR('V', 81, struct v4l2_chip_ident)
1459#endif 1469#endif
1460#define VIDIOC_S_HW_FREQ_SEEK _IOW('V', 82, struct v4l2_hw_freq_seek) 1470#define VIDIOC_S_HW_FREQ_SEEK _IOW('V', 82, struct v4l2_hw_freq_seek)
1471/* Reminder: when adding new ioctls please add support for them to
1472 drivers/media/video/v4l2-compat-ioctl32.c as well! */
1461 1473
1462#ifdef __OLD_VIDIOC_ 1474#ifdef __OLD_VIDIOC_
1463/* for compatibility, will go away some day */ 1475/* for compatibility, will go away some day */
diff --git a/include/media/i2c-addr.h b/include/media/i2c-addr.h
index e7ff44a35ca0..5d0f56054d26 100644
--- a/include/media/i2c-addr.h
+++ b/include/media/i2c-addr.h
@@ -12,8 +12,6 @@
12/* bttv address list */ 12/* bttv address list */
13#define I2C_ADDR_TSA5522 0xc2 13#define I2C_ADDR_TSA5522 0xc2
14#define I2C_ADDR_TDA7432 0x8a 14#define I2C_ADDR_TDA7432 0x8a
15#define I2C_ADDR_BT832_ALT1 0x88
16#define I2C_ADDR_BT832_ALT2 0x8a // alternate setting
17#define I2C_ADDR_TDA8425 0x82 15#define I2C_ADDR_TDA8425 0x82
18#define I2C_ADDR_TDA9840 0x84 16#define I2C_ADDR_TDA9840 0x84
19#define I2C_ADDR_TDA9850 0xb6 /* also used by 9855,9873 */ 17#define I2C_ADDR_TDA9850 0xb6 /* also used by 9855,9873 */
diff --git a/include/media/ir-common.h b/include/media/ir-common.h
index 38f2d93c3957..5bf2ea00678c 100644
--- a/include/media/ir-common.h
+++ b/include/media/ir-common.h
@@ -157,6 +157,8 @@ extern IR_KEYTAB_TYPE ir_codes_avermedia_a16d[IR_KEYTAB_SIZE];
157extern IR_KEYTAB_TYPE ir_codes_encore_enltv_fm53[IR_KEYTAB_SIZE]; 157extern IR_KEYTAB_TYPE ir_codes_encore_enltv_fm53[IR_KEYTAB_SIZE];
158extern IR_KEYTAB_TYPE ir_codes_real_audio_220_32_keys[IR_KEYTAB_SIZE]; 158extern IR_KEYTAB_TYPE ir_codes_real_audio_220_32_keys[IR_KEYTAB_SIZE];
159extern IR_KEYTAB_TYPE ir_codes_msi_tvanywhere_plus[IR_KEYTAB_SIZE]; 159extern IR_KEYTAB_TYPE ir_codes_msi_tvanywhere_plus[IR_KEYTAB_SIZE];
160extern IR_KEYTAB_TYPE ir_codes_ati_tv_wonder_hd_600[IR_KEYTAB_SIZE];
161extern IR_KEYTAB_TYPE ir_codes_kworld_plus_tv_analog[IR_KEYTAB_SIZE];
160#endif 162#endif
161 163
162/* 164/*
diff --git a/include/media/ov772x.h b/include/media/ov772x.h
new file mode 100644
index 000000000000..e391d55edb95
--- /dev/null
+++ b/include/media/ov772x.h
@@ -0,0 +1,21 @@
1/* ov772x Camera
2 *
3 * Copyright (C) 2008 Renesas Solutions Corp.
4 * Kuninori Morimoto <morimoto.kuninori@renesas.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 __OV772X_H__
12#define __OV772X_H__
13
14#include <media/soc_camera.h>
15
16struct ov772x_camera_info {
17 unsigned long buswidth;
18 struct soc_camera_link link;
19};
20
21#endif /* __OV772X_H__ */
diff --git a/include/media/saa7146_vv.h b/include/media/saa7146_vv.h
index 1d104096619c..6bbb0d93bb5f 100644
--- a/include/media/saa7146_vv.h
+++ b/include/media/saa7146_vv.h
@@ -216,8 +216,7 @@ void saa7146_set_gpio(struct saa7146_dev *saa, u8 pin, u8 data);
216extern struct saa7146_use_ops saa7146_video_uops; 216extern struct saa7146_use_ops saa7146_video_uops;
217int saa7146_start_preview(struct saa7146_fh *fh); 217int saa7146_start_preview(struct saa7146_fh *fh);
218int saa7146_stop_preview(struct saa7146_fh *fh); 218int saa7146_stop_preview(struct saa7146_fh *fh);
219int saa7146_video_do_ioctl(struct inode *inode, struct file *file, 219int saa7146_video_do_ioctl(struct file *file, unsigned int cmd, void *arg);
220 unsigned int cmd, void *arg);
221 220
222/* from saa7146_vbi.c */ 221/* from saa7146_vbi.c */
223extern struct saa7146_use_ops saa7146_vbi_uops; 222extern struct saa7146_use_ops saa7146_vbi_uops;
diff --git a/include/media/soc_camera.h b/include/media/soc_camera.h
index c5de7bb19fda..425b6a98c95c 100644
--- a/include/media/soc_camera.h
+++ b/include/media/soc_camera.h
@@ -12,9 +12,10 @@
12#ifndef SOC_CAMERA_H 12#ifndef SOC_CAMERA_H
13#define SOC_CAMERA_H 13#define SOC_CAMERA_H
14 14
15#include <linux/mutex.h>
16#include <linux/pm.h>
15#include <linux/videodev2.h> 17#include <linux/videodev2.h>
16#include <media/videobuf-core.h> 18#include <media/videobuf-core.h>
17#include <linux/pm.h>
18 19
19struct soc_camera_device { 20struct soc_camera_device {
20 struct list_head list; 21 struct list_head list;
@@ -36,14 +37,19 @@ struct soc_camera_device {
36 unsigned char iface; /* Host number */ 37 unsigned char iface; /* Host number */
37 unsigned char devnum; /* Device number per host */ 38 unsigned char devnum; /* Device number per host */
38 unsigned char buswidth; /* See comment in .c */ 39 unsigned char buswidth; /* See comment in .c */
40 struct soc_camera_sense *sense; /* See comment in struct definition */
39 struct soc_camera_ops *ops; 41 struct soc_camera_ops *ops;
40 struct video_device *vdev; 42 struct video_device *vdev;
41 const struct soc_camera_data_format *current_fmt; 43 const struct soc_camera_data_format *current_fmt;
42 const struct soc_camera_data_format *formats; 44 const struct soc_camera_data_format *formats;
43 int num_formats; 45 int num_formats;
46 struct soc_camera_format_xlate *user_formats;
47 int num_user_formats;
44 struct module *owner; 48 struct module *owner;
45 /* soc_camera.c private count. Only accessed with video_lock held */ 49 void *host_priv; /* Per-device host private data */
50 /* soc_camera.c private count. Only accessed with .video_lock held */
46 int use_count; 51 int use_count;
52 struct mutex video_lock; /* Protects device data */
47}; 53};
48 54
49struct soc_camera_file { 55struct soc_camera_file {
@@ -56,7 +62,7 @@ struct soc_camera_host {
56 struct device dev; 62 struct device dev;
57 unsigned char nr; /* Host number */ 63 unsigned char nr; /* Host number */
58 void *priv; 64 void *priv;
59 char *drv_name; 65 const char *drv_name;
60 struct soc_camera_host_ops *ops; 66 struct soc_camera_host_ops *ops;
61}; 67};
62 68
@@ -64,25 +70,33 @@ struct soc_camera_host_ops {
64 struct module *owner; 70 struct module *owner;
65 int (*add)(struct soc_camera_device *); 71 int (*add)(struct soc_camera_device *);
66 void (*remove)(struct soc_camera_device *); 72 void (*remove)(struct soc_camera_device *);
67 int (*suspend)(struct soc_camera_device *, pm_message_t state); 73 int (*suspend)(struct soc_camera_device *, pm_message_t);
68 int (*resume)(struct soc_camera_device *); 74 int (*resume)(struct soc_camera_device *);
69 int (*set_fmt_cap)(struct soc_camera_device *, __u32, 75 int (*get_formats)(struct soc_camera_device *, int,
70 struct v4l2_rect *); 76 struct soc_camera_format_xlate *);
71 int (*try_fmt_cap)(struct soc_camera_device *, struct v4l2_format *); 77 int (*set_fmt)(struct soc_camera_device *, __u32, struct v4l2_rect *);
78 int (*try_fmt)(struct soc_camera_device *, struct v4l2_format *);
72 void (*init_videobuf)(struct videobuf_queue *, 79 void (*init_videobuf)(struct videobuf_queue *,
73 struct soc_camera_device *); 80 struct soc_camera_device *);
74 int (*reqbufs)(struct soc_camera_file *, struct v4l2_requestbuffers *); 81 int (*reqbufs)(struct soc_camera_file *, struct v4l2_requestbuffers *);
75 int (*querycap)(struct soc_camera_host *, struct v4l2_capability *); 82 int (*querycap)(struct soc_camera_host *, struct v4l2_capability *);
76 int (*try_bus_param)(struct soc_camera_device *, __u32);
77 int (*set_bus_param)(struct soc_camera_device *, __u32); 83 int (*set_bus_param)(struct soc_camera_device *, __u32);
78 unsigned int (*poll)(struct file *, poll_table *); 84 unsigned int (*poll)(struct file *, poll_table *);
79}; 85};
80 86
87#define SOCAM_SENSOR_INVERT_PCLK (1 << 0)
88#define SOCAM_SENSOR_INVERT_MCLK (1 << 1)
89#define SOCAM_SENSOR_INVERT_HSYNC (1 << 2)
90#define SOCAM_SENSOR_INVERT_VSYNC (1 << 3)
91#define SOCAM_SENSOR_INVERT_DATA (1 << 4)
92
81struct soc_camera_link { 93struct soc_camera_link {
82 /* Camera bus id, used to match a camera and a bus */ 94 /* Camera bus id, used to match a camera and a bus */
83 int bus_id; 95 int bus_id;
84 /* GPIO number to switch between 8 and 10 bit modes */ 96 /* GPIO number to switch between 8 and 10 bit modes */
85 unsigned int gpio; 97 unsigned int gpio;
98 /* Per camera SOCAM_SENSOR_* bus flags */
99 unsigned long flags;
86 /* Optional callbacks to power on or off and reset the sensor */ 100 /* Optional callbacks to power on or off and reset the sensor */
87 int (*power)(struct device *, int); 101 int (*power)(struct device *, int);
88 int (*reset)(struct device *); 102 int (*reset)(struct device *);
@@ -106,13 +120,35 @@ extern void soc_camera_device_unregister(struct soc_camera_device *icd);
106extern int soc_camera_video_start(struct soc_camera_device *icd); 120extern int soc_camera_video_start(struct soc_camera_device *icd);
107extern void soc_camera_video_stop(struct soc_camera_device *icd); 121extern void soc_camera_video_stop(struct soc_camera_device *icd);
108 122
123extern const struct soc_camera_data_format *soc_camera_format_by_fourcc(
124 struct soc_camera_device *icd, unsigned int fourcc);
125extern const struct soc_camera_format_xlate *soc_camera_xlate_by_fourcc(
126 struct soc_camera_device *icd, unsigned int fourcc);
127
109struct soc_camera_data_format { 128struct soc_camera_data_format {
110 char *name; 129 const char *name;
111 unsigned int depth; 130 unsigned int depth;
112 __u32 fourcc; 131 __u32 fourcc;
113 enum v4l2_colorspace colorspace; 132 enum v4l2_colorspace colorspace;
114}; 133};
115 134
135/**
136 * struct soc_camera_format_xlate - match between host and sensor formats
137 * @cam_fmt: sensor format provided by the sensor
138 * @host_fmt: host format after host translation from cam_fmt
139 * @buswidth: bus width for this format
140 *
141 * Host and sensor translation structure. Used in table of host and sensor
142 * formats matchings in soc_camera_device. A host can override the generic list
143 * generation by implementing get_formats(), and use it for format checks and
144 * format setup.
145 */
146struct soc_camera_format_xlate {
147 const struct soc_camera_data_format *cam_fmt;
148 const struct soc_camera_data_format *host_fmt;
149 unsigned char buswidth;
150};
151
116struct soc_camera_ops { 152struct soc_camera_ops {
117 struct module *owner; 153 struct module *owner;
118 int (*probe)(struct soc_camera_device *); 154 int (*probe)(struct soc_camera_device *);
@@ -123,13 +159,14 @@ struct soc_camera_ops {
123 int (*release)(struct soc_camera_device *); 159 int (*release)(struct soc_camera_device *);
124 int (*start_capture)(struct soc_camera_device *); 160 int (*start_capture)(struct soc_camera_device *);
125 int (*stop_capture)(struct soc_camera_device *); 161 int (*stop_capture)(struct soc_camera_device *);
126 int (*set_fmt_cap)(struct soc_camera_device *, __u32, 162 int (*set_fmt)(struct soc_camera_device *, __u32, struct v4l2_rect *);
127 struct v4l2_rect *); 163 int (*try_fmt)(struct soc_camera_device *, struct v4l2_format *);
128 int (*try_fmt_cap)(struct soc_camera_device *, struct v4l2_format *);
129 unsigned long (*query_bus_param)(struct soc_camera_device *); 164 unsigned long (*query_bus_param)(struct soc_camera_device *);
130 int (*set_bus_param)(struct soc_camera_device *, unsigned long); 165 int (*set_bus_param)(struct soc_camera_device *, unsigned long);
131 int (*get_chip_id)(struct soc_camera_device *, 166 int (*get_chip_id)(struct soc_camera_device *,
132 struct v4l2_chip_ident *); 167 struct v4l2_chip_ident *);
168 int (*set_std)(struct soc_camera_device *, v4l2_std_id *);
169 int (*enum_input)(struct soc_camera_device *, struct v4l2_input *);
133#ifdef CONFIG_VIDEO_ADV_DEBUG 170#ifdef CONFIG_VIDEO_ADV_DEBUG
134 int (*get_register)(struct soc_camera_device *, struct v4l2_register *); 171 int (*get_register)(struct soc_camera_device *, struct v4l2_register *);
135 int (*set_register)(struct soc_camera_device *, struct v4l2_register *); 172 int (*set_register)(struct soc_camera_device *, struct v4l2_register *);
@@ -140,6 +177,32 @@ struct soc_camera_ops {
140 int num_controls; 177 int num_controls;
141}; 178};
142 179
180#define SOCAM_SENSE_PCLK_CHANGED (1 << 0)
181
182/**
183 * This struct can be attached to struct soc_camera_device by the host driver
184 * to request sense from the camera, for example, when calling .set_fmt(). The
185 * host then can check which flags are set and verify respective values if any.
186 * For example, if SOCAM_SENSE_PCLK_CHANGED is set, it means, pixclock has
187 * changed during this operation. After completion the host should detach sense.
188 *
189 * @flags ored SOCAM_SENSE_* flags
190 * @master_clock if the host wants to be informed about pixel-clock
191 * change, it better set master_clock.
192 * @pixel_clock_max maximum pixel clock frequency supported by the host,
193 * camera is not allowed to exceed this.
194 * @pixel_clock if the camera driver changed pixel clock during this
195 * operation, it sets SOCAM_SENSE_PCLK_CHANGED, uses
196 * master_clock to calculate the new pixel-clock and
197 * sets this field.
198 */
199struct soc_camera_sense {
200 unsigned long flags;
201 unsigned long master_clock;
202 unsigned long pixel_clock_max;
203 unsigned long pixel_clock;
204};
205
143static inline struct v4l2_queryctrl const *soc_camera_find_qctrl( 206static inline struct v4l2_queryctrl const *soc_camera_find_qctrl(
144 struct soc_camera_ops *ops, int id) 207 struct soc_camera_ops *ops, int id)
145{ 208{
@@ -158,15 +221,20 @@ static inline struct v4l2_queryctrl const *soc_camera_find_qctrl(
158#define SOCAM_HSYNC_ACTIVE_LOW (1 << 3) 221#define SOCAM_HSYNC_ACTIVE_LOW (1 << 3)
159#define SOCAM_VSYNC_ACTIVE_HIGH (1 << 4) 222#define SOCAM_VSYNC_ACTIVE_HIGH (1 << 4)
160#define SOCAM_VSYNC_ACTIVE_LOW (1 << 5) 223#define SOCAM_VSYNC_ACTIVE_LOW (1 << 5)
161#define SOCAM_DATAWIDTH_8 (1 << 6) 224#define SOCAM_DATAWIDTH_4 (1 << 6)
162#define SOCAM_DATAWIDTH_9 (1 << 7) 225#define SOCAM_DATAWIDTH_8 (1 << 7)
163#define SOCAM_DATAWIDTH_10 (1 << 8) 226#define SOCAM_DATAWIDTH_9 (1 << 8)
164#define SOCAM_DATAWIDTH_16 (1 << 9) 227#define SOCAM_DATAWIDTH_10 (1 << 9)
165#define SOCAM_PCLK_SAMPLE_RISING (1 << 10) 228#define SOCAM_DATAWIDTH_15 (1 << 10)
166#define SOCAM_PCLK_SAMPLE_FALLING (1 << 11) 229#define SOCAM_DATAWIDTH_16 (1 << 11)
230#define SOCAM_PCLK_SAMPLE_RISING (1 << 12)
231#define SOCAM_PCLK_SAMPLE_FALLING (1 << 13)
232#define SOCAM_DATA_ACTIVE_HIGH (1 << 14)
233#define SOCAM_DATA_ACTIVE_LOW (1 << 15)
167 234
168#define SOCAM_DATAWIDTH_MASK (SOCAM_DATAWIDTH_8 | SOCAM_DATAWIDTH_9 | \ 235#define SOCAM_DATAWIDTH_MASK (SOCAM_DATAWIDTH_4 | SOCAM_DATAWIDTH_8 | \
169 SOCAM_DATAWIDTH_10 | SOCAM_DATAWIDTH_16) 236 SOCAM_DATAWIDTH_9 | SOCAM_DATAWIDTH_10 | \
237 SOCAM_DATAWIDTH_15 | SOCAM_DATAWIDTH_16)
170 238
171static inline unsigned long soc_camera_bus_param_compatible( 239static inline unsigned long soc_camera_bus_param_compatible(
172 unsigned long camera_flags, unsigned long bus_flags) 240 unsigned long camera_flags, unsigned long bus_flags)
@@ -182,4 +250,7 @@ static inline unsigned long soc_camera_bus_param_compatible(
182 return (!hsync || !vsync || !pclk) ? 0 : common_flags; 250 return (!hsync || !vsync || !pclk) ? 0 : common_flags;
183} 251}
184 252
253extern unsigned long soc_camera_apply_sensor_flags(struct soc_camera_link *icl,
254 unsigned long flags);
255
185#endif 256#endif
diff --git a/include/media/tvp514x.h b/include/media/tvp514x.h
new file mode 100644
index 000000000000..5e7ee968c6dc
--- /dev/null
+++ b/include/media/tvp514x.h
@@ -0,0 +1,118 @@
1/*
2 * drivers/media/video/tvp514x.h
3 *
4 * Copyright (C) 2008 Texas Instruments Inc
5 * Author: Vaibhav Hiremath <hvaibhav@ti.com>
6 *
7 * Contributors:
8 * Sivaraj R <sivaraj@ti.com>
9 * Brijesh R Jadav <brijesh.j@ti.com>
10 * Hardik Shah <hardik.shah@ti.com>
11 * Manjunath Hadli <mrh@ti.com>
12 * Karicheri Muralidharan <m-karicheri2@ti.com>
13 *
14 * This package is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License version 2 as
16 * published by the Free Software Foundation.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 *
27 */
28
29#ifndef _TVP514X_H
30#define _TVP514X_H
31
32/*
33 * Other macros
34 */
35#define TVP514X_MODULE_NAME "tvp514x"
36
37#define TVP514X_XCLK_BT656 (27000000)
38
39/* Number of pixels and number of lines per frame for different standards */
40#define NTSC_NUM_ACTIVE_PIXELS (720)
41#define NTSC_NUM_ACTIVE_LINES (480)
42#define PAL_NUM_ACTIVE_PIXELS (720)
43#define PAL_NUM_ACTIVE_LINES (576)
44
45/**
46 * enum tvp514x_input - enum for different decoder input pin
47 * configuration.
48 */
49enum tvp514x_input {
50 /*
51 * CVBS input selection
52 */
53 INPUT_CVBS_VI1A = 0x0,
54 INPUT_CVBS_VI1B,
55 INPUT_CVBS_VI1C,
56 INPUT_CVBS_VI2A = 0x04,
57 INPUT_CVBS_VI2B,
58 INPUT_CVBS_VI2C,
59 INPUT_CVBS_VI3A = 0x08,
60 INPUT_CVBS_VI3B,
61 INPUT_CVBS_VI3C,
62 INPUT_CVBS_VI4A = 0x0C,
63 /*
64 * S-Video input selection
65 */
66 INPUT_SVIDEO_VI2A_VI1A = 0x44,
67 INPUT_SVIDEO_VI2B_VI1B,
68 INPUT_SVIDEO_VI2C_VI1C,
69 INPUT_SVIDEO_VI2A_VI3A = 0x54,
70 INPUT_SVIDEO_VI2B_VI3B,
71 INPUT_SVIDEO_VI2C_VI3C,
72 INPUT_SVIDEO_VI4A_VI1A = 0x4C,
73 INPUT_SVIDEO_VI4A_VI1B,
74 INPUT_SVIDEO_VI4A_VI1C,
75 INPUT_SVIDEO_VI4A_VI3A = 0x5C,
76 INPUT_SVIDEO_VI4A_VI3B,
77 INPUT_SVIDEO_VI4A_VI3C,
78
79 /* Need to add entries for
80 * RGB, YPbPr and SCART.
81 */
82 INPUT_INVALID
83};
84
85/**
86 * enum tvp514x_output - enum for output format
87 * supported.
88 *
89 */
90enum tvp514x_output {
91 OUTPUT_10BIT_422_EMBEDDED_SYNC = 0,
92 OUTPUT_20BIT_422_SEPERATE_SYNC,
93 OUTPUT_10BIT_422_SEPERATE_SYNC = 3,
94 OUTPUT_INVALID
95};
96
97/**
98 * struct tvp514x_platform_data - Platform data values and access functions.
99 * @power_set: Power state access function, zero is off, non-zero is on.
100 * @ifparm: Interface parameters access function.
101 * @priv_data_set: Device private data (pointer) access function.
102 * @clk_polarity: Clock polarity of the current interface.
103 * @ hs_polarity: HSYNC Polarity configuration for current interface.
104 * @ vs_polarity: VSYNC Polarity configuration for current interface.
105 */
106struct tvp514x_platform_data {
107 char *master;
108 int (*power_set) (enum v4l2_power on);
109 int (*ifparm) (struct v4l2_ifparm *p);
110 int (*priv_data_set) (void *);
111 /* Interface control params */
112 bool clk_polarity;
113 bool hs_polarity;
114 bool vs_polarity;
115};
116
117
118#endif /* ifndef _TVP514X_H */
diff --git a/include/media/tw9910.h b/include/media/tw9910.h
new file mode 100644
index 000000000000..73231e7880d8
--- /dev/null
+++ b/include/media/tw9910.h
@@ -0,0 +1,39 @@
1/*
2 * tw9910 Driver header
3 *
4 * Copyright (C) 2008 Renesas Solutions Corp.
5 * Kuninori Morimoto <morimoto.kuninori@renesas.com>
6 *
7 * Based on ov772x.h
8 *
9 * Copyright (C) Kuninori Morimoto <morimoto.kuninori@renesas.com>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
14 */
15
16#ifndef __TW9910_H__
17#define __TW9910_H__
18
19#include <media/soc_camera.h>
20
21enum tw9910_mpout_pin {
22 TW9910_MPO_VLOSS,
23 TW9910_MPO_HLOCK,
24 TW9910_MPO_SLOCK,
25 TW9910_MPO_VLOCK,
26 TW9910_MPO_MONO,
27 TW9910_MPO_DET50,
28 TW9910_MPO_FIELD,
29 TW9910_MPO_RTCO,
30};
31
32struct tw9910_video_info {
33 unsigned long buswidth;
34 enum tw9910_mpout_pin mpout;
35 struct soc_camera_link link;
36};
37
38
39#endif /* __TW9910_H__ */
diff --git a/include/media/v4l2-chip-ident.h b/include/media/v4l2-chip-ident.h
index d73a8e9028a5..43dbb659f1f5 100644
--- a/include/media/v4l2-chip-ident.h
+++ b/include/media/v4l2-chip-ident.h
@@ -60,6 +60,8 @@ enum {
60 60
61 /* OmniVision sensors: reserved range 250-299 */ 61 /* OmniVision sensors: reserved range 250-299 */
62 V4L2_IDENT_OV7670 = 250, 62 V4L2_IDENT_OV7670 = 250,
63 V4L2_IDENT_OV7720 = 251,
64 V4L2_IDENT_OV7725 = 252,
63 65
64 /* Conexant MPEG encoder/decoders: reserved range 410-420 */ 66 /* Conexant MPEG encoder/decoders: reserved range 410-420 */
65 V4L2_IDENT_CX23415 = 415, 67 V4L2_IDENT_CX23415 = 415,
@@ -69,6 +71,9 @@ enum {
69 /* module vp27smpx: just ident 2700 */ 71 /* module vp27smpx: just ident 2700 */
70 V4L2_IDENT_VP27SMPX = 2700, 72 V4L2_IDENT_VP27SMPX = 2700,
71 73
74 /* module tvp5150 */
75 V4L2_IDENT_TVP5150 = 5150,
76
72 /* module cs5345: just ident 5345 */ 77 /* module cs5345: just ident 5345 */
73 V4L2_IDENT_CS5345 = 5345, 78 V4L2_IDENT_CS5345 = 5345,
74 79
@@ -82,6 +87,9 @@ enum {
82 /* module wm8775: just ident 8775 */ 87 /* module wm8775: just ident 8775 */
83 V4L2_IDENT_WM8775 = 8775, 88 V4L2_IDENT_WM8775 = 8775,
84 89
90 /* module tw9910: just ident 9910 */
91 V4L2_IDENT_TW9910 = 9910,
92
85 /* module cs53132a: just ident 53132 */ 93 /* module cs53132a: just ident 53132 */
86 V4L2_IDENT_CS53l32A = 53132, 94 V4L2_IDENT_CS53l32A = 53132,
87 95
@@ -166,8 +174,10 @@ enum {
166 V4L2_IDENT_MT9M001C12ST = 45000, 174 V4L2_IDENT_MT9M001C12ST = 45000,
167 V4L2_IDENT_MT9M001C12STM = 45005, 175 V4L2_IDENT_MT9M001C12STM = 45005,
168 V4L2_IDENT_MT9M111 = 45007, 176 V4L2_IDENT_MT9M111 = 45007,
177 V4L2_IDENT_MT9M112 = 45008,
169 V4L2_IDENT_MT9V022IX7ATC = 45010, /* No way to detect "normal" I77ATx */ 178 V4L2_IDENT_MT9V022IX7ATC = 45010, /* No way to detect "normal" I77ATx */
170 V4L2_IDENT_MT9V022IX7ATM = 45015, /* and "lead free" IA7ATx chips */ 179 V4L2_IDENT_MT9V022IX7ATM = 45015, /* and "lead free" IA7ATx chips */
180 V4L2_IDENT_MT9T031 = 45020,
171}; 181};
172 182
173#endif 183#endif
diff --git a/include/media/v4l2-common.h b/include/media/v4l2-common.h
index 2f8719abf5cb..f99c866d8c37 100644
--- a/include/media/v4l2-common.h
+++ b/include/media/v4l2-common.h
@@ -57,6 +57,29 @@
57 57
58/* ------------------------------------------------------------------------- */ 58/* ------------------------------------------------------------------------- */
59 59
60/* These printk constructs can be used with v4l2_device and v4l2_subdev */
61#define v4l2_printk(level, dev, fmt, arg...) \
62 printk(level "%s: " fmt, (dev)->name , ## arg)
63
64#define v4l2_err(dev, fmt, arg...) \
65 v4l2_printk(KERN_ERR, dev, fmt , ## arg)
66
67#define v4l2_warn(dev, fmt, arg...) \
68 v4l2_printk(KERN_WARNING, dev, fmt , ## arg)
69
70#define v4l2_info(dev, fmt, arg...) \
71 v4l2_printk(KERN_INFO, dev, fmt , ## arg)
72
73/* These three macros assume that the debug level is set with a module
74 parameter called 'debug'. */
75#define v4l2_dbg(level, debug, dev, fmt, arg...) \
76 do { \
77 if (debug >= (level)) \
78 v4l2_printk(KERN_DEBUG, dev, fmt , ## arg); \
79 } while (0)
80
81/* ------------------------------------------------------------------------- */
82
60/* Priority helper functions */ 83/* Priority helper functions */
61 84
62struct v4l2_prio_state { 85struct v4l2_prio_state {
@@ -104,11 +127,29 @@ struct i2c_driver;
104struct i2c_adapter; 127struct i2c_adapter;
105struct i2c_client; 128struct i2c_client;
106struct i2c_device_id; 129struct i2c_device_id;
130struct v4l2_device;
131struct v4l2_subdev;
132struct v4l2_subdev_ops;
107 133
108int v4l2_i2c_attach(struct i2c_adapter *adapter, int address, struct i2c_driver *driver, 134int v4l2_i2c_attach(struct i2c_adapter *adapter, int address, struct i2c_driver *driver,
109 const char *name, 135 const char *name,
110 int (*probe)(struct i2c_client *, const struct i2c_device_id *)); 136 int (*probe)(struct i2c_client *, const struct i2c_device_id *));
111 137
138/* Load an i2c module and return an initialized v4l2_subdev struct.
139 Only call request_module if module_name != NULL.
140 The client_type argument is the name of the chip that's on the adapter. */
141struct v4l2_subdev *v4l2_i2c_new_subdev(struct i2c_adapter *adapter,
142 const char *module_name, const char *client_type, u8 addr);
143/* Probe and load an i2c module and return an initialized v4l2_subdev struct.
144 Only call request_module if module_name != NULL.
145 The client_type argument is the name of the chip that's on the adapter. */
146struct v4l2_subdev *v4l2_i2c_new_probed_subdev(struct i2c_adapter *adapter,
147 const char *module_name, const char *client_type,
148 const unsigned short *addrs);
149/* Initialize an v4l2_subdev with data from an i2c_client struct */
150void v4l2_i2c_subdev_init(struct v4l2_subdev *sd, struct i2c_client *client,
151 const struct v4l2_subdev_ops *ops);
152
112/* ------------------------------------------------------------------------- */ 153/* ------------------------------------------------------------------------- */
113 154
114/* Internal ioctls */ 155/* Internal ioctls */
diff --git a/include/media/v4l2-dev.h b/include/media/v4l2-dev.h
index a0a6b41c5e09..0a88d1d17d30 100644
--- a/include/media/v4l2-dev.h
+++ b/include/media/v4l2-dev.h
@@ -25,6 +25,12 @@
25#define VFL_TYPE_MAX 4 25#define VFL_TYPE_MAX 4
26 26
27struct v4l2_ioctl_callbacks; 27struct v4l2_ioctl_callbacks;
28struct v4l2_device;
29
30/* Flag to mark the video_device struct as unregistered.
31 Drivers can set this flag if they want to block all future
32 device access. It is set by video_unregister_device. */
33#define V4L2_FL_UNREGISTERED (0)
28 34
29/* 35/*
30 * Newer version of video_device, handled by videodev2.c 36 * Newer version of video_device, handled by videodev2.c
@@ -39,15 +45,20 @@ struct video_device
39 45
40 /* sysfs */ 46 /* sysfs */
41 struct device dev; /* v4l device */ 47 struct device dev; /* v4l device */
42 struct cdev cdev; /* character device */ 48 struct cdev *cdev; /* character device */
43 void (*cdev_release)(struct kobject *kobj); 49
50 /* Set either parent or v4l2_dev if your driver uses v4l2_device */
44 struct device *parent; /* device parent */ 51 struct device *parent; /* device parent */
52 struct v4l2_device *v4l2_dev; /* v4l2_device parent */
45 53
46 /* device info */ 54 /* device info */
47 char name[32]; 55 char name[32];
48 int vfl_type; 56 int vfl_type;
57 /* 'minor' is set to -1 if the registration failed */
49 int minor; 58 int minor;
50 u16 num; 59 u16 num;
60 /* use bitops to set/clear/test flags */
61 unsigned long flags;
51 /* attribute to differentiate multiple indices on one physical device */ 62 /* attribute to differentiate multiple indices on one physical device */
52 int index; 63 int index;
53 64
@@ -58,7 +69,7 @@ struct video_device
58 v4l2_std_id current_norm; /* Current tvnorm */ 69 v4l2_std_id current_norm; /* Current tvnorm */
59 70
60 /* callbacks */ 71 /* callbacks */
61 void (*release)(struct video_device *vfd); 72 void (*release)(struct video_device *vdev);
62 73
63 /* ioctl callbacks */ 74 /* ioctl callbacks */
64 const struct v4l2_ioctl_ops *ioctl_ops; 75 const struct v4l2_ioctl_ops *ioctl_ops;
@@ -67,36 +78,41 @@ struct video_device
67/* dev to video-device */ 78/* dev to video-device */
68#define to_video_device(cd) container_of(cd, struct video_device, dev) 79#define to_video_device(cd) container_of(cd, struct video_device, dev)
69 80
70/* Register and unregister devices. Note that if video_register_device fails, 81/* Register video devices. Note that if video_register_device fails,
71 the release() callback of the video_device structure is *not* called, so 82 the release() callback of the video_device structure is *not* called, so
72 the caller is responsible for freeing any data. Usually that means that 83 the caller is responsible for freeing any data. Usually that means that
73 you call video_device_release() on failure. */ 84 you call video_device_release() on failure.
74int __must_check video_register_device(struct video_device *vfd, int type, int nr); 85
75int __must_check video_register_device_index(struct video_device *vfd, 86 Also note that vdev->minor is set to -1 if the registration failed. */
87int __must_check video_register_device(struct video_device *vdev, int type, int nr);
88int __must_check video_register_device_index(struct video_device *vdev,
76 int type, int nr, int index); 89 int type, int nr, int index);
77void video_unregister_device(struct video_device *vfd); 90
91/* Unregister video devices. Will do nothing if vdev == NULL or
92 vdev->minor < 0. */
93void video_unregister_device(struct video_device *vdev);
78 94
79/* helper functions to alloc/release struct video_device, the 95/* helper functions to alloc/release struct video_device, the
80 latter can also be used for video_device->release(). */ 96 latter can also be used for video_device->release(). */
81struct video_device * __must_check video_device_alloc(void); 97struct video_device * __must_check video_device_alloc(void);
82 98
83/* this release function frees the vfd pointer */ 99/* this release function frees the vdev pointer */
84void video_device_release(struct video_device *vfd); 100void video_device_release(struct video_device *vdev);
85 101
86/* this release function does nothing, use when the video_device is a 102/* this release function does nothing, use when the video_device is a
87 static global struct. Note that having a static video_device is 103 static global struct. Note that having a static video_device is
88 a dubious construction at best. */ 104 a dubious construction at best. */
89void video_device_release_empty(struct video_device *vfd); 105void video_device_release_empty(struct video_device *vdev);
90 106
91/* helper functions to access driver private data. */ 107/* helper functions to access driver private data. */
92static inline void *video_get_drvdata(struct video_device *dev) 108static inline void *video_get_drvdata(struct video_device *vdev)
93{ 109{
94 return dev_get_drvdata(&dev->dev); 110 return dev_get_drvdata(&vdev->dev);
95} 111}
96 112
97static inline void video_set_drvdata(struct video_device *dev, void *data) 113static inline void video_set_drvdata(struct video_device *vdev, void *data)
98{ 114{
99 dev_set_drvdata(&dev->dev, data); 115 dev_set_drvdata(&vdev->dev, data);
100} 116}
101 117
102struct video_device *video_devdata(struct file *file); 118struct video_device *video_devdata(struct file *file);
@@ -108,4 +124,9 @@ static inline void *video_drvdata(struct file *file)
108 return video_get_drvdata(video_devdata(file)); 124 return video_get_drvdata(video_devdata(file));
109} 125}
110 126
127static inline int video_is_unregistered(struct video_device *vdev)
128{
129 return test_bit(V4L2_FL_UNREGISTERED, &vdev->flags);
130}
131
111#endif /* _V4L2_DEV_H */ 132#endif /* _V4L2_DEV_H */
diff --git a/include/media/v4l2-device.h b/include/media/v4l2-device.h
new file mode 100644
index 000000000000..97b283a04289
--- /dev/null
+++ b/include/media/v4l2-device.h
@@ -0,0 +1,109 @@
1/*
2 V4L2 device support header.
3
4 Copyright (C) 2008 Hans Verkuil <hverkuil@xs4all.nl>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#ifndef _V4L2_DEVICE_H
22#define _V4L2_DEVICE_H
23
24#include <media/v4l2-subdev.h>
25
26/* Each instance of a V4L2 device should create the v4l2_device struct,
27 either stand-alone or embedded in a larger struct.
28
29 It allows easy access to sub-devices (see v4l2-subdev.h) and provides
30 basic V4L2 device-level support.
31 */
32
33#define V4L2_DEVICE_NAME_SIZE (BUS_ID_SIZE + 16)
34
35struct v4l2_device {
36 /* dev->driver_data points to this struct */
37 struct device *dev;
38 /* used to keep track of the registered subdevs */
39 struct list_head subdevs;
40 /* lock this struct; can be used by the driver as well if this
41 struct is embedded into a larger struct. */
42 spinlock_t lock;
43 /* unique device name, by default the driver name + bus ID */
44 char name[V4L2_DEVICE_NAME_SIZE];
45};
46
47/* Initialize v4l2_dev and make dev->driver_data point to v4l2_dev */
48int __must_check v4l2_device_register(struct device *dev, struct v4l2_device *v4l2_dev);
49/* Set v4l2_dev->dev->driver_data to NULL and unregister all sub-devices */
50void v4l2_device_unregister(struct v4l2_device *v4l2_dev);
51
52/* Register a subdev with a v4l2 device. While registered the subdev module
53 is marked as in-use. An error is returned if the module is no longer
54 loaded when you attempt to register it. */
55int __must_check v4l2_device_register_subdev(struct v4l2_device *dev, struct v4l2_subdev *sd);
56/* Unregister a subdev with a v4l2 device. Can also be called if the subdev
57 wasn't registered. In that case it will do nothing. */
58void v4l2_device_unregister_subdev(struct v4l2_subdev *sd);
59
60/* Iterate over all subdevs. */
61#define v4l2_device_for_each_subdev(sd, dev) \
62 list_for_each_entry(sd, &(dev)->subdevs, list)
63
64/* Call the specified callback for all subdevs matching the condition.
65 Ignore any errors. Note that you cannot add or delete a subdev
66 while walking the subdevs list. */
67#define __v4l2_device_call_subdevs(dev, cond, o, f, args...) \
68 do { \
69 struct v4l2_subdev *sd; \
70 \
71 list_for_each_entry(sd, &(dev)->subdevs, list) \
72 if ((cond) && sd->ops->o && sd->ops->o->f) \
73 sd->ops->o->f(sd , ##args); \
74 } while (0)
75
76/* Call the specified callback for all subdevs matching the condition.
77 If the callback returns an error other than 0 or -ENOIOCTLCMD, then
78 return with that error code. Note that you cannot add or delete a
79 subdev while walking the subdevs list. */
80#define __v4l2_device_call_subdevs_until_err(dev, cond, o, f, args...) \
81({ \
82 struct v4l2_subdev *sd; \
83 int err = 0; \
84 \
85 list_for_each_entry(sd, &(dev)->subdevs, list) { \
86 if ((cond) && sd->ops->o && sd->ops->o->f) \
87 err = sd->ops->o->f(sd , ##args); \
88 if (err && err != -ENOIOCTLCMD) \
89 break; \
90 } \
91 (err == -ENOIOCTLCMD) ? 0 : err; \
92})
93
94/* Call the specified callback for all subdevs matching grp_id (if 0, then
95 match them all). Ignore any errors. Note that you cannot add or delete
96 a subdev while walking the subdevs list. */
97#define v4l2_device_call_all(dev, grp_id, o, f, args...) \
98 __v4l2_device_call_subdevs(dev, \
99 !(grp_id) || sd->grp_id == (grp_id), o, f , ##args)
100
101/* Call the specified callback for all subdevs matching grp_id (if 0, then
102 match them all). If the callback returns an error other than 0 or
103 -ENOIOCTLCMD, then return with that error code. Note that you cannot
104 add or delete a subdev while walking the subdevs list. */
105#define v4l2_device_call_until_err(dev, grp_id, o, f, args...) \
106 __v4l2_device_call_subdevs_until_err(dev, \
107 !(grp_id) || sd->grp_id == (grp_id), o, f , ##args)
108
109#endif
diff --git a/include/media/v4l2-int-device.h b/include/media/v4l2-int-device.h
index 9c2df41dbf92..ecda3c725837 100644
--- a/include/media/v4l2-int-device.h
+++ b/include/media/v4l2-int-device.h
@@ -183,6 +183,9 @@ enum v4l2_int_ioctl_num {
183 vidioc_int_s_crop_num, 183 vidioc_int_s_crop_num,
184 vidioc_int_g_parm_num, 184 vidioc_int_g_parm_num,
185 vidioc_int_s_parm_num, 185 vidioc_int_s_parm_num,
186 vidioc_int_querystd_num,
187 vidioc_int_s_std_num,
188 vidioc_int_s_video_routing_num,
186 189
187 /* 190 /*
188 * 191 *
@@ -284,6 +287,9 @@ V4L2_INT_WRAPPER_1(g_crop, struct v4l2_crop, *);
284V4L2_INT_WRAPPER_1(s_crop, struct v4l2_crop, *); 287V4L2_INT_WRAPPER_1(s_crop, struct v4l2_crop, *);
285V4L2_INT_WRAPPER_1(g_parm, struct v4l2_streamparm, *); 288V4L2_INT_WRAPPER_1(g_parm, struct v4l2_streamparm, *);
286V4L2_INT_WRAPPER_1(s_parm, struct v4l2_streamparm, *); 289V4L2_INT_WRAPPER_1(s_parm, struct v4l2_streamparm, *);
290V4L2_INT_WRAPPER_1(querystd, v4l2_std_id, *);
291V4L2_INT_WRAPPER_1(s_std, v4l2_std_id, *);
292V4L2_INT_WRAPPER_1(s_video_routing, struct v4l2_routing, *);
287 293
288V4L2_INT_WRAPPER_0(dev_init); 294V4L2_INT_WRAPPER_0(dev_init);
289V4L2_INT_WRAPPER_0(dev_exit); 295V4L2_INT_WRAPPER_0(dev_exit);
diff --git a/include/media/v4l2-ioctl.h b/include/media/v4l2-ioctl.h
index e6ba25b3d7c8..fcdb58c4ce07 100644
--- a/include/media/v4l2-ioctl.h
+++ b/include/media/v4l2-ioctl.h
@@ -232,6 +232,12 @@ struct v4l2_ioctl_ops {
232 int (*vidioc_g_chip_ident) (struct file *file, void *fh, 232 int (*vidioc_g_chip_ident) (struct file *file, void *fh,
233 struct v4l2_chip_ident *chip); 233 struct v4l2_chip_ident *chip);
234 234
235 int (*vidioc_enum_framesizes) (struct file *file, void *fh,
236 struct v4l2_frmsizeenum *fsize);
237
238 int (*vidioc_enum_frameintervals) (struct file *file, void *fh,
239 struct v4l2_frmivalenum *fival);
240
235 /* For other private ioctls */ 241 /* For other private ioctls */
236 int (*vidioc_default) (struct file *file, void *fh, 242 int (*vidioc_default) (struct file *file, void *fh,
237 int cmd, void *arg); 243 int cmd, void *arg);
@@ -285,15 +291,13 @@ extern long v4l_compat_ioctl32(struct file *file, unsigned int cmd,
285 unsigned long arg); 291 unsigned long arg);
286 292
287/* Include support for obsoleted stuff */ 293/* Include support for obsoleted stuff */
288extern int video_usercopy(struct inode *inode, struct file *file, 294extern int video_usercopy(struct file *file, unsigned int cmd,
289 unsigned int cmd, unsigned long arg, 295 unsigned long arg, v4l2_kioctl func);
290 int (*func)(struct inode *inode, struct file *file,
291 unsigned int cmd, void *arg));
292 296
293/* Standard handlers for V4L ioctl's */ 297/* Standard handlers for V4L ioctl's */
294 298
295/* This prototype is used on fops.unlocked_ioctl */ 299/* This prototype is used on fops.unlocked_ioctl */
296extern int __video_ioctl2(struct file *file, 300extern long __video_ioctl2(struct file *file,
297 unsigned int cmd, unsigned long arg); 301 unsigned int cmd, unsigned long arg);
298 302
299/* This prototype is used on fops.ioctl 303/* This prototype is used on fops.ioctl
diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h
new file mode 100644
index 000000000000..ceef016bb0b7
--- /dev/null
+++ b/include/media/v4l2-subdev.h
@@ -0,0 +1,189 @@
1/*
2 V4L2 sub-device support header.
3
4 Copyright (C) 2008 Hans Verkuil <hverkuil@xs4all.nl>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#ifndef _V4L2_SUBDEV_H
22#define _V4L2_SUBDEV_H
23
24#include <media/v4l2-common.h>
25
26struct v4l2_device;
27struct v4l2_subdev;
28struct tuner_setup;
29
30/* Sub-devices are devices that are connected somehow to the main bridge
31 device. These devices are usually audio/video muxers/encoders/decoders or
32 sensors and webcam controllers.
33
34 Usually these devices are controlled through an i2c bus, but other busses
35 may also be used.
36
37 The v4l2_subdev struct provides a way of accessing these devices in a
38 generic manner. Most operations that these sub-devices support fall in
39 a few categories: core ops, audio ops, video ops and tuner ops.
40
41 More categories can be added if needed, although this should remain a
42 limited set (no more than approx. 8 categories).
43
44 Each category has its own set of ops that subdev drivers can implement.
45
46 A subdev driver can leave the pointer to the category ops NULL if
47 it does not implement them (e.g. an audio subdev will generally not
48 implement the video category ops). The exception is the core category:
49 this must always be present.
50
51 These ops are all used internally so it is no problem to change, remove
52 or add ops or move ops from one to another category. Currently these
53 ops are based on the original ioctls, but since ops are not limited to
54 one argument there is room for improvement here once all i2c subdev
55 drivers are converted to use these ops.
56 */
57
58/* Core ops: it is highly recommended to implement at least these ops:
59
60 g_chip_ident
61 log_status
62 g_register
63 s_register
64
65 This provides basic debugging support.
66
67 The ioctl ops is meant for generic ioctl-like commands. Depending on
68 the use-case it might be better to use subdev-specific ops (currently
69 not yet implemented) since ops provide proper type-checking.
70 */
71struct v4l2_subdev_core_ops {
72 int (*g_chip_ident)(struct v4l2_subdev *sd, struct v4l2_chip_ident *chip);
73 int (*log_status)(struct v4l2_subdev *sd);
74 int (*init)(struct v4l2_subdev *sd, u32 val);
75 int (*s_standby)(struct v4l2_subdev *sd, u32 standby);
76 int (*reset)(struct v4l2_subdev *sd, u32 val);
77 int (*s_gpio)(struct v4l2_subdev *sd, u32 val);
78 int (*queryctrl)(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc);
79 int (*g_ctrl)(struct v4l2_subdev *sd, struct v4l2_control *ctrl);
80 int (*s_ctrl)(struct v4l2_subdev *sd, struct v4l2_control *ctrl);
81 int (*querymenu)(struct v4l2_subdev *sd, struct v4l2_querymenu *qm);
82 int (*ioctl)(struct v4l2_subdev *sd, unsigned int cmd, void *arg);
83#ifdef CONFIG_VIDEO_ADV_DEBUG
84 int (*g_register)(struct v4l2_subdev *sd, struct v4l2_register *reg);
85 int (*s_register)(struct v4l2_subdev *sd, struct v4l2_register *reg);
86#endif
87};
88
89struct v4l2_subdev_tuner_ops {
90 int (*s_mode)(struct v4l2_subdev *sd, enum v4l2_tuner_type);
91 int (*s_radio)(struct v4l2_subdev *sd);
92 int (*s_frequency)(struct v4l2_subdev *sd, struct v4l2_frequency *freq);
93 int (*g_frequency)(struct v4l2_subdev *sd, struct v4l2_frequency *freq);
94 int (*g_tuner)(struct v4l2_subdev *sd, struct v4l2_tuner *vt);
95 int (*s_tuner)(struct v4l2_subdev *sd, struct v4l2_tuner *vt);
96 int (*s_std)(struct v4l2_subdev *sd, v4l2_std_id norm);
97 int (*s_type_addr)(struct v4l2_subdev *sd, struct tuner_setup *type);
98 int (*s_config)(struct v4l2_subdev *sd, const struct v4l2_priv_tun_config *config);
99};
100
101struct v4l2_subdev_audio_ops {
102 int (*s_clock_freq)(struct v4l2_subdev *sd, u32 freq);
103 int (*s_i2s_clock_freq)(struct v4l2_subdev *sd, u32 freq);
104 int (*s_routing)(struct v4l2_subdev *sd, const struct v4l2_routing *route);
105};
106
107struct v4l2_subdev_video_ops {
108 int (*s_routing)(struct v4l2_subdev *sd, const struct v4l2_routing *route);
109 int (*s_crystal_freq)(struct v4l2_subdev *sd, struct v4l2_crystal_freq *freq);
110 int (*decode_vbi_line)(struct v4l2_subdev *sd, struct v4l2_decode_vbi_line *vbi_line);
111 int (*s_vbi_data)(struct v4l2_subdev *sd, const struct v4l2_sliced_vbi_data *vbi_data);
112 int (*g_vbi_data)(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_data *vbi_data);
113 int (*g_sliced_vbi_cap)(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_cap *cap);
114 int (*s_std_output)(struct v4l2_subdev *sd, v4l2_std_id std);
115 int (*s_stream)(struct v4l2_subdev *sd, int enable);
116 int (*s_fmt)(struct v4l2_subdev *sd, struct v4l2_format *fmt);
117 int (*g_fmt)(struct v4l2_subdev *sd, struct v4l2_format *fmt);
118};
119
120struct v4l2_subdev_ops {
121 const struct v4l2_subdev_core_ops *core;
122 const struct v4l2_subdev_tuner_ops *tuner;
123 const struct v4l2_subdev_audio_ops *audio;
124 const struct v4l2_subdev_video_ops *video;
125};
126
127#define V4L2_SUBDEV_NAME_SIZE 32
128
129/* Each instance of a subdev driver should create this struct, either
130 stand-alone or embedded in a larger struct.
131 */
132struct v4l2_subdev {
133 struct list_head list;
134 struct module *owner;
135 struct v4l2_device *dev;
136 const struct v4l2_subdev_ops *ops;
137 /* name must be unique */
138 char name[V4L2_SUBDEV_NAME_SIZE];
139 /* can be used to group similar subdevs, value is driver-specific */
140 u32 grp_id;
141 /* pointer to private data */
142 void *priv;
143};
144
145static inline void v4l2_set_subdevdata(struct v4l2_subdev *sd, void *p)
146{
147 sd->priv = p;
148}
149
150static inline void *v4l2_get_subdevdata(const struct v4l2_subdev *sd)
151{
152 return sd->priv;
153}
154
155/* Convert an ioctl-type command to the proper v4l2_subdev_ops function call.
156 This is used by subdev modules that can be called by both old-style ioctl
157 commands and through the v4l2_subdev_ops.
158
159 The ioctl API of the subdev driver can call this function to call the
160 right ops based on the ioctl cmd and arg.
161
162 Once all subdev drivers have been converted and all drivers no longer
163 use the ioctl interface, then this function can be removed.
164 */
165int v4l2_subdev_command(struct v4l2_subdev *sd, unsigned cmd, void *arg);
166
167static inline void v4l2_subdev_init(struct v4l2_subdev *sd,
168 const struct v4l2_subdev_ops *ops)
169{
170 INIT_LIST_HEAD(&sd->list);
171 /* ops->core MUST be set */
172 BUG_ON(!ops || !ops->core);
173 sd->ops = ops;
174 sd->dev = NULL;
175 sd->name[0] = '\0';
176 sd->grp_id = 0;
177 sd->priv = NULL;
178}
179
180/* Call an ops of a v4l2_subdev, doing the right checks against
181 NULL pointers.
182
183 Example: err = v4l2_subdev_call(sd, core, g_chip_ident, &chip);
184 */
185#define v4l2_subdev_call(sd, o, f, args...) \
186 (!(sd) ? -ENODEV : (((sd) && (sd)->ops->o && (sd)->ops->o->f) ? \
187 (sd)->ops->o->f((sd) , ##args) : -ENOIOCTLCMD))
188
189#endif
diff --git a/sound/i2c/other/tea575x-tuner.c b/sound/i2c/other/tea575x-tuner.c
index c13a178383ba..549b4eba1496 100644
--- a/sound/i2c/other/tea575x-tuner.c
+++ b/sound/i2c/other/tea575x-tuner.c
@@ -18,7 +18,7 @@
18 * along with this program; if not, write to the Free Software 18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 * 20 *
21 */ 21 */
22 22
23#include <asm/io.h> 23#include <asm/io.h>
24#include <linux/delay.h> 24#include <linux/delay.h>
@@ -89,7 +89,7 @@ static int snd_tea575x_ioctl(struct inode *inode, struct file *file,
89{ 89{
90 struct snd_tea575x *tea = video_drvdata(file); 90 struct snd_tea575x *tea = video_drvdata(file);
91 void __user *arg = (void __user *)data; 91 void __user *arg = (void __user *)data;
92 92
93 switch(cmd) { 93 switch(cmd) {
94 case VIDIOCGCAP: 94 case VIDIOCGCAP:
95 { 95 {
@@ -110,9 +110,9 @@ static int snd_tea575x_ioctl(struct inode *inode, struct file *file,
110 case VIDIOCGTUNER: 110 case VIDIOCGTUNER:
111 { 111 {
112 struct video_tuner v; 112 struct video_tuner v;
113 if (copy_from_user(&v, arg,sizeof(v))!=0) 113 if (copy_from_user(&v, arg,sizeof(v))!=0)
114 return -EFAULT; 114 return -EFAULT;
115 if (v.tuner) /* Only 1 tuner */ 115 if (v.tuner) /* Only 1 tuner */
116 return -EINVAL; 116 return -EINVAL;
117 v.rangelow = (87*16000); 117 v.rangelow = (87*16000);
118 v.rangehigh = (108*16000); 118 v.rangehigh = (108*16000);
@@ -144,24 +144,24 @@ static int snd_tea575x_ioctl(struct inode *inode, struct file *file,
144 snd_tea575x_set_freq(tea); 144 snd_tea575x_set_freq(tea);
145 return 0; 145 return 0;
146 case VIDIOCGAUDIO: 146 case VIDIOCGAUDIO:
147 { 147 {
148 struct video_audio v; 148 struct video_audio v;
149 memset(&v, 0, sizeof(v)); 149 memset(&v, 0, sizeof(v));
150 strcpy(v.name, "Radio"); 150 strcpy(v.name, "Radio");
151 if(copy_to_user(arg,&v, sizeof(v))) 151 if(copy_to_user(arg,&v, sizeof(v)))
152 return -EFAULT; 152 return -EFAULT;
153 return 0; 153 return 0;
154 } 154 }
155 case VIDIOCSAUDIO: 155 case VIDIOCSAUDIO:
156 { 156 {
157 struct video_audio v; 157 struct video_audio v;
158 if(copy_from_user(&v, arg, sizeof(v))) 158 if(copy_from_user(&v, arg, sizeof(v)))
159 return -EFAULT; 159 return -EFAULT;
160 if (tea->ops->mute) 160 if (tea->ops->mute)
161 tea->ops->mute(tea, 161 tea->ops->mute(tea,
162 (v.flags & 162 (v.flags &
163 VIDEO_AUDIO_MUTE) ? 1 : 0); 163 VIDEO_AUDIO_MUTE) ? 1 : 0);
164 if(v.audio) 164 if(v.audio)
165 return -EINVAL; 165 return -EINVAL;
166 return 0; 166 return 0;
167 } 167 }
@@ -240,11 +240,11 @@ static int __init alsa_tea575x_module_init(void)
240{ 240{
241 return 0; 241 return 0;
242} 242}
243 243
244static void __exit alsa_tea575x_module_exit(void) 244static void __exit alsa_tea575x_module_exit(void)
245{ 245{
246} 246}
247 247
248module_init(alsa_tea575x_module_init) 248module_init(alsa_tea575x_module_init)
249module_exit(alsa_tea575x_module_exit) 249module_exit(alsa_tea575x_module_exit)
250 250